@cloudnux/local-cloud-provider 0.7.0 → 0.11.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,14 +1,8 @@
1
- // ../../../node_modules/tsup/assets/esm_shims.js
2
- import path from "path";
3
- import { fileURLToPath } from "url";
4
- var getFilename = () => fileURLToPath(import.meta.url);
5
- var getDirname = () => path.dirname(getFilename());
6
- var __dirname = /* @__PURE__ */ getDirname();
7
-
8
1
  // src/dev-console-plugin/plugin.ts
9
- import path4 from "path";
2
+ import path3 from "path";
10
3
  import fastifyStatic from "@fastify/static";
11
4
  import fsPlugin3 from "fastify-plugin";
5
+ import { createRequire } from "module";
12
6
 
13
7
  // src/queue-plugin/plugin.ts
14
8
  import fsPlugin from "fastify-plugin";
@@ -693,11 +687,11 @@ function stringToArray(string) {
693
687
  var stringToArray_default = stringToArray;
694
688
 
695
689
  // ../../../node_modules/lodash-es/_hasPath.js
696
- function hasPath(object, path5, hasFunc) {
697
- path5 = castPath_default(path5, object);
698
- var index = -1, length = path5.length, result = false;
690
+ function hasPath(object, path4, hasFunc) {
691
+ path4 = castPath_default(path4, object);
692
+ var index = -1, length = path4.length, result = false;
699
693
  while (++index < length) {
700
- var key = toKey_default(path5[index]);
694
+ var key = toKey_default(path4[index]);
701
695
  if (!(result = object != null && hasFunc(object, key))) {
702
696
  break;
703
697
  }
@@ -720,8 +714,8 @@ function baseHas(object, key) {
720
714
  var baseHas_default = baseHas;
721
715
 
722
716
  // ../../../node_modules/lodash-es/has.js
723
- function has(object, path5) {
724
- return object != null && hasPath_default(object, path5, baseHas_default);
717
+ function has(object, path4) {
718
+ return object != null && hasPath_default(object, path4, baseHas_default);
725
719
  }
726
720
  var has_default = has;
727
721
 
@@ -878,12 +872,14 @@ var errorToString = (error) => {
878
872
 
879
873
  // ../../utils/src/logging/index.ts
880
874
  var currentLogLevel = logLevels[env("LOG_LEVEL")?.toLowerCase()] ?? logLevels.info;
875
+ var module = "default";
876
+ var requestId = "";
881
877
  var logger = {
882
878
  fatal: (message, meta) => {
883
879
  if (currentLogLevel >= logLevels.fatal) {
884
880
  console.error(
885
881
  `[${(/* @__PURE__ */ new Date()).toTimeString()}]`,
886
- `${chalk.bgRed.white(" fatal ")}${EOL}`,
882
+ `${chalk.bgRed.white(" fatal ")} - ${module || "unknown module"} - ${requestId || "no request ID"} - ${EOL}`,
887
883
  errorToString(message),
888
884
  meta ? `${EOL}${JSON.stringify(meta, null, 2)}` : ""
889
885
  );
@@ -893,7 +889,7 @@ var logger = {
893
889
  if (currentLogLevel >= logLevels.error) {
894
890
  console.error(
895
891
  `[${(/* @__PURE__ */ new Date()).toTimeString()}]`,
896
- `${chalk.bgRed.white(" error ")}${EOL}`,
892
+ `${chalk.bgRed.white(" error ")} - ${module || "unknown module"} - ${requestId || "no request ID"} - ${EOL}`,
897
893
  errorToString(message),
898
894
  meta ? `${EOL}${JSON.stringify(meta, null, 2)}` : ""
899
895
  );
@@ -903,7 +899,7 @@ var logger = {
903
899
  if (currentLogLevel >= logLevels.warn) {
904
900
  console.warn(
905
901
  `[${(/* @__PURE__ */ new Date()).toTimeString()}]`,
906
- `${chalk.bgYellow.black(" warn ")}${EOL}`,
902
+ `${chalk.bgYellow.black(" warn ")} - ${module || "unknown module"} - ${requestId || "no request ID"} - ${EOL}`,
907
903
  errorToString(message),
908
904
  meta ? `${EOL}${JSON.stringify(meta, null, 2)}` : ""
909
905
  );
@@ -913,7 +909,7 @@ var logger = {
913
909
  if (currentLogLevel >= logLevels.info) {
914
910
  console.info(
915
911
  `[${(/* @__PURE__ */ new Date()).toTimeString()}]`,
916
- `${chalk.bgBlue.white(" info ")}${EOL}`,
912
+ `${chalk.bgBlue.white(" info ")} - ${module || "unknown module"} - ${requestId || "no request ID"} - ${EOL}`,
917
913
  message,
918
914
  meta ? `${EOL}${JSON.stringify(meta, null, 2)}` : ""
919
915
  );
@@ -923,7 +919,7 @@ var logger = {
923
919
  if (currentLogLevel >= logLevels.debug) {
924
920
  console.debug(
925
921
  `[${(/* @__PURE__ */ new Date()).toTimeString()}]`,
926
- `${chalk.bgWhite.black(" debug ")}${EOL}`,
922
+ `${chalk.bgWhite.black(" debug ")} - ${module || "unknown module"} - ${requestId || "no request ID"} - ${EOL}`,
927
923
  message,
928
924
  meta ? `${EOL}${JSON.stringify(meta, null, 2)}` : ""
929
925
  );
@@ -955,15 +951,14 @@ var mergeConfig = (defaultConfig, userConfig) => ({
955
951
  ...userConfig?.persistence || {}
956
952
  }
957
953
  });
958
- var createQueueService = (handler, module) => ({
954
+ var createQueueService = (handler, module2) => ({
959
955
  handler,
960
956
  incoming: [],
961
957
  processing: [],
962
958
  dlq: [],
963
959
  timeoutId: null,
964
960
  processingBatch: false,
965
- activeProcessing: 0,
966
- module
961
+ module: module2
967
962
  });
968
963
  var createQueueMessage = (body, headers) => {
969
964
  const id = Date.now().toString() + Math.random().toString(36).substring(2, 7);
@@ -1009,7 +1004,6 @@ var createQueueSummary = (queueService, config) => ({
1009
1004
  processing: queueService.processing.length,
1010
1005
  dlq: queueService.dlq.length,
1011
1006
  isProcessing: queueService.processingBatch,
1012
- activeProcessing: queueService.activeProcessing,
1013
1007
  configuration: {
1014
1008
  batchSize: config.batchSize,
1015
1009
  batchWindowMs: config.batchWindowMs,
@@ -1051,7 +1045,7 @@ var logError = (message, messageId, queueName, error) => {
1051
1045
  logger.error(`${logSymbols.error} ${chalk2.red(message)} ${chalk2.yellow(messageId)} in queue ${chalk2.magenta(queueName)}: ${error}`);
1052
1046
  };
1053
1047
  var logRetryScheduled = (messageId, delayMs) => {
1054
- logger.info(`${chalk2.blue("\u23F1\uFE0F Scheduling retry")} for message ${chalk2.yellow(messageId)} in ${chalk2.cyan(delayMs)}ms`);
1048
+ logger.debug(`${chalk2.blue("\u23F1\uFE0F Scheduling retry")} for message ${chalk2.yellow(messageId)} in ${chalk2.cyan(delayMs)}ms`);
1055
1049
  };
1056
1050
  var logDLQOperation = (operation, count, queueName) => {
1057
1051
  logger.warn(`${logSymbols.warning} ${chalk2.yellow(operation)} ${chalk2.red(count)} messages from DLQ for ${chalk2.green(queueName)}`);
@@ -1084,7 +1078,7 @@ var handleProcessingError = async (queueName, message, queueService, error, conf
1084
1078
  }, delayMs);
1085
1079
  }
1086
1080
  };
1087
- var createBatchProcessor = (processMessage, config, saveQueueState) => async (queueName, queueService) => {
1081
+ var createBatchProcessor = (processMessage, config, dirtyQueues) => async (queueName, queueService) => {
1088
1082
  if (queueService.timeoutId) {
1089
1083
  clearTimeout(queueService.timeoutId);
1090
1084
  queueService.timeoutId = null;
@@ -1102,8 +1096,8 @@ var createBatchProcessor = (processMessage, config, saveQueueState) => async (qu
1102
1096
  await Promise.all(messagesToProcess.map((message) => {
1103
1097
  return processMessage(queueName, message, queueService);
1104
1098
  }));
1105
- if (config.persistence.enabled && saveQueueState) {
1106
- await saveQueueState(queueName);
1099
+ if (config.persistence.enabled && dirtyQueues) {
1100
+ dirtyQueues.add(queueName);
1107
1101
  }
1108
1102
  } finally {
1109
1103
  queueService.processingBatch = false;
@@ -1129,7 +1123,7 @@ var handleImmediateProcessing = (queueService, config, processBatch, queueName)
1129
1123
 
1130
1124
  // src/queue-plugin/persistence.ts
1131
1125
  import * as fs from "fs/promises";
1132
- import * as path2 from "path";
1126
+ import * as path from "path";
1133
1127
  import chalk3 from "chalk";
1134
1128
  import logSymbols2 from "log-symbols";
1135
1129
  var createQueueData = (queueService) => ({
@@ -1145,18 +1139,21 @@ var restoreDates = (messages) => {
1145
1139
  if (msg.failedAt) msg.failedAt = new Date(msg.failedAt);
1146
1140
  });
1147
1141
  };
1148
- var createPersistenceInitializer = (config, loadAllQueueStates, saveAllQueueStates) => async () => {
1142
+ var createPersistenceInitializer = (config, loadAllQueueStates, saveDirtyQueueStates, saveAllQueueStates, intervalIdHolder) => async () => {
1149
1143
  try {
1150
1144
  await fs.mkdir(config.persistence.directory, { recursive: true });
1151
1145
  if (config.persistence.loadOnStartup) {
1152
1146
  await loadAllQueueStates();
1153
1147
  }
1154
1148
  if (config.persistence.saveInterval > 0) {
1155
- setInterval(saveAllQueueStates, config.persistence.saveInterval);
1149
+ intervalIdHolder.id = setInterval(saveDirtyQueueStates, config.persistence.saveInterval);
1156
1150
  }
1157
1151
  if (config.persistence.saveOnShutdown) {
1158
1152
  const shutdownHandler = async () => {
1159
1153
  logger.debug("Saving queue state before shutdown...");
1154
+ if (intervalIdHolder.id) {
1155
+ clearInterval(intervalIdHolder.id);
1156
+ }
1160
1157
  await saveAllQueueStates();
1161
1158
  process.exit(0);
1162
1159
  };
@@ -1165,7 +1162,8 @@ var createPersistenceInitializer = (config, loadAllQueueStates, saveAllQueueStat
1165
1162
  }
1166
1163
  logger.debug(`${logSymbols2.success} ${chalk3.green("Queue persistence initialized:")} ${chalk3.yellow(config.persistence.directory)}`);
1167
1164
  } catch (error) {
1168
- logger.error(`${logSymbols2.error} ${chalk3.red("Failed to initialize queue persistence:")} ${chalk3.yellow(error.message)}`);
1165
+ console.log("[logger]", logger);
1166
+ logger.error(`${logSymbols2.error} ${chalk3.red("Failed to initialize queue persistence:")} ${chalk3.yellow(error?.message)}`);
1169
1167
  }
1170
1168
  };
1171
1169
  var createQueueStateSaver = (config) => async (queueName, queueService) => {
@@ -1173,13 +1171,13 @@ var createQueueStateSaver = (config) => async (queueName, queueService) => {
1173
1171
  if (!queueService) return;
1174
1172
  const queueData = createQueueData(queueService);
1175
1173
  const now = Date.now();
1176
- const queueFilePath = path2.join(config.persistence.directory, `${queueName}.json`);
1177
- const tempFilePath = path2.join(config.persistence.directory, `${queueName}.${now}temp.json`);
1174
+ const queueFilePath = path.join(config.persistence.directory, `${queueName}.json`);
1175
+ const tempFilePath = path.join(config.persistence.directory, `${queueName}.${now}temp.json`);
1178
1176
  await fs.writeFile(tempFilePath, JSON.stringify(queueData, null, 2), "utf8");
1179
1177
  await fs.rename(tempFilePath, queueFilePath);
1180
- logger.info(`${logSymbols2.info} ${chalk3.blue("Queue state saved:")} ${chalk3.green(queueName)}`);
1178
+ logger.debug(`${logSymbols2.info} ${chalk3.blue("Queue state saved:")} ${chalk3.green(queueName)}`);
1181
1179
  } catch (error) {
1182
- logger.error(`Failed to save queue state for ${queueName}:`, error);
1180
+ logger.error(`Failed to save queue state for ${queueName}:`, error?.message);
1183
1181
  }
1184
1182
  };
1185
1183
  var createAllQueuesStateSaver = (config, saveQueueState) => (queues) => async () => {
@@ -1189,7 +1187,21 @@ var createAllQueuesStateSaver = (config, saveQueueState) => (queues) => async ()
1189
1187
  }
1190
1188
  logger.debug(`${logSymbols2.success} ${chalk3.green("All queue states saved to")} ${chalk3.yellow(config.persistence.directory)}`);
1191
1189
  } catch (error) {
1192
- logger.error(`${logSymbols2.error} ${chalk3.red("Failed to save all queue states:")} ${chalk3.yellow(error.message)}`);
1190
+ logger.error(`${logSymbols2.error} ${chalk3.red("Failed to save all queue states:")} ${chalk3.yellow(error?.message)}`);
1191
+ }
1192
+ };
1193
+ var createDirtyQueuesStateSaver = (saveQueueState, dirtyQueues) => (queues) => async () => {
1194
+ if (dirtyQueues.size === 0) return;
1195
+ try {
1196
+ const queueNames = [...dirtyQueues];
1197
+ dirtyQueues.clear();
1198
+ for (const queueName of queueNames) {
1199
+ if (queues[queueName]) {
1200
+ await saveQueueState(queueName, queues[queueName]);
1201
+ }
1202
+ }
1203
+ } catch (error) {
1204
+ logger.error(`${logSymbols2.error} ${chalk3.red("Failed to save dirty queue states:")} ${chalk3.yellow(error?.message)}`);
1193
1205
  }
1194
1206
  };
1195
1207
  var createQueueStateLoader = (config, scheduleProcessing, processMessage) => (queues) => async (queueName) => {
@@ -1198,7 +1210,7 @@ var createQueueStateLoader = (config, scheduleProcessing, processMessage) => (qu
1198
1210
  logger.warn(`Skipping load for non-existent queue: ${queueName}`);
1199
1211
  return;
1200
1212
  }
1201
- const queueFilePath = path2.join(config.persistence.directory, `${queueName}.json`);
1213
+ const queueFilePath = path.join(config.persistence.directory, `${queueName}.json`);
1202
1214
  try {
1203
1215
  const data = await fs.readFile(queueFilePath, "utf8");
1204
1216
  const queueData = JSON.parse(data);
@@ -1228,7 +1240,7 @@ var createQueueStateLoader = (config, scheduleProcessing, processMessage) => (qu
1228
1240
  }
1229
1241
  }
1230
1242
  } catch (error) {
1231
- logger.error(`Failed to load queue state for ${queueName}:`, error);
1243
+ logger.error(`Failed to load queue state for ${queueName}:`, error?.message);
1232
1244
  }
1233
1245
  };
1234
1246
  var createAllQueuesStateLoader = (config, loadQueueState) => async () => {
@@ -1236,12 +1248,12 @@ var createAllQueuesStateLoader = (config, loadQueueState) => async () => {
1236
1248
  const files = await fs.readdir(config.persistence.directory);
1237
1249
  const queueFiles = files.filter((file) => file.endsWith(".json") && !file.includes(".temp."));
1238
1250
  for (const file of queueFiles) {
1239
- const queueName = path2.basename(file, ".json");
1251
+ const queueName = path.basename(file, ".json");
1240
1252
  await loadQueueState(queueName);
1241
1253
  }
1242
1254
  logger.debug("All queue states loaded");
1243
1255
  } catch (error) {
1244
- logger.error("Failed to load queue states:", error);
1256
+ logger.error("Failed to load queue states:", error?.message);
1245
1257
  }
1246
1258
  };
1247
1259
 
@@ -1309,6 +1321,7 @@ var isValidQueueName = (queueName) => {
1309
1321
  var createQueueManager = ({
1310
1322
  config,
1311
1323
  queues,
1324
+ dirtyQueues,
1312
1325
  saveQueueState,
1313
1326
  loadQueueState,
1314
1327
  scheduleProcessing,
@@ -1327,7 +1340,7 @@ var createQueueManager = ({
1327
1340
  throw new Error("Handler must be a function");
1328
1341
  }
1329
1342
  };
1330
- const addQueue = async (queueName, handler, module) => {
1343
+ const addQueue = async (queueName, handler, module2) => {
1331
1344
  try {
1332
1345
  validateQueueName(queueName);
1333
1346
  validateHandler(handler);
@@ -1335,7 +1348,7 @@ var createQueueManager = ({
1335
1348
  logger.warn(`${logSymbols3.warning} ${chalk4.yellow("Queue already exists:")} ${chalk4.magenta(queueName)}.`);
1336
1349
  return;
1337
1350
  }
1338
- queues[queueName] = createQueueService(handler, module);
1351
+ queues[queueName] = createQueueService(handler, module2);
1339
1352
  if (config.persistence.enabled && loadQueueState) {
1340
1353
  await loadQueueState(queueName);
1341
1354
  }
@@ -1377,10 +1390,10 @@ var createQueueManager = ({
1377
1390
  return false;
1378
1391
  }
1379
1392
  };
1380
- const listQueues = (module) => {
1393
+ const listQueues = (module2) => {
1381
1394
  return Object.keys(queues).filter((queueName) => {
1382
1395
  const queueService = queues[queueName];
1383
- return !module || queueService.module === module;
1396
+ return !module2 || queueService.module === module2;
1384
1397
  }).sort();
1385
1398
  };
1386
1399
  const getQueueStats = (queueName) => {
@@ -1419,8 +1432,8 @@ var createQueueManager = ({
1419
1432
  queues[queueName].incoming.push(message);
1420
1433
  scheduleProcessing(queueName, queues[queueName]);
1421
1434
  handleImmediateProcessing(queues[queueName], config, processBatch, queueName);
1422
- if (config.persistence.enabled && saveQueueState) {
1423
- await saveQueueState(queueName, queues[queueName]);
1435
+ if (config.persistence.enabled) {
1436
+ dirtyQueues.add(queueName);
1424
1437
  }
1425
1438
  return {
1426
1439
  id: message.id,
@@ -1441,8 +1454,8 @@ var createQueueManager = ({
1441
1454
  }
1442
1455
  logDLQOperation("Moving", processedCount, queueName);
1443
1456
  scheduleProcessing(queueName, queues[queueName]);
1444
- if (saveQueueState) {
1445
- await saveQueueState(queueName, queues[queueName]);
1457
+ if (config.persistence.enabled) {
1458
+ dirtyQueues.add(queueName);
1446
1459
  }
1447
1460
  return {
1448
1461
  status: "success",
@@ -1463,8 +1476,8 @@ var createQueueManager = ({
1463
1476
  };
1464
1477
  }
1465
1478
  logDLQOperation("Purging", purgedCount, queueName);
1466
- if (saveQueueState) {
1467
- await saveQueueState(queueName, queues[queueName]);
1479
+ if (config.persistence.enabled) {
1480
+ dirtyQueues.add(queueName);
1468
1481
  }
1469
1482
  return {
1470
1483
  status: "success",
@@ -1495,14 +1508,18 @@ var createQueueDecorator = (queueManager) => (app) => {
1495
1508
  var queuesPlugin = fsPlugin(async (app, options) => {
1496
1509
  const config = mergeConfig(DEFAULT_CONFIG, options.config);
1497
1510
  const queues = {};
1511
+ const dirtyQueues = /* @__PURE__ */ new Set();
1512
+ const intervalIdHolder = {};
1498
1513
  const processMessage = createProcessMessageHandler(config);
1499
1514
  const saveQueueState = config.persistence.enabled ? createQueueStateSaver(config) : void 0;
1500
1515
  const saveAllQueueStates = config.persistence.enabled && saveQueueState ? createAllQueuesStateSaver(config, saveQueueState)(queues) : async () => {
1501
1516
  };
1517
+ const saveDirtyQueueStates = config.persistence.enabled && saveQueueState ? createDirtyQueuesStateSaver(saveQueueState, dirtyQueues)(queues) : async () => {
1518
+ };
1502
1519
  const processBatch = createBatchProcessor(
1503
1520
  processMessage,
1504
1521
  config,
1505
- saveQueueState ? (queueName) => saveQueueState(queueName, queues[queueName]) : void 0
1522
+ config.persistence.enabled ? dirtyQueues : void 0
1506
1523
  );
1507
1524
  const scheduleProcessing = createProcessingScheduler(processBatch, config);
1508
1525
  const loadQueueState = config.persistence.enabled ? createQueueStateLoader(
@@ -1513,11 +1530,12 @@ var queuesPlugin = fsPlugin(async (app, options) => {
1513
1530
  };
1514
1531
  const loadAllQueueStates = config.persistence.enabled ? createAllQueuesStateLoader(config, loadQueueState) : async () => {
1515
1532
  };
1516
- const initializePersistence = config.persistence.enabled ? createPersistenceInitializer(config, loadAllQueueStates, saveAllQueueStates) : async () => {
1533
+ const initializePersistence = config.persistence.enabled ? createPersistenceInitializer(config, loadAllQueueStates, saveDirtyQueueStates, saveAllQueueStates, intervalIdHolder) : async () => {
1517
1534
  };
1518
1535
  const queueManager = createQueueManager({
1519
1536
  config,
1520
1537
  queues,
1538
+ dirtyQueues,
1521
1539
  saveQueueState: saveQueueState ? (queueName) => saveQueueState(queueName, queues[queueName]) : void 0,
1522
1540
  loadQueueState,
1523
1541
  scheduleProcessing,
@@ -1921,17 +1939,22 @@ var scheduleJob = (scheduler, state, executeJobFn) => {
1921
1939
  updatedScheduler.timerId = setTimeout(() => {
1922
1940
  executeJobFn(updatedScheduler);
1923
1941
  }, timeUntilNextRun);
1924
- logger.info(`${chalk6.blue("\u{1F4C5} Scheduled job")} ${chalk6.green(scheduler.job.name)} to run in ${chalk6.cyan(Math.round(timeUntilNextRun / 1e3))}s`);
1942
+ logger.debug(`${chalk6.blue("\u{1F4C5} Scheduled job")} ${chalk6.green(scheduler.job.name)} to run in ${chalk6.cyan(Math.round(timeUntilNextRun / 1e3))}s`);
1925
1943
  }
1926
1944
  return updatedScheduler;
1927
1945
  };
1928
1946
  var executeJobWithTimeout = async (handler, job, execution, timeoutMs) => {
1929
- return Promise.race([
1930
- handler(job, execution),
1931
- new Promise(
1932
- (_, reject) => setTimeout(() => reject(new Error("Job execution timeout")), timeoutMs)
1933
- )
1934
- ]);
1947
+ let timerId;
1948
+ try {
1949
+ return await Promise.race([
1950
+ handler(job, execution),
1951
+ new Promise((_, reject) => {
1952
+ timerId = setTimeout(() => reject(new Error("Job execution timeout")), timeoutMs);
1953
+ })
1954
+ ]);
1955
+ } finally {
1956
+ clearTimeout(timerId);
1957
+ }
1935
1958
  };
1936
1959
  var updateJobAfterExecution = (job, execution, config) => {
1937
1960
  const updatedJob = {
@@ -1956,11 +1979,11 @@ var handleExecutionSuccess = (execution, result) => {
1956
1979
 
1957
1980
  // src/schedule-plugin/persistence.ts
1958
1981
  import * as fs2 from "fs/promises";
1959
- import * as path3 from "path";
1982
+ import * as path2 from "path";
1960
1983
  import chalk7 from "chalk";
1961
1984
  import logSymbols5 from "log-symbols";
1962
- var createStateFilePath = (directory) => path3.join(directory, "scheduler-state.json");
1963
- var createTempFilePath = (directory) => path3.join(directory, `scheduler-state.${Date.now()}.temp.json`);
1985
+ var createStateFilePath = (directory) => path2.join(directory, "scheduler-state.json");
1986
+ var createTempFilePath = (directory) => path2.join(directory, `scheduler-state.${Date.now()}.temp.json`);
1964
1987
  var serializeSchedulerState = (schedulers, executionHistory) => ({
1965
1988
  jobs: Object.values(schedulers).map((s) => s.job),
1966
1989
  executions: executionHistory.slice(-100),
@@ -1974,7 +1997,7 @@ var saveSchedulerState = async (state) => {
1974
1997
  const tempFile = createTempFilePath(state.config.persistence.directory);
1975
1998
  await fs2.writeFile(tempFile, JSON.stringify(serializedState, null, 2), "utf8");
1976
1999
  await fs2.rename(tempFile, stateFile);
1977
- logger.info(`${logSymbols5.info} ${chalk7.blue("Enhanced scheduler state saved")}`);
2000
+ logger.debug(`${logSymbols5.info} ${chalk7.blue("Enhanced scheduler state saved")}`);
1978
2001
  } catch (error) {
1979
2002
  logger.error("Failed to save scheduler state:", error);
1980
2003
  }
@@ -1986,7 +2009,7 @@ var loadSchedulerStateData = async (directory) => {
1986
2009
  return JSON.parse(data);
1987
2010
  } catch (error) {
1988
2011
  if (error.code === "ENOENT") {
1989
- logger.info(`${chalk7.blue("No previous scheduler state found - starting fresh")}`);
2012
+ logger.debug(`${chalk7.blue("No previous scheduler state found - starting fresh")}`);
1990
2013
  } else {
1991
2014
  logger.error("Failed to load scheduler state:", error);
1992
2015
  }
@@ -1999,20 +2022,20 @@ var validateAndAdjustNextRun = (job, savedNextRun, lastRestartTime, config) => {
1999
2022
  return calculateNextRunFromLastRun(job, job.lastRun, config);
2000
2023
  }
2001
2024
  if (savedNextRun <= now) {
2002
- logger.info(`${chalk7.yellow("\u23F0 Saved next run is in the past for")} ${chalk7.green(job.name)} - recalculating`);
2025
+ logger.debug(`${chalk7.yellow("\u23F0 Saved next run is in the past for")} ${chalk7.green(job.name)} - recalculating`);
2003
2026
  return calculateNextRunFromLastRun(job, job.lastRun, config);
2004
2027
  }
2005
2028
  const timeSinceRestart = now.getTime() - lastRestartTime.getTime();
2006
2029
  const isRapidRestart = timeSinceRestart < config.restartBehavior.rapidRestartThreshold;
2007
2030
  if (isRapidRestart) {
2008
- logger.info(`${chalk7.blue("\u26A1 Rapid restart detected for")} ${chalk7.green(job.name)} - preserving saved timing`);
2031
+ logger.debug(`${chalk7.blue("\u26A1 Rapid restart detected for")} ${chalk7.green(job.name)} - preserving saved timing`);
2009
2032
  return savedNextRun;
2010
2033
  }
2011
2034
  if (job.cronExpression || job.intervalMs) {
2012
2035
  const expectedNextRun = calculateNextRunFromLastRun(job, job.lastRun, config);
2013
2036
  const timeDiff = Math.abs(savedNextRun.getTime() - expectedNextRun.getTime());
2014
2037
  if (timeDiff > config.restartBehavior.maxTimingDrift) {
2015
- logger.info(`${chalk7.yellow("\u{1F527} Adjusting timing for")} ${chalk7.green(job.name)} - drift of ${Math.round(timeDiff / 1e3)}s detected`);
2038
+ logger.debug(`${chalk7.yellow("\u{1F527} Adjusting timing for")} ${chalk7.green(job.name)} - drift of ${Math.round(timeDiff / 1e3)}s detected`);
2016
2039
  return expectedNextRun;
2017
2040
  }
2018
2041
  }
@@ -2026,7 +2049,7 @@ var restoreJobFromSavedData = (scheduler, savedJob, config, lastRestartTime) =>
2026
2049
  lastRun: savedJob.lastRun ? new Date(savedJob.lastRun) : void 0
2027
2050
  };
2028
2051
  if (definitionChanged) {
2029
- logger.info(`${chalk7.yellow("\u{1F504} Job definition changed:")} ${chalk7.green(savedJob.name)} - recalculating schedule`);
2052
+ logger.debug(`${chalk7.yellow("\u{1F504} Job definition changed:")} ${chalk7.green(savedJob.name)} - recalculating schedule`);
2030
2053
  updatedJob.nextRun = calculateNextRunFromLastRun(updatedJob, updatedJob.lastRun, config);
2031
2054
  } else {
2032
2055
  const savedNextRun = savedJob.nextRun ? new Date(savedJob.nextRun) : void 0;
@@ -2036,7 +2059,7 @@ var restoreJobFromSavedData = (scheduler, savedJob, config, lastRestartTime) =>
2036
2059
  const result = parseCronExpression(updatedJob.cronExpression, updatedJob.lastRun, {
2037
2060
  timezone: updatedJob.timezone
2038
2061
  });
2039
- logger.info(`${chalk7.blue("\u{1F4C5} Job restored:")} ${chalk7.green(savedJob.name)} - ${result.description} - next: ${chalk7.cyan(updatedJob.nextRun.toLocaleString())}`);
2062
+ logger.debug(`${chalk7.blue("\u{1F4C5} Job restored:")} ${chalk7.green(savedJob.name)} - ${result.description} - next: ${chalk7.cyan(updatedJob.nextRun.toLocaleString())}`);
2040
2063
  }
2041
2064
  return { ...scheduler, job: updatedJob };
2042
2065
  };
@@ -2079,16 +2102,11 @@ var cleanupExecutionHistory = (state) => {
2079
2102
  0,
2080
2103
  state.executionHistory.length - state.config.cleanup.maxExecutionHistory
2081
2104
  );
2082
- logger.info(`${chalk8.blue("\u{1F9F9} Cleaned up")} ${removed.length} old execution records`);
2105
+ logger.debug(`${chalk8.blue("\u{1F9F9} Cleaned up")} ${removed.length} old execution records`);
2083
2106
  return removed;
2084
2107
  }
2085
2108
  return [];
2086
2109
  };
2087
- var startCleanupInterval = (state) => {
2088
- return setInterval(() => {
2089
- cleanupExecutionHistory(state);
2090
- }, state.config.cleanup.cleanupInterval);
2091
- };
2092
2110
 
2093
2111
  // src/schedule-plugin/core.ts
2094
2112
  var DEFAULT_CONFIG2 = {
@@ -2140,6 +2158,8 @@ var createInitialState = (config) => {
2140
2158
  executionHistory: [],
2141
2159
  isShuttingDown: false,
2142
2160
  runningExecutions: 0,
2161
+ isDirty: false,
2162
+ lastCleanupTime: Date.now(),
2143
2163
  lastRestartTime: /* @__PURE__ */ new Date(),
2144
2164
  config
2145
2165
  };
@@ -2172,18 +2192,18 @@ var createSchedulerFunctions = (state) => {
2172
2192
  );
2173
2193
  const completedExecution = handleExecutionSuccess(execution, result);
2174
2194
  state.executions[execution.id] = completedExecution;
2175
- scheduler.job = updateJobAfterExecution(scheduler.job, execution, state.config);
2176
2195
  } catch (error) {
2177
2196
  const failedExecution = handleExecutionError(execution, error);
2178
2197
  state.executions[execution.id] = failedExecution;
2179
2198
  } finally {
2180
2199
  scheduler.isRunning = false;
2181
2200
  state.runningExecutions--;
2201
+ scheduler.job = updateJobAfterExecution(scheduler.job, execution, state.config);
2182
2202
  if (scheduler.job.enabled && !state.isShuttingDown) {
2183
2203
  scheduleJobFn(scheduler);
2184
2204
  }
2185
2205
  if (state.config.persistence.enabled) {
2186
- await saveSchedulerState(state);
2206
+ state.isDirty = true;
2187
2207
  }
2188
2208
  }
2189
2209
  };
@@ -2205,11 +2225,18 @@ var initializeScheduler = async (state, scheduleJobFn) => {
2205
2225
  );
2206
2226
  state.schedulers = schedulers;
2207
2227
  state.executionHistory = executionHistory;
2208
- if (state.config.persistence.saveInterval > 0) {
2209
- setInterval(() => saveSchedulerState(state), state.config.persistence.saveInterval);
2210
- }
2211
2228
  }
2212
- state.cleanupInterval = startCleanupInterval(state);
2229
+ const tickInterval = state.config.persistence.saveInterval > 0 ? state.config.persistence.saveInterval : state.config.cleanup.cleanupInterval;
2230
+ state.tickInterval = setInterval(async () => {
2231
+ if (state.isDirty && state.config.persistence.enabled) {
2232
+ state.isDirty = false;
2233
+ await saveSchedulerState(state);
2234
+ }
2235
+ if (Date.now() - state.lastCleanupTime >= state.config.cleanup.cleanupInterval) {
2236
+ state.lastCleanupTime = Date.now();
2237
+ cleanupExecutionHistory(state);
2238
+ }
2239
+ }, tickInterval);
2213
2240
  for (const scheduler of Object.values(state.schedulers)) {
2214
2241
  if (scheduler.job.enabled) {
2215
2242
  scheduleJobFn(scheduler);
@@ -2240,11 +2267,11 @@ var createJobFromDefinition = (jobDef, config) => {
2240
2267
  const result = parseCronExpression(cronExpression, void 0, {
2241
2268
  timezone: jobDef.timezone ?? config.cron.defaultTimezone
2242
2269
  });
2243
- logger.info(`${chalk10.blue("\u{1F4C5} Job")} ${chalk10.green(jobDef.name)}: ${result.description} - Next: ${chalk10.cyan(result.nextRun.toLocaleString())}`);
2270
+ logger.debug(`${chalk10.blue("\u{1F4C5} Job")} ${chalk10.green(jobDef.name)}: ${result.description} - Next: ${chalk10.cyan(result.nextRun.toLocaleString())}`);
2244
2271
  const upcoming = getNextExecutions(cronExpression, 3, {
2245
2272
  timezone: jobDef.timezone ?? config.cron.defaultTimezone
2246
2273
  });
2247
- logger.info(`${chalk10.blue(" Upcoming:")} ${upcoming.map((d) => d.toLocaleTimeString()).join(", ")}`);
2274
+ logger.debug(`${chalk10.blue(" Upcoming:")} ${upcoming.map((d) => d.toLocaleTimeString()).join(", ")}`);
2248
2275
  }
2249
2276
  const job = {
2250
2277
  id: generateJobId(),
@@ -2308,19 +2335,19 @@ var createExecutionsData = (state) => ({
2308
2335
  running: Object.values(state.executions).filter((e) => e.status === "running")
2309
2336
  });
2310
2337
  var registerDashboardRoute = (app, state) => {
2311
- app.get("/dashboard", async function(_, reply) {
2338
+ app.get("/schedule/dashboard", async function(_, reply) {
2312
2339
  const dashboardData = createDashboardData(state);
2313
2340
  return reply.status(200).send(dashboardData);
2314
2341
  });
2315
2342
  };
2316
2343
  var registerExecutionsRoute = (app, state) => {
2317
- app.get("/executions", async function(_, reply) {
2344
+ app.get("/schedule/executions", async function(_, reply) {
2318
2345
  const executionsData = createExecutionsData(state);
2319
2346
  return reply.status(200).send(executionsData);
2320
2347
  });
2321
2348
  };
2322
2349
  var registerTriggerJobRoute = (app, state, executeJobFn) => {
2323
- app.post("/jobs/:jobId/trigger", async function(request, reply) {
2350
+ app.post("/schedule/jobs/:jobId/trigger", async function(request, reply) {
2324
2351
  const scheduler = state.schedulers[request.params.jobId];
2325
2352
  if (!scheduler) {
2326
2353
  return reply.status(404).send({ error: "Job not found" });
@@ -2333,7 +2360,7 @@ var registerTriggerJobRoute = (app, state, executeJobFn) => {
2333
2360
  });
2334
2361
  };
2335
2362
  var registerEnableJobRoute = (app, state, scheduleJobFn) => {
2336
- app.put("/jobs/:jobId/enable", async function(request, reply) {
2363
+ app.put("/schedule/jobs/:jobId/enable", async function(request, reply) {
2337
2364
  const scheduler = state.schedulers[request.params.jobId];
2338
2365
  if (!scheduler) {
2339
2366
  return reply.status(404).send({ error: "Job not found" });
@@ -2345,7 +2372,7 @@ var registerEnableJobRoute = (app, state, scheduleJobFn) => {
2345
2372
  });
2346
2373
  };
2347
2374
  var registerDisableJobRoute = (app, state) => {
2348
- app.put("/jobs/:jobId/disable", async function(request, reply) {
2375
+ app.put("/schedule/jobs/:jobId/disable", async function(request, reply) {
2349
2376
  const scheduler = state.schedulers[request.params.jobId];
2350
2377
  if (!scheduler) {
2351
2378
  return reply.status(404).send({ error: "Job not found" });
@@ -2439,8 +2466,8 @@ var createSchedulerManager = ({
2439
2466
  return false;
2440
2467
  }
2441
2468
  };
2442
- const listJobs = (module) => {
2443
- return Object.values(state.schedulers).filter((s) => !module || s.job.module === module).map((s) => s.job.name).sort();
2469
+ const listJobs = (module2) => {
2470
+ return Object.values(state.schedulers).filter((s) => !module2 || s.job.module === module2).map((s) => s.job.name).sort();
2444
2471
  };
2445
2472
  const getJobStats = (jobName) => {
2446
2473
  try {
@@ -2459,7 +2486,7 @@ var createSchedulerManager = ({
2459
2486
  throw new Error(`Job '${jobName}' does not exist`);
2460
2487
  }
2461
2488
  if (scheduler.job.enabled) {
2462
- logger.info(`${logSymbols9.info} ${chalk11.blue("Job is already enabled:")} ${chalk11.magenta(jobName)}`);
2489
+ logger.debug(`${logSymbols9.info} ${chalk11.blue("Job is already enabled:")} ${chalk11.magenta(jobName)}`);
2463
2490
  return;
2464
2491
  }
2465
2492
  scheduler.job.enabled = true;
@@ -2478,7 +2505,7 @@ var createSchedulerManager = ({
2478
2505
  throw new Error(`Job '${jobName}' does not exist`);
2479
2506
  }
2480
2507
  if (!scheduler.job.enabled) {
2481
- logger.info(`${logSymbols9.info} ${chalk11.blue("Job is already disabled:")} ${chalk11.magenta(jobName)}`);
2508
+ logger.debug(`${logSymbols9.info} ${chalk11.blue("Job is already disabled:")} ${chalk11.magenta(jobName)}`);
2482
2509
  return;
2483
2510
  }
2484
2511
  scheduler.job.enabled = false;
@@ -2579,6 +2606,7 @@ var RouteRegistry = class {
2579
2606
  var routeRegistry = new RouteRegistry();
2580
2607
 
2581
2608
  // src/dev-console-plugin/plugin.ts
2609
+ var require2 = createRequire(import.meta.url);
2582
2610
  var LogStore = class {
2583
2611
  logs = [];
2584
2612
  maxLogs = 1e3;
@@ -2596,8 +2624,8 @@ var LogStore = class {
2596
2624
  getLogsByLevel(level, limit = 100) {
2597
2625
  return this.logs.filter((log) => log.level === level).slice(0, limit);
2598
2626
  }
2599
- getLogsByModule(module, limit = 100) {
2600
- return this.logs.filter((log) => log.module === module).slice(0, limit);
2627
+ getLogsByModule(module2, limit = 100) {
2628
+ return this.logs.filter((log) => log.module === module2).slice(0, limit);
2601
2629
  }
2602
2630
  getLogsByTrigger(triggerType, triggerName, limit = 100) {
2603
2631
  return this.logs.filter(
@@ -2627,7 +2655,7 @@ var captureConsoleLog = (level, originalMethod) => {
2627
2655
  originalMethod.apply(console, args);
2628
2656
  const message = args.join(" ");
2629
2657
  let source = "unknown";
2630
- let module;
2658
+ let module2;
2631
2659
  let trigger;
2632
2660
  let triggerType;
2633
2661
  if (message.includes("Queue") || message.includes("queue")) {
@@ -2647,7 +2675,7 @@ var captureConsoleLog = (level, originalMethod) => {
2647
2675
  if (routeMatch) trigger = routeMatch[0];
2648
2676
  }
2649
2677
  const moduleMatch = message.match(/module[:\s]+([a-zA-Z0-9_-]+)/i) || message.match(/\[([a-zA-Z0-9_-]+)\]/) || message.match(/in\s+([a-zA-Z0-9_-]+)\s+module/i);
2650
- if (moduleMatch) module = moduleMatch[1];
2678
+ if (moduleMatch) module2 = moduleMatch[1];
2651
2679
  logStore.addLog({
2652
2680
  id: Date.now().toString() + Math.random().toString(36).substr(2, 9),
2653
2681
  timestamp: /* @__PURE__ */ new Date(),
@@ -2655,7 +2683,7 @@ var captureConsoleLog = (level, originalMethod) => {
2655
2683
  message: message.replace(/\x1b\[[0-9;]*m/g, ""),
2656
2684
  // Remove ANSI colors
2657
2685
  source,
2658
- module,
2686
+ module: module2,
2659
2687
  trigger,
2660
2688
  triggerType
2661
2689
  });
@@ -2855,7 +2883,7 @@ async function devConsolePluginFunction(fastify, options = {}) {
2855
2883
  }
2856
2884
  });
2857
2885
  fastify.post(`/${prefix}/queues`, async (request, reply) => {
2858
- const { queueName, module } = request.body;
2886
+ const { queueName, module: module2 } = request.body;
2859
2887
  const queueManager = fastify.queues;
2860
2888
  if (!queueManager) {
2861
2889
  return reply.status(503).send({ error: "Queue service not available" });
@@ -2867,7 +2895,7 @@ async function devConsolePluginFunction(fastify, options = {}) {
2867
2895
  const handler = async (message) => {
2868
2896
  console.log(`Processing message in ${queueName}:`, message);
2869
2897
  };
2870
- await queueManager.addQueue(queueName, handler, module);
2898
+ await queueManager.addQueue(queueName, handler, module2);
2871
2899
  return reply.status(201).send({
2872
2900
  status: "success",
2873
2901
  message: `Queue ${queueName} created successfully`,
@@ -2968,7 +2996,7 @@ async function devConsolePluginFunction(fastify, options = {}) {
2968
2996
  limit = 100,
2969
2997
  level,
2970
2998
  source,
2971
- module,
2999
+ module: module2,
2972
3000
  trigger,
2973
3001
  triggerType
2974
3002
  } = request.query;
@@ -2979,9 +3007,9 @@ async function devConsolePluginFunction(fastify, options = {}) {
2979
3007
  if (source) {
2980
3008
  logs = logs.filter((log) => log.source === source);
2981
3009
  }
2982
- if (module) {
3010
+ if (module2) {
2983
3011
  logs = logs.filter(
2984
- (log) => log.module === module || log.message.toLowerCase().includes(module.toLowerCase())
3012
+ (log) => log.module === module2 || log.message.toLowerCase().includes(module2.toLowerCase())
2985
3013
  );
2986
3014
  }
2987
3015
  if (trigger && triggerType) {
@@ -3014,7 +3042,9 @@ async function devConsolePluginFunction(fastify, options = {}) {
3014
3042
  });
3015
3043
  });
3016
3044
  if (enableUI) {
3017
- const devConsolePath = path4.resolve(__dirname, "../../../packages/dev-console/dist");
3045
+ const devConsolePath = path3.dirname(
3046
+ require2.resolve("@cloudnux/dev-console/dist/index.html")
3047
+ );
3018
3048
  await fastify.register(fastifyStatic, {
3019
3049
  root: devConsolePath,
3020
3050
  decorateReply: true