@gravito/horizon 3.0.1 → 3.2.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.
- package/README.md +93 -80
- package/README.zh-TW.md +102 -8
- package/dist/index.cjs +603 -140
- package/dist/index.d.cts +563 -188
- package/dist/index.d.ts +563 -188
- package/dist/index.js +603 -140
- package/package.json +7 -5
package/dist/index.d.cts
CHANGED
|
@@ -2,65 +2,136 @@ import { CacheManager } from '@gravito/stasis';
|
|
|
2
2
|
import { ActionCallback, Logger, HookManager, GravitoOrbit, PlanetCore } from '@gravito/core';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* High-performance cron expression evaluator with LRU caching and fallback support.
|
|
6
|
+
*
|
|
7
|
+
* Employs a tiered strategy for cron evaluation:
|
|
8
|
+
* 1. Cache: O(1) lookup for high-frequency checks.
|
|
9
|
+
* 2. Simple Parser: Lightweight evaluator for standard expressions.
|
|
10
|
+
* 3. Advanced Parser: Dynamic import of `cron-parser` for complex expressions.
|
|
11
|
+
*
|
|
12
|
+
* @internal
|
|
6
13
|
*/
|
|
7
14
|
declare class CronParser {
|
|
15
|
+
private static cache;
|
|
16
|
+
/** Cache duration in milliseconds (1 minute). */
|
|
17
|
+
private static readonly CACHE_TTL;
|
|
18
|
+
/** Maximum number of unique expression/timezone combinations to store. */
|
|
19
|
+
private static readonly MAX_CACHE_SIZE;
|
|
8
20
|
/**
|
|
9
|
-
*
|
|
21
|
+
* Calculates the next occurrence of a cron expression.
|
|
22
|
+
*
|
|
23
|
+
* Dynamically loads `cron-parser` to minimize initial bundle size and memory footprint.
|
|
24
|
+
*
|
|
25
|
+
* @param expression - Valid 5-part cron expression.
|
|
26
|
+
* @param timezone - Target timezone for evaluation (default: "UTC").
|
|
27
|
+
* @param currentDate - Reference time to calculate from (default: now).
|
|
28
|
+
* @returns Resolves to the next execution Date object.
|
|
29
|
+
* @throws {Error} If the expression format is invalid.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* const next = await CronParser.nextDate('0 0 * * *');
|
|
34
|
+
* ```
|
|
10
35
|
*/
|
|
11
36
|
static nextDate(expression: string, timezone?: string, currentDate?: Date): Promise<Date>;
|
|
12
37
|
/**
|
|
13
|
-
*
|
|
38
|
+
* Determines if a task is due for execution at the specified time.
|
|
39
|
+
*
|
|
40
|
+
* Uses minute-precision caching to optimize repeated evaluations within
|
|
41
|
+
* the same scheduling window. Implements LRU eviction to maintain memory efficiency.
|
|
42
|
+
*
|
|
43
|
+
* @param expression - Cron expression to evaluate.
|
|
44
|
+
* @param timezone - Execution timezone.
|
|
45
|
+
* @param currentDate - Reference time for the check.
|
|
46
|
+
* @returns True if the expression matches the reference time.
|
|
14
47
|
*/
|
|
15
48
|
static isDue(expression: string, timezone?: string, currentDate?: Date): Promise<boolean>;
|
|
49
|
+
/**
|
|
50
|
+
* Internal logic for tiered cron evaluation.
|
|
51
|
+
*
|
|
52
|
+
* @param expression - Cron expression.
|
|
53
|
+
* @param timezone - Target timezone.
|
|
54
|
+
* @param currentDate - Current time.
|
|
55
|
+
* @returns Boolean indicating if the task is due.
|
|
56
|
+
*
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
private static computeIsDue;
|
|
60
|
+
/**
|
|
61
|
+
* Evicts the oldest entry from the cache when capacity is reached.
|
|
62
|
+
*
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
private static cleanupCache;
|
|
66
|
+
/**
|
|
67
|
+
* Purges all entries from the internal cache.
|
|
68
|
+
* Useful for testing or when global timezone settings change.
|
|
69
|
+
*/
|
|
70
|
+
static clearCache(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Compares two dates with minute precision.
|
|
73
|
+
*
|
|
74
|
+
* @internal
|
|
75
|
+
*/
|
|
16
76
|
private static minuteMatches;
|
|
17
77
|
}
|
|
18
78
|
|
|
19
79
|
/**
|
|
20
|
-
*
|
|
80
|
+
* Contract for distributed lock storage backends.
|
|
21
81
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
82
|
+
* Defines the essential operations required to manage mutual exclusion across
|
|
83
|
+
* multiple scheduler instances. Implementations must ensure atomicity for
|
|
84
|
+
* distributed safety.
|
|
24
85
|
*
|
|
25
86
|
* @public
|
|
26
87
|
* @since 3.0.0
|
|
27
88
|
*/
|
|
28
89
|
interface LockStore {
|
|
29
90
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
91
|
+
* Attempts to acquire a mutex lock for a specific key.
|
|
92
|
+
*
|
|
93
|
+
* Must be atomic. If the key is already locked, it should return false
|
|
94
|
+
* immediately without blocking.
|
|
95
|
+
*
|
|
96
|
+
* @param key - The unique lock identifier.
|
|
97
|
+
* @param ttlSeconds - Expiration duration in seconds to prevent deadlocks.
|
|
98
|
+
* @returns True if the lock was successfully acquired.
|
|
34
99
|
*/
|
|
35
100
|
acquire(key: string, ttlSeconds: number): Promise<boolean>;
|
|
36
101
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
102
|
+
* Explicitly releases a held lock.
|
|
103
|
+
*
|
|
104
|
+
* Should be idempotent; releasing a non-existent lock should not throw.
|
|
105
|
+
*
|
|
106
|
+
* @param key - The lock identifier to remove.
|
|
39
107
|
*/
|
|
40
108
|
release(key: string): Promise<void>;
|
|
41
109
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* @param
|
|
110
|
+
* Forcibly acquires or refreshes a lock, overwriting any existing state.
|
|
111
|
+
*
|
|
112
|
+
* @param key - The lock identifier.
|
|
113
|
+
* @param ttlSeconds - New expiration duration.
|
|
45
114
|
*/
|
|
46
115
|
forceAcquire(key: string, ttlSeconds: number): Promise<void>;
|
|
47
116
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
117
|
+
* Checks if a lock is currently active and not expired.
|
|
118
|
+
*
|
|
119
|
+
* @param key - The lock identifier.
|
|
120
|
+
* @returns True if the lock exists.
|
|
50
121
|
*/
|
|
51
122
|
exists(key: string): Promise<boolean>;
|
|
52
123
|
}
|
|
53
124
|
|
|
54
125
|
/**
|
|
55
|
-
*
|
|
126
|
+
* Distributed lock implementation backed by Gravito Stasis.
|
|
56
127
|
*
|
|
57
|
-
*
|
|
58
|
-
* across multiple application
|
|
128
|
+
* Leverages the shared cache system (Redis, Memcached, etc.) to provide
|
|
129
|
+
* atomic locking across multiple application nodes.
|
|
59
130
|
*
|
|
60
131
|
* @example
|
|
61
132
|
* ```typescript
|
|
62
|
-
* const store = new CacheLockStore(cacheManager
|
|
63
|
-
* const
|
|
133
|
+
* const store = new CacheLockStore(cacheManager);
|
|
134
|
+
* const locked = await store.acquire('nightly-sync', 600);
|
|
64
135
|
* ```
|
|
65
136
|
*
|
|
66
137
|
* @since 3.0.0
|
|
@@ -69,37 +140,61 @@ interface LockStore {
|
|
|
69
140
|
declare class CacheLockStore implements LockStore {
|
|
70
141
|
private cache;
|
|
71
142
|
private prefix;
|
|
143
|
+
/**
|
|
144
|
+
* Initializes the store with a cache manager.
|
|
145
|
+
*
|
|
146
|
+
* @param cache - The Stasis cache instance.
|
|
147
|
+
* @param prefix - Key prefix to avoid collisions in the shared namespace.
|
|
148
|
+
*/
|
|
72
149
|
constructor(cache: CacheManager, prefix?: string);
|
|
150
|
+
/**
|
|
151
|
+
* Computes the fully qualified cache key.
|
|
152
|
+
*
|
|
153
|
+
* @internal
|
|
154
|
+
*/
|
|
73
155
|
private getKey;
|
|
156
|
+
/**
|
|
157
|
+
* Atomic 'add' operation ensures only one node succeeds.
|
|
158
|
+
*
|
|
159
|
+
* @param key - Lock key.
|
|
160
|
+
* @param ttlSeconds - Expiration.
|
|
161
|
+
*/
|
|
74
162
|
acquire(key: string, ttlSeconds: number): Promise<boolean>;
|
|
163
|
+
/**
|
|
164
|
+
* Removes the lock key from cache.
|
|
165
|
+
*
|
|
166
|
+
* @param key - Lock key.
|
|
167
|
+
*/
|
|
75
168
|
release(key: string): Promise<void>;
|
|
169
|
+
/**
|
|
170
|
+
* Overwrites the lock key, effectively resetting the TTL.
|
|
171
|
+
*
|
|
172
|
+
* @param key - Lock key.
|
|
173
|
+
* @param ttlSeconds - New expiration.
|
|
174
|
+
*/
|
|
76
175
|
forceAcquire(key: string, ttlSeconds: number): Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* Validates if the lock key is present in the cache.
|
|
178
|
+
*
|
|
179
|
+
* @param key - Lock key.
|
|
180
|
+
*/
|
|
77
181
|
exists(key: string): Promise<boolean>;
|
|
78
182
|
}
|
|
79
183
|
|
|
80
184
|
/**
|
|
81
|
-
*
|
|
185
|
+
* Orchestrator for distributed locks to prevent concurrent task execution.
|
|
82
186
|
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
187
|
+
* Implements a pluggable storage pattern, allowing the scheduler to operate
|
|
188
|
+
* in both single-node (Memory) and multi-node (Cache/Redis) environments.
|
|
189
|
+
* Provides a unified interface for safe lock acquisition and release.
|
|
85
190
|
*
|
|
86
191
|
* @example
|
|
87
192
|
* ```typescript
|
|
88
|
-
* //
|
|
89
|
-
* const locks = new LockManager('
|
|
90
|
-
*
|
|
91
|
-
* //
|
|
92
|
-
* const
|
|
93
|
-
*
|
|
94
|
-
* // Acquire a lock
|
|
95
|
-
* const acquired = await locks.acquire('task:send-emails', 300)
|
|
96
|
-
* if (acquired) {
|
|
97
|
-
* try {
|
|
98
|
-
* // Execute task
|
|
99
|
-
* } finally {
|
|
100
|
-
* await locks.release('task:send-emails')
|
|
101
|
-
* }
|
|
102
|
-
* }
|
|
193
|
+
* // Production setup with distributed cache
|
|
194
|
+
* const locks = new LockManager('cache', { cache: cacheManager });
|
|
195
|
+
*
|
|
196
|
+
* // Attempt to acquire a mutex lock for 5 minutes
|
|
197
|
+
* const acquired = await locks.acquire('task:db-backup', 300);
|
|
103
198
|
* ```
|
|
104
199
|
*
|
|
105
200
|
* @since 3.0.0
|
|
@@ -107,81 +202,202 @@ declare class CacheLockStore implements LockStore {
|
|
|
107
202
|
*/
|
|
108
203
|
declare class LockManager {
|
|
109
204
|
private store;
|
|
205
|
+
/**
|
|
206
|
+
* Initializes the manager with a specific storage driver.
|
|
207
|
+
*
|
|
208
|
+
* @param driver - Strategy identifier or a custom `LockStore` implementation.
|
|
209
|
+
* @param context - Dependencies required by certain drivers (e.g., CacheManager).
|
|
210
|
+
* @throws {Error} If 'cache' driver is selected but no `CacheManager` is provided.
|
|
211
|
+
*/
|
|
110
212
|
constructor(driver: 'memory' | 'cache' | LockStore, context?: {
|
|
111
213
|
cache?: CacheManager;
|
|
112
214
|
});
|
|
215
|
+
/**
|
|
216
|
+
* Attempts to acquire a lock. Fails if the key is already locked.
|
|
217
|
+
*
|
|
218
|
+
* @param key - Unique identifier for the lock.
|
|
219
|
+
* @param ttlSeconds - Time-to-live in seconds before the lock expires.
|
|
220
|
+
* @returns True if the lock was successfully acquired.
|
|
221
|
+
*/
|
|
113
222
|
acquire(key: string, ttlSeconds: number): Promise<boolean>;
|
|
223
|
+
/**
|
|
224
|
+
* Explicitly releases a held lock.
|
|
225
|
+
*
|
|
226
|
+
* @param key - The lock identifier to remove.
|
|
227
|
+
* @returns Resolves when the lock is deleted.
|
|
228
|
+
*/
|
|
114
229
|
release(key: string): Promise<void>;
|
|
230
|
+
/**
|
|
231
|
+
* Forcibly acquires or overwrites an existing lock.
|
|
232
|
+
*
|
|
233
|
+
* Used for execution locks where the latest attempt should take precedence
|
|
234
|
+
* if the previous one is deemed expired.
|
|
235
|
+
*
|
|
236
|
+
* @param key - Lock identifier.
|
|
237
|
+
* @param ttlSeconds - Expiration duration.
|
|
238
|
+
*/
|
|
115
239
|
forceAcquire(key: string, ttlSeconds: number): Promise<void>;
|
|
240
|
+
/**
|
|
241
|
+
* Checks if a specific lock currently exists and is not expired.
|
|
242
|
+
*
|
|
243
|
+
* @param key - Lock identifier.
|
|
244
|
+
* @returns True if the key is locked and active.
|
|
245
|
+
*/
|
|
116
246
|
exists(key: string): Promise<boolean>;
|
|
117
247
|
}
|
|
118
248
|
|
|
119
249
|
/**
|
|
120
|
-
*
|
|
250
|
+
* Lightweight, in-memory lock store for local development and single-node deployments.
|
|
121
251
|
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
252
|
+
* Implements the `LockStore` contract using a local `Map`. It does not support
|
|
253
|
+
* shared state across processes or servers.
|
|
124
254
|
*
|
|
125
255
|
* @example
|
|
126
256
|
* ```typescript
|
|
127
|
-
* const store = new MemoryLockStore()
|
|
128
|
-
* const
|
|
129
|
-
* if (acquired) {
|
|
130
|
-
* // Execute task
|
|
131
|
-
* await store.release('task-123')
|
|
132
|
-
* }
|
|
257
|
+
* const store = new MemoryLockStore();
|
|
258
|
+
* const ok = await store.acquire('local-job', 60);
|
|
133
259
|
* ```
|
|
134
260
|
*
|
|
135
261
|
* @since 3.0.0
|
|
136
262
|
* @public
|
|
137
263
|
*/
|
|
138
264
|
declare class MemoryLockStore implements LockStore {
|
|
265
|
+
/** Map of lock keys to their expiration timestamps (ms). */
|
|
139
266
|
private locks;
|
|
267
|
+
/**
|
|
268
|
+
* Acquires a local lock if the key is not already active.
|
|
269
|
+
*
|
|
270
|
+
* @param key - Lock identifier.
|
|
271
|
+
* @param ttlSeconds - Expiration duration.
|
|
272
|
+
*/
|
|
140
273
|
acquire(key: string, ttlSeconds: number): Promise<boolean>;
|
|
274
|
+
/**
|
|
275
|
+
* Deletes the lock from local memory.
|
|
276
|
+
*
|
|
277
|
+
* @param key - Lock identifier.
|
|
278
|
+
*/
|
|
141
279
|
release(key: string): Promise<void>;
|
|
280
|
+
/**
|
|
281
|
+
* Sets or overwrites a local lock.
|
|
282
|
+
*
|
|
283
|
+
* @param key - Lock identifier.
|
|
284
|
+
* @param ttlSeconds - Expiration.
|
|
285
|
+
*/
|
|
142
286
|
forceAcquire(key: string, ttlSeconds: number): Promise<void>;
|
|
287
|
+
/**
|
|
288
|
+
* Checks if a local lock is present and hasn't expired.
|
|
289
|
+
*
|
|
290
|
+
* Automatically purges expired locks upon checking.
|
|
291
|
+
*
|
|
292
|
+
* @param key - Lock identifier.
|
|
293
|
+
*/
|
|
143
294
|
exists(key: string): Promise<boolean>;
|
|
144
295
|
}
|
|
145
296
|
|
|
146
297
|
/**
|
|
147
|
-
* Represents
|
|
298
|
+
* Represents the configuration and state of a scheduled task.
|
|
299
|
+
*
|
|
300
|
+
* Encapsulates all metadata required by the scheduler to evaluate frequency,
|
|
301
|
+
* manage distributed locking, and execute task logic with reliability controls.
|
|
148
302
|
*
|
|
149
303
|
* @public
|
|
150
304
|
* @since 3.0.0
|
|
151
305
|
*/
|
|
152
306
|
interface ScheduledTask {
|
|
153
|
-
/**
|
|
307
|
+
/**
|
|
308
|
+
* Unique identifier for the task.
|
|
309
|
+
* Used for logging, hook identification, and as part of the lock key.
|
|
310
|
+
*/
|
|
154
311
|
name: string;
|
|
155
|
-
/**
|
|
312
|
+
/**
|
|
313
|
+
* Standard 5-part cron expression defining execution frequency.
|
|
314
|
+
* Format: "minute hour day month weekday"
|
|
315
|
+
*/
|
|
156
316
|
expression: string;
|
|
157
|
-
/**
|
|
317
|
+
/**
|
|
318
|
+
* Timezone identifier for evaluating the cron expression.
|
|
319
|
+
* @defaultValue "UTC"
|
|
320
|
+
*/
|
|
158
321
|
timezone: string;
|
|
159
|
-
/**
|
|
322
|
+
/**
|
|
323
|
+
* The asynchronous task logic to be executed.
|
|
324
|
+
*/
|
|
160
325
|
callback: () => void | Promise<void>;
|
|
161
|
-
/**
|
|
326
|
+
/**
|
|
327
|
+
* Whether to ensure single-point execution across a distributed environment.
|
|
328
|
+
* When true, uses a time-window lock to prevent multiple servers from running
|
|
329
|
+
* the same task in the same scheduling window.
|
|
330
|
+
*/
|
|
162
331
|
shouldRunOnOneServer: boolean;
|
|
163
|
-
/**
|
|
332
|
+
/**
|
|
333
|
+
* Duration in seconds to hold the distributed time-window lock.
|
|
334
|
+
* @defaultValue 300
|
|
335
|
+
*/
|
|
164
336
|
lockTtl: number;
|
|
165
|
-
/**
|
|
337
|
+
/**
|
|
338
|
+
* Whether to execute the task in a non-blocking background mode.
|
|
339
|
+
* If true, the scheduler won't wait for completion before processing the next task.
|
|
340
|
+
*/
|
|
166
341
|
background: boolean;
|
|
167
|
-
/**
|
|
342
|
+
/**
|
|
343
|
+
* Optional target node role required for execution.
|
|
344
|
+
* Tasks will only run if the current node matches this role.
|
|
345
|
+
*/
|
|
168
346
|
nodeRole?: string;
|
|
169
|
-
/**
|
|
347
|
+
/**
|
|
348
|
+
* Raw shell command if the task was created via `scheduler.exec()`.
|
|
349
|
+
*/
|
|
170
350
|
command?: string;
|
|
171
|
-
/**
|
|
351
|
+
/**
|
|
352
|
+
* Maximum execution time in milliseconds before the task is aborted.
|
|
353
|
+
* @defaultValue 3600000
|
|
354
|
+
*/
|
|
355
|
+
timeout?: number;
|
|
356
|
+
/**
|
|
357
|
+
* Number of times to retry a failed task.
|
|
358
|
+
* @defaultValue 0
|
|
359
|
+
*/
|
|
360
|
+
retries?: number;
|
|
361
|
+
/**
|
|
362
|
+
* Delay between retry attempts in milliseconds.
|
|
363
|
+
* @defaultValue 1000
|
|
364
|
+
*/
|
|
365
|
+
retryDelay?: number;
|
|
366
|
+
/**
|
|
367
|
+
* Whether to prevent concurrent executions of the same task.
|
|
368
|
+
* If true, a new instance won't start if the previous one is still running.
|
|
369
|
+
*/
|
|
370
|
+
preventOverlapping: boolean;
|
|
371
|
+
/**
|
|
372
|
+
* Maximum duration in seconds for the execution lock.
|
|
373
|
+
* Prevents deadlocks if a task crashes without releasing the lock.
|
|
374
|
+
* @defaultValue 3600
|
|
375
|
+
*/
|
|
376
|
+
overlappingExpiresAt: number;
|
|
377
|
+
/**
|
|
378
|
+
* Collection of callbacks executed upon successful task completion.
|
|
379
|
+
*/
|
|
172
380
|
onSuccessCallbacks: ActionCallback[];
|
|
173
|
-
/**
|
|
381
|
+
/**
|
|
382
|
+
* Collection of callbacks executed when the task fails after all retries.
|
|
383
|
+
*/
|
|
174
384
|
onFailureCallbacks: ActionCallback[];
|
|
175
385
|
}
|
|
176
386
|
/**
|
|
177
|
-
* Fluent
|
|
387
|
+
* Fluent builder for defining and configuring scheduled tasks.
|
|
388
|
+
*
|
|
389
|
+
* Provides a human-readable API for setting execution frequency, constraints,
|
|
390
|
+
* reliability settings, and lifecycle hooks.
|
|
178
391
|
*
|
|
179
392
|
* @example
|
|
180
393
|
* ```typescript
|
|
181
|
-
* scheduler.task('backup')
|
|
182
|
-
* .
|
|
183
|
-
*
|
|
184
|
-
*
|
|
394
|
+
* scheduler.task('backup-db', async () => {
|
|
395
|
+
* await db.backup();
|
|
396
|
+
* })
|
|
397
|
+
* .dailyAt('03:00')
|
|
398
|
+
* .onOneServer()
|
|
399
|
+
* .withoutOverlapping()
|
|
400
|
+
* .retry(3, 5000);
|
|
185
401
|
* ```
|
|
186
402
|
*
|
|
187
403
|
* @public
|
|
@@ -190,188 +406,259 @@ interface ScheduledTask {
|
|
|
190
406
|
declare class TaskSchedule {
|
|
191
407
|
private task;
|
|
192
408
|
/**
|
|
193
|
-
*
|
|
409
|
+
* Initializes a new schedule instance with default settings.
|
|
194
410
|
*
|
|
195
|
-
* @param name -
|
|
196
|
-
* @param callback -
|
|
411
|
+
* @param name - Unique task name used for identification and locking.
|
|
412
|
+
* @param callback - Logic to execute on schedule.
|
|
197
413
|
*/
|
|
198
414
|
constructor(name: string, callback: () => void | Promise<void>);
|
|
199
415
|
/**
|
|
200
|
-
*
|
|
416
|
+
* Configures a raw 5-part cron expression.
|
|
417
|
+
*
|
|
418
|
+
* @param expression - Cron string (e.g., "0 0 * * *").
|
|
419
|
+
* @returns The TaskSchedule instance for chaining.
|
|
420
|
+
* @throws {Error} If expression format is invalid or contains forbidden characters.
|
|
201
421
|
*
|
|
202
|
-
* @
|
|
203
|
-
*
|
|
422
|
+
* @example
|
|
423
|
+
* ```typescript
|
|
424
|
+
* schedule.cron('0 9-17 * * 1-5'); // 9-5 on weekdays
|
|
425
|
+
* ```
|
|
204
426
|
*/
|
|
205
427
|
cron(expression: string): this;
|
|
206
428
|
/**
|
|
207
|
-
*
|
|
429
|
+
* Schedules execution every minute.
|
|
208
430
|
*
|
|
209
|
-
* @returns The TaskSchedule instance.
|
|
431
|
+
* @returns The TaskSchedule instance for chaining.
|
|
210
432
|
*/
|
|
211
433
|
everyMinute(): this;
|
|
212
434
|
/**
|
|
213
|
-
*
|
|
435
|
+
* Schedules execution every five minutes.
|
|
214
436
|
*
|
|
215
|
-
* @returns The TaskSchedule instance.
|
|
437
|
+
* @returns The TaskSchedule instance for chaining.
|
|
216
438
|
*/
|
|
217
439
|
everyFiveMinutes(): this;
|
|
218
440
|
/**
|
|
219
|
-
*
|
|
441
|
+
* Schedules execution every ten minutes.
|
|
220
442
|
*
|
|
221
|
-
* @returns The TaskSchedule instance.
|
|
443
|
+
* @returns The TaskSchedule instance for chaining.
|
|
222
444
|
*/
|
|
223
445
|
everyTenMinutes(): this;
|
|
224
446
|
/**
|
|
225
|
-
*
|
|
447
|
+
* Schedules execution every fifteen minutes.
|
|
226
448
|
*
|
|
227
|
-
* @returns The TaskSchedule instance.
|
|
449
|
+
* @returns The TaskSchedule instance for chaining.
|
|
228
450
|
*/
|
|
229
451
|
everyFifteenMinutes(): this;
|
|
230
452
|
/**
|
|
231
|
-
*
|
|
453
|
+
* Schedules execution every thirty minutes.
|
|
232
454
|
*
|
|
233
|
-
* @returns The TaskSchedule instance.
|
|
455
|
+
* @returns The TaskSchedule instance for chaining.
|
|
234
456
|
*/
|
|
235
457
|
everyThirtyMinutes(): this;
|
|
236
458
|
/**
|
|
237
|
-
*
|
|
459
|
+
* Schedules execution hourly at the top of the hour.
|
|
238
460
|
*
|
|
239
|
-
* @returns The TaskSchedule instance.
|
|
461
|
+
* @returns The TaskSchedule instance for chaining.
|
|
240
462
|
*/
|
|
241
463
|
hourly(): this;
|
|
242
464
|
/**
|
|
243
|
-
*
|
|
465
|
+
* Schedules execution hourly at a specific minute.
|
|
244
466
|
*
|
|
245
|
-
* @param minute -
|
|
246
|
-
* @returns The TaskSchedule instance.
|
|
467
|
+
* @param minute - Target minute (0-59).
|
|
468
|
+
* @returns The TaskSchedule instance for chaining.
|
|
469
|
+
* @throws {Error} If minute is outside 0-59 range.
|
|
247
470
|
*/
|
|
248
471
|
hourlyAt(minute: number): this;
|
|
249
472
|
/**
|
|
250
|
-
*
|
|
473
|
+
* Schedules execution daily at midnight.
|
|
251
474
|
*
|
|
252
|
-
* @returns The TaskSchedule instance.
|
|
475
|
+
* @returns The TaskSchedule instance for chaining.
|
|
253
476
|
*/
|
|
254
477
|
daily(): this;
|
|
255
478
|
/**
|
|
256
|
-
*
|
|
479
|
+
* Schedules execution daily at a specific time.
|
|
257
480
|
*
|
|
258
|
-
* @param time -
|
|
259
|
-
* @returns The TaskSchedule instance.
|
|
481
|
+
* @param time - 24-hour time string in "HH:mm" format.
|
|
482
|
+
* @returns The TaskSchedule instance for chaining.
|
|
483
|
+
* @throws {Error} If time format is invalid or values are out of range.
|
|
484
|
+
*
|
|
485
|
+
* @example
|
|
486
|
+
* ```typescript
|
|
487
|
+
* schedule.dailyAt('14:30');
|
|
488
|
+
* ```
|
|
260
489
|
*/
|
|
261
490
|
dailyAt(time: string): this;
|
|
262
491
|
/**
|
|
263
|
-
*
|
|
492
|
+
* Schedules execution weekly on Sunday at midnight.
|
|
264
493
|
*
|
|
265
|
-
* @returns The TaskSchedule instance.
|
|
494
|
+
* @returns The TaskSchedule instance for chaining.
|
|
266
495
|
*/
|
|
267
496
|
weekly(): this;
|
|
268
497
|
/**
|
|
269
|
-
*
|
|
498
|
+
* Schedules execution weekly on a specific day and time.
|
|
499
|
+
*
|
|
500
|
+
* @param day - Day index (0-6, where 0 is Sunday).
|
|
501
|
+
* @param time - Optional 24-hour time string "HH:mm" (default "00:00").
|
|
502
|
+
* @returns The TaskSchedule instance for chaining.
|
|
503
|
+
* @throws {Error} If day index or time format is invalid.
|
|
270
504
|
*
|
|
271
|
-
* @
|
|
272
|
-
*
|
|
273
|
-
*
|
|
505
|
+
* @example
|
|
506
|
+
* ```typescript
|
|
507
|
+
* schedule.weeklyOn(1, '09:00'); // Mondays at 9 AM
|
|
508
|
+
* ```
|
|
274
509
|
*/
|
|
275
510
|
weeklyOn(day: number, time?: string): this;
|
|
276
511
|
/**
|
|
277
|
-
*
|
|
512
|
+
* Schedules execution monthly on the first day at midnight.
|
|
278
513
|
*
|
|
279
|
-
* @returns The TaskSchedule instance.
|
|
514
|
+
* @returns The TaskSchedule instance for chaining.
|
|
280
515
|
*/
|
|
281
516
|
monthly(): this;
|
|
282
517
|
/**
|
|
283
|
-
*
|
|
518
|
+
* Schedules execution monthly on a specific day and time.
|
|
284
519
|
*
|
|
285
|
-
* @param day - Day of month (1-31)
|
|
286
|
-
* @param time -
|
|
287
|
-
* @returns The TaskSchedule instance.
|
|
520
|
+
* @param day - Day of month (1-31).
|
|
521
|
+
* @param time - Optional 24-hour time string "HH:mm" (default "00:00").
|
|
522
|
+
* @returns The TaskSchedule instance for chaining.
|
|
523
|
+
* @throws {Error} If day or time format is invalid.
|
|
288
524
|
*/
|
|
289
525
|
monthlyOn(day: number, time?: string): this;
|
|
290
526
|
/**
|
|
291
|
-
*
|
|
527
|
+
* Specifies the timezone for evaluating schedule frequency.
|
|
292
528
|
*
|
|
293
|
-
* @param timezone -
|
|
294
|
-
* @returns The TaskSchedule instance.
|
|
529
|
+
* @param timezone - IANA timezone identifier (e.g., "America/New_York").
|
|
530
|
+
* @returns The TaskSchedule instance for chaining.
|
|
531
|
+
* @throws {Error} If the timezone identifier is not recognized by the system.
|
|
295
532
|
*/
|
|
296
533
|
timezone(timezone: string): this;
|
|
297
534
|
/**
|
|
298
|
-
*
|
|
299
|
-
*
|
|
535
|
+
* Modifies the execution time of the existing frequency.
|
|
536
|
+
* Typically used after frequency methods like daily() or weekly().
|
|
300
537
|
*
|
|
301
|
-
* @param time -
|
|
302
|
-
* @returns The TaskSchedule instance.
|
|
538
|
+
* @param time - 24-hour time string in "HH:mm" format.
|
|
539
|
+
* @returns The TaskSchedule instance for chaining.
|
|
540
|
+
* @throws {Error} If time format is invalid.
|
|
303
541
|
*/
|
|
304
542
|
at(time: string): this;
|
|
305
543
|
/**
|
|
306
|
-
*
|
|
307
|
-
*
|
|
544
|
+
* Enables distributed locking to ensure only one instance runs globally.
|
|
545
|
+
* Prevents duplicate execution when multiple servers are polling the same schedule.
|
|
308
546
|
*
|
|
309
|
-
* @param lockTtlSeconds -
|
|
310
|
-
* @returns The TaskSchedule instance.
|
|
547
|
+
* @param lockTtlSeconds - Duration in seconds to hold the window lock (default 300).
|
|
548
|
+
* @returns The TaskSchedule instance for chaining.
|
|
311
549
|
*/
|
|
312
550
|
onOneServer(lockTtlSeconds?: number): this;
|
|
313
551
|
/**
|
|
314
|
-
*
|
|
315
|
-
* Prevents overlapping executions of the same task.
|
|
552
|
+
* Prevents a new task instance from starting if the previous one is still running.
|
|
316
553
|
*
|
|
317
|
-
*
|
|
318
|
-
*
|
|
554
|
+
* Unlike `onOneServer()` which uses a time-window lock, this uses an execution lock
|
|
555
|
+
* to handle long-running tasks that might span multiple scheduling intervals.
|
|
556
|
+
*
|
|
557
|
+
* @param expiresAt - Max duration in seconds to keep the execution lock (default 3600).
|
|
558
|
+
* @returns The TaskSchedule instance for chaining.
|
|
559
|
+
*
|
|
560
|
+
* @example
|
|
561
|
+
* ```typescript
|
|
562
|
+
* // Prevents overlapping if the heavy operation takes > 1 minute
|
|
563
|
+
* scheduler.task('data-sync', heavySync)
|
|
564
|
+
* .everyMinute()
|
|
565
|
+
* .withoutOverlapping();
|
|
566
|
+
* ```
|
|
319
567
|
*/
|
|
320
568
|
withoutOverlapping(expiresAt?: number): this;
|
|
321
569
|
/**
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
* but affects how we handle error catching and lock release.
|
|
570
|
+
* Executes the task in background mode.
|
|
571
|
+
* The scheduler will not wait for this task to finish before proceeding to the next.
|
|
325
572
|
*
|
|
326
|
-
* @returns The TaskSchedule instance.
|
|
573
|
+
* @returns The TaskSchedule instance for chaining.
|
|
327
574
|
*/
|
|
328
575
|
runInBackground(): this;
|
|
329
576
|
/**
|
|
330
|
-
*
|
|
577
|
+
* Restricts task execution to nodes with a specific role.
|
|
331
578
|
*
|
|
332
|
-
* @param role -
|
|
333
|
-
* @returns The TaskSchedule instance.
|
|
579
|
+
* @param role - Target role identifier (e.g., "worker").
|
|
580
|
+
* @returns The TaskSchedule instance for chaining.
|
|
334
581
|
*/
|
|
335
582
|
onNode(role: string): this;
|
|
336
583
|
/**
|
|
337
|
-
*
|
|
584
|
+
* Defines a maximum execution time for the task.
|
|
585
|
+
*
|
|
586
|
+
* @param ms - Timeout duration in milliseconds.
|
|
587
|
+
* @returns The TaskSchedule instance for chaining.
|
|
588
|
+
* @throws {Error} If timeout is not a positive number.
|
|
589
|
+
*/
|
|
590
|
+
timeout(ms: number): this;
|
|
591
|
+
/**
|
|
592
|
+
* Configures automatic retry behavior for failed executions.
|
|
593
|
+
*
|
|
594
|
+
* @param attempts - Max number of retries (default 3).
|
|
595
|
+
* @param delayMs - Wait time between retries in milliseconds (default 1000).
|
|
596
|
+
* @returns The TaskSchedule instance for chaining.
|
|
597
|
+
* @throws {Error} If attempts or delay are negative.
|
|
598
|
+
*/
|
|
599
|
+
retry(attempts?: number, delayMs?: number): this;
|
|
600
|
+
/**
|
|
601
|
+
* Sets the shell command for execution-based tasks.
|
|
338
602
|
*
|
|
339
603
|
* @param command - The command string.
|
|
340
|
-
* @returns The TaskSchedule instance.
|
|
604
|
+
* @returns The TaskSchedule instance for chaining.
|
|
341
605
|
* @internal
|
|
342
606
|
*/
|
|
343
607
|
setCommand(command: string): this;
|
|
344
608
|
/**
|
|
345
|
-
*
|
|
609
|
+
* Registers a callback to execute upon successful task completion.
|
|
346
610
|
*
|
|
347
|
-
* @param callback -
|
|
348
|
-
* @returns The TaskSchedule instance.
|
|
611
|
+
* @param callback - Function to run on success.
|
|
612
|
+
* @returns The TaskSchedule instance for chaining.
|
|
349
613
|
*/
|
|
350
614
|
onSuccess(callback: ActionCallback): this;
|
|
351
615
|
/**
|
|
352
|
-
*
|
|
616
|
+
* Registers a callback to execute when the task fails.
|
|
353
617
|
*
|
|
354
|
-
* @param callback -
|
|
355
|
-
* @returns The TaskSchedule instance.
|
|
618
|
+
* @param callback - Function to run on failure.
|
|
619
|
+
* @returns The TaskSchedule instance for chaining.
|
|
356
620
|
*/
|
|
357
621
|
onFailure(callback: ActionCallback): this;
|
|
358
622
|
/**
|
|
359
|
-
*
|
|
623
|
+
* Attaches a human-readable description to the task.
|
|
360
624
|
*
|
|
361
|
-
* @param _text -
|
|
362
|
-
* @returns The TaskSchedule instance.
|
|
625
|
+
* @param _text - Description text.
|
|
626
|
+
* @returns The TaskSchedule instance for chaining.
|
|
363
627
|
*/
|
|
364
628
|
description(_text: string): this;
|
|
365
629
|
/**
|
|
366
|
-
*
|
|
630
|
+
* Returns the final task configuration.
|
|
367
631
|
*
|
|
368
|
-
* @returns The ScheduledTask object.
|
|
632
|
+
* @returns The constructed ScheduledTask object.
|
|
369
633
|
*/
|
|
370
634
|
getTask(): ScheduledTask;
|
|
371
635
|
}
|
|
372
636
|
|
|
373
637
|
/**
|
|
374
|
-
*
|
|
638
|
+
* Central registry and execution engine for scheduled tasks.
|
|
639
|
+
*
|
|
640
|
+
* Orchestrates the lifecycle of scheduled jobs by evaluating frequencies,
|
|
641
|
+
* managing distributed locks to prevent duplicate execution, and handling
|
|
642
|
+
* reliability features like retries and timeouts.
|
|
643
|
+
*
|
|
644
|
+
* Architecture Principles:
|
|
645
|
+
* - Distributed Safety: Uses lock keys scoped to minute precision for global deduplication.
|
|
646
|
+
* - Non-blocking: Executes tasks in parallel using fire-and-forget patterns.
|
|
647
|
+
* - Observability: Emits granular lifecycle hooks for monitoring and alerting.
|
|
648
|
+
*
|
|
649
|
+
* @example
|
|
650
|
+
* ```typescript
|
|
651
|
+
* const scheduler = new SchedulerManager(lockManager, logger, hooks, 'worker');
|
|
652
|
+
*
|
|
653
|
+
* // Define a maintenance task
|
|
654
|
+
* scheduler.task('daily-cleanup', async () => {
|
|
655
|
+
* await db.cleanup();
|
|
656
|
+
* })
|
|
657
|
+
* .dailyAt('03:00')
|
|
658
|
+
* .onOneServer();
|
|
659
|
+
* ```
|
|
660
|
+
*
|
|
661
|
+
* @public
|
|
375
662
|
*/
|
|
376
663
|
declare class SchedulerManager {
|
|
377
664
|
lockManager: LockManager;
|
|
@@ -379,80 +666,153 @@ declare class SchedulerManager {
|
|
|
379
666
|
private hooks?;
|
|
380
667
|
private currentNodeRole?;
|
|
381
668
|
private tasks;
|
|
669
|
+
/**
|
|
670
|
+
* Initializes the scheduler engine.
|
|
671
|
+
*
|
|
672
|
+
* @param lockManager - Backend for distributed locking.
|
|
673
|
+
* @param logger - Optional logger for operational visibility.
|
|
674
|
+
* @param hooks - Optional manager for lifecycle event hooks.
|
|
675
|
+
* @param currentNodeRole - Role identifier for the local node (used for filtering).
|
|
676
|
+
*/
|
|
382
677
|
constructor(lockManager: LockManager, logger?: Logger | undefined, hooks?: HookManager | undefined, currentNodeRole?: string | undefined);
|
|
383
678
|
/**
|
|
384
|
-
*
|
|
679
|
+
* Registers a new callback-based scheduled task.
|
|
680
|
+
*
|
|
681
|
+
* @param name - Unique task name used for identification and locking.
|
|
682
|
+
* @param callback - Asynchronous function containing the task logic.
|
|
683
|
+
* @returns A fluent TaskSchedule instance for further configuration.
|
|
385
684
|
*
|
|
386
|
-
* @
|
|
387
|
-
*
|
|
388
|
-
*
|
|
685
|
+
* @example
|
|
686
|
+
* ```typescript
|
|
687
|
+
* scheduler.task('process-queues', async () => {
|
|
688
|
+
* await queue.process();
|
|
689
|
+
* }).everyMinute();
|
|
690
|
+
* ```
|
|
389
691
|
*/
|
|
390
692
|
task(name: string, callback: () => void | Promise<void>): TaskSchedule;
|
|
391
693
|
/**
|
|
392
|
-
*
|
|
694
|
+
* Registers a shell command as a scheduled task.
|
|
393
695
|
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
396
|
-
* @
|
|
696
|
+
* Executes the command via `sh -c` on matching nodes.
|
|
697
|
+
*
|
|
698
|
+
* @param name - Unique identifier for the command task.
|
|
699
|
+
* @param command - Raw shell command string.
|
|
700
|
+
* @returns A fluent TaskSchedule instance.
|
|
701
|
+
* @throws {Error} If the shell command returns a non-zero exit code during execution.
|
|
702
|
+
*
|
|
703
|
+
* @example
|
|
704
|
+
* ```typescript
|
|
705
|
+
* scheduler.exec('log-rotate', 'logrotate /etc/logrotate.conf')
|
|
706
|
+
* .daily()
|
|
707
|
+
* .onNode('worker');
|
|
708
|
+
* ```
|
|
397
709
|
*/
|
|
398
710
|
exec(name: string, command: string): TaskSchedule;
|
|
399
711
|
/**
|
|
400
|
-
*
|
|
712
|
+
* Injects a pre-configured TaskSchedule instance into the registry.
|
|
401
713
|
*
|
|
402
|
-
* @param schedule -
|
|
714
|
+
* @param schedule - Configured task schedule to register.
|
|
403
715
|
*/
|
|
404
716
|
add(schedule: TaskSchedule): void;
|
|
405
717
|
/**
|
|
406
|
-
*
|
|
718
|
+
* Exports all registered tasks for external inspection or serialization.
|
|
407
719
|
*
|
|
408
|
-
* @returns An array of
|
|
720
|
+
* @returns An array of raw task configurations.
|
|
409
721
|
*/
|
|
410
722
|
getTasks(): ScheduledTask[];
|
|
411
723
|
/**
|
|
412
|
-
*
|
|
413
|
-
*
|
|
724
|
+
* Main evaluation loop that triggers tasks due for execution.
|
|
725
|
+
*
|
|
726
|
+
* Should be invoked every minute by a system timer (systemd/cron) or daemon.
|
|
727
|
+
* Performs frequency checks, role filtering, and parallel execution.
|
|
414
728
|
*
|
|
415
|
-
* @param date -
|
|
416
|
-
* @returns
|
|
729
|
+
* @param date - Reference time for cron evaluation (default: current time).
|
|
730
|
+
* @returns Resolves when all due tasks have been initiated.
|
|
417
731
|
*/
|
|
418
732
|
run(date?: Date): Promise<void>;
|
|
419
733
|
/**
|
|
420
|
-
*
|
|
734
|
+
* Executes an individual task after validating execution constraints.
|
|
735
|
+
*
|
|
736
|
+
* Evaluates node roles, overlapping prevention, and distributed time-window locks
|
|
737
|
+
* before initiating the actual task logic.
|
|
738
|
+
*
|
|
739
|
+
* @param task - Target task configuration.
|
|
740
|
+
* @param date - Reference time used for lock key generation.
|
|
421
741
|
*
|
|
422
|
-
* @param task - The task to execute.
|
|
423
742
|
* @internal
|
|
424
743
|
*/
|
|
425
744
|
runTask(task: ScheduledTask, date?: Date): Promise<void>;
|
|
426
745
|
/**
|
|
427
|
-
*
|
|
746
|
+
* Internal wrapper for executing task logic with reliability controls.
|
|
428
747
|
*
|
|
429
|
-
*
|
|
748
|
+
* Handles timeouts, retries, and emits lifecycle hooks for monitoring.
|
|
749
|
+
*
|
|
750
|
+
* @param task - The scheduled task to execute.
|
|
751
|
+
* @returns Resolves when the task (and its retries) completes or fails permanently.
|
|
752
|
+
*
|
|
753
|
+
* @internal
|
|
430
754
|
*/
|
|
431
755
|
private executeTask;
|
|
432
756
|
}
|
|
433
757
|
|
|
434
758
|
/**
|
|
435
|
-
*
|
|
436
|
-
*
|
|
437
|
-
*
|
|
759
|
+
* Enterprise task scheduler orbit enabling distributed cron-based job execution.
|
|
760
|
+
*
|
|
761
|
+
* Provides the infrastructure for defining scheduled tasks with distributed locking,
|
|
762
|
+
* preventing duplicate execution across multi-server deployments. Integrates seamlessly
|
|
763
|
+
* with Gravito's orbit system to expose the scheduler in both the IoC container and
|
|
764
|
+
* request context.
|
|
765
|
+
*
|
|
766
|
+
* Design rationale: Uses pluggable lock backends (memory/cache) to support both
|
|
767
|
+
* development (single-node) and production (multi-node) environments without code changes.
|
|
438
768
|
*
|
|
439
769
|
* @example
|
|
770
|
+
* Single-node development setup:
|
|
440
771
|
* ```typescript
|
|
441
|
-
*
|
|
442
|
-
*
|
|
772
|
+
* await PlanetCore.boot({
|
|
773
|
+
* config: {
|
|
774
|
+
* scheduler: {
|
|
775
|
+
* lock: { driver: 'memory' }
|
|
776
|
+
* }
|
|
777
|
+
* },
|
|
778
|
+
* orbits: [OrbitHorizon]
|
|
779
|
+
* })
|
|
780
|
+
* ```
|
|
443
781
|
*
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
*
|
|
782
|
+
* @example
|
|
783
|
+
* Multi-node production with distributed locking:
|
|
784
|
+
* ```typescript
|
|
785
|
+
* import { OrbitCache } from '@gravito/stasis'
|
|
786
|
+
*
|
|
787
|
+
* await PlanetCore.boot({
|
|
788
|
+
* config: {
|
|
789
|
+
* scheduler: {
|
|
790
|
+
* lock: { driver: 'cache' },
|
|
791
|
+
* nodeRole: 'worker'
|
|
792
|
+
* }
|
|
793
|
+
* },
|
|
794
|
+
* orbits: [
|
|
795
|
+
* OrbitCache, // Must load before Horizon
|
|
796
|
+
* OrbitHorizon
|
|
797
|
+
* ]
|
|
798
|
+
* })
|
|
447
799
|
* ```
|
|
800
|
+
*
|
|
448
801
|
* @public
|
|
449
802
|
*/
|
|
450
803
|
declare class OrbitHorizon implements GravitoOrbit {
|
|
451
804
|
/**
|
|
452
|
-
*
|
|
453
|
-
* Registers the SchedulerManager and configures the distributed lock driver.
|
|
805
|
+
* Integrates the Horizon scheduler into the PlanetCore lifecycle.
|
|
454
806
|
*
|
|
455
|
-
*
|
|
807
|
+
* Orchestrates the initialization sequence:
|
|
808
|
+
* 1. Resolves lock backend (memory or cache-based).
|
|
809
|
+
* 2. Instantiates SchedulerManager with global dependencies (logger, hooks).
|
|
810
|
+
* 3. Registers the scheduler in the IoC container for CLI and global access.
|
|
811
|
+
* 4. Injects the scheduler into the request context via middleware.
|
|
812
|
+
*
|
|
813
|
+
* @param core - PlanetCore instance providing configuration and service container.
|
|
814
|
+
*
|
|
815
|
+
* @throws {Error} If the cache driver is explicitly requested but `CacheManager` is unavailable.
|
|
456
816
|
*/
|
|
457
817
|
install(core: PlanetCore): void;
|
|
458
818
|
}
|
|
@@ -464,51 +824,66 @@ declare module '@gravito/core' {
|
|
|
464
824
|
}
|
|
465
825
|
|
|
466
826
|
/**
|
|
467
|
-
*
|
|
827
|
+
* Encapsulates the outcome of a child process execution.
|
|
828
|
+
*
|
|
829
|
+
* Provides status codes and captured stream outputs for programmatic inspection.
|
|
468
830
|
*
|
|
469
831
|
* @public
|
|
470
832
|
* @since 3.0.0
|
|
471
833
|
*/
|
|
472
834
|
interface ProcessResult {
|
|
473
|
-
/**
|
|
835
|
+
/** numeric exit code returned by the operating system (0 typically denotes success). */
|
|
474
836
|
exitCode: number;
|
|
475
|
-
/**
|
|
837
|
+
/** Captured UTF-8 encoded text from the standard output stream. */
|
|
476
838
|
stdout: string;
|
|
477
|
-
/**
|
|
839
|
+
/** Captured UTF-8 encoded text from the standard error stream. */
|
|
478
840
|
stderr: string;
|
|
479
|
-
/**
|
|
841
|
+
/** Semantic indicator of successful completion (mapped from exitCode === 0). */
|
|
480
842
|
success: boolean;
|
|
481
843
|
}
|
|
482
844
|
/**
|
|
483
|
-
*
|
|
845
|
+
* Spawns a shell command and asynchronously captures its full output.
|
|
846
|
+
*
|
|
847
|
+
* Leverages the Gravito runtime adapter to ensure compatibility across different
|
|
848
|
+
* JavaScript runtimes (Bun, Node.js). Executes commands within a shell (`sh -c`)
|
|
849
|
+
* to support pipes, redirects, and environment variables.
|
|
850
|
+
*
|
|
851
|
+
* @param command - Raw shell command string to execute.
|
|
852
|
+
* @returns Resolves to a detailed `ProcessResult` object.
|
|
484
853
|
*
|
|
485
|
-
* @
|
|
486
|
-
*
|
|
854
|
+
* @example
|
|
855
|
+
* ```typescript
|
|
856
|
+
* const result = await runProcess('ls -lh /var/logs');
|
|
857
|
+
* if (result.success) {
|
|
858
|
+
* processLogs(result.stdout);
|
|
859
|
+
* }
|
|
860
|
+
* ```
|
|
487
861
|
*
|
|
488
862
|
* @public
|
|
489
863
|
* @since 3.0.0
|
|
490
864
|
*/
|
|
491
865
|
declare function runProcess(command: string): Promise<ProcessResult>;
|
|
492
866
|
/**
|
|
493
|
-
*
|
|
867
|
+
* Utility class for managing child process lifecycles.
|
|
494
868
|
*
|
|
495
|
-
*
|
|
496
|
-
*
|
|
869
|
+
* Acts as a wrapper for `runProcess` to maintain compatibility with earlier
|
|
870
|
+
* versions of the framework.
|
|
497
871
|
*
|
|
498
872
|
* @example
|
|
499
873
|
* ```typescript
|
|
500
|
-
* const
|
|
501
|
-
* if (result.success) {
|
|
502
|
-
* console.log(result.stdout)
|
|
503
|
-
* } else {
|
|
504
|
-
* console.error(result.stderr)
|
|
505
|
-
* }
|
|
874
|
+
* const { stdout } = await Process.run('bun -v');
|
|
506
875
|
* ```
|
|
507
876
|
*
|
|
508
877
|
* @since 3.0.0
|
|
509
878
|
* @public
|
|
510
879
|
*/
|
|
511
880
|
declare class Process {
|
|
881
|
+
/**
|
|
882
|
+
* Static alias for `runProcess`.
|
|
883
|
+
*
|
|
884
|
+
* @param command - Command to execute.
|
|
885
|
+
* @returns Process outcome.
|
|
886
|
+
*/
|
|
512
887
|
static run(command: string): Promise<ProcessResult>;
|
|
513
888
|
}
|
|
514
889
|
|