eternal-timer 2.5.1 → 4.0.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.
Files changed (66) hide show
  1. package/README.md +189 -50
  2. package/dist/cjs/EventEmitter.d.ts +12 -0
  3. package/dist/cjs/EventEmitter.d.ts.map +1 -0
  4. package/dist/cjs/EventEmitter.js +50 -0
  5. package/dist/cjs/EventEmitter.js.map +1 -0
  6. package/dist/cjs/TimersManager/JSONLTimersManager.d.ts +17 -5
  7. package/dist/cjs/TimersManager/JSONLTimersManager.d.ts.map +1 -1
  8. package/dist/cjs/TimersManager/JSONLTimersManager.js +19 -21
  9. package/dist/cjs/TimersManager/JSONLTimersManager.js.map +1 -1
  10. package/dist/cjs/TimersManager/PlainTextTimersManager.d.ts +2 -1
  11. package/dist/cjs/TimersManager/PlainTextTimersManager.d.ts.map +1 -1
  12. package/dist/cjs/TimersManager/PlainTextTimersManager.js +1 -0
  13. package/dist/cjs/TimersManager/PlainTextTimersManager.js.map +1 -1
  14. package/dist/cjs/TimersManager/TimersManager.d.ts +39 -37
  15. package/dist/cjs/TimersManager/TimersManager.d.ts.map +1 -1
  16. package/dist/cjs/TimersManager/TimersManager.js +62 -55
  17. package/dist/cjs/TimersManager/TimersManager.js.map +1 -1
  18. package/dist/cjs/TimersStore/JSONLTimersStore.d.ts +4 -4
  19. package/dist/cjs/TimersStore/JSONLTimersStore.d.ts.map +1 -1
  20. package/dist/cjs/TimersStore/JSONLTimersStore.js +5 -3
  21. package/dist/cjs/TimersStore/JSONLTimersStore.js.map +1 -1
  22. package/dist/cjs/TimersStore/PlainTextTimersStore.d.ts +4 -4
  23. package/dist/cjs/TimersStore/PlainTextTimersStore.d.ts.map +1 -1
  24. package/dist/cjs/TimersStore/PlainTextTimersStore.js.map +1 -1
  25. package/dist/cjs/TimersStore/TimersStore.d.ts +7 -7
  26. package/dist/cjs/TimersStore/TimersStore.d.ts.map +1 -1
  27. package/dist/cjs/TimersStore/TimersStore.js.map +1 -1
  28. package/dist/cjs/types.d.ts +19 -7
  29. package/dist/cjs/types.d.ts.map +1 -1
  30. package/dist/esm/EventEmitter.d.ts +12 -0
  31. package/dist/esm/EventEmitter.d.ts.map +1 -0
  32. package/dist/esm/EventEmitter.js +46 -0
  33. package/dist/esm/EventEmitter.js.map +1 -0
  34. package/dist/esm/TimersManager/JSONLTimersManager.d.ts +17 -5
  35. package/dist/esm/TimersManager/JSONLTimersManager.d.ts.map +1 -1
  36. package/dist/esm/TimersManager/JSONLTimersManager.js +19 -21
  37. package/dist/esm/TimersManager/JSONLTimersManager.js.map +1 -1
  38. package/dist/esm/TimersManager/PlainTextTimersManager.d.ts +2 -1
  39. package/dist/esm/TimersManager/PlainTextTimersManager.d.ts.map +1 -1
  40. package/dist/esm/TimersManager/PlainTextTimersManager.js +1 -0
  41. package/dist/esm/TimersManager/PlainTextTimersManager.js.map +1 -1
  42. package/dist/esm/TimersManager/TimersManager.d.ts +39 -37
  43. package/dist/esm/TimersManager/TimersManager.d.ts.map +1 -1
  44. package/dist/esm/TimersManager/TimersManager.js +62 -55
  45. package/dist/esm/TimersManager/TimersManager.js.map +1 -1
  46. package/dist/esm/TimersStore/JSONLTimersStore.d.ts +4 -4
  47. package/dist/esm/TimersStore/JSONLTimersStore.d.ts.map +1 -1
  48. package/dist/esm/TimersStore/JSONLTimersStore.js +5 -3
  49. package/dist/esm/TimersStore/JSONLTimersStore.js.map +1 -1
  50. package/dist/esm/TimersStore/PlainTextTimersStore.d.ts +4 -4
  51. package/dist/esm/TimersStore/PlainTextTimersStore.d.ts.map +1 -1
  52. package/dist/esm/TimersStore/PlainTextTimersStore.js.map +1 -1
  53. package/dist/esm/TimersStore/TimersStore.d.ts +7 -7
  54. package/dist/esm/TimersStore/TimersStore.d.ts.map +1 -1
  55. package/dist/esm/TimersStore/TimersStore.js.map +1 -1
  56. package/dist/esm/types.d.ts +19 -7
  57. package/dist/esm/types.d.ts.map +1 -1
  58. package/package.json +2 -5
  59. package/dist/cjs/Log.d.ts +0 -8
  60. package/dist/cjs/Log.d.ts.map +0 -1
  61. package/dist/cjs/Log.js +0 -61
  62. package/dist/cjs/Log.js.map +0 -1
  63. package/dist/esm/Log.d.ts +0 -8
  64. package/dist/esm/Log.d.ts.map +0 -1
  65. package/dist/esm/Log.js +0 -24
  66. package/dist/esm/Log.js.map +0 -1
package/README.md CHANGED
@@ -8,7 +8,7 @@ A simple and persistent timer library for Node.js. Timers are saved to a file an
8
8
 
9
9
  ## Features
10
10
 
11
- - **Monitor Timers (asynchronous)**: Start monitoring expired timers asynchronously; the function returns immediately and the callback is called when timers expire.
11
+ - **Monitor Timers (event-driven)**: Start monitoring expired timers and react to events like `expired`, `started`, `stopped`, and `updated` through an event system.
12
12
  - **Persistence**: Save timer data to a file that persists across process restarts
13
13
  - **Choice of Format**: Choose between JSON Lines for rich data or plain text for lightweight storage.
14
14
 
@@ -24,7 +24,7 @@ You can choose between two manager classes depending on the desired storage form
24
24
 
25
25
  ### `JSONLTimersManager` (JSON Lines)
26
26
 
27
- Use this manager to store timers in a `.jsonl` file, which allows for storing `title` and `description`.
27
+ Use this manager to store timers in a `.jsonl` file, which allows for storing `extra` data.
28
28
 
29
29
  ```javascript
30
30
  import { JSONLTimersManager } from 'eternal-timer';
@@ -34,12 +34,15 @@ async function main() {
34
34
  const manager = new JSONLTimersManager();
35
35
 
36
36
  // Create a timer (5 seconds) with a title and description
37
- const timerId = await manager.createTimer({length: 5000, title: 'My Timer', description: 'This is a test timer.'});
37
+ const timerId = await manager.createTimer({length: 5000, extra: { title: 'My Timer', description: 'This is a test timer.' }});
38
38
  console.log('Timer created:', timerId);
39
39
 
40
- // Monitor timers (executes when timer expires)
41
- const interval = await manager.checkTimers(async (timer) => {
42
- console.log('Timer expired:', timer.id, timer.title);
40
+ // Start monitoring for expired timers
41
+ const interval = await manager.checkStart();
42
+
43
+ // Listen for 'expired' events
44
+ manager.on('expired', (timer) => {
45
+ console.log('Timer expired:', timer.id, timer.extra?.title);
43
46
  });
44
47
 
45
48
  // Display all timers
@@ -71,8 +74,11 @@ async function main() {
71
74
  const timerId = await manager.createTimer(5000);
72
75
  console.log('Timer created:', timerId);
73
76
 
74
- // Monitor timers
75
- const interval = await manager.checkTimers(async (timer) => {
77
+ // Start monitoring for expired timers
78
+ const interval = await manager.checkStart();
79
+
80
+ // Listen for 'expired' events
81
+ manager.on('expired', (timer) => {
76
82
  console.log('Timer expired:', timer.id);
77
83
  });
78
84
 
@@ -83,7 +89,7 @@ async function main() {
83
89
  // Stop monitoring after a while
84
90
  setTimeout(() => {
85
91
  clearInterval(interval);
86
- console.log('Stopped monitoring timers.');
92
+ console.log('Stopped monitoring for timers.');
87
93
  }, 10000);
88
94
  }
89
95
 
@@ -99,25 +105,57 @@ Creates a manager for timers stored in **JSON Lines** format.
99
105
 
100
106
  - **`timerfiledir`** (optional, string): Path to the timer file. Defaults to `.timers.jsonl` in the project root.
101
107
 
102
- #### `changeTitle(id: string, newTitle: string): Promise<void>`
103
- Changes the title of an existing timer.
108
+ #### `changeExtra(id: string, newExtra: Extra): Promise<void>`
109
+ Changes the `extra` data of an existing timer.
104
110
 
105
111
  - **`id`**: The ID of the timer to modify.
106
- - **`newTitle`**: The new title for the timer.
112
+ - **`newExtra`**: The new `extra` object for the timer.
107
113
 
108
- **Returns:** A `Promise<void>` that resolves when the timer's title has been updated.
114
+ **Returns:** A `Promise<void>` that resolves when the timer's `extra` data has been updated.
109
115
 
110
116
  **Throws:** An error if: the timer with the specified ID is not found, or a file operation fails.
111
117
 
112
- #### `changeDescription(id: string, newDescription: string): Promise<void>`
113
- Changes the description of an existing timer.
118
+ #### Using the `Extra` Type Parameter
114
119
 
115
- - **`id`**: The ID of the timer to modify.
116
- - **`newDescription`**: The new description for the timer.
120
+ The `JSONLTimersManager` is a generic class that accepts a type parameter `Extra`. This allows you to define the structure of the `extra` object that will be stored with your timers. By default, `Extra` is an empty object `{}`.
117
121
 
118
- **Returns:** A `Promise<void>` that resolves when the timer's description has been updated.
122
+ **Example:** Defining and using a custom `Extra` type
119
123
 
120
- **Throws:** An error if: the timer with the specified ID is not found, or a file operation fails.
124
+ ```typescript
125
+ import { JSONLTimersManager } from 'eternal-timer';
126
+
127
+ interface MyTimerExtra {
128
+ title?: string;
129
+ description?: string;
130
+ category?: string;
131
+ }
132
+
133
+ async function main() {
134
+ // Specify MyTimerExtra as the type argument for JSONLTimersManager
135
+ const manager = new JSONLTimersManager<MyTimerExtra>();
136
+
137
+ // Create a timer with custom extra data
138
+ const timerId = await manager.createTimer({
139
+ length: 10000,
140
+ extra: {
141
+ title: 'Project Alpha Deadline',
142
+ description: 'Final submission for project Alpha.',
143
+ category: 'Work'
144
+ }
145
+ });
146
+ console.log('Timer created:', timerId);
147
+
148
+ // Retrieve and access the custom extra data
149
+ const timers = await manager.showTimers();
150
+ const myTimer = timers.find(t => t.id === timerId);
151
+ if (myTimer) {
152
+ console.log('Timer title:', myTimer.extra?.title);
153
+ console.log('Timer category:', myTimer.extra?.category);
154
+ }
155
+ }
156
+
157
+ main();
158
+ ```
121
159
 
122
160
  ### `PlainTextTimersManager`
123
161
 
@@ -128,30 +166,55 @@ Creates a manager for timers stored in **plain-text** format.
128
166
 
129
167
  ---
130
168
 
131
- ### `createTimer(options: CreateTimerOptions<T>): Promise<string>`
169
+ ### `createTimer(options: CreateTimerOptions<T, Extra>): Promise<string>`
132
170
 
133
171
  Creates a new timer and saves it to the file.
134
172
 
135
173
  #### Parameters
136
174
 
137
- - **`options`**
175
+ - **`options`** (`CreateTimerOptions<T, Extra>`)
176
+ - When using `PlainTextTimersManager` (type `PlainText`):
177
+ - `number` — The timer's duration in milliseconds.
178
+ - When using `JSONLTimersManager` (type `JSONL`):
179
+ - `{ length: number; extra?: Extra }`
180
+ - `length` (number): The timer's duration in milliseconds.
181
+ - `extra` (optional, `Extra` object): An object containing arbitrary user-defined metadata for the timer.
138
182
 
139
- When using `"PlainText"` storage:
140
- - `number` — Timer duration in milliseconds.
183
+ **Returns** A `Promise<string>` that resolves to the timer's unique ID (UUID).
141
184
 
142
- When using `"JSONL"` storage:
143
- - `{ length: number; title?: string; description?: string }`
144
- - `length` (number): Timer duration in milliseconds.
145
- - `title` (optional, string): A title for the timer.
146
- - `description` (optional, string): A description for the timer.
185
+ **Throws** An error if: `length` is invalid (e.g., negative) or a file operation fails.
147
186
 
148
- - `number` — Timer duration in milliseconds.
149
- ⚠ Not recommended. See [Storage Formats](#storage-formats).
187
+ **Examples:**
150
188
 
151
- **Returns** A `Promise<string>` that resolves to the timer's unique ID (UUID).
189
+ ```javascript
190
+ // For PlainTextTimersManager with a custom Extra type
191
+ import { PlainTextTimersManager } from 'eternal-timer';
192
+
193
+ // For PlainTextTimersManager
194
+ const manager = new PlainTextTimersManager();
195
+ const newTimerId = await manager.createTimer(5000); // Create a 5-second timer
196
+ console.log('Created PlainText timer with ID:', newTimerId);
197
+ ```
152
198
 
153
- **Throws** An error if: `length` is invalid (e.g., negative) or a file operation fails
199
+ ```typescript
200
+ // For JSONLTimersManager with a custom Extra type
201
+ import { JSONLTimersManager } from 'eternal-timer';
202
+
203
+ interface MyCustomExtra {
204
+ purpose: string;
205
+ userId: string;
206
+ }
154
207
 
208
+ const jsonlManager = new JSONLTimersManager<MyCustomExtra>();
209
+ const jsonlTimerId = await jsonlManager.createTimer({
210
+ length: 10000, // 10 seconds
211
+ extra: {
212
+ purpose: "Session Timeout",
213
+ userId: "user-123"
214
+ }
215
+ });
216
+ console.log('Created JSONL timer with ID:', jsonlTimerId);
217
+ ```
155
218
  ### `removeTimer(id: string): Promise<void>`
156
219
 
157
220
  Removes a timer by its ID.
@@ -162,22 +225,61 @@ Removes a timer by its ID.
162
225
 
163
226
  **Throws:** An error if the timer with the specified ID is not found or if a file operation fails.
164
227
 
165
- ### `checkTimers(callback: (timer: Timer) => void | Promise<void>, interval?: number): Promise<NodeJS.Timeout>`
228
+ ### `checkStart(interval?: number): Promise<NodeJS.Timeout>`
229
+
230
+ Starts the timer checking loop. This method should be called once after creating an instance of a `TimersManager` to begin detecting expired timers. Events like `expired`, `errored`, `started`, `stopped`, and `updated` are emitted, which can be listened to using the `on` method.
231
+
232
+ - **`interval`** (optional, number): Polling interval in milliseconds (default: 200ms)
233
+
234
+ **Returns:** The interval ID which can be used to stop the loop with `clearInterval()`.
235
+
236
+ **Throws:** If file operation fails during checking.
237
+
238
+ ### `on<K extends keyof TimerEvents<T, Extra>>(event: K, listener: (payload: TimerEvents<T, Extra>[K]) => void | Promise<void>): void`
239
+
240
+ Registers an event listener for a specific timer event.
241
+
242
+ - **`event`**: The name of the event to listen for (e.g., `'expired'`, `'started'`, `'stopped'`, `'updated'`, `'errored'`).
243
+ - **`listener`**: The callback function to execute when the event is emitted. It receives the event payload as an argument.
244
+
245
+ **Returns:** `void`
246
+
247
+ **Example:**
248
+ ```javascript
249
+ manager.on('expired', (timer) => {
250
+ console.log(`Timer ${timer.id} expired!`);
251
+ });
252
+
253
+ manager.on('errored', (error) => {
254
+ console.error('Timer event error:', error);
255
+ });
256
+ ```
257
+
258
+ ### `once<K extends keyof TimerEvents<T, Extra>>(event: K, listener: (payload: TimerEvents<T, Extra>[K]) => void | Promise<void>): void`
259
+
260
+ Registers a one-time event listener for a specific timer event. The listener will be invoked only once for the specified event, after which it will be automatically removed.
166
261
 
167
- Starts monitoring timers at the specified interval and invokes the provided
168
- `callback` when a timer expires.
262
+ - **`event`**: The name of the event to listen for.
263
+ - **`listener`**: The callback function to execute when the event is emitted.
169
264
 
170
- For each expired timer, the `callback` is awaited before processing continues.
171
- Monitoring runs periodically in the background and can be stopped using the
172
- returned `NodeJS.Timeout`.
265
+ **Returns:** `void`
173
266
 
174
- - **callback**: An async function invoked with the expired `timer`.
175
- - **interval** *(optional, number)*: Interval in milliseconds for checking timers.
176
- Defaults to `200`.
267
+ ### `off<K extends keyof TimerEvents<T, Extra>>(event: K, listener: (payload: TimerEvents<T, Extra>[K]) => void | Promise<void>): void`
177
268
 
178
- **Returns:** A `NodeJS.Timeout` that can be passed to `clearInterval()` to stop monitoring.
269
+ Removes a specific event listener for a given event.
179
270
 
180
- **Throws:** An error if a timer storage operation fails.
271
+ - **`event`**: The name of the event from which to remove the listener.
272
+ - **`listener`**: The listener function to remove.
273
+
274
+ **Returns:** `void`
275
+
276
+ ### `offAll<K extends keyof TimerEvents<T, Extra>>(event: K): void`
277
+
278
+ Removes all event listeners for a specific event.
279
+
280
+ - **`event`**: The name of the event for which to remove all listeners.
281
+
282
+ **Returns:** `void`
181
283
 
182
284
  ### `showTimers(): Promise<Timer[]>`
183
285
 
@@ -198,6 +300,13 @@ Adjusts the remaining time of a specified timer. This can be used to extend or s
198
300
 
199
301
  **Throws:** An error if: the timer with the specified ID is not found, the resulting remaining time would be negative, or a file operation fails.
200
302
 
303
+ **Example:**
304
+ ```javascript
305
+ // Assuming 'timerId' is the ID of an existing timer
306
+ await manager.adjustRemainingTime(timerId, 60000); // Add 1 minute to the timer
307
+ await manager.adjustRemainingTime(timerId, -30000); // Subtract 30 seconds from the timer
308
+ ```
309
+
201
310
  ## Type Definition
202
311
 
203
312
  The `StorageType` has the following structure:
@@ -208,15 +317,45 @@ type StorageType = "JSONL" | "PlainText"
208
317
  The `Timer` object has the following structure:
209
318
 
210
319
  ```typescript
211
- type Timer<T extends StorageType> = {
212
- id: string;
213
- start: number;
214
- stop: number;
215
- } & (T extends "JSONL"
216
- ? { title?: string; description?: string }
217
- : {});
320
+ type Timer<T extends StorageType, Extra extends object> =
321
+ T extends "JSONL"
322
+ ? {
323
+ id: string;
324
+ start: number;
325
+ stop: number;
326
+ extra: Extra
327
+ }
328
+ : {
329
+ id: string;
330
+ start: number;
331
+ stop: number;
332
+ };
333
+ ```
334
+ `Extra` is a generic type parameter that represents an object containing arbitrary user-defined metadata for JSONL timers. By default, it's `object`. For example, it can be `{ title?: string; description?: string }`.
335
+
336
+ The `CreateTimerOptions` type is used when creating new timers:
337
+ ```typescript
338
+ type CreateTimerOptions<T extends StorageType, Extra extends object> = T extends "JSONL"
339
+ ? {
340
+ length: number;
341
+ extra: Extra
342
+ }
343
+ : T extends "PlainText"
344
+ ? number
345
+ : never;
218
346
  ```
219
347
 
348
+ The `TimerEvents` type defines the events emitted by `TimersManager`:
349
+ ```typescript
350
+ type TimerEvents<T extends StorageType, Extra extends object> = {
351
+ expired: Timer<T, Extra>
352
+ errored: Error
353
+ interval: void
354
+ started: Timer<T, Extra>
355
+ stopped: Timer<T, Extra>
356
+ updated: { old: Timer<T, Extra>, new: Timer<T, Extra> }
357
+ }
358
+ ```
220
359
  ## Scripts
221
360
 
222
361
  - `npm run build`: Compile TypeScript
@@ -0,0 +1,12 @@
1
+ import type { StorageType, TimerEvents } from "./types.js";
2
+ export declare class EventEmitter<T extends StorageType, Extra extends object> {
3
+ protected listeners: {
4
+ [K in keyof TimerEvents<T, Extra>]?: ((payload: TimerEvents<T, Extra>[K]) => void | Promise<void>)[];
5
+ };
6
+ on<K extends keyof TimerEvents<T, Extra>>(event: K, listener: (payload: TimerEvents<T, Extra>[K]) => void | Promise<void>): void;
7
+ once<K extends keyof TimerEvents<T, Extra>>(event: K, listener: (payload: TimerEvents<T, Extra>[K]) => void | Promise<void>): void;
8
+ off<K extends keyof TimerEvents<T, Extra>>(event: K, listener: (payload: TimerEvents<T, Extra>[K]) => void | Promise<void>): void;
9
+ offAll<K extends keyof TimerEvents<T, Extra>>(event: K): void;
10
+ protected emit<K extends keyof TimerEvents<T, Extra>>(event: K, payload: TimerEvents<T, Extra>[K]): Promise<void>;
11
+ }
12
+ //# sourceMappingURL=EventEmitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventEmitter.d.ts","sourceRoot":"","sources":["../../src/EventEmitter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3D,qBAAa,YAAY,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,SAAS,MAAM;IACpE,SAAS,CAAC,SAAS,EAAE;SACb,CAAC,IAAI,MAAM,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAClC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAChC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE;KAC/B,CAAM;IAEH,EAAE,CAAC,CAAC,SAAS,MAAM,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,EAC9C,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACnE,IAAI;IAOA,IAAI,CAAC,CAAC,SAAS,MAAM,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,EAChD,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACnE,IAAI;IAQA,GAAG,CAAC,CAAC,SAAS,MAAM,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,EAC/C,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACnE,IAAI;IAUA,MAAM,CAAC,CAAC,SAAS,MAAM,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,EAClD,KAAK,EAAE,CAAC,GACN,IAAI;cAIS,IAAI,CAAC,CAAC,SAAS,MAAM,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,EACzD,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC;CAoBhB"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventEmitter = void 0;
4
+ class EventEmitter {
5
+ listeners = {};
6
+ on(event, listener) {
7
+ if (!this.listeners[event]) {
8
+ this.listeners[event] = [];
9
+ }
10
+ this.listeners[event].push(listener);
11
+ }
12
+ once(event, listener) {
13
+ const wrapper = (payload) => {
14
+ this.off(event, wrapper);
15
+ return listener(payload);
16
+ };
17
+ this.on(event, wrapper);
18
+ }
19
+ off(event, listener) {
20
+ const listeners = this.listeners[event];
21
+ if (!listeners)
22
+ return;
23
+ const index = listeners.indexOf(listener);
24
+ if (index !== -1) {
25
+ listeners.splice(index, 1);
26
+ }
27
+ }
28
+ offAll(event) {
29
+ this.listeners[event] = [];
30
+ }
31
+ async emit(event, payload) {
32
+ const listeners = this.listeners[event];
33
+ if (!listeners?.length)
34
+ return;
35
+ const errors = [];
36
+ await Promise.all(listeners.map(async (l) => {
37
+ try {
38
+ await l(payload);
39
+ }
40
+ catch (e) {
41
+ errors.push(e);
42
+ }
43
+ }));
44
+ if (errors.length > 0) {
45
+ throw new AggregateError(errors, `Errors in event "${event}"`);
46
+ }
47
+ }
48
+ }
49
+ exports.EventEmitter = EventEmitter;
50
+ //# sourceMappingURL=EventEmitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventEmitter.js","sourceRoot":"","sources":["../../src/EventEmitter.ts"],"names":[],"mappings":";;;AAEA,MAAa,YAAY;IACd,SAAS,GAIZ,EAAE,CAAC;IAEH,EAAE,CACR,KAAQ,EACR,QAAqE;QAErE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC5B,CAAC;QACK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAEM,IAAI,CACV,KAAQ,EACR,QAAqE;QAErE,MAAM,OAAO,GAAG,CAAC,OAAiC,EAAE,EAAE;YACrD,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACzB,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC1B,CAAC,CAAC;QACF,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzB,CAAC;IAEM,GAAG,CACT,KAAQ,EACR,QAAqE;QAErE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YAClB,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC5B,CAAC;IACF,CAAC;IAEM,MAAM,CACZ,KAAQ;QAER,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;IAC5B,CAAC;IAES,KAAK,CAAC,IAAI,CACnB,KAAQ,EACR,OAAiC;QAEjC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,CAAC,SAAS,EAAE,MAAM;YAAE,OAAO;QAE/B,MAAM,MAAM,GAAc,EAAE,CAAC;QAE7B,MAAM,OAAO,CAAC,GAAG,CAChB,SAAS,CAAC,GAAG,CAAC,KAAK,EAAC,CAAC,EAAC,EAAE;YACvB,IAAI,CAAC;gBACJ,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;YAClB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,CAAC;QACF,CAAC,CAAC,CACF,CAAC;QAEF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,cAAc,CAAC,MAAM,EAAE,oBAAoB,KAAK,GAAG,CAAC,CAAC;QAChE,CAAC;IACF,CAAC;CACD;AAtED,oCAsEC"}
@@ -9,11 +9,23 @@ import { JSONLTimersStore } from "../TimersStore/JSONLTimersStore.js";
9
9
  * - Timers are persisted in a file
10
10
  * - Expired timers are detected by polling
11
11
  */
12
- export declare class JSONLTimersManager extends TimersManager<"JSONL"> {
13
- protected TimersStore: JSONLTimersStore | null;
12
+ export declare class JSONLTimersManager<Extra extends object = object> extends TimersManager<"JSONL", Extra> {
13
+ protected TimersStore: JSONLTimersStore<Extra> | null;
14
14
  protected getDefaultFilename(): string;
15
- protected createTimersStore(): Promise<JSONLTimersStore>;
16
- changeTitle(id: string, newTitle: string): Promise<void>;
17
- changeDescription(id: string, newDescription: string): Promise<void>;
15
+ protected createTimersStore(): Promise<JSONLTimersStore<Extra>>;
16
+ protected type: "JSONL";
17
+ /**
18
+ * changeExtra
19
+ * @description Change extra field
20
+ * @param {string} id
21
+ * @param {Extra} newExtra
22
+ * @returns Promise resolving when the operation is complete
23
+ * @throws If timer with id not found or file operation fails
24
+ * @example
25
+ * const timer = await manager.createTimer({ length: 1000, extra: {author: "someone"} });
26
+ * await changeExtra(timer, {author: "SUKEsann2000"});
27
+ * // extra is changed and author will be "SUKEsann2000" instead of "someone"
28
+ */
29
+ changeExtra(id: string, newExtra: Extra): Promise<void>;
18
30
  }
19
31
  //# sourceMappingURL=JSONLTimersManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"JSONLTimersManager.d.ts","sourceRoot":"","sources":["../../../src/TimersManager/JSONLTimersManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE;;;;;;;;GAQG;AACH,qBAAa,kBAAmB,SAAQ,aAAa,CAAC,OAAO,CAAC;IAC7D,UAAmB,WAAW,EAAE,gBAAgB,GAAG,IAAI,CAAQ;cAE5C,kBAAkB,IAAI,MAAM;cAItB,iBAAiB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAI1D,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBxD,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAkBjF"}
1
+ {"version":3,"file":"JSONLTimersManager.d.ts","sourceRoot":"","sources":["../../../src/TimersManager/JSONLTimersManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE;;;;;;;;GAQG;AACH,qBAAa,kBAAkB,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC;IACnG,UAAmB,WAAW,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAAG,IAAI,CAAQ;cAEnD,kBAAkB,IAAI,MAAM;cAItB,iBAAiB,IAAI,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAI9E,UAAmB,IAAI,EAAE,OAAO,CAAoB;IAEpD;;;;;;;;;;;OAWG;IACU,WAAW,CACvB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,KAAK,GACb,OAAO,CAAC,IAAI,CAAC;CAqBhB"}
@@ -20,37 +20,35 @@ class JSONLTimersManager extends TimersManager_js_1.TimersManager {
20
20
  async createTimersStore() {
21
21
  return new JSONLTimersStore_js_1.JSONLTimersStore(this.timerfiledir);
22
22
  }
23
- async changeTitle(id, newTitle) {
23
+ type = "JSONL";
24
+ /**
25
+ * changeExtra
26
+ * @description Change extra field
27
+ * @param {string} id
28
+ * @param {Extra} newExtra
29
+ * @returns Promise resolving when the operation is complete
30
+ * @throws If timer with id not found or file operation fails
31
+ * @example
32
+ * const timer = await manager.createTimer({ length: 1000, extra: {author: "someone"} });
33
+ * await changeExtra(timer, {author: "SUKEsann2000"});
34
+ * // extra is changed and author will be "SUKEsann2000" instead of "someone"
35
+ */
36
+ async changeExtra(id, newExtra) {
24
37
  return this.runExclusive(async () => {
25
38
  this.TimersStore ??= await this.createTimersStore();
26
39
  try {
27
40
  const timers = await this.TimersStore.loadTimers();
28
41
  const index = timers?.findIndex(t => t.id === id);
29
- if (index === -1) {
42
+ if (index === -1 || timers[index] === undefined) {
30
43
  throw new Error(`Timer with id ${id} not found`);
31
44
  }
32
- timers[index].title = newTitle;
45
+ const old = { ...timers[index] };
46
+ timers[index].extra = newExtra;
33
47
  await this.TimersStore.saveTimers(timers);
48
+ await this.emit("updated", { old, new: timers[index] });
34
49
  }
35
50
  catch (e) {
36
- throw new Error(`Error when changing title`, { cause: e });
37
- }
38
- });
39
- }
40
- async changeDescription(id, newDescription) {
41
- return this.runExclusive(async () => {
42
- this.TimersStore ??= await this.createTimersStore();
43
- try {
44
- const timers = await this.TimersStore.loadTimers();
45
- const index = timers?.findIndex(t => t.id === id);
46
- if (index === -1) {
47
- throw new Error(`Timer with id ${id} not found`);
48
- }
49
- timers[index].description = newDescription;
50
- await this.TimersStore.saveTimers(timers);
51
- }
52
- catch (e) {
53
- throw new Error(`Error when changing description`, { cause: e });
51
+ throw new Error(`Error when changing extra`, { cause: e });
54
52
  }
55
53
  });
56
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"JSONLTimersManager.js","sourceRoot":"","sources":["../../../src/TimersManager/JSONLTimersManager.ts"],"names":[],"mappings":";;;AAAA,yDAAmD;AACnD,4EAAsE;AAEtE;;;;;;;;GAQG;AACH,MAAa,kBAAmB,SAAQ,gCAAsB;IAC1C,WAAW,GAA4B,IAAI,CAAC;IAE5C,kBAAkB;QACpC,OAAO,eAAe,CAAC;IACxB,CAAC;IAEkB,KAAK,CAAC,iBAAiB;QACzC,OAAO,IAAI,sCAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,EAAU,EAAE,QAAgB;QACpD,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YACnC,IAAI,CAAC,WAAW,KAAK,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACpD,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;gBAEnD,MAAM,KAAK,GAAG,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;gBAClD,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;oBAClB,MAAM,IAAI,KAAK,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAC;gBAClD,CAAC;gBAED,MAAM,CAAC,KAAK,CAAE,CAAC,KAAK,GAAG,QAAQ,CAAC;gBAChC,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC3C,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YAC5D,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,iBAAiB,CAAC,EAAU,EAAE,cAAsB;QAChE,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YACnC,IAAI,CAAC,WAAW,KAAK,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACpD,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;gBAEnD,MAAM,KAAK,GAAG,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;gBAClD,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;oBAClB,MAAM,IAAI,KAAK,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAC;gBAClD,CAAC;gBAED,MAAM,CAAC,KAAK,CAAE,CAAC,WAAW,GAAG,cAAc,CAAC;gBAC5C,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC3C,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,iCAAiC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YAClE,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;CACD;AAhDD,gDAgDC"}
1
+ {"version":3,"file":"JSONLTimersManager.js","sourceRoot":"","sources":["../../../src/TimersManager/JSONLTimersManager.ts"],"names":[],"mappings":";;;AAAA,yDAAmD;AACnD,4EAAsE;AAEtE;;;;;;;;GAQG;AACH,MAAa,kBAAkD,SAAQ,gCAA6B;IAChF,WAAW,GAAmC,IAAI,CAAC;IAEnD,kBAAkB;QACpC,OAAO,eAAe,CAAC;IACxB,CAAC;IAEkB,KAAK,CAAC,iBAAiB;QACzC,OAAO,IAAI,sCAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC;IAEkB,IAAI,GAAY,OAAgB,CAAC;IAEpD;;;;;;;;;;;OAWG;IACI,KAAK,CAAC,WAAW,CACvB,EAAU,EACV,QAAe;QAEf,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YACnC,IAAI,CAAC,WAAW,KAAK,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACpD,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;gBAEnD,MAAM,KAAK,GAAG,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;gBAClD,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;oBACjD,MAAM,IAAI,KAAK,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAC;gBAClD,CAAC;gBAED,MAAM,GAAG,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBAEjC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,QAAQ,CAAC;gBAC/B,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;gBAC1C,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACzD,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YAC5D,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;CACD;AAjDD,gDAiDC"}
@@ -9,9 +9,10 @@ import { PlainTextTimersStore } from "../TimersStore/PlainTextTimersStore.js";
9
9
  * - Timers are persisted in a file
10
10
  * - Expired timers are detected by polling
11
11
  */
12
- export declare class PlainTextTimersManager extends TimersManager<"PlainText"> {
12
+ export declare class PlainTextTimersManager extends TimersManager<"PlainText", object> {
13
13
  protected TimersStore: PlainTextTimersStore | null;
14
14
  protected getDefaultFilename(): string;
15
15
  protected createTimersStore(): Promise<PlainTextTimersStore>;
16
+ protected type: "PlainText";
16
17
  }
17
18
  //# sourceMappingURL=PlainTextTimersManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlainTextTimersManager.d.ts","sourceRoot":"","sources":["../../../src/TimersManager/PlainTextTimersManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAE9E;;;;;;;;GAQG;AACH,qBAAa,sBAAuB,SAAQ,aAAa,CAAC,WAAW,CAAC;IACrE,UAAmB,WAAW,EAAE,oBAAoB,GAAG,IAAI,CAAQ;cAEhD,kBAAkB,IAAI,MAAM;cAI/B,iBAAiB,IAAI,OAAO,CAAC,oBAAoB,CAAC;CAGlE"}
1
+ {"version":3,"file":"PlainTextTimersManager.d.ts","sourceRoot":"","sources":["../../../src/TimersManager/PlainTextTimersManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAE9E;;;;;;;;GAQG;AACH,qBAAa,sBAAuB,SAAQ,aAAa,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7E,UAAmB,WAAW,EAAE,oBAAoB,GAAG,IAAI,CAAQ;cAEhD,kBAAkB,IAAI,MAAM;cAI/B,iBAAiB,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAIlE,UAAmB,IAAI,EAAE,WAAW,CAAwB;CAC5D"}
@@ -20,6 +20,7 @@ class PlainTextTimersManager extends TimersManager_js_1.TimersManager {
20
20
  async createTimersStore() {
21
21
  return new PlainTextTimersStore_js_1.PlainTextTimersStore(this.timerfiledir);
22
22
  }
23
+ type = "PlainText";
23
24
  }
24
25
  exports.PlainTextTimersManager = PlainTextTimersManager;
25
26
  //# sourceMappingURL=PlainTextTimersManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlainTextTimersManager.js","sourceRoot":"","sources":["../../../src/TimersManager/PlainTextTimersManager.ts"],"names":[],"mappings":";;;AAAA,yDAAmD;AACnD,oFAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAa,sBAAuB,SAAQ,gCAA0B;IAClD,WAAW,GAAgC,IAAI,CAAC;IAEhD,kBAAkB;QACpC,OAAO,SAAS,CAAC;IAClB,CAAC;IAES,KAAK,CAAC,iBAAiB;QAChC,OAAO,IAAI,8CAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACpD,CAAC;CACD;AAVD,wDAUC"}
1
+ {"version":3,"file":"PlainTextTimersManager.js","sourceRoot":"","sources":["../../../src/TimersManager/PlainTextTimersManager.ts"],"names":[],"mappings":";;;AAAA,yDAAmD;AACnD,oFAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAa,sBAAuB,SAAQ,gCAAkC;IAC1D,WAAW,GAAgC,IAAI,CAAC;IAEhD,kBAAkB;QACpC,OAAO,SAAS,CAAC;IAClB,CAAC;IAES,KAAK,CAAC,iBAAiB;QAChC,OAAO,IAAI,8CAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACpD,CAAC;IAEkB,IAAI,GAAgB,WAAoB,CAAC;CAC5D;AAZD,wDAYC"}