@hardlydifficult/daemon 1.0.0 → 1.0.1

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 (2) hide show
  1. package/README.md +58 -67
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,123 +1,114 @@
1
- # @hardlydifficult/teardown
1
+ # @hardlydifficult/daemon
2
2
 
3
- Idempotent resource teardown with signal trapping. Register cleanup functions once at resource creation time — all exit paths call a single `run()`.
3
+ Idempotent resource teardown with signal trapping and LIFO cleanup ordering.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install @hardlydifficult/teardown
8
+ npm install @hardlydifficult/daemon
9
9
  ```
10
10
 
11
11
  ## Quick Start
12
12
 
13
13
  ```typescript
14
- import { createTeardown } from "@hardlydifficult/teardown";
14
+ import { createTeardown, runContinuousLoop } from "@hardlydifficult/daemon";
15
15
 
16
+ // Register cleanup functions
16
17
  const teardown = createTeardown();
17
- teardown.add(() => server.stop());
18
- teardown.add(() => db.close());
18
+ teardown.add(() => console.log("Closing server"));
19
+ teardown.add(() => console.log("Closing database"));
19
20
  teardown.trapSignals();
20
21
 
21
- // Any manual exit path:
22
+ // Run teardown when ready
22
23
  await teardown.run();
24
+ // Logs:
25
+ // Closing database
26
+ // Closing server
23
27
  ```
24
28
 
25
- ## Creating a Teardown Registry
29
+ ## Teardown Management
26
30
 
27
- Use `createTeardown()` to create a new teardown registry that manages cleanup functions.
31
+ Resource cleanup registry with idempotent execution and LIFO ordering.
28
32
 
29
- ```typescript
30
- import { createTeardown } from "@hardlydifficult/teardown";
33
+ ### `createTeardown()`
31
34
 
35
+ Creates a teardown registry for managing resource cleanup.
36
+
37
+ ```typescript
32
38
  const teardown = createTeardown();
33
39
  ```
34
40
 
35
- ## Registering Cleanup Functions
41
+ #### `.add(fn: () => void | Promise<void>): () => void`
36
42
 
37
- Call `add()` to register a cleanup function. Functions run in LIFO order (last added runs first). The `add()` method returns an unregister function for selective cleanup.
43
+ Registers a teardown function. Returns an unregister function.
38
44
 
39
45
  ```typescript
40
46
  const teardown = createTeardown();
41
-
42
- // Register sync cleanup
43
- teardown.add(() => {
44
- console.log("Closing server");
45
- server.stop();
47
+ const unregister = teardown.add(async () => {
48
+ await server.close();
46
49
  });
47
50
 
48
- // Register async cleanup
49
- teardown.add(async () => {
50
- console.log("Closing database");
51
- await db.close();
52
- });
53
-
54
- // Unregister a specific function
55
- const unregister = teardown.add(() => {
56
- console.log("This won't run");
57
- });
51
+ // Unregister before teardown if needed
58
52
  unregister();
59
-
60
- await teardown.run();
61
- // Output:
62
- // Closing database
63
- // Closing server
64
53
  ```
65
54
 
66
- ## Running Teardown
55
+ #### `.run(): Promise<void>`
67
56
 
68
- Call `run()` to execute all registered cleanup functions in LIFO order. The method is idempotent — subsequent calls are no-ops.
57
+ Runs all teardown functions in LIFO order. Idempotent — subsequent calls are no-ops.
69
58
 
70
59
  ```typescript
71
60
  const teardown = createTeardown();
72
- teardown.add(() => console.log("cleanup"));
73
-
74
- await teardown.run();
75
- // Output: cleanup
61
+ teardown.add(() => console.log("First"));
62
+ teardown.add(() => console.log("Second"));
76
63
 
77
64
  await teardown.run();
78
- // No output (idempotent)
65
+ // Logs:
66
+ // Second
67
+ // First
79
68
  ```
80
69
 
81
- ## Signal Trapping
70
+ #### `.trapSignals(): () => void`
82
71
 
83
- Call `trapSignals()` to automatically run teardown when the process receives SIGTERM or SIGINT signals. Returns an untrap function to remove signal handlers.
72
+ Wires SIGTERM/SIGINT handlers to run teardown and exit. Returns an untrap function to remove handlers.
84
73
 
85
74
  ```typescript
86
75
  const teardown = createTeardown();
87
- teardown.add(() => server.stop());
88
-
89
- // Wire SIGTERM/SIGINT to run() then process.exit(0)
90
76
  const untrap = teardown.trapSignals();
91
77
 
92
- // Later, if needed:
78
+ // Later, to stop trapping signals
93
79
  untrap();
94
80
  ```
95
81
 
96
- ## Error Resilience
82
+ ## Continuous Loop Execution
97
83
 
98
- Each teardown function is wrapped in try/catch. Errors don't block remaining teardowns — all functions run regardless of failures.
84
+ Runs cyclic tasks with graceful shutdown support.
99
85
 
100
- ```typescript
101
- const teardown = createTeardown();
86
+ ### `runContinuousLoop(options: ContinuousLoopOptions): Promise<void>`
102
87
 
103
- teardown.add(() => {
104
- throw new Error("First cleanup fails");
105
- });
106
- teardown.add(() => {
107
- console.log("Second cleanup still runs");
108
- });
88
+ Executes a cycle function repeatedly with interruptible sleep and signal handling.
109
89
 
110
- await teardown.run();
111
- // Output: Second cleanup still runs
90
+ ```typescript
91
+ import { runContinuousLoop } from "@hardlydifficult/daemon";
92
+
93
+ await runContinuousLoop({
94
+ intervalSeconds: 5,
95
+ runCycle: async (isShutdownRequested) => {
96
+ if (isShutdownRequested()) {
97
+ return;
98
+ }
99
+ // Perform work here
100
+ console.log("Running cycle...");
101
+ },
102
+ onShutdown: async () => {
103
+ console.log("Shutdown complete");
104
+ }
105
+ });
112
106
  ```
113
107
 
114
- ## Behavior Reference
108
+ #### Options
115
109
 
116
- | Behavior | Details |
117
- |----------|---------|
118
- | **LIFO order** | Teardowns run in reverse registration order (last added runs first) |
119
- | **Idempotent** | `run()` executes once; subsequent calls are no-ops |
120
- | **Error resilient** | Each function is wrapped in try/catch; failures don't block remaining teardowns |
121
- | **Safe unregister** | `add()` returns an unregister function; safe to call multiple times |
122
- | **Post-run add** | `add()` after `run()` is a silent no-op |
123
- | **Duplicate safe** | Same function added twice runs twice; unregister only removes its own registration |
110
+ | Name | Type | Description |
111
+ |-------------------|---------------------------------|------------------------------------------------|
112
+ | `intervalSeconds` | `number` | Interval between cycles in seconds |
113
+ | `runCycle` | `(isShutdownRequested: () => boolean) => Promise<unknown>` | Callback to run each cycle (shutdown check provided) |
114
+ | `onShutdown?` | `() => Promise<void>` | Optional cleanup callback after shutdown |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardlydifficult/daemon",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [