@cloudnux/local-cloud-provider 0.16.0 → 0.18.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.
@@ -0,0 +1,24 @@
1
+ import { FastifyPluginOptions, FastifyPluginAsync } from 'fastify';
2
+
3
+ type InvokeHandlerFn = (envelop: {
4
+ payload?: any;
5
+ calledModule: string;
6
+ invokeTriggerName: string;
7
+ }) => Promise<any>;
8
+ interface InvokeManager {
9
+ register(module: string, name: string, handler: InvokeHandlerFn): void;
10
+ get(module: string, name: string): InvokeHandlerFn | undefined;
11
+ list(): string[];
12
+ }
13
+ interface InvokePluginOptions extends FastifyPluginOptions {
14
+ prefix?: string;
15
+ }
16
+ declare module 'fastify' {
17
+ interface FastifyInstance {
18
+ invokes: InvokeManager;
19
+ }
20
+ }
21
+
22
+ declare const invokesPlugin: FastifyPluginAsync<InvokePluginOptions>;
23
+
24
+ export { type InvokeHandlerFn, type InvokeManager, type InvokePluginOptions, invokesPlugin };
@@ -0,0 +1,23 @@
1
+ // src/invoke-plugin/plugin.ts
2
+ import fsPlugin from "fastify-plugin";
3
+ var invokesPlugin = fsPlugin(async (app) => {
4
+ const registry = /* @__PURE__ */ new Map();
5
+ const invokeManager = {
6
+ register(module, name, handler) {
7
+ const key = `${module}:${name}`;
8
+ registry.set(key, handler);
9
+ },
10
+ get(module, name) {
11
+ const key = `${module}:${name}`;
12
+ return registry.get(key);
13
+ },
14
+ list() {
15
+ return Array.from(registry.keys());
16
+ }
17
+ };
18
+ app.decorate("invokes", invokeManager);
19
+ });
20
+ export {
21
+ invokesPlugin
22
+ };
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/invoke-plugin/plugin.ts"],"sourcesContent":["import { FastifyInstance, FastifyPluginAsync } from \"fastify\";\nimport fsPlugin from \"fastify-plugin\";\n\nimport { InvokePluginOptions, InvokeManager, InvokeHandlerFn } from \"./types\";\n\nexport const invokesPlugin: FastifyPluginAsync<InvokePluginOptions> =\n fsPlugin(async (app: FastifyInstance) => {\n const registry = new Map<string, InvokeHandlerFn>();\n const invokeManager: InvokeManager = {\n register(module, name, handler) {\n const key = `${module}:${name}`;\n registry.set(key, handler);\n },\n get(module, name) {\n const key = `${module}:${name}`;\n return registry.get(key);\n },\n list() {\n return Array.from(registry.keys());\n },\n };\n\n app.decorate('invokes', invokeManager);\n });\n"],"mappings":";AACA,OAAO,cAAc;AAId,IAAM,gBACT,SAAS,OAAO,QAAyB;AACrC,QAAM,WAAW,oBAAI,IAA6B;AAClD,QAAM,gBAA+B;AAAA,IACjC,SAAS,QAAQ,MAAM,SAAS;AAC5B,YAAM,MAAM,GAAG,MAAM,IAAI,IAAI;AAC7B,eAAS,IAAI,KAAK,OAAO;AAAA,IAC7B;AAAA,IACA,IAAI,QAAQ,MAAM;AACd,YAAM,MAAM,GAAG,MAAM,IAAI,IAAI;AAC7B,aAAO,SAAS,IAAI,GAAG;AAAA,IAC3B;AAAA,IACA,OAAO;AACH,aAAO,MAAM,KAAK,SAAS,KAAK,CAAC;AAAA,IACrC;AAAA,EACJ;AAEA,MAAI,SAAS,WAAW,aAAa;AACzC,CAAC;","names":[]}
@@ -31,11 +31,11 @@ interface QueueConfig {
31
31
  maxConcurrent: number;
32
32
  retryBackoff: boolean;
33
33
  persistence: {
34
- enabled: boolean;
34
+ enabled?: boolean;
35
35
  directory: string;
36
- saveInterval: number;
37
- saveOnShutdown: boolean;
38
- loadOnStartup: boolean;
36
+ saveInterval?: number;
37
+ saveOnShutdown?: boolean;
38
+ loadOnStartup?: boolean;
39
39
  };
40
40
  }
41
41
  interface QueueSummary {
@@ -90,13 +90,17 @@ interface QueueManager {
90
90
  purged: number;
91
91
  } | null>;
92
92
  }
93
+ type ScheduleProcessingFn = (queueName: string, queueService: QueueService, overrideDelay?: number | null) => void;
94
+ interface SchedulerRef {
95
+ current?: ScheduleProcessingFn;
96
+ }
93
97
  interface QueueDecoratorOptions {
94
98
  config: QueueConfig;
95
99
  queues: Record<string, QueueService>;
96
100
  dirtyQueues: Set<string>;
97
101
  saveQueueState?: (queueName: string, queueService: QueueService) => Promise<void>;
98
102
  loadQueueState?: (queueName: string) => Promise<void>;
99
- scheduleProcessing: (queueName: string, queueService: QueueService) => void;
103
+ scheduleProcessing: ScheduleProcessingFn;
100
104
  processBatch: (queueName: string, queueService: QueueService) => Promise<void>;
101
105
  }
102
106
  declare module 'fastify' {
@@ -107,4 +111,4 @@ declare module 'fastify' {
107
111
 
108
112
  declare const queuesPlugin: FastifyPluginAsync<QueuePluginOptions>;
109
113
 
110
- export { type EventHandler, type QueueConfig, type QueueDecoratorOptions, type QueueManager, type QueueMessage, type QueuePluginOptions, type QueueRegistryItem, type QueueService, type QueueSummary, queuesPlugin };
114
+ export { type EventHandler, type QueueConfig, type QueueDecoratorOptions, type QueueManager, type QueueMessage, type QueuePluginOptions, type QueueRegistryItem, type QueueService, type QueueSummary, type ScheduleProcessingFn, type SchedulerRef, queuesPlugin };
@@ -1042,16 +1042,40 @@ var createQueueService = (handler, module) => ({
1042
1042
  });
1043
1043
  var createQueueMessage = (body, headers) => {
1044
1044
  const id = Date.now().toString() + Math.random().toString(36).substring(2, 7);
1045
- return {
1045
+ const message = {
1046
1046
  id,
1047
1047
  timestamp: /* @__PURE__ */ new Date(),
1048
1048
  attempts: 0,
1049
1049
  payload: body,
1050
1050
  attributes: headers
1051
1051
  };
1052
+ const delaySeconds = Number(headers?.["x-delay-seconds"]);
1053
+ if (delaySeconds > 0) {
1054
+ message.nextAttempt = new Date(Date.now() + delaySeconds * 1e3);
1055
+ }
1056
+ return message;
1057
+ };
1058
+ var isMessageReady = (message, now = Date.now()) => {
1059
+ return !message.nextAttempt || message.nextAttempt.getTime() <= now;
1052
1060
  };
1053
1061
  var moveToProcessing = (queueService, batchSize) => {
1054
- return queueService.incoming.splice(0, batchSize);
1062
+ const now = Date.now();
1063
+ const ready = [];
1064
+ const remaining = [];
1065
+ for (const message of queueService.incoming) {
1066
+ if (ready.length < batchSize && isMessageReady(message, now)) {
1067
+ ready.push(message);
1068
+ } else {
1069
+ remaining.push(message);
1070
+ }
1071
+ }
1072
+ queueService.incoming = remaining;
1073
+ return ready;
1074
+ };
1075
+ var getNextReadyDelay = (queueService) => {
1076
+ const nextAttempts = queueService.incoming.filter((message) => message.nextAttempt).map((message) => message.nextAttempt.getTime());
1077
+ if (nextAttempts.length === 0) return null;
1078
+ return Math.max(0, Math.min(...nextAttempts) - Date.now());
1055
1079
  };
1056
1080
  var removeFromProcessing = (queueService, messageId) => {
1057
1081
  queueService.processing = queueService.processing.filter((msg) => msg.id !== messageId);
@@ -1162,7 +1186,7 @@ var handleProcessingError = async (queueName, message, queueService, config) =>
1162
1186
  }, delayMs);
1163
1187
  }
1164
1188
  };
1165
- var createBatchProcessor = (processMessage, config, dirtyQueues) => async (queueName, queueService) => {
1189
+ var createBatchProcessor = (processMessage, config, dirtyQueues, schedulerRef) => async (queueName, queueService) => {
1166
1190
  if (queueService.timeoutId) {
1167
1191
  clearTimeout(queueService.timeoutId);
1168
1192
  queueService.timeoutId = null;
@@ -1173,18 +1197,21 @@ var createBatchProcessor = (processMessage, config, dirtyQueues) => async (queue
1173
1197
  try {
1174
1198
  queueService.processingBatch = true;
1175
1199
  const messagesToProcess = moveToProcessing(queueService, config.batchSize);
1176
- if (messagesToProcess.length === 0) {
1177
- return;
1178
- }
1179
- queueService.processing.push(...messagesToProcess);
1180
- await Promise.all(messagesToProcess.map((message) => {
1181
- return processMessage(queueName, message, queueService);
1182
- }));
1183
- if (config.persistence.enabled && dirtyQueues) {
1184
- dirtyQueues.add(queueName);
1200
+ if (messagesToProcess.length > 0) {
1201
+ queueService.processing.push(...messagesToProcess);
1202
+ await Promise.all(messagesToProcess.map((message) => {
1203
+ return processMessage(queueName, message, queueService);
1204
+ }));
1205
+ if (config.persistence.enabled && dirtyQueues) {
1206
+ dirtyQueues.add(queueName);
1207
+ }
1185
1208
  }
1186
1209
  } finally {
1187
1210
  queueService.processingBatch = false;
1211
+ const nextReadyDelay = getNextReadyDelay(queueService);
1212
+ if (nextReadyDelay !== null) {
1213
+ schedulerRef?.current?.(queueName, queueService, nextReadyDelay);
1214
+ }
1188
1215
  }
1189
1216
  };
1190
1217
  var createProcessingScheduler = (processBatch, config) => (queueName, queueService, overrideDelay = null) => {
@@ -1227,7 +1254,7 @@ var createPersistenceInitializer = (config, loadAllQueueStates, saveDirtyQueueSt
1227
1254
  if (config.persistence.loadOnStartup) {
1228
1255
  await loadAllQueueStates();
1229
1256
  }
1230
- if (config.persistence.saveInterval > 0) {
1257
+ if (config.persistence.saveInterval && config.persistence.saveInterval > 0) {
1231
1258
  intervalIdHolder.id = setInterval(saveDirtyQueueStates, config.persistence.saveInterval);
1232
1259
  }
1233
1260
  if (config.persistence.saveOnShutdown) {
@@ -1595,12 +1622,15 @@ var queuesPlugin = fsPlugin(async (app, options) => {
1595
1622
  };
1596
1623
  const saveDirtyQueueStates = config.persistence.enabled && saveQueueState ? createDirtyQueuesStateSaver(saveQueueState, dirtyQueues)(queues) : async () => {
1597
1624
  };
1625
+ const schedulerRef = {};
1598
1626
  const processBatch = createBatchProcessor(
1599
1627
  processMessage,
1600
1628
  config,
1601
- config.persistence.enabled ? dirtyQueues : void 0
1629
+ config.persistence.enabled ? dirtyQueues : void 0,
1630
+ schedulerRef
1602
1631
  );
1603
1632
  const scheduleProcessing = createProcessingScheduler(processBatch, config);
1633
+ schedulerRef.current = scheduleProcessing;
1604
1634
  const loadQueueState = config.persistence.enabled ? createQueueStateLoader(
1605
1635
  config,
1606
1636
  scheduleProcessing,