@motiadev/core 0.8.2-beta.140-131607 → 0.8.2-beta.140-799293

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,7 +2,6 @@ export * from './src/types';
2
2
  export { createServer, MotiaServer } from './src/server';
3
3
  export { createStepHandlers, MotiaEventManager } from './src/step-handlers';
4
4
  export { createEventManager } from './src/event-manager';
5
- export { queueManager } from './src/queue-manager';
6
5
  export { Logger } from './src/logger';
7
6
  export { createStateAdapter } from './src/state/create-state-adapter';
8
7
  export { setupCronHandlers, CronManager } from './src/cron-handler';
@@ -17,4 +16,3 @@ export { Motia } from './src/motia';
17
16
  export { NoPrinter, Printer } from './src/printer';
18
17
  export { NoTracer } from './src/observability/no-tracer';
19
18
  export { config } from './src/config';
20
- export { validateInfrastructureConfig, type InfrastructureValidationError, type InfrastructureValidationResult, } from './src/infrastructure-validator';
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.validateInfrastructureConfig = exports.config = exports.NoTracer = exports.Printer = exports.NoPrinter = exports.trackEvent = exports.isAnalyticsEnabled = exports.getUserIdentifier = exports.getProjectIdentifier = exports.createMermaidGenerator = exports.getStreamConfig = exports.getStepConfig = exports.LockedData = exports.isNoopStep = exports.isEventStep = exports.isCronStep = exports.isApiStep = exports.setupCronHandlers = exports.createStateAdapter = exports.Logger = exports.queueManager = exports.createEventManager = exports.createStepHandlers = exports.createServer = void 0;
17
+ exports.config = exports.NoTracer = exports.Printer = exports.NoPrinter = exports.trackEvent = exports.isAnalyticsEnabled = exports.getUserIdentifier = exports.getProjectIdentifier = exports.createMermaidGenerator = exports.getStreamConfig = exports.getStepConfig = exports.LockedData = exports.isNoopStep = exports.isEventStep = exports.isCronStep = exports.isApiStep = exports.setupCronHandlers = exports.createStateAdapter = exports.Logger = exports.createEventManager = exports.createStepHandlers = exports.createServer = void 0;
18
18
  __exportStar(require("./src/types"), exports);
19
19
  var server_1 = require("./src/server");
20
20
  Object.defineProperty(exports, "createServer", { enumerable: true, get: function () { return server_1.createServer; } });
@@ -22,8 +22,6 @@ var step_handlers_1 = require("./src/step-handlers");
22
22
  Object.defineProperty(exports, "createStepHandlers", { enumerable: true, get: function () { return step_handlers_1.createStepHandlers; } });
23
23
  var event_manager_1 = require("./src/event-manager");
24
24
  Object.defineProperty(exports, "createEventManager", { enumerable: true, get: function () { return event_manager_1.createEventManager; } });
25
- var queue_manager_1 = require("./src/queue-manager");
26
- Object.defineProperty(exports, "queueManager", { enumerable: true, get: function () { return queue_manager_1.queueManager; } });
27
25
  var logger_1 = require("./src/logger");
28
26
  Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_1.Logger; } });
29
27
  var create_state_adapter_1 = require("./src/state/create-state-adapter");
@@ -54,5 +52,3 @@ var no_tracer_1 = require("./src/observability/no-tracer");
54
52
  Object.defineProperty(exports, "NoTracer", { enumerable: true, get: function () { return no_tracer_1.NoTracer; } });
55
53
  var config_1 = require("./src/config");
56
54
  Object.defineProperty(exports, "config", { enumerable: true, get: function () { return config_1.config; } });
57
- var infrastructure_validator_1 = require("./src/infrastructure-validator");
58
- Object.defineProperty(exports, "validateInfrastructureConfig", { enumerable: true, get: function () { return infrastructure_validator_1.validateInfrastructureConfig; } });
@@ -1,5 +1,5 @@
1
1
  import { Motia } from './motia';
2
- import { Step, InfrastructureConfig } from './types';
2
+ import { Step } from './types';
3
3
  import { Logger } from './logger';
4
4
  import { Tracer } from './observability';
5
5
  type CallStepFileOptions = {
@@ -9,7 +9,6 @@ type CallStepFileOptions = {
9
9
  contextInFirstArg?: boolean;
10
10
  logger: Logger;
11
11
  tracer: Tracer;
12
- infrastructure?: Partial<InfrastructureConfig>;
13
12
  };
14
13
  export declare const callStepFile: <TData>(options: CallStepFileOptions, motia: Motia) => Promise<TData | undefined>;
15
14
  export {};
@@ -31,7 +31,7 @@ const getLanguageBasedRunner = (stepFilePath = '') => {
31
31
  throw Error(`Unsupported file extension ${stepFilePath}`);
32
32
  };
33
33
  const callStepFile = (options, motia) => {
34
- const { step, traceId, data, tracer, logger, contextInFirstArg = false, infrastructure } = options;
34
+ const { step, traceId, data, tracer, logger, contextInFirstArg = false } = options;
35
35
  const flows = step.config.flows;
36
36
  return new Promise((resolve, reject) => {
37
37
  const streamConfig = motia.lockedData.getStreams();
@@ -39,7 +39,6 @@ const callStepFile = (options, motia) => {
39
39
  const jsonData = JSON.stringify({ data, flows, traceId, contextInFirstArg, streams });
40
40
  const { runner, command, args } = getLanguageBasedRunner(step.filePath);
41
41
  let result;
42
- let timeoutId;
43
42
  const processManager = new process_manager_1.ProcessManager({
44
43
  command,
45
44
  args: [...args, runner, step.filePath, jsonData],
@@ -53,21 +52,6 @@ const callStepFile = (options, motia) => {
53
52
  type: step.config.type,
54
53
  streams: streams.length,
55
54
  });
56
- const timeoutSeconds = infrastructure?.handler?.timeout;
57
- if (timeoutSeconds) {
58
- timeoutId = setTimeout(() => {
59
- processManager.kill();
60
- const errorMessage = `Step execution timed out after ${timeoutSeconds} seconds`;
61
- logger.error(errorMessage, { step: step.config.name, timeout: timeoutSeconds });
62
- tracer.end({ message: errorMessage });
63
- (0, utils_1.trackEvent)('step_execution_timeout', {
64
- stepName: step.config.name,
65
- traceId,
66
- timeout: timeoutSeconds,
67
- });
68
- reject(new Error(errorMessage));
69
- }, timeoutSeconds * 1000);
70
- }
71
55
  processManager
72
56
  .spawn()
73
57
  .then(() => {
@@ -79,12 +63,13 @@ const callStepFile = (options, motia) => {
79
63
  traceId,
80
64
  message: err.message,
81
65
  });
66
+ }
67
+ if (err) {
82
68
  tracer.end({
83
69
  message: err.message,
84
70
  code: err.code,
85
71
  stack: err.stack?.replace(new RegExp(`${motia.lockedData.baseDir}/`), ''),
86
72
  });
87
- reject(new Error(err.message || 'Handler execution failed'));
88
73
  }
89
74
  else {
90
75
  tracer.end();
@@ -162,8 +147,6 @@ const callStepFile = (options, motia) => {
162
147
  });
163
148
  processManager.onStderr((data) => logger.error(Buffer.from(data).toString()));
164
149
  processManager.onProcessClose((code) => {
165
- if (timeoutId)
166
- clearTimeout(timeoutId);
167
150
  processManager.close();
168
151
  if (code !== 0 && code !== null) {
169
152
  const error = { message: `Process exited with code ${code}`, code };
@@ -177,8 +160,6 @@ const callStepFile = (options, motia) => {
177
160
  }
178
161
  });
179
162
  processManager.onProcessError((error) => {
180
- if (timeoutId)
181
- clearTimeout(timeoutId);
182
163
  processManager.close();
183
164
  tracer.end({
184
165
  message: error.message,
@@ -200,8 +181,6 @@ const callStepFile = (options, motia) => {
200
181
  });
201
182
  })
202
183
  .catch((error) => {
203
- if (timeoutId)
204
- clearTimeout(timeoutId);
205
184
  tracer.end({
206
185
  message: error.message,
207
186
  code: error.code,
@@ -1,32 +1,26 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createEventManager = void 0;
4
- const queue_manager_1 = require("./queue-manager");
5
- const defaults_1 = require("./infrastructure-validator/defaults");
4
+ const logger_1 = require("./logger");
6
5
  const createEventManager = () => {
7
6
  const handlers = {};
8
7
  const emit = async (event, file) => {
9
- await queue_manager_1.queueManager.enqueue(event.topic, event);
8
+ const eventHandlers = handlers[event.topic] ?? [];
9
+ const { logger, ...rest } = event;
10
+ logger.debug('[Flow Emit] Event emitted', { handlers: eventHandlers.length, data: rest, file });
11
+ eventHandlers.map((eventHandler) => eventHandler.handler(event));
10
12
  };
11
13
  const subscribe = (config) => {
12
- const { event, handler, filePath } = config;
14
+ const { event, handlerName, handler, filePath } = config;
13
15
  if (!handlers[event]) {
14
16
  handlers[event] = [];
15
17
  }
18
+ logger_1.globalLogger.debug('[Flow Sub] Subscribing to event', { event, handlerName });
16
19
  handlers[event].push({ filePath, handler: handler });
17
- queue_manager_1.queueManager.subscribe(event, handler, defaults_1.DEFAULT_QUEUE_CONFIG, filePath);
18
20
  };
19
21
  const unsubscribe = (config) => {
20
22
  const { filePath, event } = config;
21
- const eventHandlers = handlers[event];
22
- if (!eventHandlers) {
23
- return;
24
- }
25
- const handlerToRemove = eventHandlers.find((h) => h.filePath === filePath);
26
- if (handlerToRemove) {
27
- queue_manager_1.queueManager.unsubscribe(event, handlerToRemove.handler);
28
- }
29
- handlers[event] = eventHandlers.filter((handler) => handler.filePath !== filePath);
23
+ handlers[event] = handlers[event]?.filter((handler) => handler.filePath !== filePath);
30
24
  };
31
25
  return { emit, subscribe, unsubscribe };
32
26
  };
@@ -10,6 +10,7 @@ export declare class LockedData {
10
10
  readonly baseDir: string;
11
11
  readonly streamAdapter: 'file' | 'memory';
12
12
  private readonly printer;
13
+ readonly motiaFileStoragePath: string;
13
14
  flows: Record<string, Flow>;
14
15
  activeSteps: Step[];
15
16
  devSteps: Step[];
@@ -19,7 +20,7 @@ export declare class LockedData {
19
20
  private streamHandlers;
20
21
  private streams;
21
22
  private streamWrapper?;
22
- constructor(baseDir: string, streamAdapter: "file" | "memory" | undefined, printer: Printer);
23
+ constructor(baseDir: string, streamAdapter: "file" | "memory" | undefined, printer: Printer, motiaFileStoragePath?: string);
23
24
  applyStreamWrapper<TData>(streamWrapper: StreamWrapper<TData>): void;
24
25
  saveTypes(): void;
25
26
  on(event: FlowEvent, handler: (flowName: string) => void): void;
@@ -12,10 +12,11 @@ const file_stream_adapter_1 = require("./streams/adapters/file-stream-adapter");
12
12
  const memory_stream_adapter_1 = require("./streams/adapters/memory-stream-adapter");
13
13
  const generate_types_1 = require("./types/generate-types");
14
14
  class LockedData {
15
- constructor(baseDir, streamAdapter = 'file', printer) {
15
+ constructor(baseDir, streamAdapter = 'file', printer, motiaFileStoragePath = '.motia') {
16
16
  this.baseDir = baseDir;
17
17
  this.streamAdapter = streamAdapter;
18
18
  this.printer = printer;
19
+ this.motiaFileStoragePath = motiaFileStoragePath;
19
20
  this.flows = {};
20
21
  this.activeSteps = [];
21
22
  this.devSteps = [];
@@ -266,7 +267,7 @@ class LockedData {
266
267
  }
267
268
  createStreamAdapter(streamName) {
268
269
  if (this.streamAdapter === 'file') {
269
- return new file_stream_adapter_1.FileStreamAdapter(this.baseDir, streamName);
270
+ return new file_stream_adapter_1.FileStreamAdapter(this.baseDir, streamName, this.motiaFileStoragePath);
270
271
  }
271
272
  return new memory_stream_adapter_1.MemoryStreamAdapter();
272
273
  }
@@ -3,14 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createStepHandlers = void 0;
4
4
  const call_step_file_1 = require("./call-step-file");
5
5
  const logger_1 = require("./logger");
6
- const defaults_1 = require("./infrastructure-validator/defaults");
7
- const validations_1 = require("./infrastructure-validator/validations");
8
- const queue_manager_1 = require("./queue-manager");
9
6
  const createStepHandlers = (motia) => {
10
7
  const eventSteps = motia.lockedData.eventSteps();
11
- const handlerMap = new Map();
12
8
  logger_1.globalLogger.debug(`[step handler] creating step handlers for ${eventSteps.length} steps`);
13
9
  const removeLogger = (event) => {
10
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
14
11
  const { logger, tracer, ...rest } = event;
15
12
  return rest;
16
13
  };
@@ -18,50 +15,34 @@ const createStepHandlers = (motia) => {
18
15
  const { config, filePath } = step;
19
16
  const { subscribes, name } = config;
20
17
  logger_1.globalLogger.debug('[step handler] establishing step subscriptions', { filePath, step: step.config.name });
21
- if (config.infrastructure) {
22
- logger_1.globalLogger.debug('[step handler] validating infrastructure config', {
23
- step: name,
24
- hasInputSchema: !!config.input,
25
- infrastructure: config.infrastructure,
26
- });
27
- const validationResult = (0, validations_1.validateInfrastructureConfig)(config.infrastructure, config.input);
28
- if (!validationResult.success && validationResult.errors) {
29
- logger_1.globalLogger.error('[step handler] Infrastructure configuration validation failed', {
30
- step: name,
31
- filePath,
32
- errors: validationResult.errors,
33
- });
34
- return;
35
- }
36
- logger_1.globalLogger.debug('[step handler] infrastructure config validated successfully', {
37
- step: name,
38
- });
39
- }
40
- const queueConfig = (0, defaults_1.getQueueConfigWithDefaults)(config.infrastructure);
41
- const handlers = [];
42
18
  subscribes.forEach((subscribe) => {
43
- const handler = async (event) => {
44
- const { data, traceId } = event;
45
- const logger = event.logger.child({ step: step.config.name });
46
- const tracer = event.tracer.child(step, logger);
47
- logger_1.globalLogger.debug('[step handler] received event', { event: removeLogger(event), step: name });
48
- await (0, call_step_file_1.callStepFile)({ step, data, traceId, tracer, logger, infrastructure: config.infrastructure }, motia);
49
- };
50
- queue_manager_1.queueManager.subscribe(subscribe, handler, queueConfig, subscribe);
51
- handlers.push({ topic: subscribe, handler });
19
+ motia.eventManager.subscribe({
20
+ filePath,
21
+ event: subscribe,
22
+ handlerName: step.config.name,
23
+ handler: async (event) => {
24
+ const { data, traceId } = event;
25
+ const logger = event.logger.child({ step: step.config.name });
26
+ const tracer = event.tracer.child(step, logger);
27
+ logger_1.globalLogger.debug('[step handler] received event', { event: removeLogger(event), step: name });
28
+ try {
29
+ await (0, call_step_file_1.callStepFile)({ step, data, traceId, tracer, logger }, motia);
30
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
+ }
32
+ catch (error) {
33
+ const message = typeof error === 'string' ? error : error.message;
34
+ logger.error(message);
35
+ }
36
+ },
37
+ });
52
38
  });
53
- handlerMap.set(filePath, handlers);
54
39
  };
55
40
  const removeHandler = (step) => {
56
- const { filePath } = step;
57
- const handlers = handlerMap.get(filePath);
58
- if (handlers) {
59
- handlers.forEach(({ topic, handler }) => {
60
- queue_manager_1.queueManager.unsubscribe(topic, handler);
61
- logger_1.globalLogger.debug('[step handler] unsubscribed handler', { filePath, topic, step: step.config.name });
62
- });
63
- handlerMap.delete(filePath);
64
- }
41
+ const { config, filePath } = step;
42
+ const { subscribes } = config;
43
+ subscribes.forEach((subscribe) => {
44
+ motia.eventManager.unsubscribe({ filePath, event: subscribe });
45
+ });
65
46
  };
66
47
  eventSteps.forEach(createHandler);
67
48
  return { removeHandler, createHandler };
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validateStep = void 0;
4
4
  const zod_1 = require("zod");
5
- const schemas_1 = require("./infrastructure-validator/schemas");
6
5
  const objectSchema = zod_1.z.object({
7
6
  type: zod_1.z.literal('object'),
8
7
  properties: zod_1.z.record(zod_1.z.any()),
@@ -61,7 +60,6 @@ const eventSchema = zod_1.z
61
60
  input: zod_1.z.union([jsonSchema, zod_1.z.object({}), zod_1.z.null()]).optional(),
62
61
  flows: zod_1.z.array(zod_1.z.string()).optional(),
63
62
  includeFiles: zod_1.z.array(zod_1.z.string()).optional(),
64
- infrastructure: schemas_1.infrastructureSchema.optional(),
65
63
  })
66
64
  .strict();
67
65
  const apiSchema = zod_1.z
@@ -6,7 +6,7 @@ export type FileAdapterConfig = {
6
6
  export declare class FileStreamAdapter<TData> extends StreamAdapter<TData> {
7
7
  private readonly filePath;
8
8
  private readonly streamsDir;
9
- constructor(filePath: string, streamName: string);
9
+ constructor(filePath: string, streamName: string, motiaFileStoragePath?: string);
10
10
  init(): void;
11
11
  getGroup(groupId: string): Promise<BaseStreamItem<TData>[]>;
12
12
  get(groupId: string, key: string): Promise<BaseStreamItem<TData> | null>;
@@ -41,9 +41,9 @@ const fs_1 = __importDefault(require("fs"));
41
41
  const path = __importStar(require("path"));
42
42
  const stream_adapter_1 = require("./stream-adapter");
43
43
  class FileStreamAdapter extends stream_adapter_1.StreamAdapter {
44
- constructor(filePath, streamName) {
44
+ constructor(filePath, streamName, motiaFileStoragePath = '.motia') {
45
45
  super();
46
- this.streamsDir = path.join(filePath, '.motia', 'streams');
46
+ this.streamsDir = path.join(filePath, motiaFileStoragePath, 'streams');
47
47
  this.filePath = path.join(this.streamsDir, `${streamName}.stream.json`);
48
48
  }
49
49
  init() {
@@ -30,22 +30,6 @@ export type Emit = string | {
30
30
  label?: string;
31
31
  conditional?: boolean;
32
32
  };
33
- export type HandlerConfig = {
34
- ram: number;
35
- cpu?: number;
36
- timeout: number;
37
- };
38
- export type QueueConfig = {
39
- type: 'fifo' | 'standard';
40
- messageGroupId?: string | null;
41
- maxRetries: number;
42
- visibilityTimeout: number;
43
- delaySeconds: number;
44
- };
45
- export type InfrastructureConfig = {
46
- handler?: Partial<HandlerConfig>;
47
- queue?: Partial<QueueConfig>;
48
- };
49
33
  export type EventConfig = {
50
34
  type: 'event';
51
35
  name: string;
@@ -61,7 +45,6 @@ export type EventConfig = {
61
45
  * Needs to be relative to the step file.
62
46
  */
63
47
  includeFiles?: string[];
64
- infrastructure?: Partial<InfrastructureConfig>;
65
48
  };
66
49
  export type NoopConfig = {
67
50
  type: 'noop';
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@motiadev/core",
3
3
  "description": "Core functionality for the Motia framework, providing the foundation for building event-driven workflows.",
4
4
  "main": "dist/index.js",
5
- "version": "0.8.2-beta.140-131607",
5
+ "version": "0.8.2-beta.140-799293",
6
6
  "dependencies": {
7
7
  "@amplitude/analytics-node": "^1.3.8",
8
8
  "body-parser": "^1.20.3",
@@ -1,3 +0,0 @@
1
- import { InfrastructureConfig, QueueConfig } from '../types';
2
- export declare const DEFAULT_QUEUE_CONFIG: QueueConfig;
3
- export declare function getQueueConfigWithDefaults(infrastructure?: InfrastructureConfig): QueueConfig;
@@ -1,17 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_QUEUE_CONFIG = void 0;
4
- exports.getQueueConfigWithDefaults = getQueueConfigWithDefaults;
5
- exports.DEFAULT_QUEUE_CONFIG = {
6
- type: 'standard',
7
- maxRetries: 3,
8
- visibilityTimeout: 900,
9
- messageGroupId: null,
10
- delaySeconds: 0,
11
- };
12
- function getQueueConfigWithDefaults(infrastructure) {
13
- return {
14
- ...exports.DEFAULT_QUEUE_CONFIG,
15
- ...(infrastructure?.queue || {}),
16
- };
17
- }
@@ -1,3 +0,0 @@
1
- export { AWS_LAMBDA_LIMITS, AWS_LAMBDA_CPU_RATIO, getProportionalCpu, handlerBaseSchema, handlerSchema, queueSchema, infrastructureSchema, createInfrastructureSchema, } from './schemas';
2
- export { type InfrastructureValidationError, type InfrastructureValidationResult } from './types';
3
- export { validateInfrastructureConfig } from './validations';
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateInfrastructureConfig = exports.createInfrastructureSchema = exports.infrastructureSchema = exports.queueSchema = exports.handlerSchema = exports.handlerBaseSchema = exports.getProportionalCpu = exports.AWS_LAMBDA_CPU_RATIO = exports.AWS_LAMBDA_LIMITS = void 0;
4
- var schemas_1 = require("./schemas");
5
- Object.defineProperty(exports, "AWS_LAMBDA_LIMITS", { enumerable: true, get: function () { return schemas_1.AWS_LAMBDA_LIMITS; } });
6
- Object.defineProperty(exports, "AWS_LAMBDA_CPU_RATIO", { enumerable: true, get: function () { return schemas_1.AWS_LAMBDA_CPU_RATIO; } });
7
- Object.defineProperty(exports, "getProportionalCpu", { enumerable: true, get: function () { return schemas_1.getProportionalCpu; } });
8
- Object.defineProperty(exports, "handlerBaseSchema", { enumerable: true, get: function () { return schemas_1.handlerBaseSchema; } });
9
- Object.defineProperty(exports, "handlerSchema", { enumerable: true, get: function () { return schemas_1.handlerSchema; } });
10
- Object.defineProperty(exports, "queueSchema", { enumerable: true, get: function () { return schemas_1.queueSchema; } });
11
- Object.defineProperty(exports, "infrastructureSchema", { enumerable: true, get: function () { return schemas_1.infrastructureSchema; } });
12
- Object.defineProperty(exports, "createInfrastructureSchema", { enumerable: true, get: function () { return schemas_1.createInfrastructureSchema; } });
13
- var validations_1 = require("./validations");
14
- Object.defineProperty(exports, "validateInfrastructureConfig", { enumerable: true, get: function () { return validations_1.validateInfrastructureConfig; } });
@@ -1,308 +0,0 @@
1
- import { z } from 'zod';
2
- import { ZodInput } from '../types';
3
- export declare const AWS_LAMBDA_LIMITS: {
4
- readonly MIN_RAM_MB: 128;
5
- readonly MAX_RAM_MB: 10240;
6
- readonly MIN_TIMEOUT_SECONDS: 1;
7
- readonly MAX_TIMEOUT_SECONDS: 900;
8
- };
9
- export declare const AWS_LAMBDA_CPU_RATIO: Record<number, number>;
10
- export declare function getProportionalCpu(ramMb: number): number;
11
- export declare const handlerBaseSchema: z.ZodObject<{
12
- ram: z.ZodNumber;
13
- timeout: z.ZodNumber;
14
- cpu: z.ZodOptional<z.ZodNumber>;
15
- }, "strip", z.ZodTypeAny, {
16
- ram: number;
17
- timeout: number;
18
- cpu?: number | undefined;
19
- }, {
20
- ram: number;
21
- timeout: number;
22
- cpu?: number | undefined;
23
- }>;
24
- export declare const handlerSchema: z.ZodEffects<z.ZodObject<{
25
- ram: z.ZodOptional<z.ZodNumber>;
26
- timeout: z.ZodOptional<z.ZodNumber>;
27
- cpu: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
28
- }, "strip", z.ZodTypeAny, {
29
- ram?: number | undefined;
30
- timeout?: number | undefined;
31
- cpu?: number | undefined;
32
- }, {
33
- ram?: number | undefined;
34
- timeout?: number | undefined;
35
- cpu?: number | undefined;
36
- }>, {
37
- ram?: number | undefined;
38
- timeout?: number | undefined;
39
- cpu?: number | undefined;
40
- }, {
41
- ram?: number | undefined;
42
- timeout?: number | undefined;
43
- cpu?: number | undefined;
44
- }>;
45
- export declare const queueSchema: z.ZodObject<{
46
- type: z.ZodEnum<["standard", "fifo"]>;
47
- visibilityTimeout: z.ZodNumber;
48
- messageGroupId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
49
- maxRetries: z.ZodNumber;
50
- delaySeconds: z.ZodOptional<z.ZodNumber>;
51
- }, "strip", z.ZodTypeAny, {
52
- type: "standard" | "fifo";
53
- visibilityTimeout: number;
54
- maxRetries: number;
55
- messageGroupId?: string | null | undefined;
56
- delaySeconds?: number | undefined;
57
- }, {
58
- type: "standard" | "fifo";
59
- visibilityTimeout: number;
60
- maxRetries: number;
61
- messageGroupId?: string | null | undefined;
62
- delaySeconds?: number | undefined;
63
- }>;
64
- export declare const infrastructureSchema: z.ZodEffects<z.ZodObject<{
65
- handler: z.ZodOptional<z.ZodEffects<z.ZodObject<{
66
- ram: z.ZodOptional<z.ZodNumber>;
67
- timeout: z.ZodOptional<z.ZodNumber>;
68
- cpu: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
69
- }, "strip", z.ZodTypeAny, {
70
- ram?: number | undefined;
71
- timeout?: number | undefined;
72
- cpu?: number | undefined;
73
- }, {
74
- ram?: number | undefined;
75
- timeout?: number | undefined;
76
- cpu?: number | undefined;
77
- }>, {
78
- ram?: number | undefined;
79
- timeout?: number | undefined;
80
- cpu?: number | undefined;
81
- }, {
82
- ram?: number | undefined;
83
- timeout?: number | undefined;
84
- cpu?: number | undefined;
85
- }>>;
86
- queue: z.ZodOptional<z.ZodObject<{
87
- type: z.ZodOptional<z.ZodEnum<["standard", "fifo"]>>;
88
- visibilityTimeout: z.ZodOptional<z.ZodNumber>;
89
- messageGroupId: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
90
- maxRetries: z.ZodOptional<z.ZodNumber>;
91
- delaySeconds: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
92
- }, "strip", z.ZodTypeAny, {
93
- type?: "standard" | "fifo" | undefined;
94
- visibilityTimeout?: number | undefined;
95
- messageGroupId?: string | null | undefined;
96
- maxRetries?: number | undefined;
97
- delaySeconds?: number | undefined;
98
- }, {
99
- type?: "standard" | "fifo" | undefined;
100
- visibilityTimeout?: number | undefined;
101
- messageGroupId?: string | null | undefined;
102
- maxRetries?: number | undefined;
103
- delaySeconds?: number | undefined;
104
- }>>;
105
- }, "strip", z.ZodTypeAny, {
106
- handler?: {
107
- ram?: number | undefined;
108
- timeout?: number | undefined;
109
- cpu?: number | undefined;
110
- } | undefined;
111
- queue?: {
112
- type?: "standard" | "fifo" | undefined;
113
- visibilityTimeout?: number | undefined;
114
- messageGroupId?: string | null | undefined;
115
- maxRetries?: number | undefined;
116
- delaySeconds?: number | undefined;
117
- } | undefined;
118
- }, {
119
- handler?: {
120
- ram?: number | undefined;
121
- timeout?: number | undefined;
122
- cpu?: number | undefined;
123
- } | undefined;
124
- queue?: {
125
- type?: "standard" | "fifo" | undefined;
126
- visibilityTimeout?: number | undefined;
127
- messageGroupId?: string | null | undefined;
128
- maxRetries?: number | undefined;
129
- delaySeconds?: number | undefined;
130
- } | undefined;
131
- }>, {
132
- handler?: {
133
- ram?: number | undefined;
134
- timeout?: number | undefined;
135
- cpu?: number | undefined;
136
- } | undefined;
137
- queue?: {
138
- type?: "standard" | "fifo" | undefined;
139
- visibilityTimeout?: number | undefined;
140
- messageGroupId?: string | null | undefined;
141
- maxRetries?: number | undefined;
142
- delaySeconds?: number | undefined;
143
- } | undefined;
144
- }, {
145
- handler?: {
146
- ram?: number | undefined;
147
- timeout?: number | undefined;
148
- cpu?: number | undefined;
149
- } | undefined;
150
- queue?: {
151
- type?: "standard" | "fifo" | undefined;
152
- visibilityTimeout?: number | undefined;
153
- messageGroupId?: string | null | undefined;
154
- maxRetries?: number | undefined;
155
- delaySeconds?: number | undefined;
156
- } | undefined;
157
- }>;
158
- export declare const createInfrastructureSchema: (inputSchema?: ZodInput) => z.ZodEffects<z.ZodEffects<z.ZodObject<{
159
- handler: z.ZodOptional<z.ZodEffects<z.ZodObject<{
160
- ram: z.ZodOptional<z.ZodNumber>;
161
- timeout: z.ZodOptional<z.ZodNumber>;
162
- cpu: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
163
- }, "strip", z.ZodTypeAny, {
164
- ram?: number | undefined;
165
- timeout?: number | undefined;
166
- cpu?: number | undefined;
167
- }, {
168
- ram?: number | undefined;
169
- timeout?: number | undefined;
170
- cpu?: number | undefined;
171
- }>, {
172
- ram?: number | undefined;
173
- timeout?: number | undefined;
174
- cpu?: number | undefined;
175
- }, {
176
- ram?: number | undefined;
177
- timeout?: number | undefined;
178
- cpu?: number | undefined;
179
- }>>;
180
- queue: z.ZodOptional<z.ZodObject<{
181
- type: z.ZodOptional<z.ZodEnum<["standard", "fifo"]>>;
182
- visibilityTimeout: z.ZodOptional<z.ZodNumber>;
183
- messageGroupId: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
184
- maxRetries: z.ZodOptional<z.ZodNumber>;
185
- delaySeconds: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
186
- }, "strip", z.ZodTypeAny, {
187
- type?: "standard" | "fifo" | undefined;
188
- visibilityTimeout?: number | undefined;
189
- messageGroupId?: string | null | undefined;
190
- maxRetries?: number | undefined;
191
- delaySeconds?: number | undefined;
192
- }, {
193
- type?: "standard" | "fifo" | undefined;
194
- visibilityTimeout?: number | undefined;
195
- messageGroupId?: string | null | undefined;
196
- maxRetries?: number | undefined;
197
- delaySeconds?: number | undefined;
198
- }>>;
199
- }, "strip", z.ZodTypeAny, {
200
- handler?: {
201
- ram?: number | undefined;
202
- timeout?: number | undefined;
203
- cpu?: number | undefined;
204
- } | undefined;
205
- queue?: {
206
- type?: "standard" | "fifo" | undefined;
207
- visibilityTimeout?: number | undefined;
208
- messageGroupId?: string | null | undefined;
209
- maxRetries?: number | undefined;
210
- delaySeconds?: number | undefined;
211
- } | undefined;
212
- }, {
213
- handler?: {
214
- ram?: number | undefined;
215
- timeout?: number | undefined;
216
- cpu?: number | undefined;
217
- } | undefined;
218
- queue?: {
219
- type?: "standard" | "fifo" | undefined;
220
- visibilityTimeout?: number | undefined;
221
- messageGroupId?: string | null | undefined;
222
- maxRetries?: number | undefined;
223
- delaySeconds?: number | undefined;
224
- } | undefined;
225
- }>, {
226
- handler?: {
227
- ram?: number | undefined;
228
- timeout?: number | undefined;
229
- cpu?: number | undefined;
230
- } | undefined;
231
- queue?: {
232
- type?: "standard" | "fifo" | undefined;
233
- visibilityTimeout?: number | undefined;
234
- messageGroupId?: string | null | undefined;
235
- maxRetries?: number | undefined;
236
- delaySeconds?: number | undefined;
237
- } | undefined;
238
- }, {
239
- handler?: {
240
- ram?: number | undefined;
241
- timeout?: number | undefined;
242
- cpu?: number | undefined;
243
- } | undefined;
244
- queue?: {
245
- type?: "standard" | "fifo" | undefined;
246
- visibilityTimeout?: number | undefined;
247
- messageGroupId?: string | null | undefined;
248
- maxRetries?: number | undefined;
249
- delaySeconds?: number | undefined;
250
- } | undefined;
251
- }>, {
252
- handler?: {
253
- ram?: number | undefined;
254
- timeout?: number | undefined;
255
- cpu?: number | undefined;
256
- } | undefined;
257
- queue?: {
258
- type?: "standard" | "fifo" | undefined;
259
- visibilityTimeout?: number | undefined;
260
- messageGroupId?: string | null | undefined;
261
- maxRetries?: number | undefined;
262
- delaySeconds?: number | undefined;
263
- } | undefined;
264
- }, {
265
- handler?: {
266
- ram?: number | undefined;
267
- timeout?: number | undefined;
268
- cpu?: number | undefined;
269
- } | undefined;
270
- queue?: {
271
- type?: "standard" | "fifo" | undefined;
272
- visibilityTimeout?: number | undefined;
273
- messageGroupId?: string | null | undefined;
274
- maxRetries?: number | undefined;
275
- delaySeconds?: number | undefined;
276
- } | undefined;
277
- }>;
278
- export declare const createQueueSchema: (inputSchema?: ZodInput) => z.ZodEffects<z.ZodObject<{
279
- type: z.ZodEnum<["standard", "fifo"]>;
280
- visibilityTimeout: z.ZodNumber;
281
- messageGroupId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
282
- maxRetries: z.ZodNumber;
283
- delaySeconds: z.ZodOptional<z.ZodNumber>;
284
- }, "strip", z.ZodTypeAny, {
285
- type: "standard" | "fifo";
286
- visibilityTimeout: number;
287
- maxRetries: number;
288
- messageGroupId?: string | null | undefined;
289
- delaySeconds?: number | undefined;
290
- }, {
291
- type: "standard" | "fifo";
292
- visibilityTimeout: number;
293
- maxRetries: number;
294
- messageGroupId?: string | null | undefined;
295
- delaySeconds?: number | undefined;
296
- }>, {
297
- type: "standard" | "fifo";
298
- visibilityTimeout: number;
299
- maxRetries: number;
300
- messageGroupId?: string | null | undefined;
301
- delaySeconds?: number | undefined;
302
- }, {
303
- type: "standard" | "fifo";
304
- visibilityTimeout: number;
305
- maxRetries: number;
306
- messageGroupId?: string | null | undefined;
307
- delaySeconds?: number | undefined;
308
- }>;
@@ -1,177 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createQueueSchema = exports.createInfrastructureSchema = exports.infrastructureSchema = exports.queueSchema = exports.handlerSchema = exports.handlerBaseSchema = exports.AWS_LAMBDA_CPU_RATIO = exports.AWS_LAMBDA_LIMITS = void 0;
4
- exports.getProportionalCpu = getProportionalCpu;
5
- const zod_1 = require("zod");
6
- exports.AWS_LAMBDA_LIMITS = {
7
- MIN_RAM_MB: 128,
8
- MAX_RAM_MB: 10240,
9
- MIN_TIMEOUT_SECONDS: 1,
10
- MAX_TIMEOUT_SECONDS: 900,
11
- };
12
- exports.AWS_LAMBDA_CPU_RATIO = {
13
- 128: 0.0625,
14
- 256: 0.125,
15
- 512: 0.25,
16
- 1024: 0.5,
17
- 1536: 0.75,
18
- 2048: 1,
19
- 3008: 1.5,
20
- 4096: 2,
21
- 5120: 2.5,
22
- 6144: 3,
23
- 7168: 3.5,
24
- 8192: 4,
25
- 9216: 4.5,
26
- 10240: 5,
27
- };
28
- function getProportionalCpu(ramMb) {
29
- const ramValues = Object.keys(exports.AWS_LAMBDA_CPU_RATIO)
30
- .map(Number)
31
- .sort((a, b) => a - b);
32
- const exact = exports.AWS_LAMBDA_CPU_RATIO[ramMb];
33
- if (exact !== undefined) {
34
- return exact;
35
- }
36
- for (let i = 0; i < ramValues.length - 1; i++) {
37
- const lower = ramValues[i];
38
- const upper = ramValues[i + 1];
39
- if (ramMb > lower && ramMb < upper) {
40
- const lowerCpu = exports.AWS_LAMBDA_CPU_RATIO[lower];
41
- const upperCpu = exports.AWS_LAMBDA_CPU_RATIO[upper];
42
- const ratio = (ramMb - lower) / (upper - lower);
43
- return lowerCpu + (upperCpu - lowerCpu) * ratio;
44
- }
45
- }
46
- return ramMb <= ramValues[0]
47
- ? exports.AWS_LAMBDA_CPU_RATIO[ramValues[0]]
48
- : exports.AWS_LAMBDA_CPU_RATIO[ramValues[ramValues.length - 1]];
49
- }
50
- exports.handlerBaseSchema = zod_1.z.object({
51
- ram: zod_1.z
52
- .number()
53
- .min(exports.AWS_LAMBDA_LIMITS.MIN_RAM_MB, `RAM must be at least ${exports.AWS_LAMBDA_LIMITS.MIN_RAM_MB} MB`)
54
- .max(exports.AWS_LAMBDA_LIMITS.MAX_RAM_MB, `RAM cannot exceed ${exports.AWS_LAMBDA_LIMITS.MAX_RAM_MB} MB`),
55
- timeout: zod_1.z
56
- .number()
57
- .min(exports.AWS_LAMBDA_LIMITS.MIN_TIMEOUT_SECONDS, `Timeout must be at least ${exports.AWS_LAMBDA_LIMITS.MIN_TIMEOUT_SECONDS}s`)
58
- .max(exports.AWS_LAMBDA_LIMITS.MAX_TIMEOUT_SECONDS, `Timeout cannot exceed ${exports.AWS_LAMBDA_LIMITS.MAX_TIMEOUT_SECONDS}s`),
59
- cpu: zod_1.z.number().optional(),
60
- });
61
- exports.handlerSchema = exports.handlerBaseSchema.partial().superRefine((handler, ctx) => {
62
- if (handler.cpu === undefined || handler.ram === undefined) {
63
- return;
64
- }
65
- const expectedCpu = getProportionalCpu(handler.ram);
66
- const tolerance = 0.1;
67
- if (Math.abs(handler.cpu - expectedCpu) > tolerance) {
68
- ctx.addIssue({
69
- code: zod_1.z.ZodIssueCode.custom,
70
- path: ['handler', 'cpu'],
71
- message: `CPU (${handler.cpu} vCPU) is not proportional to RAM (${handler.ram} MB). Expected approximately ${expectedCpu.toFixed(2)} vCPU`,
72
- });
73
- }
74
- });
75
- exports.queueSchema = zod_1.z.object({
76
- type: zod_1.z.enum(['standard', 'fifo']),
77
- visibilityTimeout: zod_1.z.number(),
78
- messageGroupId: zod_1.z.string().nullable().optional(),
79
- maxRetries: zod_1.z.number().min(0, 'maxRetries cannot be negative'),
80
- delaySeconds: zod_1.z
81
- .number()
82
- .min(0, 'delaySeconds cannot be negative')
83
- .max(900, 'delaySeconds cannot exceed 900 seconds (15 minutes)')
84
- .optional(),
85
- });
86
- exports.infrastructureSchema = zod_1.z
87
- .object({
88
- handler: exports.handlerSchema.optional(),
89
- queue: exports.queueSchema.partial().optional(),
90
- })
91
- .superRefine((config, ctx) => {
92
- if (config.queue?.visibilityTimeout !== undefined && config.handler?.timeout !== undefined) {
93
- if (config.queue.visibilityTimeout <= config.handler.timeout) {
94
- ctx.addIssue({
95
- code: zod_1.z.ZodIssueCode.custom,
96
- path: ['queue', 'visibilityTimeout'],
97
- message: `Visibility timeout (${config.queue.visibilityTimeout}s) must be greater than handler timeout (${config.handler.timeout}s) to prevent premature message redelivery`,
98
- });
99
- }
100
- }
101
- if (config.queue?.type === 'fifo' && !config.queue?.messageGroupId) {
102
- ctx.addIssue({
103
- code: zod_1.z.ZodIssueCode.custom,
104
- path: ['queue', 'messageGroupId'],
105
- message: 'messageGroupId is required when queue type is "fifo"',
106
- });
107
- }
108
- });
109
- function validateMessageGroupId(messageGroupId, inputSchema, ctx, pathPrefix = ['queue', 'messageGroupId']) {
110
- if (!messageGroupId || messageGroupId === 'traceId') {
111
- return;
112
- }
113
- if (!inputSchema) {
114
- ctx.addIssue({
115
- code: zod_1.z.ZodIssueCode.custom,
116
- path: pathPrefix,
117
- message: `Cannot validate messageGroupId "${messageGroupId}" - step has no input schema defined`,
118
- });
119
- return;
120
- }
121
- if (messageGroupId.includes('.') || messageGroupId.includes('[')) {
122
- ctx.addIssue({
123
- code: zod_1.z.ZodIssueCode.custom,
124
- path: pathPrefix,
125
- message: `messageGroupId "${messageGroupId}" must be a simple field path. Nested paths and template expressions are not supported`,
126
- });
127
- return;
128
- }
129
- try {
130
- if (inputSchema instanceof zod_1.z.ZodObject) {
131
- const shape = inputSchema.shape;
132
- if (!shape || !(messageGroupId in shape)) {
133
- ctx.addIssue({
134
- code: zod_1.z.ZodIssueCode.custom,
135
- path: pathPrefix,
136
- message: `messageGroupId "${messageGroupId}" does not exist in step's input schema`,
137
- });
138
- }
139
- }
140
- else if (typeof inputSchema === 'object' && inputSchema !== null && 'properties' in inputSchema) {
141
- const properties = inputSchema.properties;
142
- if (!properties || typeof properties !== 'object' || !(messageGroupId in properties)) {
143
- ctx.addIssue({
144
- code: zod_1.z.ZodIssueCode.custom,
145
- path: pathPrefix,
146
- message: `messageGroupId "${messageGroupId}" does not exist in step's input schema`,
147
- });
148
- }
149
- }
150
- else {
151
- ctx.addIssue({
152
- code: zod_1.z.ZodIssueCode.custom,
153
- path: pathPrefix,
154
- message: `Failed to validate messageGroupId "${messageGroupId}" against input schema: inputSchema is not a valid schema object`,
155
- });
156
- }
157
- }
158
- catch (error) {
159
- ctx.addIssue({
160
- code: zod_1.z.ZodIssueCode.custom,
161
- path: pathPrefix,
162
- message: `Failed to validate messageGroupId "${messageGroupId}" against input schema: ${error instanceof Error ? error.message : 'Unknown error'}`,
163
- });
164
- }
165
- }
166
- const createInfrastructureSchema = (inputSchema) => {
167
- return exports.infrastructureSchema.superRefine((config, ctx) => {
168
- validateMessageGroupId(config.queue?.messageGroupId, inputSchema, ctx, ['queue', 'messageGroupId']);
169
- });
170
- };
171
- exports.createInfrastructureSchema = createInfrastructureSchema;
172
- const createQueueSchema = (inputSchema) => {
173
- return exports.queueSchema.superRefine((config, ctx) => {
174
- validateMessageGroupId(config.messageGroupId, inputSchema, ctx, ['messageGroupId']);
175
- });
176
- };
177
- exports.createQueueSchema = createQueueSchema;
@@ -1,20 +0,0 @@
1
- export type InfrastructureValidationError = {
2
- path: string;
3
- message: string;
4
- };
5
- export type InfrastructureValidationResult = {
6
- success: true;
7
- } | {
8
- success: false;
9
- errors?: InfrastructureValidationError[];
10
- };
11
- export type QueueValidationError = {
12
- path: string;
13
- message: string;
14
- };
15
- export type QueueValidationResult = {
16
- success: true;
17
- } | {
18
- success: false;
19
- errors?: QueueValidationError[];
20
- };
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,4 +0,0 @@
1
- import { InfrastructureValidationResult, QueueValidationResult } from './types';
2
- import { ZodInput } from '../types';
3
- export declare const validateQueueConfig: (queueConfig: unknown) => QueueValidationResult;
4
- export declare const validateInfrastructureConfig: (infrastructureConfig: unknown, inputSchema?: ZodInput) => InfrastructureValidationResult;
@@ -1,60 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateInfrastructureConfig = exports.validateQueueConfig = void 0;
4
- const zod_1 = require("zod");
5
- const schemas_1 = require("./schemas");
6
- const validateQueueConfig = (queueConfig) => {
7
- try {
8
- const schema = (0, schemas_1.createQueueSchema)();
9
- schema.parse(queueConfig);
10
- return { success: true };
11
- }
12
- catch (error) {
13
- if (error instanceof zod_1.z.ZodError) {
14
- const errors = error.errors.map((err) => ({
15
- path: err.path.length > 0 ? err.path.join('.') : 'queue',
16
- message: err.message,
17
- }));
18
- return {
19
- success: false,
20
- errors,
21
- };
22
- }
23
- return {
24
- success: false,
25
- errors: [
26
- { path: 'queue', message: `Unexpected validation error: ${error instanceof Error ? error.message : 'Unknown error'}` },
27
- ],
28
- };
29
- }
30
- };
31
- exports.validateQueueConfig = validateQueueConfig;
32
- const validateInfrastructureConfig = (infrastructureConfig, inputSchema) => {
33
- try {
34
- const schema = (0, schemas_1.createInfrastructureSchema)(inputSchema);
35
- schema.parse(infrastructureConfig);
36
- return { success: true };
37
- }
38
- catch (error) {
39
- if (error instanceof zod_1.z.ZodError) {
40
- const errors = error.errors.map((err) => ({
41
- path: err.path.length > 0 ? err.path.join('.') : 'infrastructure',
42
- message: err.message,
43
- }));
44
- return {
45
- success: false,
46
- errors,
47
- };
48
- }
49
- return {
50
- success: false,
51
- errors: [
52
- {
53
- path: 'infrastructure',
54
- message: `Unexpected validation error: ${error instanceof Error ? error.message : 'Unknown error'}`,
55
- },
56
- ],
57
- };
58
- }
59
- };
60
- exports.validateInfrastructureConfig = validateInfrastructureConfig;
@@ -1,17 +0,0 @@
1
- import { Event, QueueConfig, Handler } from './types';
2
- declare class QueueManager {
3
- private queues;
4
- private subscriptions;
5
- private lockedGroups;
6
- private processingTimers;
7
- private processQueue;
8
- private processMessage;
9
- private removeMessageFromQueue;
10
- private startQueueProcessor;
11
- enqueue<TData>(topic: string, event: Event<TData>): Promise<void>;
12
- subscribe(topic: string, handler: Handler, queueConfig: QueueConfig, subscriptionId: string): void;
13
- unsubscribe(topic: string, handler: Handler): void;
14
- reset(): void;
15
- }
16
- export declare const queueManager: QueueManager;
17
- export {};
@@ -1,176 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.queueManager = void 0;
4
- const crypto_1 = require("crypto");
5
- const logger_1 = require("./logger");
6
- function extractMessageGroupId(event, messageGroupId) {
7
- if (!messageGroupId) {
8
- return undefined;
9
- }
10
- if (messageGroupId === 'traceId') {
11
- return event.traceId;
12
- }
13
- try {
14
- const data = event.data;
15
- const value = data[messageGroupId];
16
- return value !== undefined && value !== null ? String(value) : undefined;
17
- }
18
- catch {
19
- return undefined;
20
- }
21
- }
22
- class QueueManager {
23
- constructor() {
24
- this.queues = {};
25
- this.subscriptions = {};
26
- this.lockedGroups = new Set();
27
- this.processingTimers = {};
28
- }
29
- processQueue(topic) {
30
- const queue = this.queues[topic];
31
- if (!queue || queue.length === 0) {
32
- return;
33
- }
34
- const now = Date.now();
35
- const visibleMessages = queue.filter((msg) => msg.visibleAt <= now);
36
- for (const message of visibleMessages) {
37
- if (message.queueConfig.type === 'fifo' && message.messageGroupId) {
38
- const lockKey = `${topic}:${message.messageGroupId}`;
39
- if (this.lockedGroups.has(lockKey)) {
40
- continue;
41
- }
42
- this.lockedGroups.add(lockKey);
43
- this.processMessage(topic, message, lockKey);
44
- }
45
- else {
46
- this.processMessage(topic, message);
47
- }
48
- }
49
- }
50
- processMessage(topic, message, lockKey) {
51
- const handlers = this.subscriptions[topic] || [];
52
- const handler = handlers.find((s) => s.internalSubscriptionId === message.internalSubscriptionId) ||
53
- handlers.find((s) => s.subscriptionId === message.subscriptionId) ||
54
- handlers[0];
55
- if (!handler) {
56
- this.removeMessageFromQueue(topic, message.id);
57
- if (lockKey) {
58
- this.lockedGroups.delete(lockKey);
59
- }
60
- return;
61
- }
62
- const visibilityTimeoutMs = handler.queueConfig.visibilityTimeout * 1000;
63
- message.visibleAt = Date.now() + visibilityTimeoutMs;
64
- handler.handler(message.event)
65
- .then(() => {
66
- this.removeMessageFromQueue(topic, message.id);
67
- if (lockKey) {
68
- this.lockedGroups.delete(lockKey);
69
- }
70
- })
71
- .catch((error) => {
72
- message.attempts++;
73
- if (message.attempts >= handler.queueConfig.maxRetries) {
74
- logger_1.globalLogger.error('[Queue DLQ] Message moved to dead-letter queue after max retries', {
75
- topic,
76
- messageId: message.id,
77
- attempts: message.attempts,
78
- error: error instanceof Error ? error.message : 'Unknown error',
79
- });
80
- this.removeMessageFromQueue(topic, message.id);
81
- if (lockKey) {
82
- this.lockedGroups.delete(lockKey);
83
- }
84
- }
85
- else {
86
- message.visibleAt = Date.now() + handler.queueConfig.visibilityTimeout * 1000;
87
- if (lockKey) {
88
- this.lockedGroups.delete(lockKey);
89
- }
90
- }
91
- });
92
- }
93
- removeMessageFromQueue(topic, messageId) {
94
- const queue = this.queues[topic];
95
- if (!queue) {
96
- return;
97
- }
98
- const index = queue.findIndex((msg) => msg.id === messageId);
99
- if (index !== -1) {
100
- queue.splice(index, 1);
101
- }
102
- if (queue.length === 0) {
103
- delete this.queues[topic];
104
- if (this.processingTimers[topic]) {
105
- clearInterval(this.processingTimers[topic]);
106
- delete this.processingTimers[topic];
107
- }
108
- }
109
- }
110
- startQueueProcessor(topic) {
111
- if (this.processingTimers[topic]) {
112
- return;
113
- }
114
- this.processingTimers[topic] = setInterval(() => {
115
- this.processQueue(topic);
116
- }, 100);
117
- }
118
- async enqueue(topic, event) {
119
- const handlers = this.subscriptions[topic] || [];
120
- if (handlers.length === 0) {
121
- return;
122
- }
123
- for (const subscription of handlers) {
124
- const messageGroupId = extractMessageGroupId(event, subscription.queueConfig.messageGroupId);
125
- const delayMs = subscription.queueConfig.delaySeconds * 1000;
126
- const visibleAt = Date.now() + delayMs;
127
- const queuedMessage = {
128
- id: (0, crypto_1.randomUUID)(),
129
- event,
130
- attempts: 0,
131
- visibleAt,
132
- messageGroupId,
133
- queueConfig: subscription.queueConfig,
134
- subscriptionId: subscription.subscriptionId,
135
- internalSubscriptionId: subscription.internalSubscriptionId,
136
- };
137
- if (!this.queues[topic]) {
138
- this.queues[topic] = [];
139
- }
140
- this.queues[topic].push(queuedMessage);
141
- this.startQueueProcessor(topic);
142
- }
143
- setImmediate(() => this.processQueue(topic));
144
- }
145
- subscribe(topic, handler, queueConfig, subscriptionId) {
146
- if (!this.subscriptions[topic]) {
147
- this.subscriptions[topic] = [];
148
- }
149
- const internalSubscriptionId = (0, crypto_1.randomUUID)();
150
- this.subscriptions[topic].push({ handler, queueConfig, subscriptionId, internalSubscriptionId });
151
- if (this.queues[topic] && this.queues[topic].length > 0) {
152
- this.startQueueProcessor(topic);
153
- }
154
- }
155
- unsubscribe(topic, handler) {
156
- if (!this.subscriptions[topic]) {
157
- return;
158
- }
159
- this.subscriptions[topic] = this.subscriptions[topic].filter((sub) => sub.handler !== handler);
160
- if (this.subscriptions[topic].length === 0) {
161
- delete this.subscriptions[topic];
162
- if (this.processingTimers[topic]) {
163
- clearInterval(this.processingTimers[topic]);
164
- delete this.processingTimers[topic];
165
- }
166
- }
167
- }
168
- reset() {
169
- Object.values(this.processingTimers).forEach((timer) => clearInterval(timer));
170
- this.queues = {};
171
- this.subscriptions = {};
172
- this.lockedGroups = new Set();
173
- this.processingTimers = {};
174
- }
175
- }
176
- exports.queueManager = new QueueManager();