eternal-timer 1.2.3 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createTimer = createTimer;
7
+ exports.removeTimer = removeTimer;
8
+ exports.checkTimers = checkTimers;
9
+ exports.showTimers = showTimers;
10
+ exports.getRemainingTimer = getRemainingTimer;
11
+ const fs_1 = __importDefault(require("fs"));
12
+ const path_1 = __importDefault(require("path"));
13
+ const searchRoot_js_1 = __importDefault(require("./searchRoot.js"));
14
+ const uuid_1 = require("uuid");
15
+ // search root folder of project
16
+ const rootdir = (0, searchRoot_js_1.default)();
17
+ const timerfiledir = path_1.default.join(rootdir, ".timers");
18
+ /**
19
+ * createFile
20
+ * @description create `.timers` file
21
+ * @returns void
22
+ * @throws If file operation fails
23
+ * @example
24
+ * await createFile();
25
+ */
26
+ async function createFile() {
27
+ if (!fs_1.default.existsSync(timerfiledir)) {
28
+ fs_1.default.writeFile(timerfiledir, "", (data) => {
29
+ console.log("The file was created in ", timerfiledir);
30
+ });
31
+ }
32
+ return;
33
+ }
34
+ /**
35
+ * createTimer
36
+ * @description Creates a new timer.
37
+ * @param length Timer duration in milliseconds
38
+ * @returns Promise that resolves to the timer ID (UUID)
39
+ * @throws If length is invalid(e.g. length < 0) or file operation fails
40
+ * @example
41
+ * const newTimer = await createTimer(5000);
42
+ * // newTimer will be id of the timer
43
+ */
44
+ async function createTimer(length) {
45
+ try {
46
+ await createFile();
47
+ if (length < 0) {
48
+ throw new Error(`Invailed length: ${length}`);
49
+ }
50
+ length = Math.trunc(length);
51
+ // uuid, start, end
52
+ const id = (0, uuid_1.v4)();
53
+ const now = Date.now();
54
+ const newTimerData = `${id} ${now.toString()} ${(now + length).toString()}`;
55
+ await fs_1.default.promises.appendFile(timerfiledir, newTimerData + "\n");
56
+ return id;
57
+ }
58
+ catch (e) {
59
+ throw new Error(`Error when creating timer: ${e}`);
60
+ }
61
+ }
62
+ /**
63
+ * removeTimer
64
+ * @description Removes a timer by ID.
65
+ * @param id ID of the timer to remove
66
+ * @returns void
67
+ * @throws If file operation fails
68
+ * @example
69
+ * await removeTimer(id);
70
+ */
71
+ async function removeTimer(id) {
72
+ try {
73
+ const timersRaw = fs_1.default.readFileSync(timerfiledir, "utf-8");
74
+ const timersData = timersRaw.split(/\r?\n/);
75
+ const filteredTimers = timersData.filter(line => line.split(" ")[0] !== id);
76
+ await fs_1.default.promises.writeFile(timerfiledir, filteredTimers.join("\n"), "utf-8");
77
+ return;
78
+ }
79
+ catch (e) {
80
+ throw new Error(`Error when removing timer: ${e}`);
81
+ }
82
+ }
83
+ /**
84
+ * @description Starts monitoring expired timers asynchronously and returns immediately. The callback is invoked asynchronously when a timer expires.
85
+ * @param callback Function invoked when an expired timer is detected (called asynchronously)
86
+ * @param interval (number, optional): Check interval in milliseconds (default: 50ms)
87
+ * @throws If file operation fails
88
+ * @example
89
+ * checkTimers((timer) => {
90
+ * console.log(`A timer was stopped: ${timer.id}`);
91
+ * });
92
+ */
93
+ async function checkTimers(callback, interval = 50) {
94
+ try {
95
+ await createFile();
96
+ setInterval(() => {
97
+ const timersDataRaw = fs_1.default.readFileSync(timerfiledir, "utf-8");
98
+ const timersData = timersDataRaw.split(/\r?\n/);
99
+ const timersSet = new Set();
100
+ checkTimerfileSyntax(timersDataRaw);
101
+ for (const timerData of timersData) {
102
+ if (!timerData.trim())
103
+ continue;
104
+ const [id, startStr, stopStr] = timerData.split(" ");
105
+ timersSet.add({
106
+ id: id,
107
+ start: startStr,
108
+ stop: stopStr
109
+ });
110
+ }
111
+ const now = Date.now();
112
+ for (const timer of timersSet) {
113
+ if (Number(timer.stop) <= now) {
114
+ removeTimer(timer.id);
115
+ callback(timer);
116
+ }
117
+ }
118
+ }, interval);
119
+ }
120
+ catch (e) {
121
+ throw new Error(`Error when checking alarm: ${e}`);
122
+ }
123
+ }
124
+ /**
125
+ * showTimers
126
+ * @description Retrieves all active timers.
127
+ * @returns Array of `Timer` objects
128
+ * @throws If file operation fails
129
+ * @example
130
+ * const timers = await showTimers();
131
+ * console.log(JSON.stringify(timers))
132
+ */
133
+ async function showTimers() {
134
+ try {
135
+ await createFile();
136
+ const timersRaw = fs_1.default.readFileSync(timerfiledir, "utf-8");
137
+ const timersData = timersRaw.split(/\r?\n/);
138
+ let timersJSON = [];
139
+ for (const timerData of timersData) {
140
+ const splitedTimerData = timerData.split(" ");
141
+ timersJSON.push({
142
+ id: splitedTimerData[0],
143
+ start: splitedTimerData[1],
144
+ stop: splitedTimerData[2]
145
+ });
146
+ }
147
+ return timersJSON;
148
+ }
149
+ catch (e) {
150
+ throw new Error(`Error when showing timers: ${e}`);
151
+ }
152
+ }
153
+ /**
154
+ * getRemainingTimer
155
+ * @description Retrieves the remaining time of a timer by ID.
156
+ * @param id timer's id you want to get remaining time(ms)
157
+ * @returns Remaining time of the timer(ms)
158
+ * @throws If timer with the specified ID is not found or file operation fails
159
+ * @example
160
+ * const remaining: number = await getRemainingTimer(id);
161
+ * console.log(`Remaining time: ${remaining} ms`);
162
+ */
163
+ async function getRemainingTimer(id) {
164
+ try {
165
+ const timersRaw = fs_1.default.readFileSync(timerfiledir, "utf-8");
166
+ const timersData = timersRaw.split(/\r?\n/);
167
+ for (const timerData of timersData) {
168
+ const splitedTimerData = timerData.split(" ");
169
+ if (splitedTimerData[0] === id) {
170
+ const now = Date.now();
171
+ const stop = Number(splitedTimerData[2]);
172
+ return Math.max(0, stop - now);
173
+ }
174
+ }
175
+ throw new Error(`Timer with id ${id} not found`);
176
+ }
177
+ catch (e) {
178
+ throw new Error(`Error when getting remaining timer: ${e}`);
179
+ }
180
+ }
181
+ async function checkTimerfileSyntax(fileData) {
182
+ const throwing = () => {
183
+ throw new Error(`Timer file's syntax is wrong`);
184
+ };
185
+ const timersData = fileData.trim().split('\n');
186
+ for (const timerData of timersData) {
187
+ const timerArray = timerData.split(/\s+/);
188
+ if (timerArray.length !== 3)
189
+ throwing();
190
+ if (timerArray[0]?.length !== 36)
191
+ throwing();
192
+ if (timerArray[1].trim() === "")
193
+ throwing();
194
+ if (timerArray[2].trim() === "")
195
+ throwing();
196
+ }
197
+ return;
198
+ }
199
+ //# sourceMappingURL=index.js.map
@@ -45,4 +45,15 @@ export declare function checkTimers(callback: (timer: Timer) => void, interval?:
45
45
  * console.log(JSON.stringify(timers))
46
46
  */
47
47
  export declare function showTimers(): Promise<Timer[]>;
48
+ /**
49
+ * getRemainingTimer
50
+ * @description Retrieves the remaining time of a timer by ID.
51
+ * @param id timer's id you want to get remaining time(ms)
52
+ * @returns Remaining time of the timer(ms)
53
+ * @throws If timer with the specified ID is not found or file operation fails
54
+ * @example
55
+ * const remaining: number = await getRemainingTimer(id);
56
+ * console.log(`Remaining time: ${remaining} ms`);
57
+ */
58
+ export declare function getRemainingTimer(id: string): Promise<number>;
48
59
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,KAAK,GAAG;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAA;CACf,CAAA;AAuBD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBjE;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAY3D;AAED;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EAAE,QAAQ,GAAE,MAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCxG;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAmBnD;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBnE"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchRoot.d.ts","sourceRoot":"","sources":["../../src/searchRoot.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,WAQjC"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = searchRoot;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ /**
10
+ * searchRoot
11
+ * @description searching root directly of the project
12
+ * @returns directly of the project(string)
13
+ */
14
+ function searchRoot() {
15
+ let dir = process.cwd();
16
+ while (!fs_1.default.existsSync(path_1.default.join(dir, "package.json"))) {
17
+ const parent = path_1.default.dirname(dir);
18
+ if (parent === dir)
19
+ break;
20
+ dir = parent;
21
+ }
22
+ return dir;
23
+ }
24
+ //# sourceMappingURL=searchRoot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchRoot.js","sourceRoot":"","sources":["../../src/searchRoot.ts"],"names":[],"mappings":";;;;;AAQA,6BAQC;AAhBD,4CAAoB;AACpB,gDAAwB;AAExB;;;;GAIG;AACH,SAAwB,UAAU;IAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACxB,OAAO,CAAC,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,cAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QACtB,GAAG,GAAG,MAAM,CAAC;IACrB,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC"}
@@ -0,0 +1,59 @@
1
+ export type Timer = {
2
+ id: string;
3
+ start: string;
4
+ stop: string;
5
+ };
6
+ /**
7
+ * createTimer
8
+ * @description Creates a new timer.
9
+ * @param length Timer duration in milliseconds
10
+ * @returns Promise that resolves to the timer ID (UUID)
11
+ * @throws If length is invalid(e.g. length < 0) or file operation fails
12
+ * @example
13
+ * const newTimer = await createTimer(5000);
14
+ * // newTimer will be id of the timer
15
+ */
16
+ export declare function createTimer(length: number): Promise<string>;
17
+ /**
18
+ * removeTimer
19
+ * @description Removes a timer by ID.
20
+ * @param id ID of the timer to remove
21
+ * @returns void
22
+ * @throws If file operation fails
23
+ * @example
24
+ * await removeTimer(id);
25
+ */
26
+ export declare function removeTimer(id: string): Promise<void>;
27
+ /**
28
+ * @description Starts monitoring expired timers asynchronously and returns immediately. The callback is invoked asynchronously when a timer expires.
29
+ * @param callback Function invoked when an expired timer is detected (called asynchronously)
30
+ * @param interval (number, optional): Check interval in milliseconds (default: 50ms)
31
+ * @throws If file operation fails
32
+ * @example
33
+ * checkTimers((timer) => {
34
+ * console.log(`A timer was stopped: ${timer.id}`);
35
+ * });
36
+ */
37
+ export declare function checkTimers(callback: (timer: Timer) => void, interval?: number): Promise<void>;
38
+ /**
39
+ * showTimers
40
+ * @description Retrieves all active timers.
41
+ * @returns Array of `Timer` objects
42
+ * @throws If file operation fails
43
+ * @example
44
+ * const timers = await showTimers();
45
+ * console.log(JSON.stringify(timers))
46
+ */
47
+ export declare function showTimers(): Promise<Timer[]>;
48
+ /**
49
+ * getRemainingTimer
50
+ * @description Retrieves the remaining time of a timer by ID.
51
+ * @param id timer's id you want to get remaining time(ms)
52
+ * @returns Remaining time of the timer(ms)
53
+ * @throws If timer with the specified ID is not found or file operation fails
54
+ * @example
55
+ * const remaining: number = await getRemainingTimer(id);
56
+ * console.log(`Remaining time: ${remaining} ms`);
57
+ */
58
+ export declare function getRemainingTimer(id: string): Promise<number>;
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,KAAK,GAAG;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAA;CACf,CAAA;AAuBD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBjE;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAY3D;AAED;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EAAE,QAAQ,GAAE,MAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCxG;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAmBnD;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBnE"}
@@ -140,6 +140,34 @@ export async function showTimers() {
140
140
  throw new Error(`Error when showing timers: ${e}`);
141
141
  }
142
142
  }
143
+ /**
144
+ * getRemainingTimer
145
+ * @description Retrieves the remaining time of a timer by ID.
146
+ * @param id timer's id you want to get remaining time(ms)
147
+ * @returns Remaining time of the timer(ms)
148
+ * @throws If timer with the specified ID is not found or file operation fails
149
+ * @example
150
+ * const remaining: number = await getRemainingTimer(id);
151
+ * console.log(`Remaining time: ${remaining} ms`);
152
+ */
153
+ export async function getRemainingTimer(id) {
154
+ try {
155
+ const timersRaw = fs.readFileSync(timerfiledir, "utf-8");
156
+ const timersData = timersRaw.split(/\r?\n/);
157
+ for (const timerData of timersData) {
158
+ const splitedTimerData = timerData.split(" ");
159
+ if (splitedTimerData[0] === id) {
160
+ const now = Date.now();
161
+ const stop = Number(splitedTimerData[2]);
162
+ return Math.max(0, stop - now);
163
+ }
164
+ }
165
+ throw new Error(`Timer with id ${id} not found`);
166
+ }
167
+ catch (e) {
168
+ throw new Error(`Error when getting remaining timer: ${e}`);
169
+ }
170
+ }
143
171
  async function checkTimerfileSyntax(fileData) {
144
172
  const throwing = () => {
145
173
  throw new Error(`Timer file's syntax is wrong`);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * searchRoot
3
+ * @description searching root directly of the project
4
+ * @returns directly of the project(string)
5
+ */
6
+ export default function searchRoot(): string;
7
+ //# sourceMappingURL=searchRoot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchRoot.d.ts","sourceRoot":"","sources":["../../src/searchRoot.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,WAQjC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchRoot.js","sourceRoot":"","sources":["../../src/searchRoot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU;IAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QACtB,GAAG,GAAG,MAAM,CAAC;IACrB,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC"}
package/package.json CHANGED
@@ -1,12 +1,10 @@
1
1
  {
2
2
  "name": "eternal-timer",
3
- "version": "1.2.3",
3
+ "version": "1.4.0",
4
4
  "description": "timer for node.js package",
5
- "main": "dist/index.js",
6
5
  "scripts": {
7
6
  "dev": "nodemon --watch src --exec ts-node src/index.ts",
8
- "build": "tsc",
9
- "start": "node dist/index.js"
7
+ "build": "tsc -p tsconfig.esm.json && tsc -p tsconfig.cjs.json && node scripts/rename-cjs.js"
10
8
  },
11
9
  "repository": {
12
10
  "type": "git",
@@ -26,9 +24,16 @@
26
24
  "ts-node": "^10.9.2",
27
25
  "typescript": "^5.9.3"
28
26
  },
29
- "types": "dist/index.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "import": "./dist/esm/index.js",
30
+ "require": "./dist/cjs/index.cjs",
31
+ "types": "./dist/esm/index.d.ts"
32
+ }
33
+ },
34
+ "types": "dist/esm/index.d.ts",
30
35
  "dependencies": {
31
36
  "uuid": "^13.0.0"
32
37
  },
33
- "files": [ "dist" ]
38
+ "files": [ "dist", "src" ]
34
39
  }
package/src/index.ts ADDED
@@ -0,0 +1,202 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import searchRoot from "./searchRoot.js";
4
+ import { v4 as uuidv4 } from "uuid";
5
+
6
+ export type Timer = {
7
+ id: string,
8
+ start: string,
9
+ stop: string
10
+ }
11
+
12
+ // search root folder of project
13
+ const rootdir = searchRoot();
14
+ const timerfiledir = path.join(rootdir, ".timers");
15
+
16
+ /**
17
+ * createFile
18
+ * @description create `.timers` file
19
+ * @returns void
20
+ * @throws If file operation fails
21
+ * @example
22
+ * await createFile();
23
+ */
24
+ async function createFile(): Promise<void> {
25
+ if (!fs.existsSync(timerfiledir)) {
26
+ fs.writeFile(timerfiledir, "", (data) => {
27
+ console.log("The file was created in ", timerfiledir);
28
+ });
29
+ }
30
+ return;
31
+ }
32
+
33
+ /**
34
+ * createTimer
35
+ * @description Creates a new timer.
36
+ * @param length Timer duration in milliseconds
37
+ * @returns Promise that resolves to the timer ID (UUID)
38
+ * @throws If length is invalid(e.g. length < 0) or file operation fails
39
+ * @example
40
+ * const newTimer = await createTimer(5000);
41
+ * // newTimer will be id of the timer
42
+ */
43
+ export async function createTimer(length: number): Promise<string> {
44
+ try {
45
+ await createFile();
46
+
47
+ if (length < 0) {
48
+ throw new Error(`Invailed length: ${length}`);
49
+ }
50
+
51
+ length = Math.trunc(length);
52
+
53
+ // uuid, start, end
54
+ const id = uuidv4();
55
+ const now = Date.now();
56
+ const newTimerData = `${id} ${now.toString()} ${(now + length).toString()}`;
57
+ await fs.promises.appendFile(timerfiledir, newTimerData + "\n");
58
+ return id;
59
+ } catch (e) {
60
+ throw new Error(`Error when creating timer: ${e}`);
61
+ }
62
+ }
63
+
64
+ /**
65
+ * removeTimer
66
+ * @description Removes a timer by ID.
67
+ * @param id ID of the timer to remove
68
+ * @returns void
69
+ * @throws If file operation fails
70
+ * @example
71
+ * await removeTimer(id);
72
+ */
73
+ export async function removeTimer(id: string): Promise<void> {
74
+ try {
75
+ const timersRaw: string = fs.readFileSync(timerfiledir, "utf-8");
76
+ const timersData: string[] = timersRaw.split(/\r?\n/);
77
+
78
+ const filteredTimers = timersData.filter(line => line.split(" ")[0] !== id);
79
+
80
+ await fs.promises.writeFile(timerfiledir, filteredTimers.join("\n"), "utf-8");
81
+ return;
82
+ } catch (e) {
83
+ throw new Error(`Error when removing timer: ${e}`);
84
+ }
85
+ }
86
+
87
+ /**
88
+ * @description Starts monitoring expired timers asynchronously and returns immediately. The callback is invoked asynchronously when a timer expires.
89
+ * @param callback Function invoked when an expired timer is detected (called asynchronously)
90
+ * @param interval (number, optional): Check interval in milliseconds (default: 50ms)
91
+ * @throws If file operation fails
92
+ * @example
93
+ * checkTimers((timer) => {
94
+ * console.log(`A timer was stopped: ${timer.id}`);
95
+ * });
96
+ */
97
+ export async function checkTimers(callback: (timer: Timer) => void, interval: number = 50): Promise<void> {
98
+ try {
99
+ await createFile();
100
+
101
+ setInterval(() => {
102
+ const timersDataRaw: string = fs.readFileSync(timerfiledir, "utf-8");
103
+ const timersData: string[] = timersDataRaw.split(/\r?\n/);
104
+ const timersSet = new Set<Timer>();
105
+ checkTimerfileSyntax(timersDataRaw);
106
+
107
+ for (const timerData of timersData) {
108
+ if (!timerData.trim()) continue;
109
+ const [id, startStr, stopStr] = timerData.split(" ");
110
+ timersSet.add({
111
+ id: id!,
112
+ start: startStr!,
113
+ stop: stopStr!
114
+ });
115
+ }
116
+
117
+ const now = Date.now();
118
+ for (const timer of timersSet) {
119
+ if (Number(timer.stop) <= now) {
120
+ removeTimer(timer.id);
121
+ callback(timer);
122
+ }
123
+ }
124
+
125
+ }, interval);
126
+ } catch (e) {
127
+ throw new Error(`Error when checking alarm: ${e}`);
128
+ }
129
+ }
130
+
131
+ /**
132
+ * showTimers
133
+ * @description Retrieves all active timers.
134
+ * @returns Array of `Timer` objects
135
+ * @throws If file operation fails
136
+ * @example
137
+ * const timers = await showTimers();
138
+ * console.log(JSON.stringify(timers))
139
+ */
140
+ export async function showTimers(): Promise<Timer[]> {
141
+ try {
142
+ await createFile();
143
+ const timersRaw: string = fs.readFileSync(timerfiledir, "utf-8");
144
+ const timersData: string[] = timersRaw.split(/\r?\n/);
145
+
146
+ let timersJSON: Timer[] = [];
147
+ for (const timerData of timersData) {
148
+ const splitedTimerData = timerData.split(" ")
149
+ timersJSON.push({
150
+ id: splitedTimerData[0]!,
151
+ start: splitedTimerData[1]!,
152
+ stop: splitedTimerData[2]!
153
+ })
154
+ }
155
+ return timersJSON;
156
+ } catch (e) {
157
+ throw new Error(`Error when showing timers: ${e}`)
158
+ }
159
+ }
160
+
161
+ /**
162
+ * getRemainingTimer
163
+ * @description Retrieves the remaining time of a timer by ID.
164
+ * @param id timer's id you want to get remaining time(ms)
165
+ * @returns Remaining time of the timer(ms)
166
+ * @throws If timer with the specified ID is not found or file operation fails
167
+ * @example
168
+ * const remaining: number = await getRemainingTimer(id);
169
+ * console.log(`Remaining time: ${remaining} ms`);
170
+ */
171
+ export async function getRemainingTimer(id: string): Promise<number> {
172
+ try {
173
+ const timersRaw: string = fs.readFileSync(timerfiledir, "utf-8");
174
+ const timersData: string[] = timersRaw.split(/\r?\n/);
175
+ for (const timerData of timersData) {
176
+ const splitedTimerData = timerData.split(" ")
177
+ if (splitedTimerData[0] === id) {
178
+ const now = Date.now();
179
+ const stop = Number(splitedTimerData[2]);
180
+ return Math.max(0, stop - now);
181
+ }
182
+ }
183
+ throw new Error(`Timer with id ${id} not found`);
184
+ } catch (e) {
185
+ throw new Error(`Error when getting remaining timer: ${e}`);
186
+ }
187
+ }
188
+
189
+ async function checkTimerfileSyntax(fileData: string): Promise<void> {
190
+ const throwing = () => {
191
+ throw new Error(`Timer file's syntax is wrong`);
192
+ };
193
+ const timersData: string[] = fileData.trim().split('\n');
194
+ for (const timerData of timersData) {
195
+ const timerArray: string[] = timerData.split(/\s+/);
196
+ if (timerArray.length !== 3) throwing();
197
+ if (timerArray[0]?.length !== 36) throwing();
198
+ if (timerArray[1]!.trim() === "") throwing();
199
+ if (timerArray[2]!.trim() === "") throwing();
200
+ }
201
+ return;
202
+ }
@@ -0,0 +1,17 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+
4
+ /**
5
+ * searchRoot
6
+ * @description searching root directly of the project
7
+ * @returns directly of the project(string)
8
+ */
9
+ export default function searchRoot() {
10
+ let dir = process.cwd();
11
+ while (!fs.existsSync(path.join(dir, "package.json"))) {
12
+ const parent = path.dirname(dir);
13
+ if (parent === dir) break;
14
+ dir = parent;
15
+ }
16
+ return dir;
17
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,KAAK,GAAG;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAA;CACf,CAAA;AAuBD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBjE;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAY3D;AAED;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EAAE,QAAQ,GAAE,MAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCxG;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAmBnD"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,UAAU,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAQpC,gCAAgC;AAChC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;AAC7B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAEnD;;;;;;;GAOG;AACH,KAAK,UAAU,UAAU;IACrB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;YACpC,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,YAAY,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;IACP,CAAC;IACD,OAAO;AACX,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc;IAC5C,IAAI,CAAC;QACD,MAAM,UAAU,EAAE,CAAC;QAEnB,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,EAAE,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAE5B,mBAAmB;QACnB,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,YAAY,GAAG,GAAG,EAAE,IAAI,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC5E,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC,CAAC;QAChE,OAAO,EAAE,CAAC;IACd,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAU;IACxC,IAAI,CAAC;QACD,MAAM,SAAS,GAAW,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACjE,MAAM,UAAU,GAAa,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEtD,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAE5E,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QAC9E,OAAO;IACX,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgC,EAAE,WAAmB,EAAE;IACrF,IAAI,CAAC;QACD,MAAM,UAAU,EAAE,CAAC;QAEnB,WAAW,CAAC,GAAG,EAAE;YACb,MAAM,aAAa,GAAW,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACrE,MAAM,UAAU,GAAa,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC1D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAS,CAAC;YACnC,oBAAoB,CAAC,aAAa,CAAC,CAAC;YAEpC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gBACjC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;oBAAE,SAAS;gBAChC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACrD,SAAS,CAAC,GAAG,CAAC;oBACV,EAAE,EAAE,EAAG;oBACP,KAAK,EAAE,QAAS;oBAChB,IAAI,EAAE,OAAQ;iBACjB,CAAC,CAAC;YACP,CAAC;YAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;gBAC5B,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;oBAC5B,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;oBACtB,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACpB,CAAC;YACL,CAAC;QAEL,CAAC,EAAE,QAAQ,CAAC,CAAC;IACjB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC5B,IAAI,CAAC;QACD,MAAM,UAAU,EAAE,CAAC;QACnB,MAAM,SAAS,GAAW,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACjE,MAAM,UAAU,GAAa,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEtD,IAAI,UAAU,GAAY,EAAE,CAAC;QAC7B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACjC,MAAM,gBAAgB,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC7C,UAAU,CAAC,IAAI,CAAC;gBACZ,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAE;gBACxB,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAE;gBAC3B,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAE;aAC7B,CAAC,CAAA;QACN,CAAC;QACD,OAAO,UAAU,CAAC;IACtB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAA;IACtD,CAAC;AACL,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,QAAgB;IAChD,MAAM,QAAQ,GAAG,GAAG,EAAE;QAClB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACpD,CAAC,CAAC;IACF,MAAM,UAAU,GAAa,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACzD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACjC,MAAM,UAAU,GAAa,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACpD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,QAAQ,EAAE,CAAC;QACxC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,EAAE;YAAE,QAAQ,EAAE,CAAC;QAC7C,IAAI,UAAU,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,QAAQ,EAAE,CAAC;QAC7C,IAAI,UAAU,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,QAAQ,EAAE,CAAC;IACjD,CAAC;IACD,OAAO;AACX,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"searchRoot.d.ts","sourceRoot":"","sources":["../src/searchRoot.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,WAQjC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"searchRoot.js","sourceRoot":"","sources":["../src/searchRoot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU;IAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QACtB,GAAG,GAAG,MAAM,CAAC;IACrB,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC"}
File without changes
File without changes