@cloudnux/local-cloud-provider 0.18.0 → 0.19.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.
@@ -1,1015 +1,6 @@
1
- // src/logging/pretty-writer.ts
2
- import chalk from "chalk";
3
- import { EOL as EOL2 } from "os";
4
-
5
- // ../../../node_modules/lodash-es/_freeGlobal.js
6
- var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
7
- var freeGlobal_default = freeGlobal;
8
-
9
- // ../../../node_modules/lodash-es/_root.js
10
- var freeSelf = typeof self == "object" && self && self.Object === Object && self;
11
- var root = freeGlobal_default || freeSelf || Function("return this")();
12
- var root_default = root;
13
-
14
- // ../../../node_modules/lodash-es/_Symbol.js
15
- var Symbol = root_default.Symbol;
16
- var Symbol_default = Symbol;
17
-
18
- // ../../../node_modules/lodash-es/_getRawTag.js
19
- var objectProto = Object.prototype;
20
- var hasOwnProperty = objectProto.hasOwnProperty;
21
- var nativeObjectToString = objectProto.toString;
22
- var symToStringTag = Symbol_default ? Symbol_default.toStringTag : void 0;
23
- function getRawTag(value) {
24
- var isOwn = hasOwnProperty.call(value, symToStringTag), tag = value[symToStringTag];
25
- try {
26
- value[symToStringTag] = void 0;
27
- var unmasked = true;
28
- } catch (e) {
29
- }
30
- var result = nativeObjectToString.call(value);
31
- if (unmasked) {
32
- if (isOwn) {
33
- value[symToStringTag] = tag;
34
- } else {
35
- delete value[symToStringTag];
36
- }
37
- }
38
- return result;
39
- }
40
- var getRawTag_default = getRawTag;
41
-
42
- // ../../../node_modules/lodash-es/_objectToString.js
43
- var objectProto2 = Object.prototype;
44
- var nativeObjectToString2 = objectProto2.toString;
45
- function objectToString(value) {
46
- return nativeObjectToString2.call(value);
47
- }
48
- var objectToString_default = objectToString;
49
-
50
- // ../../../node_modules/lodash-es/_baseGetTag.js
51
- var nullTag = "[object Null]";
52
- var undefinedTag = "[object Undefined]";
53
- var symToStringTag2 = Symbol_default ? Symbol_default.toStringTag : void 0;
54
- function baseGetTag(value) {
55
- if (value == null) {
56
- return value === void 0 ? undefinedTag : nullTag;
57
- }
58
- return symToStringTag2 && symToStringTag2 in Object(value) ? getRawTag_default(value) : objectToString_default(value);
59
- }
60
- var baseGetTag_default = baseGetTag;
61
-
62
- // ../../../node_modules/lodash-es/isObjectLike.js
63
- function isObjectLike(value) {
64
- return value != null && typeof value == "object";
65
- }
66
- var isObjectLike_default = isObjectLike;
67
-
68
- // ../../../node_modules/lodash-es/isSymbol.js
69
- var symbolTag = "[object Symbol]";
70
- function isSymbol(value) {
71
- return typeof value == "symbol" || isObjectLike_default(value) && baseGetTag_default(value) == symbolTag;
72
- }
73
- var isSymbol_default = isSymbol;
74
-
75
- // ../../../node_modules/lodash-es/_arrayMap.js
76
- function arrayMap(array2, iteratee) {
77
- var index = -1, length = array2 == null ? 0 : array2.length, result = Array(length);
78
- while (++index < length) {
79
- result[index] = iteratee(array2[index], index, array2);
80
- }
81
- return result;
82
- }
83
- var arrayMap_default = arrayMap;
84
-
85
- // ../../../node_modules/lodash-es/isArray.js
86
- var isArray = Array.isArray;
87
- var isArray_default = isArray;
88
-
89
- // ../../../node_modules/lodash-es/_baseToString.js
90
- var INFINITY = 1 / 0;
91
- var symbolProto = Symbol_default ? Symbol_default.prototype : void 0;
92
- var symbolToString = symbolProto ? symbolProto.toString : void 0;
93
- function baseToString(value) {
94
- if (typeof value == "string") {
95
- return value;
96
- }
97
- if (isArray_default(value)) {
98
- return arrayMap_default(value, baseToString) + "";
99
- }
100
- if (isSymbol_default(value)) {
101
- return symbolToString ? symbolToString.call(value) : "";
102
- }
103
- var result = value + "";
104
- return result == "0" && 1 / value == -INFINITY ? "-0" : result;
105
- }
106
- var baseToString_default = baseToString;
107
-
108
- // ../../../node_modules/lodash-es/_trimmedEndIndex.js
109
- var reWhitespace = /\s/;
110
- function trimmedEndIndex(string) {
111
- var index = string.length;
112
- while (index-- && reWhitespace.test(string.charAt(index))) {
113
- }
114
- return index;
115
- }
116
- var trimmedEndIndex_default = trimmedEndIndex;
117
-
118
- // ../../../node_modules/lodash-es/_baseTrim.js
119
- var reTrimStart = /^\s+/;
120
- function baseTrim(string) {
121
- return string ? string.slice(0, trimmedEndIndex_default(string) + 1).replace(reTrimStart, "") : string;
122
- }
123
- var baseTrim_default = baseTrim;
124
-
125
- // ../../../node_modules/lodash-es/isObject.js
126
- function isObject(value) {
127
- var type = typeof value;
128
- return value != null && (type == "object" || type == "function");
129
- }
130
- var isObject_default = isObject;
131
-
132
- // ../../../node_modules/lodash-es/isFunction.js
133
- var asyncTag = "[object AsyncFunction]";
134
- var funcTag = "[object Function]";
135
- var genTag = "[object GeneratorFunction]";
136
- var proxyTag = "[object Proxy]";
137
- function isFunction(value) {
138
- if (!isObject_default(value)) {
139
- return false;
140
- }
141
- var tag = baseGetTag_default(value);
142
- return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
143
- }
144
- var isFunction_default = isFunction;
145
-
146
- // ../../../node_modules/lodash-es/_coreJsData.js
147
- var coreJsData = root_default["__core-js_shared__"];
148
- var coreJsData_default = coreJsData;
149
-
150
- // ../../../node_modules/lodash-es/_isMasked.js
151
- var maskSrcKey = function() {
152
- var uid = /[^.]+$/.exec(coreJsData_default && coreJsData_default.keys && coreJsData_default.keys.IE_PROTO || "");
153
- return uid ? "Symbol(src)_1." + uid : "";
154
- }();
155
- function isMasked(func) {
156
- return !!maskSrcKey && maskSrcKey in func;
157
- }
158
- var isMasked_default = isMasked;
159
-
160
- // ../../../node_modules/lodash-es/_toSource.js
161
- var funcProto = Function.prototype;
162
- var funcToString = funcProto.toString;
163
- function toSource(func) {
164
- if (func != null) {
165
- try {
166
- return funcToString.call(func);
167
- } catch (e) {
168
- }
169
- try {
170
- return func + "";
171
- } catch (e) {
172
- }
173
- }
174
- return "";
175
- }
176
- var toSource_default = toSource;
177
-
178
- // ../../../node_modules/lodash-es/_baseIsNative.js
179
- var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
180
- var reIsHostCtor = /^\[object .+?Constructor\]$/;
181
- var funcProto2 = Function.prototype;
182
- var objectProto3 = Object.prototype;
183
- var funcToString2 = funcProto2.toString;
184
- var hasOwnProperty2 = objectProto3.hasOwnProperty;
185
- var reIsNative = RegExp(
186
- "^" + funcToString2.call(hasOwnProperty2).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"
187
- );
188
- function baseIsNative(value) {
189
- if (!isObject_default(value) || isMasked_default(value)) {
190
- return false;
191
- }
192
- var pattern = isFunction_default(value) ? reIsNative : reIsHostCtor;
193
- return pattern.test(toSource_default(value));
194
- }
195
- var baseIsNative_default = baseIsNative;
196
-
197
- // ../../../node_modules/lodash-es/_getValue.js
198
- function getValue(object, key) {
199
- return object == null ? void 0 : object[key];
200
- }
201
- var getValue_default = getValue;
202
-
203
- // ../../../node_modules/lodash-es/_getNative.js
204
- function getNative(object, key) {
205
- var value = getValue_default(object, key);
206
- return baseIsNative_default(value) ? value : void 0;
207
- }
208
- var getNative_default = getNative;
209
-
210
- // ../../../node_modules/lodash-es/_baseFindIndex.js
211
- function baseFindIndex(array2, predicate, fromIndex, fromRight) {
212
- var length = array2.length, index = fromIndex + (fromRight ? 1 : -1);
213
- while (fromRight ? index-- : ++index < length) {
214
- if (predicate(array2[index], index, array2)) {
215
- return index;
216
- }
217
- }
218
- return -1;
219
- }
220
- var baseFindIndex_default = baseFindIndex;
221
-
222
- // ../../../node_modules/lodash-es/_baseIsNaN.js
223
- function baseIsNaN(value) {
224
- return value !== value;
225
- }
226
- var baseIsNaN_default = baseIsNaN;
227
-
228
- // ../../../node_modules/lodash-es/_strictIndexOf.js
229
- function strictIndexOf(array2, value, fromIndex) {
230
- var index = fromIndex - 1, length = array2.length;
231
- while (++index < length) {
232
- if (array2[index] === value) {
233
- return index;
234
- }
235
- }
236
- return -1;
237
- }
238
- var strictIndexOf_default = strictIndexOf;
239
-
240
- // ../../../node_modules/lodash-es/_baseIndexOf.js
241
- function baseIndexOf(array2, value, fromIndex) {
242
- return value === value ? strictIndexOf_default(array2, value, fromIndex) : baseFindIndex_default(array2, baseIsNaN_default, fromIndex);
243
- }
244
- var baseIndexOf_default = baseIndexOf;
245
-
246
- // ../../../node_modules/lodash-es/_isIndex.js
247
- var MAX_SAFE_INTEGER = 9007199254740991;
248
- var reIsUint = /^(?:0|[1-9]\d*)$/;
249
- function isIndex(value, length) {
250
- var type = typeof value;
251
- length = length == null ? MAX_SAFE_INTEGER : length;
252
- return !!length && (type == "number" || type != "symbol" && reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length);
253
- }
254
- var isIndex_default = isIndex;
255
-
256
- // ../../../node_modules/lodash-es/eq.js
257
- function eq(value, other) {
258
- return value === other || value !== value && other !== other;
259
- }
260
- var eq_default = eq;
261
-
262
- // ../../../node_modules/lodash-es/isLength.js
263
- var MAX_SAFE_INTEGER2 = 9007199254740991;
264
- function isLength(value) {
265
- return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER2;
266
- }
267
- var isLength_default = isLength;
268
-
269
- // ../../../node_modules/lodash-es/_baseIsArguments.js
270
- var argsTag = "[object Arguments]";
271
- function baseIsArguments(value) {
272
- return isObjectLike_default(value) && baseGetTag_default(value) == argsTag;
273
- }
274
- var baseIsArguments_default = baseIsArguments;
275
-
276
- // ../../../node_modules/lodash-es/isArguments.js
277
- var objectProto4 = Object.prototype;
278
- var hasOwnProperty3 = objectProto4.hasOwnProperty;
279
- var propertyIsEnumerable = objectProto4.propertyIsEnumerable;
280
- var isArguments = baseIsArguments_default(/* @__PURE__ */ function() {
281
- return arguments;
282
- }()) ? baseIsArguments_default : function(value) {
283
- return isObjectLike_default(value) && hasOwnProperty3.call(value, "callee") && !propertyIsEnumerable.call(value, "callee");
284
- };
285
- var isArguments_default = isArguments;
286
-
287
- // ../../../node_modules/lodash-es/_isKey.js
288
- var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/;
289
- var reIsPlainProp = /^\w*$/;
290
- function isKey(value, object) {
291
- if (isArray_default(value)) {
292
- return false;
293
- }
294
- var type = typeof value;
295
- if (type == "number" || type == "symbol" || type == "boolean" || value == null || isSymbol_default(value)) {
296
- return true;
297
- }
298
- return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || object != null && value in Object(object);
299
- }
300
- var isKey_default = isKey;
301
-
302
- // ../../../node_modules/lodash-es/_nativeCreate.js
303
- var nativeCreate = getNative_default(Object, "create");
304
- var nativeCreate_default = nativeCreate;
305
-
306
- // ../../../node_modules/lodash-es/_hashClear.js
307
- function hashClear() {
308
- this.__data__ = nativeCreate_default ? nativeCreate_default(null) : {};
309
- this.size = 0;
310
- }
311
- var hashClear_default = hashClear;
312
-
313
- // ../../../node_modules/lodash-es/_hashDelete.js
314
- function hashDelete(key) {
315
- var result = this.has(key) && delete this.__data__[key];
316
- this.size -= result ? 1 : 0;
317
- return result;
318
- }
319
- var hashDelete_default = hashDelete;
320
-
321
- // ../../../node_modules/lodash-es/_hashGet.js
322
- var HASH_UNDEFINED = "__lodash_hash_undefined__";
323
- var objectProto5 = Object.prototype;
324
- var hasOwnProperty4 = objectProto5.hasOwnProperty;
325
- function hashGet(key) {
326
- var data = this.__data__;
327
- if (nativeCreate_default) {
328
- var result = data[key];
329
- return result === HASH_UNDEFINED ? void 0 : result;
330
- }
331
- return hasOwnProperty4.call(data, key) ? data[key] : void 0;
332
- }
333
- var hashGet_default = hashGet;
334
-
335
- // ../../../node_modules/lodash-es/_hashHas.js
336
- var objectProto6 = Object.prototype;
337
- var hasOwnProperty5 = objectProto6.hasOwnProperty;
338
- function hashHas(key) {
339
- var data = this.__data__;
340
- return nativeCreate_default ? data[key] !== void 0 : hasOwnProperty5.call(data, key);
341
- }
342
- var hashHas_default = hashHas;
343
-
344
- // ../../../node_modules/lodash-es/_hashSet.js
345
- var HASH_UNDEFINED2 = "__lodash_hash_undefined__";
346
- function hashSet(key, value) {
347
- var data = this.__data__;
348
- this.size += this.has(key) ? 0 : 1;
349
- data[key] = nativeCreate_default && value === void 0 ? HASH_UNDEFINED2 : value;
350
- return this;
351
- }
352
- var hashSet_default = hashSet;
353
-
354
- // ../../../node_modules/lodash-es/_Hash.js
355
- function Hash(entries) {
356
- var index = -1, length = entries == null ? 0 : entries.length;
357
- this.clear();
358
- while (++index < length) {
359
- var entry = entries[index];
360
- this.set(entry[0], entry[1]);
361
- }
362
- }
363
- Hash.prototype.clear = hashClear_default;
364
- Hash.prototype["delete"] = hashDelete_default;
365
- Hash.prototype.get = hashGet_default;
366
- Hash.prototype.has = hashHas_default;
367
- Hash.prototype.set = hashSet_default;
368
- var Hash_default = Hash;
369
-
370
- // ../../../node_modules/lodash-es/_listCacheClear.js
371
- function listCacheClear() {
372
- this.__data__ = [];
373
- this.size = 0;
374
- }
375
- var listCacheClear_default = listCacheClear;
376
-
377
- // ../../../node_modules/lodash-es/_assocIndexOf.js
378
- function assocIndexOf(array2, key) {
379
- var length = array2.length;
380
- while (length--) {
381
- if (eq_default(array2[length][0], key)) {
382
- return length;
383
- }
384
- }
385
- return -1;
386
- }
387
- var assocIndexOf_default = assocIndexOf;
388
-
389
- // ../../../node_modules/lodash-es/_listCacheDelete.js
390
- var arrayProto = Array.prototype;
391
- var splice = arrayProto.splice;
392
- function listCacheDelete(key) {
393
- var data = this.__data__, index = assocIndexOf_default(data, key);
394
- if (index < 0) {
395
- return false;
396
- }
397
- var lastIndex = data.length - 1;
398
- if (index == lastIndex) {
399
- data.pop();
400
- } else {
401
- splice.call(data, index, 1);
402
- }
403
- --this.size;
404
- return true;
405
- }
406
- var listCacheDelete_default = listCacheDelete;
407
-
408
- // ../../../node_modules/lodash-es/_listCacheGet.js
409
- function listCacheGet(key) {
410
- var data = this.__data__, index = assocIndexOf_default(data, key);
411
- return index < 0 ? void 0 : data[index][1];
412
- }
413
- var listCacheGet_default = listCacheGet;
414
-
415
- // ../../../node_modules/lodash-es/_listCacheHas.js
416
- function listCacheHas(key) {
417
- return assocIndexOf_default(this.__data__, key) > -1;
418
- }
419
- var listCacheHas_default = listCacheHas;
420
-
421
- // ../../../node_modules/lodash-es/_listCacheSet.js
422
- function listCacheSet(key, value) {
423
- var data = this.__data__, index = assocIndexOf_default(data, key);
424
- if (index < 0) {
425
- ++this.size;
426
- data.push([key, value]);
427
- } else {
428
- data[index][1] = value;
429
- }
430
- return this;
431
- }
432
- var listCacheSet_default = listCacheSet;
433
-
434
- // ../../../node_modules/lodash-es/_ListCache.js
435
- function ListCache(entries) {
436
- var index = -1, length = entries == null ? 0 : entries.length;
437
- this.clear();
438
- while (++index < length) {
439
- var entry = entries[index];
440
- this.set(entry[0], entry[1]);
441
- }
442
- }
443
- ListCache.prototype.clear = listCacheClear_default;
444
- ListCache.prototype["delete"] = listCacheDelete_default;
445
- ListCache.prototype.get = listCacheGet_default;
446
- ListCache.prototype.has = listCacheHas_default;
447
- ListCache.prototype.set = listCacheSet_default;
448
- var ListCache_default = ListCache;
449
-
450
- // ../../../node_modules/lodash-es/_Map.js
451
- var Map = getNative_default(root_default, "Map");
452
- var Map_default = Map;
453
-
454
- // ../../../node_modules/lodash-es/_mapCacheClear.js
455
- function mapCacheClear() {
456
- this.size = 0;
457
- this.__data__ = {
458
- "hash": new Hash_default(),
459
- "map": new (Map_default || ListCache_default)(),
460
- "string": new Hash_default()
461
- };
462
- }
463
- var mapCacheClear_default = mapCacheClear;
464
-
465
- // ../../../node_modules/lodash-es/_isKeyable.js
466
- function isKeyable(value) {
467
- var type = typeof value;
468
- return type == "string" || type == "number" || type == "symbol" || type == "boolean" ? value !== "__proto__" : value === null;
469
- }
470
- var isKeyable_default = isKeyable;
471
-
472
- // ../../../node_modules/lodash-es/_getMapData.js
473
- function getMapData(map, key) {
474
- var data = map.__data__;
475
- return isKeyable_default(key) ? data[typeof key == "string" ? "string" : "hash"] : data.map;
476
- }
477
- var getMapData_default = getMapData;
478
-
479
- // ../../../node_modules/lodash-es/_mapCacheDelete.js
480
- function mapCacheDelete(key) {
481
- var result = getMapData_default(this, key)["delete"](key);
482
- this.size -= result ? 1 : 0;
483
- return result;
484
- }
485
- var mapCacheDelete_default = mapCacheDelete;
486
-
487
- // ../../../node_modules/lodash-es/_mapCacheGet.js
488
- function mapCacheGet(key) {
489
- return getMapData_default(this, key).get(key);
490
- }
491
- var mapCacheGet_default = mapCacheGet;
492
-
493
- // ../../../node_modules/lodash-es/_mapCacheHas.js
494
- function mapCacheHas(key) {
495
- return getMapData_default(this, key).has(key);
496
- }
497
- var mapCacheHas_default = mapCacheHas;
498
-
499
- // ../../../node_modules/lodash-es/_mapCacheSet.js
500
- function mapCacheSet(key, value) {
501
- var data = getMapData_default(this, key), size = data.size;
502
- data.set(key, value);
503
- this.size += data.size == size ? 0 : 1;
504
- return this;
505
- }
506
- var mapCacheSet_default = mapCacheSet;
507
-
508
- // ../../../node_modules/lodash-es/_MapCache.js
509
- function MapCache(entries) {
510
- var index = -1, length = entries == null ? 0 : entries.length;
511
- this.clear();
512
- while (++index < length) {
513
- var entry = entries[index];
514
- this.set(entry[0], entry[1]);
515
- }
516
- }
517
- MapCache.prototype.clear = mapCacheClear_default;
518
- MapCache.prototype["delete"] = mapCacheDelete_default;
519
- MapCache.prototype.get = mapCacheGet_default;
520
- MapCache.prototype.has = mapCacheHas_default;
521
- MapCache.prototype.set = mapCacheSet_default;
522
- var MapCache_default = MapCache;
523
-
524
- // ../../../node_modules/lodash-es/memoize.js
525
- var FUNC_ERROR_TEXT = "Expected a function";
526
- function memoize(func, resolver) {
527
- if (typeof func != "function" || resolver != null && typeof resolver != "function") {
528
- throw new TypeError(FUNC_ERROR_TEXT);
529
- }
530
- var memoized = function() {
531
- var args = arguments, key = resolver ? resolver.apply(this, args) : args[0], cache = memoized.cache;
532
- if (cache.has(key)) {
533
- return cache.get(key);
534
- }
535
- var result = func.apply(this, args);
536
- memoized.cache = cache.set(key, result) || cache;
537
- return result;
538
- };
539
- memoized.cache = new (memoize.Cache || MapCache_default)();
540
- return memoized;
541
- }
542
- memoize.Cache = MapCache_default;
543
- var memoize_default = memoize;
544
-
545
- // ../../../node_modules/lodash-es/_memoizeCapped.js
546
- var MAX_MEMOIZE_SIZE = 500;
547
- function memoizeCapped(func) {
548
- var result = memoize_default(func, function(key) {
549
- if (cache.size === MAX_MEMOIZE_SIZE) {
550
- cache.clear();
551
- }
552
- return key;
553
- });
554
- var cache = result.cache;
555
- return result;
556
- }
557
- var memoizeCapped_default = memoizeCapped;
558
-
559
- // ../../../node_modules/lodash-es/_stringToPath.js
560
- var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
561
- var reEscapeChar = /\\(\\)?/g;
562
- var stringToPath = memoizeCapped_default(function(string) {
563
- var result = [];
564
- if (string.charCodeAt(0) === 46) {
565
- result.push("");
566
- }
567
- string.replace(rePropName, function(match, number, quote, subString) {
568
- result.push(quote ? subString.replace(reEscapeChar, "$1") : number || match);
569
- });
570
- return result;
571
- });
572
- var stringToPath_default = stringToPath;
573
-
574
- // ../../../node_modules/lodash-es/toString.js
575
- function toString(value) {
576
- return value == null ? "" : baseToString_default(value);
577
- }
578
- var toString_default = toString;
579
-
580
- // ../../../node_modules/lodash-es/_castPath.js
581
- function castPath(value, object) {
582
- if (isArray_default(value)) {
583
- return value;
584
- }
585
- return isKey_default(value, object) ? [value] : stringToPath_default(toString_default(value));
586
- }
587
- var castPath_default = castPath;
588
-
589
- // ../../../node_modules/lodash-es/_toKey.js
590
- var INFINITY2 = 1 / 0;
591
- function toKey(value) {
592
- if (typeof value == "string" || isSymbol_default(value)) {
593
- return value;
594
- }
595
- var result = value + "";
596
- return result == "0" && 1 / value == -INFINITY2 ? "-0" : result;
597
- }
598
- var toKey_default = toKey;
599
-
600
- // ../../../node_modules/lodash-es/_baseSlice.js
601
- function baseSlice(array2, start, end) {
602
- var index = -1, length = array2.length;
603
- if (start < 0) {
604
- start = -start > length ? 0 : length + start;
605
- }
606
- end = end > length ? length : end;
607
- if (end < 0) {
608
- end += length;
609
- }
610
- length = start > end ? 0 : end - start >>> 0;
611
- start >>>= 0;
612
- var result = Array(length);
613
- while (++index < length) {
614
- result[index] = array2[index + start];
615
- }
616
- return result;
617
- }
618
- var baseSlice_default = baseSlice;
619
-
620
- // ../../../node_modules/lodash-es/_castSlice.js
621
- function castSlice(array2, start, end) {
622
- var length = array2.length;
623
- end = end === void 0 ? length : end;
624
- return !start && end >= length ? array2 : baseSlice_default(array2, start, end);
625
- }
626
- var castSlice_default = castSlice;
627
-
628
- // ../../../node_modules/lodash-es/_hasUnicode.js
629
- var rsAstralRange = "\\ud800-\\udfff";
630
- var rsComboMarksRange = "\\u0300-\\u036f";
631
- var reComboHalfMarksRange = "\\ufe20-\\ufe2f";
632
- var rsComboSymbolsRange = "\\u20d0-\\u20ff";
633
- var rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange;
634
- var rsVarRange = "\\ufe0e\\ufe0f";
635
- var rsZWJ = "\\u200d";
636
- var reHasUnicode = RegExp("[" + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + "]");
637
- function hasUnicode(string) {
638
- return reHasUnicode.test(string);
639
- }
640
- var hasUnicode_default = hasUnicode;
641
-
642
- // ../../../node_modules/lodash-es/_asciiToArray.js
643
- function asciiToArray(string) {
644
- return string.split("");
645
- }
646
- var asciiToArray_default = asciiToArray;
647
-
648
- // ../../../node_modules/lodash-es/_unicodeToArray.js
649
- var rsAstralRange2 = "\\ud800-\\udfff";
650
- var rsComboMarksRange2 = "\\u0300-\\u036f";
651
- var reComboHalfMarksRange2 = "\\ufe20-\\ufe2f";
652
- var rsComboSymbolsRange2 = "\\u20d0-\\u20ff";
653
- var rsComboRange2 = rsComboMarksRange2 + reComboHalfMarksRange2 + rsComboSymbolsRange2;
654
- var rsVarRange2 = "\\ufe0e\\ufe0f";
655
- var rsAstral = "[" + rsAstralRange2 + "]";
656
- var rsCombo = "[" + rsComboRange2 + "]";
657
- var rsFitz = "\\ud83c[\\udffb-\\udfff]";
658
- var rsModifier = "(?:" + rsCombo + "|" + rsFitz + ")";
659
- var rsNonAstral = "[^" + rsAstralRange2 + "]";
660
- var rsRegional = "(?:\\ud83c[\\udde6-\\uddff]){2}";
661
- var rsSurrPair = "[\\ud800-\\udbff][\\udc00-\\udfff]";
662
- var rsZWJ2 = "\\u200d";
663
- var reOptMod = rsModifier + "?";
664
- var rsOptVar = "[" + rsVarRange2 + "]?";
665
- var rsOptJoin = "(?:" + rsZWJ2 + "(?:" + [rsNonAstral, rsRegional, rsSurrPair].join("|") + ")" + rsOptVar + reOptMod + ")*";
666
- var rsSeq = rsOptVar + reOptMod + rsOptJoin;
667
- var rsSymbol = "(?:" + [rsNonAstral + rsCombo + "?", rsCombo, rsRegional, rsSurrPair, rsAstral].join("|") + ")";
668
- var reUnicode = RegExp(rsFitz + "(?=" + rsFitz + ")|" + rsSymbol + rsSeq, "g");
669
- function unicodeToArray(string) {
670
- return string.match(reUnicode) || [];
671
- }
672
- var unicodeToArray_default = unicodeToArray;
673
-
674
- // ../../../node_modules/lodash-es/_stringToArray.js
675
- function stringToArray(string) {
676
- return hasUnicode_default(string) ? unicodeToArray_default(string) : asciiToArray_default(string);
677
- }
678
- var stringToArray_default = stringToArray;
679
-
680
- // ../../../node_modules/lodash-es/_hasPath.js
681
- function hasPath(object, path2, hasFunc) {
682
- path2 = castPath_default(path2, object);
683
- var index = -1, length = path2.length, result = false;
684
- while (++index < length) {
685
- var key = toKey_default(path2[index]);
686
- if (!(result = object != null && hasFunc(object, key))) {
687
- break;
688
- }
689
- object = object[key];
690
- }
691
- if (result || ++index != length) {
692
- return result;
693
- }
694
- length = object == null ? 0 : object.length;
695
- return !!length && isLength_default(length) && isIndex_default(key, length) && (isArray_default(object) || isArguments_default(object));
696
- }
697
- var hasPath_default = hasPath;
698
-
699
- // ../../../node_modules/lodash-es/_baseHas.js
700
- var objectProto7 = Object.prototype;
701
- var hasOwnProperty6 = objectProto7.hasOwnProperty;
702
- function baseHas(object, key) {
703
- return object != null && hasOwnProperty6.call(object, key);
704
- }
705
- var baseHas_default = baseHas;
706
-
707
- // ../../../node_modules/lodash-es/has.js
708
- function has(object, path2) {
709
- return object != null && hasPath_default(object, path2, baseHas_default);
710
- }
711
- var has_default = has;
712
-
713
- // ../../../node_modules/lodash-es/_charsEndIndex.js
714
- function charsEndIndex(strSymbols, chrSymbols) {
715
- var index = strSymbols.length;
716
- while (index-- && baseIndexOf_default(chrSymbols, strSymbols[index], 0) > -1) {
717
- }
718
- return index;
719
- }
720
- var charsEndIndex_default = charsEndIndex;
721
-
722
- // ../../../node_modules/lodash-es/_charsStartIndex.js
723
- function charsStartIndex(strSymbols, chrSymbols) {
724
- var index = -1, length = strSymbols.length;
725
- while (++index < length && baseIndexOf_default(chrSymbols, strSymbols[index], 0) > -1) {
726
- }
727
- return index;
728
- }
729
- var charsStartIndex_default = charsStartIndex;
730
-
731
- // ../../../node_modules/lodash-es/trim.js
732
- function trim(string, chars, guard) {
733
- string = toString_default(string);
734
- if (string && (guard || chars === void 0)) {
735
- return baseTrim_default(string);
736
- }
737
- if (!string || !(chars = baseToString_default(chars))) {
738
- return string;
739
- }
740
- var strSymbols = stringToArray_default(string), chrSymbols = stringToArray_default(chars), start = charsStartIndex_default(strSymbols, chrSymbols), end = charsEndIndex_default(strSymbols, chrSymbols) + 1;
741
- return castSlice_default(strSymbols, start, end).join("");
742
- }
743
- var trim_default = trim;
744
-
745
- // ../../utils/src/config/env.ts
746
- function _env(key, defaultValue) {
747
- return has_default(process.env, key) ? process.env[key] ?? "" : defaultValue ?? "";
748
- }
749
- function int(key, defaultValue) {
750
- if (!has_default(process.env, key)) {
751
- return defaultValue ?? 0;
752
- }
753
- const value = process.env[key] ?? "0";
754
- return parseInt(value, 10);
755
- }
756
- function float(key, defaultValue) {
757
- if (!has_default(process.env, key)) {
758
- return defaultValue ?? 0;
759
- }
760
- const value = process.env[key] ?? "0";
761
- return parseFloat(value);
762
- }
763
- function bool(key, defaultValue) {
764
- if (!has_default(process.env, key)) {
765
- return defaultValue ?? false;
766
- }
767
- const value = process.env[key];
768
- return value === "true";
769
- }
770
- function json(key, defaultValue) {
771
- if (!has_default(process.env, key)) {
772
- return defaultValue ?? {};
773
- }
774
- const value = process.env[key] ?? "{}";
775
- try {
776
- return JSON.parse(value);
777
- } catch (error) {
778
- throw new Error(`Invalid json environment variable ${key}: ${error.message}`);
779
- }
780
- }
781
- function array(key, defaultValue) {
782
- if (!has_default(process.env, key)) {
783
- return defaultValue ?? [];
784
- }
785
- let value = process.env[key] ?? "";
786
- if (value.startsWith("[") && value.endsWith("]")) {
787
- value = value.substring(1, value.length - 1);
788
- }
789
- return value.split(",").map((v) => {
790
- return trim_default(trim_default(v, " "), '"');
791
- });
792
- }
793
- function date(key, defaultValue) {
794
- if (!has_default(process.env, key)) {
795
- return defaultValue ?? /* @__PURE__ */ new Date();
796
- }
797
- const value = process.env[key] ?? Date();
798
- return new Date(value);
799
- }
800
- var utils = {
801
- int,
802
- float,
803
- bool,
804
- json,
805
- array,
806
- date,
807
- /**
808
- * Gets a value from env that matches oneOf provided values
809
- * @param {string} key
810
- * @param {string[]} expectedValues
811
- * @param {string|undefined} defaultValue
812
- * @returns {string|undefined}
813
- */
814
- oneOf(key, expectedValues, defaultValue) {
815
- if (!expectedValues) {
816
- throw new Error(`env.oneOf requires expectedValues`);
817
- }
818
- if (defaultValue && !expectedValues.includes(defaultValue)) {
819
- throw new Error(`env.oneOf requires defaultValue to be included in expectedValues`);
820
- }
821
- const rawValue = env(key, defaultValue);
822
- return expectedValues.includes(rawValue) ? rawValue : defaultValue ?? "";
823
- }
824
- };
825
- var env = Object.assign(_env, utils);
826
-
827
- // ../../utils/src/logging/types.ts
828
- var logLevels = {
829
- fatal: -1,
830
- error: 0,
831
- warn: 1,
832
- info: 2,
833
- debug: 3,
834
- trace: 4
835
- };
836
-
837
- // ../../utils/src/logging/error-to-string.ts
838
- var safeJsonStringify = (value) => {
839
- const seen = /* @__PURE__ */ new WeakSet();
840
- return JSON.stringify(value, (key, currentValue) => {
841
- if (key === "constructor") return void 0;
842
- if (typeof currentValue === "object" && currentValue !== null) {
843
- if (seen.has(currentValue)) return "[Circular]";
844
- seen.add(currentValue);
845
- }
846
- return currentValue;
847
- });
848
- };
849
- var hasOwnConstructorProp = (value) => {
850
- if (typeof value !== "object" || value === null) return false;
851
- return Object.prototype.hasOwnProperty.call(value, "constructor");
852
- };
853
- var errorToString = (error) => {
854
- if (error === null) return "Null error";
855
- if (error === void 0) return "Undefined error";
856
- if (error instanceof Error) {
857
- return [
858
- `Name: ${error.name}`,
859
- `Message: ${error.message}`,
860
- `Stack: ${error.stack || "No stack trace available"}`,
861
- // Handle additional properties that might exist on custom errors
862
- ...Object.entries(error).filter(
863
- ([key, value]) => !["name", "message", "stack"].includes(key) && !hasOwnConstructorProp(value)
864
- ).map(([key, value]) => `${key}: ${safeJsonStringify(value)}`)
865
- ].join("\n");
866
- }
867
- if (typeof error === "string") return error;
868
- if (typeof error === "object") {
869
- try {
870
- return JSON.stringify(
871
- error,
872
- (key, value) => {
873
- if (key === "constructor") return void 0;
874
- return value;
875
- },
876
- 2
877
- );
878
- } catch {
879
- return `[Object that cannot be stringified: ${Object.prototype.toString.call(error)}]`;
880
- }
881
- }
882
- return String(error);
883
- };
884
-
885
- // ../../utils/src/logging/writer.ts
886
- import { EOL } from "os";
887
- var jsonWriter = (entry) => {
888
- process.stdout.write(JSON.stringify(entry) + EOL);
889
- };
890
- var _writer = jsonWriter;
891
- function setWriter(writer) {
892
- _writer = writer;
893
- }
894
- function getWriter() {
895
- return _writer;
896
- }
897
-
898
- // ../../utils/src/logging/index.ts
899
- var levelValues = {
900
- fatal: 70,
901
- error: 60,
902
- warn: 50,
903
- info: 40,
904
- debug: 30,
905
- trace: 20
906
- };
907
- var currentLogLevel = 2;
908
- var _module = "default";
909
- var _requestId = "";
910
- function writeLine(level, mergeObject, msg, bindings) {
911
- getWriter()({
912
- level: levelValues[level],
913
- levelName: level,
914
- time: Date.now(),
915
- module: bindings.module || _module,
916
- reqId: bindings.reqId || _requestId,
917
- msg: level === "error" || level === "fatal" ? errorToString(msg) : msg,
918
- ...mergeObject ? { meta: mergeObject } : {}
919
- });
920
- }
921
- function createLogger(bindings = {}) {
922
- const currentLogLevelName = env("LOG_LEVEL")?.toLowerCase() ?? "info";
923
- currentLogLevel = logLevels[currentLogLevelName] ?? logLevels.info;
924
- return {
925
- level: currentLogLevelName,
926
- fatal: (mergeObject, msg) => {
927
- if (currentLogLevel >= logLevels.fatal) {
928
- typeof mergeObject === "string" || mergeObject instanceof Error ? writeLine("fatal", null, mergeObject, bindings) : writeLine("fatal", mergeObject, msg ?? "", bindings);
929
- }
930
- },
931
- error: (mergeObject, msg) => {
932
- if (currentLogLevel >= logLevels.error) {
933
- typeof mergeObject === "string" || mergeObject instanceof Error ? writeLine("error", null, mergeObject, bindings) : writeLine("error", mergeObject, msg ?? "", bindings);
934
- }
935
- },
936
- warn: (mergeObject, msg) => {
937
- if (currentLogLevel >= logLevels.warn) {
938
- typeof mergeObject === "string" ? writeLine("warn", null, mergeObject, bindings) : writeLine("warn", mergeObject, msg ?? "", bindings);
939
- }
940
- },
941
- info: (mergeObject, msg) => {
942
- if (currentLogLevel >= logLevels.info) {
943
- typeof mergeObject === "string" ? writeLine("info", null, mergeObject, bindings) : writeLine("info", mergeObject, msg ?? "", bindings);
944
- }
945
- },
946
- debug: (mergeObject, msg) => {
947
- if (currentLogLevel >= logLevels.debug) {
948
- typeof mergeObject === "string" ? writeLine("debug", null, mergeObject, bindings) : writeLine("debug", mergeObject, msg ?? "", bindings);
949
- }
950
- },
951
- trace: (mergeObject, msg) => {
952
- if (currentLogLevel >= logLevels.trace) {
953
- typeof mergeObject === "string" ? writeLine("trace", null, mergeObject, bindings) : writeLine("trace", mergeObject, msg ?? "", bindings);
954
- }
955
- },
956
- silent: () => {
957
- },
958
- child: (childBindings) => createLogger({ ...bindings, ...childBindings })
959
- };
960
- }
961
- var logger = createLogger();
962
-
963
- // src/logging/pretty-writer.ts
964
- var levelColor = {
965
- fatal: chalk.bgRed.white,
966
- error: chalk.red,
967
- warn: chalk.yellow,
968
- info: chalk.cyan,
969
- debug: chalk.gray,
970
- trace: chalk.white
971
- };
972
- function formatTime(ms) {
973
- return new Date(ms).toTimeString().slice(0, 8);
974
- }
975
- function formatMeta(meta) {
976
- const { req, res, ...rest } = meta;
977
- const lines = [];
978
- if (req) {
979
- const reqParts = [`${req.method} ${req.url}`];
980
- if (req.remoteAddress) reqParts.push(`from ${req.remoteAddress}:${req.remotePort ?? ""}`);
981
- if (req.headers) reqParts.push(`headers=${JSON.stringify(req.headers, null, 2)}`);
982
- if (req.body !== void 0) reqParts.push(`body=${typeof req.body === "string" ? req.body : JSON.stringify(req.body, null, 2)}`);
983
- lines.push(chalk.dim(" req: " + reqParts.join(" ")));
984
- }
985
- if (res) {
986
- const resParts = [`${res.statusCode}`];
987
- if (res.headers) resParts.push(`headers=${JSON.stringify(res.headers, null, 2)}`);
988
- if (res.body !== void 0) resParts.push(`body=${typeof res.body === "string" ? res.body : JSON.stringify(res.body, null, 2)}`);
989
- lines.push(chalk.dim(" res: " + resParts.join(" ")));
990
- }
991
- if (Object.keys(rest).length) {
992
- lines.push(chalk.dim(" " + JSON.stringify(rest, null, 2)));
993
- }
994
- return lines.length ? EOL2 + lines.join(EOL2) : "";
995
- }
996
- var prettyWriter = (entry) => {
997
- const color = levelColor[entry.levelName] ?? chalk.white;
998
- const time = chalk.dim(formatTime(entry.time));
999
- const level = color(entry.levelName.toUpperCase().padEnd(5));
1000
- const module = chalk.magenta(entry.module);
1001
- const reqId = entry.reqId ? chalk.dim(`[${entry.reqId}]`) + " " : "";
1002
- const meta = entry.meta ? formatMeta(entry.meta) : "";
1003
- process.stdout.write(`${time} ${level} ${module} ${reqId}- ${entry.msg}${meta}${EOL2}`);
1004
- };
1005
- setWriter(prettyWriter);
1006
-
1007
1
  // src/schedule-plugin/plugin.ts
1008
2
  import fsPlugin from "fastify-plugin";
1009
3
 
1010
- // src/schedule-plugin/core.ts
1011
- import * as fs2 from "fs/promises";
1012
-
1013
4
  // src/schedule-plugin/cron-utils.ts
1014
5
  import { parseExpression } from "cron-parser";
1015
6
  function parseCronExpression(cronExpression, lastRun, options = {}) {
@@ -1042,7 +33,6 @@ function parseCronExpression(cronExpression, lastRun, options = {}) {
1042
33
  description: describeCronExpression(normalizedCron)
1043
34
  };
1044
35
  } catch (error) {
1045
- logger.error(`Invalid cron expression: ${cronExpression} - ${error.message}`);
1046
36
  const fallbackTime = /* @__PURE__ */ new Date();
1047
37
  fallbackTime.setHours(fallbackTime.getHours() + 1);
1048
38
  fallbackTime.setMinutes(0);
@@ -1070,8 +60,7 @@ function getNextExecutions(cronExpression, count = 5, options = {}) {
1070
60
  executions.push(interval.next().toDate());
1071
61
  }
1072
62
  return executions;
1073
- } catch (error) {
1074
- logger.error(`Error getting next executions: ${error.message}`);
63
+ } catch {
1075
64
  return [];
1076
65
  }
1077
66
  }
@@ -1344,9 +333,111 @@ var shouldSkipJob = (job) => {
1344
333
  if (job.maxRuns && job.runCount >= job.maxRuns) return true;
1345
334
  return false;
1346
335
  };
336
+ var isJobReadyToRun = (job) => {
337
+ const now = /* @__PURE__ */ new Date();
338
+ return job.nextRun.getTime() <= now.getTime();
339
+ };
1347
340
  var getTimeUntilNextRun = (job) => Math.max(0, job.nextRun.getTime() - Date.now());
1348
341
 
1349
- // src/schedule-plugin/execution.ts
342
+ // src/schedule-plugin/core.ts
343
+ var DEFAULT_CONFIG = {
344
+ tickIntervalMs: 1e3,
345
+ persistence: {
346
+ enabled: true,
347
+ directory: "./.develop/scheduler-data",
348
+ saveInterval: 3e4,
349
+ // 30 seconds
350
+ saveOnShutdown: false
351
+ },
352
+ execution: {
353
+ maxConcurrent: 5,
354
+ defaultTimeout: 3e5
355
+ // 5 minutes
356
+ },
357
+ cleanup: {
358
+ maxExecutionHistory: 1e3,
359
+ cleanupInterval: 6e5
360
+ // 10 minutes
361
+ },
362
+ restartBehavior: {
363
+ preserveNaturalTiming: true,
364
+ skipMissedRuns: true,
365
+ maxTimingDrift: 6e4,
366
+ // 1 minute
367
+ rapidRestartThreshold: 1e4
368
+ // 10 seconds
369
+ },
370
+ cron: {
371
+ defaultTimezone: void 0,
372
+ // Use system timezone
373
+ logCronDetails: true
374
+ }
375
+ };
376
+ var mergeConfig = (defaultConfig, userConfig) => ({
377
+ ...defaultConfig,
378
+ ...userConfig,
379
+ persistence: { ...defaultConfig.persistence, ...userConfig?.persistence },
380
+ execution: { ...defaultConfig.execution, ...userConfig?.execution },
381
+ cleanup: { ...defaultConfig.cleanup, ...userConfig?.cleanup },
382
+ restartBehavior: { ...defaultConfig.restartBehavior, ...userConfig?.restartBehavior },
383
+ cron: { ...defaultConfig.cron, ...userConfig?.cron }
384
+ });
385
+ var createDashboardSummary = (runtime) => {
386
+ const jobs = Object.values(runtime.schedulers).map((scheduler) => {
387
+ const upcomingExecutions = scheduler.job.cronExpression ? getNextExecutions(scheduler.job.cronExpression, 3, { timezone: scheduler.job.timezone }) : [];
388
+ const cronDescription = scheduler.job.cronExpression ? parseCronExpression(scheduler.job.cronExpression, void 0, { timezone: scheduler.job.timezone }).description : void 0;
389
+ return {
390
+ ...scheduler.job,
391
+ isRunning: scheduler.isRunning,
392
+ timeUntilNextRun: getTimeUntilNextRun(scheduler.job),
393
+ upcomingExecutions,
394
+ cronDescription
395
+ };
396
+ });
397
+ return { jobs, runningExecutions: runtime.runningExecutions };
398
+ };
399
+ var createExecutionsSummary = (runtime) => ({
400
+ executions: runtime.executionHistory.slice(-50),
401
+ // Last 50 executions
402
+ running: Object.values(runtime.executions).filter((e) => e.status === "running")
403
+ });
404
+
405
+ // src/schedule-plugin/jobs.ts
406
+ var validateJobDefinition = (jobDef) => {
407
+ if (!jobDef.cronExpression && !jobDef.intervalMs && !jobDef.delayMs) {
408
+ throw new Error(`Job ${jobDef.name} must specify a cronExpression, intervalMs, or delayMs`);
409
+ }
410
+ if (jobDef.cronExpression && detectExpressionType(jobDef.cronExpression) === "unknown") {
411
+ throw new Error(`Invalid cron expression for job: ${jobDef.name}`);
412
+ }
413
+ };
414
+ var createJobFromDefinition = (jobDef, config) => {
415
+ validateJobDefinition(jobDef);
416
+ const expressionType = detectExpressionType(jobDef.cronExpression);
417
+ const cronExpression = expressionType === "rate" ? convertRateToCron(jobDef.cronExpression).cronExpression : jobDef.cronExpression;
418
+ const job = {
419
+ id: generateJobId(),
420
+ name: jobDef.name,
421
+ cronExpression,
422
+ intervalMs: jobDef.intervalMs,
423
+ delayMs: jobDef.delayMs,
424
+ nextRun: /* @__PURE__ */ new Date(),
425
+ enabled: jobDef.enabled ?? true,
426
+ runCount: 0,
427
+ maxRuns: jobDef.maxRuns,
428
+ metadata: jobDef.metadata,
429
+ createdAt: /* @__PURE__ */ new Date(),
430
+ timezone: jobDef.timezone,
431
+ module: jobDef.module
432
+ };
433
+ job.nextRun = calculateNextRun(job, config.restartBehavior.preserveNaturalTiming);
434
+ return job;
435
+ };
436
+ var createSchedulerService = (job, handler) => ({
437
+ job,
438
+ handler,
439
+ isRunning: false
440
+ });
1350
441
  var createJobExecution = (jobId) => ({
1351
442
  id: generateExecutionId(),
1352
443
  jobId,
@@ -1360,8 +451,159 @@ var completeExecution = (execution, result, error) => ({
1360
451
  result,
1361
452
  error
1362
453
  });
1363
- var canExecuteJob = (scheduler, state) => {
1364
- if (state.isShuttingDown) {
454
+ var updateJobAfterExecution = (job, execution, config) => {
455
+ const updatedJob = {
456
+ ...job,
457
+ lastRun: execution.startTime,
458
+ runCount: job.runCount + 1
459
+ };
460
+ if (updatedJob.enabled) {
461
+ updatedJob.nextRun = calculateNextRunFromLastRun(updatedJob, updatedJob.lastRun, config);
462
+ }
463
+ return updatedJob;
464
+ };
465
+ var enableJob = (scheduler) => ({
466
+ ...scheduler,
467
+ job: {
468
+ ...scheduler.job,
469
+ enabled: true,
470
+ nextRun: calculateNextRun(scheduler.job)
471
+ }
472
+ });
473
+ var disableJob = (scheduler) => ({
474
+ ...scheduler,
475
+ job: { ...scheduler.job, enabled: false }
476
+ });
477
+
478
+ // src/schedule-plugin/persistence.ts
479
+ import * as fs from "fs/promises";
480
+ import * as path from "path";
481
+ var stateFilePath = (directory) => path.join(directory, "scheduler-state.json");
482
+ var tempFilePath = (directory) => path.join(directory, `scheduler-state.${Date.now()}.temp.json`);
483
+ var restoreExecutionHistory = (savedExecutions) => savedExecutions.map((exec) => ({
484
+ ...exec,
485
+ startTime: new Date(exec.startTime),
486
+ endTime: exec.endTime ? new Date(exec.endTime) : void 0
487
+ }));
488
+ var readStateData = async (directory) => {
489
+ const data = await fs.readFile(stateFilePath(directory), "utf8");
490
+ return JSON.parse(data);
491
+ };
492
+ var saveSchedulerState = async (runtime) => {
493
+ try {
494
+ const stateData = {
495
+ jobs: Object.values(runtime.schedulers).map((s) => s.job),
496
+ executions: runtime.executionHistory.slice(-100),
497
+ savedAt: /* @__PURE__ */ new Date(),
498
+ version: "1.0"
499
+ };
500
+ const file = stateFilePath(runtime.config.persistence.directory);
501
+ const temp = tempFilePath(runtime.config.persistence.directory);
502
+ await fs.writeFile(temp, JSON.stringify(stateData, null, 2), "utf8");
503
+ await fs.rename(temp, file);
504
+ runtime.logging.debug("Scheduler state saved");
505
+ } catch (error) {
506
+ runtime.logging.error({ error: error?.message }, "Failed to save scheduler state");
507
+ }
508
+ };
509
+ var validateAndAdjustNextRun = (job, savedNextRun, runtime) => {
510
+ const { config, lastRestartTime, logging } = runtime;
511
+ const now = /* @__PURE__ */ new Date();
512
+ if (!savedNextRun || savedNextRun <= now) {
513
+ logging.debug({ module: job.module }, `Saved next run is in the past for ${job.name} - recalculating`);
514
+ return calculateNextRunFromLastRun(job, job.lastRun, config);
515
+ }
516
+ const isRapidRestart = now.getTime() - lastRestartTime.getTime() < config.restartBehavior.rapidRestartThreshold;
517
+ if (isRapidRestart) {
518
+ logging.debug({ module: job.module }, `Rapid restart detected for ${job.name} - preserving saved timing`);
519
+ return savedNextRun;
520
+ }
521
+ if (job.cronExpression || job.intervalMs) {
522
+ const expectedNextRun = calculateNextRunFromLastRun(job, job.lastRun, config);
523
+ const drift = Math.abs(savedNextRun.getTime() - expectedNextRun.getTime());
524
+ if (drift > config.restartBehavior.maxTimingDrift) {
525
+ logging.debug({ module: job.module }, `Adjusting timing for ${job.name} - drift of ${Math.round(drift / 1e3)}s detected`);
526
+ return expectedNextRun;
527
+ }
528
+ }
529
+ return savedNextRun;
530
+ };
531
+ var loadJobState = async (runtime, scheduler) => {
532
+ try {
533
+ const stateData = await readStateData(runtime.config.persistence.directory);
534
+ if (!stateData) {
535
+ return scheduler;
536
+ }
537
+ const savedJob = stateData.jobs.find((job) => job.name === scheduler.job.name);
538
+ if (!savedJob) {
539
+ return scheduler;
540
+ }
541
+ const definitionChanged = hasJobDefinitionChanged(scheduler.job, savedJob);
542
+ const lastRun = savedJob.lastRun ? new Date(savedJob.lastRun) : void 0;
543
+ const updatedJob = {
544
+ ...scheduler.job,
545
+ runCount: savedJob.runCount,
546
+ lastRun
547
+ };
548
+ if (definitionChanged) {
549
+ runtime.logging.debug({ module: scheduler.job.module }, `Job definition changed: ${savedJob.name} - recalculating schedule`);
550
+ updatedJob.nextRun = calculateNextRunFromLastRun(updatedJob, lastRun, runtime.config);
551
+ } else {
552
+ updatedJob.nextRun = validateAndAdjustNextRun(updatedJob, savedJob.nextRun ? new Date(savedJob.nextRun) : void 0, runtime);
553
+ }
554
+ if (runtime.config.cron.logCronDetails && updatedJob.cronExpression) {
555
+ const result = parseCronExpression(updatedJob.cronExpression, updatedJob.lastRun, { timezone: updatedJob.timezone });
556
+ runtime.logging.debug(
557
+ { module: scheduler.job.module },
558
+ `Job restored: ${savedJob.name} - ${result.description} - next: ${updatedJob.nextRun.toLocaleString()}`
559
+ );
560
+ } else {
561
+ runtime.logging.debug({ module: scheduler.job.module }, `Job state restored: ${savedJob.name}`);
562
+ }
563
+ return { ...scheduler, job: updatedJob };
564
+ } catch (error) {
565
+ if (error.code === "ENOENT") {
566
+ runtime.logging.debug("No saved scheduler state found - starting fresh");
567
+ } else {
568
+ runtime.logging.error({ error: error?.message }, `Failed to load job state for ${scheduler.job.name}`);
569
+ }
570
+ return scheduler;
571
+ }
572
+ };
573
+ var loadExecutionHistory = async (runtime) => {
574
+ try {
575
+ const stateData = await readStateData(runtime.config.persistence.directory);
576
+ if (stateData?.executions) {
577
+ runtime.executionHistory = restoreExecutionHistory(stateData.executions);
578
+ }
579
+ } catch (error) {
580
+ if (error.code !== "ENOENT") {
581
+ runtime.logging.error({ error: error?.message }, "Failed to load execution history");
582
+ }
583
+ }
584
+ };
585
+ var initializePersistence = async (runtime) => {
586
+ try {
587
+ await fs.mkdir(runtime.config.persistence.directory, { recursive: true });
588
+ await loadExecutionHistory(runtime);
589
+ if (runtime.config.persistence.saveOnShutdown) {
590
+ const shutdownHandler = async () => {
591
+ runtime.logging.debug("Saving scheduler state before shutdown...");
592
+ await saveSchedulerState(runtime);
593
+ process.exit(0);
594
+ };
595
+ process.on("SIGINT", shutdownHandler);
596
+ process.on("SIGTERM", shutdownHandler);
597
+ }
598
+ runtime.logging.debug(`Scheduler persistence initialized: ${runtime.config.persistence.directory}`);
599
+ } catch (error) {
600
+ runtime.logging.error({ error: error?.message }, "Failed to initialize scheduler persistence");
601
+ }
602
+ };
603
+
604
+ // src/schedule-plugin/processing.ts
605
+ var canExecuteJob = (runtime, scheduler) => {
606
+ if (runtime.isShuttingDown) {
1365
607
  return { canExecute: false, reason: "System is shutting down" };
1366
608
  }
1367
609
  if (scheduler.isRunning) {
@@ -1371,25 +613,11 @@ var canExecuteJob = (scheduler, state) => {
1371
613
  const reason = !scheduler.job.enabled ? "Job is disabled" : "Job reached maximum runs";
1372
614
  return { canExecute: false, reason };
1373
615
  }
1374
- if (state.runningExecutions >= state.config.execution.maxConcurrent) {
616
+ if (runtime.runningExecutions >= runtime.config.execution.maxConcurrent) {
1375
617
  return { canExecute: false, reason: "Maximum concurrent executions reached" };
1376
618
  }
1377
619
  return { canExecute: true };
1378
620
  };
1379
- var scheduleJob = (scheduler, state, executeJobFn) => {
1380
- if (state.isShuttingDown) return scheduler;
1381
- const timeUntilNextRun = getTimeUntilNextRun(scheduler.job);
1382
- const updatedScheduler = { ...scheduler };
1383
- if (timeUntilNextRun <= 0) {
1384
- setImmediate(() => executeJobFn(updatedScheduler));
1385
- } else {
1386
- updatedScheduler.timerId = setTimeout(() => {
1387
- executeJobFn(updatedScheduler);
1388
- }, timeUntilNextRun);
1389
- logger.debug(`Scheduled job ${scheduler.job.name} to run in ${Math.round(timeUntilNextRun / 1e3)}s`);
1390
- }
1391
- return updatedScheduler;
1392
- };
1393
621
  var executeJobWithTimeout = async (handler, job, execution, timeoutMs) => {
1394
622
  let timerId;
1395
623
  try {
@@ -1403,627 +631,338 @@ var executeJobWithTimeout = async (handler, job, execution, timeoutMs) => {
1403
631
  clearTimeout(timerId);
1404
632
  }
1405
633
  };
1406
- var updateJobAfterExecution = (job, execution, config) => {
1407
- const updatedJob = {
1408
- ...job,
1409
- lastRun: execution.startTime,
1410
- runCount: job.runCount + 1
1411
- };
1412
- if (job.enabled) {
1413
- updatedJob.nextRun = calculateNextRunFromLastRun(updatedJob, updatedJob.lastRun, config);
1414
- }
1415
- return updatedJob;
1416
- };
1417
- var handleExecutionError = (execution, error) => {
1418
- logger.error(`Job failed ${execution.jobId}: ${error.message}`);
1419
- return completeExecution(execution, void 0, error.message);
1420
- };
1421
- var handleExecutionSuccess = (execution, result) => {
1422
- const duration = execution.endTime ? execution.endTime.getTime() - execution.startTime.getTime() : 0;
1423
- logger.debug(`Job completed in ${duration}ms`);
1424
- return completeExecution(execution, result);
1425
- };
1426
-
1427
- // src/schedule-plugin/persistence.ts
1428
- import * as fs from "fs/promises";
1429
- import * as path from "path";
1430
- var createStateFilePath = (directory) => path.join(directory, "scheduler-state.json");
1431
- var createTempFilePath = (directory) => path.join(directory, `scheduler-state.${Date.now()}.temp.json`);
1432
- var serializeSchedulerState = (schedulers, executionHistory) => ({
1433
- jobs: Object.values(schedulers).map((s) => s.job),
1434
- executions: executionHistory.slice(-100),
1435
- savedAt: /* @__PURE__ */ new Date(),
1436
- version: "1.0"
1437
- });
1438
- var saveSchedulerState = async (state) => {
1439
- try {
1440
- const serializedState = serializeSchedulerState(state.schedulers, state.executionHistory);
1441
- const stateFile = createStateFilePath(state.config.persistence.directory);
1442
- const tempFile = createTempFilePath(state.config.persistence.directory);
1443
- await fs.writeFile(tempFile, JSON.stringify(serializedState, null, 2), "utf8");
1444
- await fs.rename(tempFile, stateFile);
1445
- logger.debug("Enhanced scheduler state saved");
1446
- } catch (error) {
1447
- logger.error("Failed to save scheduler state:", error);
1448
- }
1449
- };
1450
- var loadSchedulerStateData = async (directory) => {
634
+ var executeJob = async (runtime, scheduler) => {
635
+ const execution = createJobExecution(scheduler.job.id);
636
+ runtime.executions[execution.id] = execution;
637
+ runtime.executionHistory.push(execution);
638
+ scheduler.isRunning = true;
639
+ runtime.runningExecutions++;
640
+ runtime.logging.info(`Executing job ${scheduler.job.name} (${execution.id})`);
1451
641
  try {
1452
- const stateFile = createStateFilePath(directory);
1453
- const data = await fs.readFile(stateFile, "utf8");
1454
- return JSON.parse(data);
642
+ const result = await executeJobWithTimeout(
643
+ scheduler.handler,
644
+ scheduler.job,
645
+ execution,
646
+ runtime.config.execution.defaultTimeout
647
+ );
648
+ Object.assign(execution, completeExecution(execution, result));
649
+ const duration = execution.endTime.getTime() - execution.startTime.getTime();
650
+ runtime.logging.debug(`Job completed in ${duration}ms`);
1455
651
  } catch (error) {
1456
- if (error.code === "ENOENT") {
1457
- logger.debug("No previous scheduler state found - starting fresh");
1458
- } else {
1459
- logger.error("Failed to load scheduler state:", error);
652
+ Object.assign(execution, completeExecution(execution, void 0, error.message));
653
+ runtime.logging.error(`Job failed ${scheduler.job.name}: ${error.message}`);
654
+ } finally {
655
+ scheduler.isRunning = false;
656
+ runtime.runningExecutions--;
657
+ scheduler.job = updateJobAfterExecution(scheduler.job, execution, runtime.config);
658
+ if (scheduler.job.maxRuns && scheduler.job.runCount >= scheduler.job.maxRuns) {
659
+ runtime.logging.info(`Job ${scheduler.job.name} reached max runs (${scheduler.job.maxRuns})`);
660
+ }
661
+ if (runtime.config.persistence.enabled) {
662
+ runtime.isDirty = true;
1460
663
  }
1461
- return null;
1462
664
  }
1463
665
  };
1464
- var validateAndAdjustNextRun = (job, savedNextRun, lastRestartTime, config) => {
1465
- const now = /* @__PURE__ */ new Date();
1466
- if (!savedNextRun) {
1467
- return calculateNextRunFromLastRun(job, job.lastRun, config);
1468
- }
1469
- if (savedNextRun <= now) {
1470
- logger.debug(`Saved next run is in the past for ${job.name} - recalculating`);
1471
- return calculateNextRunFromLastRun(job, job.lastRun, config);
1472
- }
1473
- const timeSinceRestart = now.getTime() - lastRestartTime.getTime();
1474
- const isRapidRestart = timeSinceRestart < config.restartBehavior.rapidRestartThreshold;
1475
- if (isRapidRestart) {
1476
- logger.debug(`Rapid restart detected for ${job.name} - preserving saved timing`);
1477
- return savedNextRun;
666
+ var dispatchJobIfDue = (runtime, scheduler) => {
667
+ if (!scheduler.job.enabled || !isJobReadyToRun(scheduler.job)) {
668
+ return;
1478
669
  }
1479
- if (job.cronExpression || job.intervalMs) {
1480
- const expectedNextRun = calculateNextRunFromLastRun(job, job.lastRun, config);
1481
- const timeDiff = Math.abs(savedNextRun.getTime() - expectedNextRun.getTime());
1482
- if (timeDiff > config.restartBehavior.maxTimingDrift) {
1483
- logger.debug(`Adjusting timing for ${job.name} - drift of ${Math.round(timeDiff / 1e3)}s detected`);
1484
- return expectedNextRun;
670
+ const { canExecute, reason } = canExecuteJob(runtime, scheduler);
671
+ if (!canExecute) {
672
+ if (reason === "Maximum concurrent executions reached") {
673
+ runtime.logging.debug({ module: scheduler.job.module }, `Delaying job ${scheduler.job.name} - ${reason}`);
1485
674
  }
675
+ return;
1486
676
  }
1487
- return savedNextRun;
677
+ runtime.logging.runWithLogContext(
678
+ { module: scheduler.job.module, reqId: scheduler.job.id },
679
+ () => executeJob(runtime, scheduler)
680
+ );
1488
681
  };
1489
- var restoreJobFromSavedData = (scheduler, savedJob, config, lastRestartTime) => {
1490
- const definitionChanged = hasJobDefinitionChanged(scheduler.job, savedJob);
1491
- const updatedJob = {
1492
- ...scheduler.job,
1493
- runCount: savedJob.runCount,
1494
- lastRun: savedJob.lastRun ? new Date(savedJob.lastRun) : void 0
1495
- };
1496
- if (definitionChanged) {
1497
- logger.debug(`Job definition changed: ${savedJob.name} - recalculating schedule`);
1498
- updatedJob.nextRun = calculateNextRunFromLastRun(updatedJob, updatedJob.lastRun, config);
1499
- } else {
1500
- const savedNextRun = savedJob.nextRun ? new Date(savedJob.nextRun) : void 0;
1501
- updatedJob.nextRun = validateAndAdjustNextRun(updatedJob, savedNextRun, lastRestartTime, config);
1502
- }
1503
- if (config.cron.logCronDetails && updatedJob.cronExpression) {
1504
- const result = parseCronExpression(updatedJob.cronExpression, updatedJob.lastRun, {
1505
- timezone: updatedJob.timezone
1506
- });
1507
- logger.debug(`Job restored: ${savedJob.name} - ${result.description} - next: ${updatedJob.nextRun.toLocaleString()}`);
682
+ var cleanupExecutionHistory = (runtime) => {
683
+ const { maxExecutionHistory } = runtime.config.cleanup;
684
+ if (runtime.executionHistory.length <= maxExecutionHistory) {
685
+ return;
1508
686
  }
1509
- return { ...scheduler, job: updatedJob };
687
+ const removed = runtime.executionHistory.splice(0, runtime.executionHistory.length - maxExecutionHistory);
688
+ runtime.logging.debug(`Cleaned up ${removed.length} old execution records`);
1510
689
  };
1511
- var restoreExecutionHistory = (savedExecutions) => {
1512
- return savedExecutions.map((exec) => ({
1513
- ...exec,
1514
- startTime: new Date(exec.startTime),
1515
- endTime: exec.endTime ? new Date(exec.endTime) : void 0
1516
- }));
690
+ var maybeCleanup = (runtime, now) => {
691
+ if (now - runtime.lastCleanupTime < runtime.config.cleanup.cleanupInterval) {
692
+ return;
693
+ }
694
+ runtime.lastCleanupTime = now;
695
+ cleanupExecutionHistory(runtime);
1517
696
  };
1518
- var loadSchedulerState = async (schedulers, config, lastRestartTime) => {
1519
- const stateData = await loadSchedulerStateData(config.persistence.directory);
1520
- if (!stateData) {
1521
- return { schedulers, executionHistory: [] };
697
+ var maybeSavePersistence = (runtime, now) => {
698
+ if (!runtime.config.persistence.enabled || !runtime.isDirty) {
699
+ return;
1522
700
  }
1523
- const restoredSchedulers = { ...schedulers };
1524
- for (const savedJob of stateData.jobs) {
1525
- const existingScheduler = Object.values(schedulers).find((s) => s.job.name === savedJob.name);
1526
- if (existingScheduler) {
1527
- const restoredScheduler = restoreJobFromSavedData(
1528
- existingScheduler,
1529
- savedJob,
1530
- config,
1531
- lastRestartTime
1532
- );
1533
- restoredSchedulers[restoredScheduler.job.id] = restoredScheduler;
1534
- }
701
+ const saveInterval = runtime.config.persistence.saveInterval ?? 0;
702
+ if (saveInterval > 0 && now - runtime.lastSavedAt >= saveInterval) {
703
+ runtime.lastSavedAt = now;
704
+ runtime.isDirty = false;
705
+ saveSchedulerState(runtime);
1535
706
  }
1536
- const executionHistory = stateData.executions ? restoreExecutionHistory(stateData.executions) : [];
1537
- logger.debug(`Enhanced scheduler state loaded (saved at ${stateData.savedAt})`);
1538
- return { schedulers: restoredSchedulers, executionHistory };
1539
707
  };
1540
-
1541
- // src/schedule-plugin/cleanup.ts
1542
- var cleanupExecutionHistory = (state) => {
1543
- if (state.executionHistory.length > state.config.cleanup.maxExecutionHistory) {
1544
- const removed = state.executionHistory.splice(
1545
- 0,
1546
- state.executionHistory.length - state.config.cleanup.maxExecutionHistory
1547
- );
1548
- logger.debug(`Cleaned up ${removed.length} old execution records`);
1549
- return removed;
708
+ var tick = (runtime) => {
709
+ const now = Date.now();
710
+ for (const scheduler of Object.values(runtime.schedulers)) {
711
+ dispatchJobIfDue(runtime, scheduler);
1550
712
  }
1551
- return [];
713
+ maybeCleanup(runtime, now);
714
+ maybeSavePersistence(runtime, now);
1552
715
  };
1553
716
 
1554
- // src/schedule-plugin/core.ts
1555
- var DEFAULT_CONFIG = {
1556
- persistence: {
1557
- enabled: true,
1558
- directory: "./.develop/scheduler-data",
1559
- saveInterval: 3e4
1560
- // 30 seconds
1561
- },
1562
- execution: {
1563
- maxConcurrent: 5,
1564
- defaultTimeout: 3e5,
1565
- // 5 minutes
1566
- retryOnError: false,
1567
- maxRetries: 3
1568
- },
1569
- cleanup: {
1570
- maxExecutionHistory: 1e3,
1571
- cleanupInterval: 6e5
1572
- // 10 minutes
1573
- },
1574
- restartBehavior: {
1575
- preserveNaturalTiming: true,
1576
- skipMissedRuns: true,
1577
- maxTimingDrift: 6e4,
1578
- // 1 minute
1579
- rapidRestartThreshold: 1e4
1580
- // 10 seconds
1581
- },
1582
- cron: {
1583
- defaultTimezone: void 0,
1584
- // Use system timezone
1585
- logCronDetails: true
717
+ // src/schedule-plugin/decorator.ts
718
+ var isValidJobName = (jobName) => {
719
+ return typeof jobName === "string" && jobName.length > 0 && /^[a-zA-Z0-9_-]+$/.test(jobName);
720
+ };
721
+ var validateJobName = (jobName) => {
722
+ if (!jobName || typeof jobName !== "string") {
723
+ throw new Error("Job name must be a non-empty string");
724
+ }
725
+ if (!isValidJobName(jobName)) {
726
+ throw new Error("Job name must contain only alphanumeric characters, hyphens, and underscores");
1586
727
  }
1587
728
  };
1588
- var mergeConfig = (defaultConfig, userConfig) => ({
1589
- ...defaultConfig,
1590
- ...userConfig,
1591
- persistence: { ...defaultConfig.persistence, ...userConfig?.persistence },
1592
- execution: { ...defaultConfig.execution, ...userConfig?.execution },
1593
- cleanup: { ...defaultConfig.cleanup, ...userConfig?.cleanup },
1594
- restartBehavior: { ...defaultConfig.restartBehavior, ...userConfig?.restartBehavior },
1595
- cron: { ...defaultConfig.cron, ...userConfig?.cron }
1596
- });
1597
- var createInitialState = (config) => {
1598
- return {
1599
- schedulers: {},
1600
- executions: {},
1601
- executionHistory: [],
1602
- isShuttingDown: false,
1603
- runningExecutions: 0,
1604
- isDirty: false,
1605
- lastCleanupTime: Date.now(),
1606
- lastRestartTime: /* @__PURE__ */ new Date(),
1607
- config
1608
- };
729
+ var validateHandler = (handler) => {
730
+ if (typeof handler !== "function") {
731
+ throw new Error("Handler must be a function");
732
+ }
1609
733
  };
1610
- var createSchedulerFunctions = (state) => {
1611
- const executeJob = async (scheduler) => {
1612
- const { canExecute, reason } = canExecuteJob(scheduler, state);
1613
- if (!canExecute) {
1614
- if (reason === "Maximum concurrent executions reached") {
1615
- logger.warn(`Delaying job ${scheduler.job.name} - ${reason}`);
1616
- scheduler.job.nextRun = new Date(Date.now() + 3e4);
1617
- scheduleJobFn(scheduler);
1618
- } else if (reason === "Job reached maximum runs") {
1619
- logger.info(`Job ${scheduler.job.name} reached max runs (${scheduler.job.maxRuns})`);
1620
- }
1621
- return;
1622
- }
1623
- const execution = createJobExecution(scheduler.job.id);
1624
- state.executions[execution.id] = execution;
1625
- state.executionHistory.push(execution);
1626
- scheduler.isRunning = true;
1627
- state.runningExecutions++;
1628
- logger.info(`Executing job ${scheduler.job.name} (${execution.id})`);
1629
- try {
1630
- const result = await executeJobWithTimeout(
1631
- scheduler.handler,
1632
- scheduler.job,
1633
- execution,
1634
- state.config.execution.defaultTimeout
734
+ var findSchedulerByName = (runtime, jobName) => Object.values(runtime.schedulers).find((scheduler) => scheduler.job.name === jobName);
735
+ var addJob = async (runtime, jobDefinition) => {
736
+ try {
737
+ validateJobName(jobDefinition.name);
738
+ validateHandler(jobDefinition.handler);
739
+ const existing = findSchedulerByName(runtime, jobDefinition.name);
740
+ if (existing) {
741
+ runtime.logging.warn({ module: jobDefinition.module }, `Job already exists: ${jobDefinition.name}.`);
742
+ return existing.job.id;
743
+ }
744
+ const job = createJobFromDefinition(jobDefinition, runtime.config);
745
+ if (runtime.config.cron.logCronDetails && job.cronExpression) {
746
+ const timezone = job.timezone ?? runtime.config.cron.defaultTimezone;
747
+ const result = parseCronExpression(job.cronExpression, void 0, { timezone });
748
+ runtime.logging.debug(
749
+ { module: jobDefinition.module },
750
+ `Job ${jobDefinition.name}: ${result.description} - Next: ${result.nextRun.toLocaleString()}`
751
+ );
752
+ const upcoming = getNextExecutions(job.cronExpression, 3, { timezone });
753
+ runtime.logging.debug(
754
+ { module: jobDefinition.module },
755
+ `Upcoming: ${upcoming.map((d) => d.toLocaleTimeString()).join(", ")}`
1635
756
  );
1636
- const completedExecution = handleExecutionSuccess(execution, result);
1637
- state.executions[execution.id] = completedExecution;
1638
- } catch (error) {
1639
- const failedExecution = handleExecutionError(execution, error);
1640
- state.executions[execution.id] = failedExecution;
1641
- } finally {
1642
- scheduler.isRunning = false;
1643
- state.runningExecutions--;
1644
- scheduler.job = updateJobAfterExecution(scheduler.job, execution, state.config);
1645
- if (scheduler.job.enabled && !state.isShuttingDown) {
1646
- scheduleJobFn(scheduler);
1647
- }
1648
- if (state.config.persistence.enabled) {
1649
- state.isDirty = true;
1650
- }
1651
757
  }
1652
- };
1653
- const scheduleJobFn = (scheduler) => {
1654
- const updatedScheduler = scheduleJob(scheduler, state, executeJob);
1655
- state.schedulers[scheduler.job.id] = updatedScheduler;
1656
- return updatedScheduler;
1657
- };
1658
- return { executeJob, scheduleJobFn };
758
+ let scheduler = createSchedulerService(job, jobDefinition.handler);
759
+ if (runtime.config.persistence.enabled) {
760
+ scheduler = await loadJobState(runtime, scheduler);
761
+ }
762
+ runtime.schedulers[scheduler.job.id] = scheduler;
763
+ runtime.logging.info({ module: jobDefinition.module }, `Job added: ${jobDefinition.name} (${scheduler.job.id})`);
764
+ return scheduler.job.id;
765
+ } catch (error) {
766
+ runtime.logging.error({ module: jobDefinition.module, error: error.message }, `Failed to add job ${jobDefinition.name}`);
767
+ throw error;
768
+ }
1659
769
  };
1660
- var initializeScheduler = async (state, scheduleJobFn) => {
770
+ var removeJob = async (runtime, jobName) => {
1661
771
  try {
1662
- if (state.config.persistence.enabled) {
1663
- await fs2.mkdir(state.config.persistence.directory, { recursive: true });
1664
- const { schedulers, executionHistory } = await loadSchedulerState(
1665
- state.schedulers,
1666
- state.config,
1667
- state.lastRestartTime
1668
- );
1669
- state.schedulers = schedulers;
1670
- state.executionHistory = executionHistory;
772
+ validateJobName(jobName);
773
+ const scheduler = findSchedulerByName(runtime, jobName);
774
+ if (!scheduler) {
775
+ throw new Error(`Job '${jobName}' does not exist`);
1671
776
  }
1672
- const tickInterval = (state.config.persistence.saveInterval || 0) > 0 ? state.config.persistence.saveInterval : state.config.cleanup.cleanupInterval;
1673
- state.tickInterval = setInterval(async () => {
1674
- if (state.isDirty && state.config.persistence.enabled) {
1675
- state.isDirty = false;
1676
- await saveSchedulerState(state);
1677
- }
1678
- if (Date.now() - state.lastCleanupTime >= state.config.cleanup.cleanupInterval) {
1679
- state.lastCleanupTime = Date.now();
1680
- cleanupExecutionHistory(state);
1681
- }
1682
- }, tickInterval);
1683
- for (const scheduler of Object.values(state.schedulers)) {
1684
- if (scheduler.job.enabled) {
1685
- scheduleJobFn(scheduler);
1686
- }
777
+ if (scheduler.isRunning) {
778
+ runtime.logging.warn({ module: scheduler.job.module }, `Removing job that is currently running: ${jobName}`);
1687
779
  }
1688
- logger.debug(`Scheduler initialized: ${Object.keys(state.schedulers).length} jobs loaded`);
780
+ delete runtime.schedulers[scheduler.job.id];
781
+ runtime.logging.info({ module: scheduler.job.module }, `Job removed: ${jobName}`);
1689
782
  } catch (error) {
1690
- logger.error(`Failed to initialize scheduler: ${error.message}`);
783
+ runtime.logging.error({ error: error.message }, `Failed to remove job ${jobName}`);
1691
784
  throw error;
1692
785
  }
1693
786
  };
1694
-
1695
- // src/schedule-plugin/jobs.ts
1696
- var validateJobDefinition = (jobDef) => {
1697
- const expressionType = detectExpressionType(jobDef.cronExpression);
1698
- if (expressionType === "unknown") {
1699
- logger.error(`Invalid cron expression for job: ${jobDef.name}`);
1700
- throw new Error(`Invalid cron expression for job: ${jobDef.name}`);
787
+ var hasJob = (runtime, jobName) => {
788
+ try {
789
+ validateJobName(jobName);
790
+ return !!findSchedulerByName(runtime, jobName);
791
+ } catch {
792
+ return false;
1701
793
  }
1702
794
  };
1703
- var createJobFromDefinition = (jobDef, config) => {
1704
- validateJobDefinition(jobDef);
1705
- const expressionType = detectExpressionType(jobDef.cronExpression);
1706
- if (config.cron.logCronDetails && jobDef.cronExpression) {
1707
- const cronExpression = expressionType === "rate" ? convertRateToCron(jobDef.cronExpression).cronExpression : jobDef.cronExpression;
1708
- const result = parseCronExpression(cronExpression, void 0, {
1709
- timezone: jobDef.timezone ?? config.cron.defaultTimezone
1710
- });
1711
- logger.debug(`Job ${jobDef.name}: ${result.description} - Next: ${result.nextRun.toLocaleString()}`);
1712
- const upcoming = getNextExecutions(cronExpression, 3, {
1713
- timezone: jobDef.timezone ?? config.cron.defaultTimezone
1714
- });
1715
- logger.debug(`Upcoming: ${upcoming.map((d) => d.toLocaleTimeString()).join(", ")}`);
1716
- }
1717
- const job = {
1718
- id: generateJobId(),
1719
- name: jobDef.name,
1720
- cronExpression: expressionType === "rate" ? convertRateToCron(jobDef.cronExpression).cronExpression : jobDef.cronExpression,
1721
- intervalMs: jobDef.intervalMs,
1722
- delayMs: jobDef.delayMs,
1723
- nextRun: /* @__PURE__ */ new Date(),
1724
- enabled: jobDef.enabled ?? true,
1725
- runCount: 0,
1726
- maxRuns: jobDef.maxRuns,
1727
- metadata: jobDef.metadata,
1728
- createdAt: /* @__PURE__ */ new Date(),
1729
- timezone: jobDef.timezone,
1730
- module: jobDef.module
1731
- };
1732
- job.nextRun = calculateNextRun(job);
1733
- return job;
795
+ var listJobs = (runtime, module) => {
796
+ return Object.values(runtime.schedulers).filter((scheduler) => !module || scheduler.job.module === module).map((scheduler) => scheduler.job.name).sort();
1734
797
  };
1735
- var createSchedulerService = (job, handler) => ({
1736
- job,
1737
- handler,
1738
- isRunning: false
1739
- });
1740
- var enableJob = (scheduler) => ({
1741
- ...scheduler,
1742
- job: {
1743
- ...scheduler.job,
1744
- enabled: true,
1745
- nextRun: calculateNextRun(scheduler.job)
1746
- }
1747
- });
1748
- var disableJob = (scheduler) => {
1749
- if (scheduler.timerId) {
1750
- clearTimeout(scheduler.timerId);
798
+ var getJobStats = (runtime, jobName) => {
799
+ try {
800
+ validateJobName(jobName);
801
+ return findSchedulerByName(runtime, jobName) ?? null;
802
+ } catch {
803
+ return null;
1751
804
  }
1752
- return {
1753
- ...scheduler,
1754
- job: { ...scheduler.job, enabled: false },
1755
- timerId: void 0
1756
- };
1757
- };
1758
-
1759
- // src/schedule-plugin/routes.ts
1760
- var createDashboardData = (state) => {
1761
- const jobs = Object.values(state.schedulers).map((s) => {
1762
- const nextExecutions = s.job.cronExpression ? getNextExecutions(s.job.cronExpression, 3, { timezone: s.job.timezone }) : [];
1763
- return {
1764
- ...s.job,
1765
- isRunning: s.isRunning,
1766
- timeUntilNextRun: getTimeUntilNextRun(s.job),
1767
- upcomingExecutions: nextExecutions,
1768
- cronDescription: s.job.cronExpression ? parseCronExpression(s.job.cronExpression, void 0, { timezone: s.job.timezone }).description : void 0
1769
- };
1770
- });
1771
- return { jobs, runningExecutions: state.runningExecutions };
1772
- };
1773
- var createExecutionsData = (state) => ({
1774
- executions: state.executionHistory.slice(-50),
1775
- // Last 50 executions
1776
- running: Object.values(state.executions).filter((e) => e.status === "running")
1777
- });
1778
- var registerDashboardRoute = (app, state) => {
1779
- app.get("/schedule/dashboard", async function(_, reply) {
1780
- const dashboardData = createDashboardData(state);
1781
- return reply.status(200).send(dashboardData);
1782
- });
1783
805
  };
1784
- var registerExecutionsRoute = (app, state) => {
1785
- app.get("/schedule/executions", async function(_, reply) {
1786
- const executionsData = createExecutionsData(state);
1787
- return reply.status(200).send(executionsData);
1788
- });
806
+ var getJobsMap = (runtime) => {
807
+ return { ...runtime.schedulers };
1789
808
  };
1790
- var registerTriggerJobRoute = (app, state, executeJobFn) => {
1791
- app.post("/schedule/jobs/:jobId/trigger", async function(request, reply) {
1792
- const scheduler = state.schedulers[request.params.jobId];
809
+ var enableJob2 = async (runtime, jobName) => {
810
+ try {
811
+ validateJobName(jobName);
812
+ const scheduler = findSchedulerByName(runtime, jobName);
1793
813
  if (!scheduler) {
1794
- return reply.status(404).send({ error: "Job not found" });
814
+ throw new Error(`Job '${jobName}' does not exist`);
1795
815
  }
1796
- if (scheduler.isRunning) {
1797
- return reply.status(409).send({ error: "Job is already running" });
816
+ if (scheduler.job.enabled) {
817
+ runtime.logging.debug({ module: scheduler.job.module }, `Job is already enabled: ${jobName}`);
818
+ return;
1798
819
  }
1799
- setImmediate(() => executeJobFn(scheduler));
1800
- return reply.status(200).send({ message: "Job triggered successfully" });
1801
- });
820
+ runtime.schedulers[scheduler.job.id] = enableJob(scheduler);
821
+ runtime.logging.info({ module: scheduler.job.module }, `Job enabled: ${jobName}`);
822
+ } catch (error) {
823
+ runtime.logging.error({ error: error.message }, `Failed to enable job ${jobName}`);
824
+ throw error;
825
+ }
1802
826
  };
1803
- var registerEnableJobRoute = (app, state, scheduleJobFn) => {
1804
- app.put("/schedule/jobs/:jobId/enable", async function(request, reply) {
1805
- const scheduler = state.schedulers[request.params.jobId];
827
+ var disableJob2 = async (runtime, jobName) => {
828
+ try {
829
+ validateJobName(jobName);
830
+ const scheduler = findSchedulerByName(runtime, jobName);
1806
831
  if (!scheduler) {
1807
- return reply.status(404).send({ error: "Job not found" });
832
+ throw new Error(`Job '${jobName}' does not exist`);
1808
833
  }
1809
- const enabledScheduler = enableJob(scheduler);
1810
- state.schedulers[request.params.jobId] = enabledScheduler;
1811
- scheduleJobFn(enabledScheduler);
1812
- return reply.status(200).send({ message: "Job enabled successfully" });
1813
- });
834
+ if (!scheduler.job.enabled) {
835
+ runtime.logging.debug({ module: scheduler.job.module }, `Job is already disabled: ${jobName}`);
836
+ return;
837
+ }
838
+ runtime.schedulers[scheduler.job.id] = disableJob(scheduler);
839
+ runtime.logging.info({ module: scheduler.job.module }, `Job disabled: ${jobName}`);
840
+ } catch (error) {
841
+ runtime.logging.error({ error: error.message }, `Failed to disable job ${jobName}`);
842
+ throw error;
843
+ }
1814
844
  };
1815
- var registerDisableJobRoute = (app, state) => {
1816
- app.put("/schedule/jobs/:jobId/disable", async function(request, reply) {
1817
- const scheduler = state.schedulers[request.params.jobId];
845
+ var triggerJob = async (runtime, jobName) => {
846
+ try {
847
+ validateJobName(jobName);
848
+ const scheduler = findSchedulerByName(runtime, jobName);
1818
849
  if (!scheduler) {
1819
- return reply.status(404).send({ error: "Job not found" });
850
+ throw new Error(`Job '${jobName}' does not exist`);
1820
851
  }
1821
- const disabledScheduler = disableJob(scheduler);
1822
- state.schedulers[request.params.jobId] = disabledScheduler;
1823
- return reply.status(200).send({ message: "Job disabled successfully" });
1824
- });
1825
- };
1826
- var registerAllRoutes = (app, state, executeJobFn, scheduleJobFn) => {
1827
- registerDashboardRoute(app, state);
1828
- registerExecutionsRoute(app, state);
1829
- registerTriggerJobRoute(app, state, executeJobFn);
1830
- registerEnableJobRoute(app, state, scheduleJobFn);
1831
- registerDisableJobRoute(app, state);
852
+ if (scheduler.isRunning) {
853
+ throw new Error(`Job '${jobName}' is already running`);
854
+ }
855
+ runtime.logging.info({ module: scheduler.job.module }, `Job triggered: ${jobName}`);
856
+ runtime.logging.runWithLogContext(
857
+ { module: scheduler.job.module, reqId: scheduler.job.id },
858
+ () => executeJob(runtime, scheduler)
859
+ );
860
+ } catch (error) {
861
+ runtime.logging.error({ error: error.message }, `Failed to trigger job ${jobName}`);
862
+ throw error;
863
+ }
1832
864
  };
865
+ var getDashboardSummary = (runtime) => createDashboardSummary(runtime);
866
+ var getExecutionsSummary = (runtime) => createExecutionsSummary(runtime);
867
+ var getJobExecutionHistory = (runtime, jobName, limit = 50) => {
868
+ const scheduler = findSchedulerByName(runtime, jobName);
869
+ if (!scheduler) {
870
+ return [];
871
+ }
872
+ return runtime.executionHistory.filter((execution) => execution.jobId === scheduler.job.id).slice(-limit).reverse();
873
+ };
874
+ var createSchedulerManager = (runtime) => ({
875
+ addJob: (jobDefinition) => addJob(runtime, jobDefinition),
876
+ removeJob: (jobName) => removeJob(runtime, jobName),
877
+ hasJob: (jobName) => hasJob(runtime, jobName),
878
+ listJobs: (module) => listJobs(runtime, module),
879
+ getJobStats: (jobName) => getJobStats(runtime, jobName),
880
+ getJobsMap: () => getJobsMap(runtime),
881
+ getConfig: () => runtime.config,
882
+ enableJob: (jobName) => enableJob2(runtime, jobName),
883
+ disableJob: (jobName) => disableJob2(runtime, jobName),
884
+ triggerJob: (jobName) => triggerJob(runtime, jobName),
885
+ getDashboardSummary: () => getDashboardSummary(runtime),
886
+ getExecutionsSummary: () => getExecutionsSummary(runtime),
887
+ getJobExecutionHistory: (jobName, limit) => getJobExecutionHistory(runtime, jobName, limit)
888
+ });
1833
889
 
1834
- // src/schedule-plugin/decorator.ts
1835
- var isValidJobName = (jobName) => {
1836
- return typeof jobName === "string" && jobName.length > 0 && /^[a-zA-Z0-9_-]+$/.test(jobName);
1837
- };
1838
- var createSchedulerManager = ({
1839
- state,
1840
- scheduleJobFn,
1841
- executeJob,
1842
- config
1843
- }) => {
1844
- const validateJobName = (jobName) => {
1845
- if (!jobName || typeof jobName !== "string") {
1846
- throw new Error("Job name must be a non-empty string");
1847
- }
1848
- if (!isValidJobName(jobName)) {
1849
- throw new Error("Job name must contain only alphanumeric characters, hyphens, and underscores");
1850
- }
1851
- };
1852
- const validateHandler = (handler) => {
1853
- if (typeof handler !== "function") {
1854
- throw new Error("Handler must be a function");
1855
- }
1856
- };
1857
- const addJob = async (jobDefinition) => {
1858
- try {
1859
- validateJobName(jobDefinition.name);
1860
- validateHandler(jobDefinition.handler);
1861
- validateJobDefinition(jobDefinition);
1862
- const existingJob = Object.values(state.schedulers).find((s) => s.job.name === jobDefinition.name);
1863
- if (existingJob) {
1864
- logger.warn(`Job already exists: ${jobDefinition.name}.`);
1865
- return existingJob.job.id;
1866
- }
1867
- const job = createJobFromDefinition(jobDefinition, config);
1868
- const scheduler = createSchedulerService(job, jobDefinition.handler);
1869
- state.schedulers[job.id] = scheduler;
1870
- if (job.enabled) {
1871
- scheduleJobFn(scheduler);
1872
- }
1873
- logger.info(`Job added: ${jobDefinition.name} (${job.id})`);
1874
- return job.id;
1875
- } catch (error) {
1876
- logger.error(`Failed to add job ${jobDefinition.name}: ${error.message}`);
1877
- throw error;
1878
- }
1879
- };
1880
- const removeJob = async (jobName) => {
1881
- try {
1882
- validateJobName(jobName);
1883
- const scheduler = Object.values(state.schedulers).find((s) => s.job.name === jobName);
1884
- if (!scheduler) {
1885
- throw new Error(`Job '${jobName}' does not exist`);
1886
- }
1887
- if (scheduler.isRunning) {
1888
- logger.warn(`Removing job that is currently running: ${jobName}`);
1889
- }
1890
- if (scheduler.timerId) {
1891
- clearTimeout(scheduler.timerId);
1892
- }
1893
- delete state.schedulers[scheduler.job.id];
1894
- logger.info(`Job removed: ${jobName}`);
1895
- } catch (error) {
1896
- logger.error(`Failed to remove job ${jobName}: ${error.message}`);
1897
- throw error;
1898
- }
1899
- };
1900
- const hasJob = (jobName) => {
1901
- try {
1902
- validateJobName(jobName);
1903
- return Object.values(state.schedulers).some((s) => s.job.name === jobName);
1904
- } catch {
1905
- return false;
1906
- }
1907
- };
1908
- const listJobs = (module) => {
1909
- return Object.values(state.schedulers).filter((s) => !module || s.job.module === module).map((s) => s.job.name).sort();
1910
- };
1911
- const getJobStats = (jobName) => {
1912
- try {
1913
- validateJobName(jobName);
1914
- const scheduler = Object.values(state.schedulers).find((s) => s.job.name === jobName);
1915
- return scheduler || null;
1916
- } catch {
1917
- return null;
1918
- }
1919
- };
1920
- const enableJob2 = async (jobName) => {
1921
- try {
1922
- validateJobName(jobName);
1923
- const scheduler = Object.values(state.schedulers).find((s) => s.job.name === jobName);
1924
- if (!scheduler) {
1925
- throw new Error(`Job '${jobName}' does not exist`);
1926
- }
1927
- if (scheduler.job.enabled) {
1928
- logger.debug(`Job is already enabled: ${jobName}`);
1929
- return;
890
+ // src/schedule-plugin/routes.ts
891
+ var registerSchedulerRoutes = (app, prefix = "schedule") => {
892
+ app.get(
893
+ `/${prefix}/dashboard`,
894
+ async (_, reply) => {
895
+ return reply.status(200).send(app.scheduler.getDashboardSummary());
896
+ }
897
+ );
898
+ app.get(
899
+ `/${prefix}/executions`,
900
+ async (_, reply) => {
901
+ return reply.status(200).send(app.scheduler.getExecutionsSummary());
902
+ }
903
+ );
904
+ app.post(
905
+ `/${prefix}/jobs/:jobName/trigger`,
906
+ async (request, reply) => {
907
+ try {
908
+ await app.scheduler.triggerJob(request.params.jobName);
909
+ return reply.status(200).send({ message: "Job triggered successfully" });
910
+ } catch (error) {
911
+ return reply.status(404).send({ error: error.message });
1930
912
  }
1931
- scheduler.job.enabled = true;
1932
- scheduleJobFn(scheduler);
1933
- logger.info(`Job enabled: ${jobName}`);
1934
- } catch (error) {
1935
- logger.error(`Failed to enable job ${jobName}: ${error.message}`);
1936
- throw error;
1937
913
  }
1938
- };
1939
- const disableJob2 = async (jobName) => {
1940
- try {
1941
- validateJobName(jobName);
1942
- const scheduler = Object.values(state.schedulers).find((s) => s.job.name === jobName);
1943
- if (!scheduler) {
1944
- throw new Error(`Job '${jobName}' does not exist`);
1945
- }
1946
- if (!scheduler.job.enabled) {
1947
- logger.debug(`Job is already disabled: ${jobName}`);
1948
- return;
914
+ );
915
+ app.put(
916
+ `/${prefix}/jobs/:jobName/enable`,
917
+ async (request, reply) => {
918
+ try {
919
+ await app.scheduler.enableJob(request.params.jobName);
920
+ return reply.status(200).send({ message: "Job enabled successfully" });
921
+ } catch (error) {
922
+ return reply.status(404).send({ error: error.message });
1949
923
  }
1950
- scheduler.job.enabled = false;
1951
- if (scheduler.timerId) {
1952
- clearTimeout(scheduler.timerId);
1953
- scheduler.timerId = void 0;
1954
- }
1955
- logger.info(`Job disabled: ${jobName}`);
1956
- } catch (error) {
1957
- logger.error(`Failed to disable job ${jobName}: ${error.message}`);
1958
- throw error;
1959
924
  }
1960
- };
1961
- const triggerJob = async (jobName) => {
1962
- try {
1963
- validateJobName(jobName);
1964
- const scheduler = Object.values(state.schedulers).find((s) => s.job.name === jobName);
1965
- if (!scheduler) {
1966
- throw new Error(`Job '${jobName}' does not exist`);
925
+ );
926
+ app.put(
927
+ `/${prefix}/jobs/:jobName/disable`,
928
+ async (request, reply) => {
929
+ try {
930
+ await app.scheduler.disableJob(request.params.jobName);
931
+ return reply.status(200).send({ message: "Job disabled successfully" });
932
+ } catch (error) {
933
+ return reply.status(404).send({ error: error.message });
1967
934
  }
1968
- if (scheduler.isRunning) {
1969
- throw new Error(`Job '${jobName}' is already running`);
1970
- }
1971
- setImmediate(() => executeJob(scheduler));
1972
- logger.info(`Job triggered: ${jobName}`);
1973
- } catch (error) {
1974
- logger.error(`Failed to trigger job ${jobName}: ${error.message}`);
1975
- throw error;
1976
935
  }
1977
- };
1978
- const getJobsMap = () => {
1979
- return { ...state.schedulers };
1980
- };
1981
- return {
1982
- addJob,
1983
- removeJob,
1984
- hasJob,
1985
- listJobs,
1986
- getJobStats,
1987
- enableJob: enableJob2,
1988
- disableJob: disableJob2,
1989
- triggerJob,
1990
- getJobsMap
1991
- };
1992
- };
1993
- var createSchedulerDecorator = (schedulerManager) => (app) => {
1994
- app.decorate("scheduler", schedulerManager);
936
+ );
1995
937
  };
1996
938
 
1997
939
  // src/schedule-plugin/plugin.ts
1998
940
  var schedulerPlugin = fsPlugin(async (app, options) => {
1999
- const config = mergeConfig(DEFAULT_CONFIG, options.config);
2000
- const state = createInitialState(config);
2001
- const { executeJob, scheduleJobFn } = createSchedulerFunctions(state);
2002
- await initializeScheduler(state, scheduleJobFn);
2003
- const schedulerManager = createSchedulerManager({
2004
- state,
2005
- config,
2006
- scheduleJobFn,
2007
- executeJob
941
+ const runtime = {
942
+ config: mergeConfig(DEFAULT_CONFIG, options.config),
943
+ schedulers: {},
944
+ executions: {},
945
+ executionHistory: [],
946
+ isShuttingDown: false,
947
+ runningExecutions: 0,
948
+ isDirty: false,
949
+ lastCleanupTime: Date.now(),
950
+ lastSavedAt: Date.now(),
951
+ lastRestartTime: /* @__PURE__ */ new Date(),
952
+ logging: app.logging
953
+ };
954
+ const tickIntervalId = setInterval(() => tick(runtime), runtime.config.tickIntervalMs);
955
+ app.addHook("onClose", async () => {
956
+ runtime.isShuttingDown = true;
957
+ clearInterval(tickIntervalId);
2008
958
  });
2009
- const decorateScheduler = createSchedulerDecorator(schedulerManager);
2010
- decorateScheduler(app);
2011
- registerAllRoutes(app, state, executeJob, scheduleJobFn);
959
+ app.decorate("scheduler", createSchedulerManager(runtime));
960
+ registerSchedulerRoutes(app, options.prefix);
961
+ if (runtime.config.persistence.enabled) {
962
+ await initializePersistence(runtime);
963
+ }
2012
964
  });
2013
965
  export {
2014
966
  schedulerPlugin
2015
967
  };
2016
- /*! Bundled license information:
2017
-
2018
- lodash-es/lodash.js:
2019
- (**
2020
- * @license
2021
- * Lodash (Custom Build) <https://lodash.com/>
2022
- * Build: `lodash modularize exports="es" -o ./`
2023
- * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
2024
- * Released under MIT license <https://lodash.com/license>
2025
- * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
2026
- * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
2027
- *)
2028
- */
2029
968
  //# sourceMappingURL=index.js.map