@crossdelta/cloudevents 0.5.6 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -28
- package/dist/index.cjs +1602 -0
- package/dist/index.d.mts +812 -0
- package/dist/index.d.ts +812 -9
- package/dist/index.js +1574 -6
- package/package.json +20 -18
- package/dist/adapters/cloudevents/cloudevents.d.ts +0 -14
- package/dist/adapters/cloudevents/cloudevents.js +0 -58
- package/dist/adapters/cloudevents/index.d.ts +0 -8
- package/dist/adapters/cloudevents/index.js +0 -7
- package/dist/adapters/cloudevents/parsers/binary-mode.d.ts +0 -5
- package/dist/adapters/cloudevents/parsers/binary-mode.js +0 -32
- package/dist/adapters/cloudevents/parsers/pubsub.d.ts +0 -5
- package/dist/adapters/cloudevents/parsers/pubsub.js +0 -54
- package/dist/adapters/cloudevents/parsers/raw-event.d.ts +0 -5
- package/dist/adapters/cloudevents/parsers/raw-event.js +0 -17
- package/dist/adapters/cloudevents/parsers/structured-mode.d.ts +0 -5
- package/dist/adapters/cloudevents/parsers/structured-mode.js +0 -18
- package/dist/adapters/cloudevents/types.d.ts +0 -29
- package/dist/adapters/cloudevents/types.js +0 -1
- package/dist/domain/contract-helper.d.ts +0 -63
- package/dist/domain/contract-helper.js +0 -61
- package/dist/domain/discovery.d.ts +0 -24
- package/dist/domain/discovery.js +0 -201
- package/dist/domain/handler-factory.d.ts +0 -49
- package/dist/domain/handler-factory.js +0 -169
- package/dist/domain/index.d.ts +0 -6
- package/dist/domain/index.js +0 -4
- package/dist/domain/types.d.ts +0 -108
- package/dist/domain/types.js +0 -6
- package/dist/domain/validation.d.ts +0 -37
- package/dist/domain/validation.js +0 -53
- package/dist/infrastructure/errors.d.ts +0 -53
- package/dist/infrastructure/errors.js +0 -54
- package/dist/infrastructure/index.d.ts +0 -4
- package/dist/infrastructure/index.js +0 -2
- package/dist/infrastructure/logging.d.ts +0 -18
- package/dist/infrastructure/logging.js +0 -27
- package/dist/middlewares/cloudevents-middleware.d.ts +0 -171
- package/dist/middlewares/cloudevents-middleware.js +0 -276
- package/dist/middlewares/index.d.ts +0 -1
- package/dist/middlewares/index.js +0 -1
- package/dist/processing/dlq-safe.d.ts +0 -82
- package/dist/processing/dlq-safe.js +0 -108
- package/dist/processing/handler-cache.d.ts +0 -36
- package/dist/processing/handler-cache.js +0 -94
- package/dist/processing/idempotency.d.ts +0 -51
- package/dist/processing/idempotency.js +0 -112
- package/dist/processing/index.d.ts +0 -4
- package/dist/processing/index.js +0 -4
- package/dist/processing/validation.d.ts +0 -41
- package/dist/processing/validation.js +0 -48
- package/dist/publishing/index.d.ts +0 -2
- package/dist/publishing/index.js +0 -2
- package/dist/publishing/nats.publisher.d.ts +0 -19
- package/dist/publishing/nats.publisher.js +0 -115
- package/dist/publishing/pubsub.publisher.d.ts +0 -39
- package/dist/publishing/pubsub.publisher.js +0 -84
- package/dist/transports/nats/base-message-processor.d.ts +0 -44
- package/dist/transports/nats/base-message-processor.js +0 -118
- package/dist/transports/nats/index.d.ts +0 -5
- package/dist/transports/nats/index.js +0 -5
- package/dist/transports/nats/jetstream-consumer.d.ts +0 -217
- package/dist/transports/nats/jetstream-consumer.js +0 -367
- package/dist/transports/nats/jetstream-message-processor.d.ts +0 -9
- package/dist/transports/nats/jetstream-message-processor.js +0 -32
- package/dist/transports/nats/nats-consumer.d.ts +0 -36
- package/dist/transports/nats/nats-consumer.js +0 -84
- package/dist/transports/nats/nats-message-processor.d.ts +0 -11
- package/dist/transports/nats/nats-message-processor.js +0 -32
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { ZodTypeAny } from 'zod';
|
|
2
|
-
export interface PublishEventOptions {
|
|
3
|
-
projectId?: string;
|
|
4
|
-
keyFilename?: string;
|
|
5
|
-
source?: string;
|
|
6
|
-
subject?: string;
|
|
7
|
-
attributes?: Record<string, string>;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Publishes an event using a Zod schema for validation and type extraction.
|
|
11
|
-
* Automatically extracts the event type from the schema and creates a CloudEvent.
|
|
12
|
-
*
|
|
13
|
-
* @param topicName - PubSub topic name
|
|
14
|
-
* @param schema - Zod schema that defines the event structure and type
|
|
15
|
-
* @param eventData - Event data that must match the schema
|
|
16
|
-
* @param options - Optional PubSub configuration
|
|
17
|
-
* @returns Promise resolving to the published message ID
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* await publishEvent(
|
|
22
|
-
* 'customer-events',
|
|
23
|
-
* CustomerCreatedSchema,
|
|
24
|
-
* { customer: { id: '123', email: 'test@example.com' } }
|
|
25
|
-
* )
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
export declare function publishEvent<T extends ZodTypeAny>(topicName: string, schema: T, eventData: unknown, options?: PublishEventOptions): Promise<string>;
|
|
29
|
-
/**
|
|
30
|
-
* Raw event publisher - bypasses schema validation.
|
|
31
|
-
* Use this when you need direct control over the event type and data.
|
|
32
|
-
*
|
|
33
|
-
* @param topicName - PubSub topic name
|
|
34
|
-
* @param eventType - Manual event type identifier
|
|
35
|
-
* @param eventData - Raw event data
|
|
36
|
-
* @param options - Optional PubSub configuration
|
|
37
|
-
* @returns Promise resolving to the published message ID
|
|
38
|
-
*/
|
|
39
|
-
export declare function publishRawEvent(topicName: string, eventType: string, eventData: unknown, options?: PublishEventOptions): Promise<string>;
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { extractTypeFromSchema } from '../domain';
|
|
2
|
-
import { createValidationError, logger } from '../infrastructure';
|
|
3
|
-
/**
|
|
4
|
-
* Publishes an event using a Zod schema for validation and type extraction.
|
|
5
|
-
* Automatically extracts the event type from the schema and creates a CloudEvent.
|
|
6
|
-
*
|
|
7
|
-
* @param topicName - PubSub topic name
|
|
8
|
-
* @param schema - Zod schema that defines the event structure and type
|
|
9
|
-
* @param eventData - Event data that must match the schema
|
|
10
|
-
* @param options - Optional PubSub configuration
|
|
11
|
-
* @returns Promise resolving to the published message ID
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```typescript
|
|
15
|
-
* await publishEvent(
|
|
16
|
-
* 'customer-events',
|
|
17
|
-
* CustomerCreatedSchema,
|
|
18
|
-
* { customer: { id: '123', email: 'test@example.com' } }
|
|
19
|
-
* )
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export async function publishEvent(topicName, schema, eventData, options) {
|
|
23
|
-
// Extract event type from schema
|
|
24
|
-
const eventType = extractTypeFromSchema(schema);
|
|
25
|
-
if (!eventType) {
|
|
26
|
-
throw new Error('Could not extract event type from schema. Make sure your schema has proper metadata.');
|
|
27
|
-
}
|
|
28
|
-
// Validate the data against the schema
|
|
29
|
-
const validationResult = schema.safeParse(eventData);
|
|
30
|
-
if (!validationResult.success) {
|
|
31
|
-
const validationDetails = validationResult.error.issues.map((issue) => ({
|
|
32
|
-
code: issue.code,
|
|
33
|
-
message: issue.message,
|
|
34
|
-
path: issue.path.filter((p) => typeof p !== 'symbol'),
|
|
35
|
-
expected: 'expected' in issue ? String(issue.expected) : undefined,
|
|
36
|
-
received: 'received' in issue ? String(issue.received) : undefined,
|
|
37
|
-
}));
|
|
38
|
-
const handlerValidationError = {
|
|
39
|
-
handlerName: `Publisher:${eventType}`,
|
|
40
|
-
validationErrors: validationDetails,
|
|
41
|
-
};
|
|
42
|
-
throw createValidationError(eventType, [handlerValidationError]);
|
|
43
|
-
}
|
|
44
|
-
return publishRawEvent(topicName, eventType, validationResult.data, options);
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Raw event publisher - bypasses schema validation.
|
|
48
|
-
* Use this when you need direct control over the event type and data.
|
|
49
|
-
*
|
|
50
|
-
* @param topicName - PubSub topic name
|
|
51
|
-
* @param eventType - Manual event type identifier
|
|
52
|
-
* @param eventData - Raw event data
|
|
53
|
-
* @param options - Optional PubSub configuration
|
|
54
|
-
* @returns Promise resolving to the published message ID
|
|
55
|
-
*/
|
|
56
|
-
export async function publishRawEvent(topicName, eventType, eventData, options) {
|
|
57
|
-
const { PubSub } = await import('@google-cloud/pubsub');
|
|
58
|
-
const pubsub = new PubSub({
|
|
59
|
-
projectId: options?.projectId,
|
|
60
|
-
keyFilename: options?.keyFilename,
|
|
61
|
-
});
|
|
62
|
-
const cloudEvent = {
|
|
63
|
-
specversion: '1.0',
|
|
64
|
-
type: eventType,
|
|
65
|
-
source: options?.source || 'hono-service',
|
|
66
|
-
id: crypto.randomUUID(),
|
|
67
|
-
time: new Date().toISOString(),
|
|
68
|
-
datacontenttype: 'application/json',
|
|
69
|
-
data: eventData,
|
|
70
|
-
...(options?.subject && { subject: options.subject }),
|
|
71
|
-
};
|
|
72
|
-
const data = JSON.stringify(cloudEvent);
|
|
73
|
-
const dataBuffer = Buffer.from(data);
|
|
74
|
-
const topic = pubsub.topic(topicName);
|
|
75
|
-
const messageId = await topic.publishMessage({
|
|
76
|
-
data: dataBuffer,
|
|
77
|
-
attributes: {
|
|
78
|
-
'content-type': 'application/cloudevents+json',
|
|
79
|
-
...options?.attributes,
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
|
-
logger.debug(`Published CloudEvent ${eventType} with ID: ${messageId}`);
|
|
83
|
-
return messageId;
|
|
84
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared message processing logic for NATS Core and JetStream consumers.
|
|
3
|
-
* Abstracts CloudEvent parsing, handler matching, validation, and execution.
|
|
4
|
-
*/
|
|
5
|
-
import type { CloudEventV1 } from 'cloudevents';
|
|
6
|
-
import type { EnrichedEvent } from '../../domain';
|
|
7
|
-
import { createProcessingContext, type DlqOptions } from '../../processing/dlq-safe';
|
|
8
|
-
import type { ProcessedHandler } from '../../processing/handler-cache';
|
|
9
|
-
export interface LoggerLike {
|
|
10
|
-
info(message: string, meta?: unknown): void;
|
|
11
|
-
warn(message: string, meta?: unknown): void;
|
|
12
|
-
error(message: string, meta?: unknown): void;
|
|
13
|
-
}
|
|
14
|
-
export interface BaseMessageProcessorDeps {
|
|
15
|
-
name: string;
|
|
16
|
-
dlqEnabled: boolean;
|
|
17
|
-
options: DlqOptions;
|
|
18
|
-
processedHandlers: ProcessedHandler[];
|
|
19
|
-
decode: (data: Uint8Array) => string;
|
|
20
|
-
logger: LoggerLike;
|
|
21
|
-
}
|
|
22
|
-
export type ProcessingContext = ReturnType<typeof createProcessingContext>;
|
|
23
|
-
export type ParseResult<T> = {
|
|
24
|
-
ok: true;
|
|
25
|
-
cloudEvent: CloudEventV1<unknown>;
|
|
26
|
-
enriched: EnrichedEvent<unknown>;
|
|
27
|
-
} | {
|
|
28
|
-
ok: false;
|
|
29
|
-
error: unknown;
|
|
30
|
-
context: ProcessingContext;
|
|
31
|
-
rawMessage: T;
|
|
32
|
-
};
|
|
33
|
-
/**
|
|
34
|
-
* Creates shared message processing utilities
|
|
35
|
-
*/
|
|
36
|
-
export declare function createBaseMessageProcessor(deps: BaseMessageProcessorDeps): {
|
|
37
|
-
toEnrichedEvent: (ce: CloudEventV1<unknown>) => EnrichedEvent<unknown>;
|
|
38
|
-
createContext: (event: EnrichedEvent<unknown>, ce?: CloudEventV1<unknown>) => import("../../processing").ProcessingContext;
|
|
39
|
-
parseCloudEvent: (data: Uint8Array) => CloudEventV1<unknown>;
|
|
40
|
-
findHandler: (event: EnrichedEvent<unknown>) => ProcessedHandler | undefined;
|
|
41
|
-
processEvent: (cloudEvent: CloudEventV1<unknown>, enriched: EnrichedEvent<unknown>) => Promise<boolean>;
|
|
42
|
-
handleParseError: (error: unknown, context: ProcessingContext, redeliveryCount?: number) => Promise<boolean>;
|
|
43
|
-
handleUnhandledError: (error: unknown, context: ProcessingContext, ackFn?: () => void) => Promise<void>;
|
|
44
|
-
};
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared message processing logic for NATS Core and JetStream consumers.
|
|
3
|
-
* Abstracts CloudEvent parsing, handler matching, validation, and execution.
|
|
4
|
-
*/
|
|
5
|
-
import { createProcessingContext, publishRecoverableError, quarantineMessage, } from '../../processing/dlq-safe';
|
|
6
|
-
import { throwValidationError, validateEventData } from '../../processing/validation';
|
|
7
|
-
/**
|
|
8
|
-
* Extracts tenantId from CloudEvent extensions
|
|
9
|
-
* Supports both 'tenantid' (CloudEvents spec lowercase) and 'tenantId' variants
|
|
10
|
-
*/
|
|
11
|
-
function extractTenantId(ce) {
|
|
12
|
-
const extensions = ce;
|
|
13
|
-
return (extensions.tenantid ?? extensions.tenantId ?? extensions.tenant_id);
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Creates shared message processing utilities
|
|
17
|
-
*/
|
|
18
|
-
export function createBaseMessageProcessor(deps) {
|
|
19
|
-
const { name, dlqEnabled, options, processedHandlers, decode, logger } = deps;
|
|
20
|
-
const toEnrichedEvent = (ce) => ({
|
|
21
|
-
eventType: ce.type,
|
|
22
|
-
source: ce.source,
|
|
23
|
-
subject: ce.subject,
|
|
24
|
-
time: ce.time ?? new Date().toISOString(),
|
|
25
|
-
messageId: ce.id,
|
|
26
|
-
data: ce.data,
|
|
27
|
-
tenantId: extractTenantId(ce),
|
|
28
|
-
});
|
|
29
|
-
const createContext = (event, ce) => createProcessingContext(event.eventType, event.data, event, ce);
|
|
30
|
-
const parseCloudEvent = (data) => {
|
|
31
|
-
return JSON.parse(decode(data));
|
|
32
|
-
};
|
|
33
|
-
const findHandler = (event) => processedHandlers.find((handler) => handler.type === event.eventType && (!handler.match || handler.match(event)));
|
|
34
|
-
const handleMissingHandler = async (context, eventType) => {
|
|
35
|
-
logger.warn(`[${name}] no handler for event type: ${eventType}`);
|
|
36
|
-
if (dlqEnabled) {
|
|
37
|
-
await quarantineMessage(context, 'no_handler', options, new Error(`No handler for event type ${eventType}`));
|
|
38
|
-
}
|
|
39
|
-
// Ack - no point in retrying if there's no handler
|
|
40
|
-
return { handled: true, shouldAck: true };
|
|
41
|
-
};
|
|
42
|
-
const handleValidationFailure = async (validationResult, handler, context) => {
|
|
43
|
-
// Log validation errors with full details for debugging
|
|
44
|
-
logger.error(`[${name}] validation failed for handler ${handler.name}`, JSON.stringify(validationResult.error, null, 2));
|
|
45
|
-
if (dlqEnabled) {
|
|
46
|
-
await quarantineMessage(context, 'validation_error', options, validationResult.error);
|
|
47
|
-
return { handled: true, shouldAck: true };
|
|
48
|
-
}
|
|
49
|
-
if (validationResult.shouldSkip) {
|
|
50
|
-
return { handled: true, shouldAck: true };
|
|
51
|
-
}
|
|
52
|
-
// Throw to trigger retry
|
|
53
|
-
throwValidationError(handler.name, validationResult.error);
|
|
54
|
-
return { handled: true, shouldAck: false }; // Never reached
|
|
55
|
-
};
|
|
56
|
-
const executeHandler = async (handler, enriched, context) => {
|
|
57
|
-
try {
|
|
58
|
-
await handler.handle(enriched.data, enriched);
|
|
59
|
-
return { success: true };
|
|
60
|
-
}
|
|
61
|
-
catch (error) {
|
|
62
|
-
if (dlqEnabled) {
|
|
63
|
-
await publishRecoverableError(context, error, options);
|
|
64
|
-
return { success: true }; // Ack after publishing to error topic
|
|
65
|
-
}
|
|
66
|
-
throw error; // Will trigger retry
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
/**
|
|
70
|
-
* Process a parsed CloudEvent message
|
|
71
|
-
* @returns true if message was handled successfully (should ack), false for retry (should nak)
|
|
72
|
-
*/
|
|
73
|
-
const processEvent = async (cloudEvent, enriched) => {
|
|
74
|
-
const context = createContext(enriched, cloudEvent);
|
|
75
|
-
const handler = findHandler(enriched);
|
|
76
|
-
if (!handler) {
|
|
77
|
-
const result = await handleMissingHandler(context, enriched.eventType);
|
|
78
|
-
return result.shouldAck;
|
|
79
|
-
}
|
|
80
|
-
const validationResult = validateEventData(handler, enriched.data);
|
|
81
|
-
if ('error' in validationResult) {
|
|
82
|
-
const result = await handleValidationFailure(validationResult, handler, context);
|
|
83
|
-
return result.shouldAck;
|
|
84
|
-
}
|
|
85
|
-
const result = await executeHandler(handler, enriched, context);
|
|
86
|
-
return result.success;
|
|
87
|
-
};
|
|
88
|
-
const handleParseError = async (error, context, redeliveryCount = 0) => {
|
|
89
|
-
logger.error(`[${name}] failed to parse CloudEvent (attempt ${redeliveryCount + 1})`, error);
|
|
90
|
-
if (dlqEnabled) {
|
|
91
|
-
await quarantineMessage(context, 'parse_error', options, error);
|
|
92
|
-
return true; // Ack after quarantine
|
|
93
|
-
}
|
|
94
|
-
// After max retries, ack to prevent infinite loop
|
|
95
|
-
return redeliveryCount >= 2;
|
|
96
|
-
};
|
|
97
|
-
const handleUnhandledError = async (error, context, ackFn) => {
|
|
98
|
-
logger.error(`[${name}] unhandled processing error`, error);
|
|
99
|
-
if (dlqEnabled) {
|
|
100
|
-
try {
|
|
101
|
-
await quarantineMessage(context, 'unhandled_error', options, error);
|
|
102
|
-
ackFn?.();
|
|
103
|
-
}
|
|
104
|
-
catch (quarantineError) {
|
|
105
|
-
logger.error(`[${name}] failed to quarantine unhandled error`, quarantineError);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
return {
|
|
110
|
-
toEnrichedEvent,
|
|
111
|
-
createContext,
|
|
112
|
-
parseCloudEvent,
|
|
113
|
-
findHandler,
|
|
114
|
-
processEvent,
|
|
115
|
-
handleParseError,
|
|
116
|
-
handleUnhandledError,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export * from './base-message-processor';
|
|
2
|
-
export * from './jetstream-consumer';
|
|
3
|
-
export { createJetStreamMessageProcessor, type JetStreamMessageProcessor, type JetStreamMessageProcessorDeps, } from './jetstream-message-processor';
|
|
4
|
-
export * from './nats-consumer';
|
|
5
|
-
export * from './nats-message-processor';
|
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
import { type ConsumerMessages } from 'nats';
|
|
2
|
-
import { type IdempotencyStore } from '../../domain';
|
|
3
|
-
import type { CloudEventsOptions } from '../../middlewares/cloudevents-middleware';
|
|
4
|
-
/**
|
|
5
|
-
* Stream configuration options
|
|
6
|
-
*/
|
|
7
|
-
export interface StreamConfig {
|
|
8
|
-
/** Maximum age of messages in the stream (ms). @default 7 days */
|
|
9
|
-
maxAge?: number;
|
|
10
|
-
/** Maximum size of the stream in bytes. @default 1GB */
|
|
11
|
-
maxBytes?: number;
|
|
12
|
-
/** Number of replicas. @default 1 */
|
|
13
|
-
replicas?: number;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Options for creating/ensuring a JetStream stream exists
|
|
17
|
-
*/
|
|
18
|
-
export interface JetStreamStreamOptions {
|
|
19
|
-
/** NATS server URL. Defaults to NATS_URL env or nats://localhost:4222 */
|
|
20
|
-
servers?: string;
|
|
21
|
-
/** NATS username for authentication (defaults to NATS_USER env var) */
|
|
22
|
-
user?: string;
|
|
23
|
-
/** NATS password for authentication (defaults to NATS_PASSWORD env var) */
|
|
24
|
-
pass?: string;
|
|
25
|
-
/** JetStream stream name */
|
|
26
|
-
stream: string;
|
|
27
|
-
/** Subjects to bind to the stream (e.g., ['orders.>', 'payments.>']) */
|
|
28
|
-
subjects: string[];
|
|
29
|
-
/** Stream configuration */
|
|
30
|
-
config?: StreamConfig;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Stream definition for batch operations
|
|
34
|
-
*/
|
|
35
|
-
export interface StreamDefinition {
|
|
36
|
-
/** JetStream stream name (e.g., 'ORDERS') */
|
|
37
|
-
stream: string;
|
|
38
|
-
/** Subjects to bind (e.g., ['orders.*']) */
|
|
39
|
-
subjects: string[];
|
|
40
|
-
/** Optional stream-specific config */
|
|
41
|
-
config?: StreamConfig;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Options for ensuring multiple JetStream streams exist
|
|
45
|
-
*/
|
|
46
|
-
export interface JetStreamStreamsOptions {
|
|
47
|
-
/** NATS server URL. Defaults to NATS_URL env or nats://localhost:4222 */
|
|
48
|
-
servers?: string;
|
|
49
|
-
/** NATS username for authentication (defaults to NATS_USER env var) */
|
|
50
|
-
user?: string;
|
|
51
|
-
/** NATS password for authentication (defaults to NATS_PASSWORD env var) */
|
|
52
|
-
pass?: string;
|
|
53
|
-
/** Array of stream definitions */
|
|
54
|
-
streams: StreamDefinition[];
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* JetStream consumer configuration
|
|
58
|
-
*/
|
|
59
|
-
export interface JetStreamConsumerOptions extends Pick<CloudEventsOptions, 'quarantineTopic' | 'errorTopic' | 'projectId' | 'source'> {
|
|
60
|
-
/** NATS server URL. Defaults to NATS_URL env or nats://localhost:4222 */
|
|
61
|
-
servers?: string;
|
|
62
|
-
/** NATS username for authentication (defaults to NATS_USER env var) */
|
|
63
|
-
user?: string;
|
|
64
|
-
/** NATS password for authentication (defaults to NATS_PASSWORD env var) */
|
|
65
|
-
pass?: string;
|
|
66
|
-
/** JetStream stream name (must already exist or use ensureJetStreamStream first) */
|
|
67
|
-
stream: string;
|
|
68
|
-
/** Durable consumer name. Required for persistence across restarts */
|
|
69
|
-
consumer: string;
|
|
70
|
-
/**
|
|
71
|
-
* Optional filter subjects for this consumer.
|
|
72
|
-
* If specified, consumer only receives messages matching these subjects.
|
|
73
|
-
* If omitted, consumer receives all messages from the stream.
|
|
74
|
-
* @example ['orders.created', 'orders.updated']
|
|
75
|
-
*/
|
|
76
|
-
filterSubjects?: string[];
|
|
77
|
-
/** Glob pattern to discover event handlers */
|
|
78
|
-
discover: string;
|
|
79
|
-
/**
|
|
80
|
-
* Where to start consuming from on first subscription.
|
|
81
|
-
* @default 'new' - Only new messages
|
|
82
|
-
* Options: 'all' | 'new' | 'last' | Date
|
|
83
|
-
*/
|
|
84
|
-
startFrom?: 'all' | 'new' | 'last' | Date;
|
|
85
|
-
/**
|
|
86
|
-
* Max number of messages to buffer for processing
|
|
87
|
-
* @default 100
|
|
88
|
-
*/
|
|
89
|
-
maxMessages?: number;
|
|
90
|
-
/**
|
|
91
|
-
* Ack wait timeout in milliseconds before message is redelivered
|
|
92
|
-
* @default 30000 (30 seconds)
|
|
93
|
-
*/
|
|
94
|
-
ackWait?: number;
|
|
95
|
-
/**
|
|
96
|
-
* Max redelivery attempts before message goes to DLQ
|
|
97
|
-
* @default 3
|
|
98
|
-
*/
|
|
99
|
-
maxDeliver?: number;
|
|
100
|
-
/**
|
|
101
|
-
* Idempotency store for deduplication. Defaults to in-memory store.
|
|
102
|
-
* Pass `false` to disable idempotency checks entirely.
|
|
103
|
-
*/
|
|
104
|
-
idempotencyStore?: IdempotencyStore | false;
|
|
105
|
-
/**
|
|
106
|
-
* TTL for idempotency records in milliseconds.
|
|
107
|
-
* @default 86400000 (24 hours)
|
|
108
|
-
*/
|
|
109
|
-
idempotencyTtl?: number;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Ensures a JetStream stream exists with the given configuration.
|
|
113
|
-
* This is typically called once during application startup or in infrastructure setup.
|
|
114
|
-
*
|
|
115
|
-
* @example
|
|
116
|
-
* ```typescript
|
|
117
|
-
* // In infrastructure/setup code:
|
|
118
|
-
* await ensureJetStreamStream({
|
|
119
|
-
* stream: 'ORDERS',
|
|
120
|
-
* subjects: ['orders.>'],
|
|
121
|
-
* config: {
|
|
122
|
-
* maxAge: 7 * 24 * 60 * 60 * 1000, // 7 days
|
|
123
|
-
* replicas: 3
|
|
124
|
-
* }
|
|
125
|
-
* })
|
|
126
|
-
* ```
|
|
127
|
-
*/
|
|
128
|
-
export declare function ensureJetStreamStream(options: JetStreamStreamOptions): Promise<void>;
|
|
129
|
-
/**
|
|
130
|
-
* Ensures multiple JetStream streams exist with a single NATS connection.
|
|
131
|
-
* More efficient than calling ensureJetStreamStream multiple times.
|
|
132
|
-
*
|
|
133
|
-
* @example
|
|
134
|
-
* ```typescript
|
|
135
|
-
* await ensureJetStreamStreams({
|
|
136
|
-
* streams: [
|
|
137
|
-
* { stream: 'ORDERS', subjects: ['orders.*'] },
|
|
138
|
-
* { stream: 'CUSTOMERS', subjects: ['customers.*'] },
|
|
139
|
-
* ]
|
|
140
|
-
* })
|
|
141
|
-
* ```
|
|
142
|
-
*/
|
|
143
|
-
export declare function ensureJetStreamStreams(options: JetStreamStreamsOptions): Promise<void>;
|
|
144
|
-
/**
|
|
145
|
-
* Consume CloudEvents from NATS JetStream with persistence and guaranteed delivery.
|
|
146
|
-
*
|
|
147
|
-
* Features:
|
|
148
|
-
* - Automatic stream and consumer creation
|
|
149
|
-
* - Durable subscriptions (survive restarts)
|
|
150
|
-
* - Automatic acknowledgments on successful processing
|
|
151
|
-
* - Configurable retry with max redelivery
|
|
152
|
-
* - Dead letter queue support
|
|
153
|
-
*
|
|
154
|
-
* @example
|
|
155
|
-
* ```typescript
|
|
156
|
-
* await consumeJetStreamEvents({
|
|
157
|
-
* stream: 'ORDERS',
|
|
158
|
-
* subjects: ['orders.>'],
|
|
159
|
-
* consumer: 'notifications',
|
|
160
|
-
* discover: `./src/events/**\/*.handler.ts`,
|
|
161
|
-
* })
|
|
162
|
-
* ```
|
|
163
|
-
*/
|
|
164
|
-
export declare function consumeJetStreamEvents(options: JetStreamConsumerOptions): Promise<ConsumerMessages>;
|
|
165
|
-
/**
|
|
166
|
-
* Options for consuming from multiple JetStream streams
|
|
167
|
-
*/
|
|
168
|
-
export interface JetStreamStreamsConsumerOptions extends Pick<CloudEventsOptions, 'quarantineTopic' | 'errorTopic' | 'projectId' | 'source'> {
|
|
169
|
-
/** NATS server URL. Defaults to NATS_URL env or nats://localhost:4222 */
|
|
170
|
-
servers?: string;
|
|
171
|
-
/** NATS username for authentication (defaults to NATS_USER env var) */
|
|
172
|
-
user?: string;
|
|
173
|
-
/** NATS password for authentication (defaults to NATS_PASSWORD env var) */
|
|
174
|
-
pass?: string;
|
|
175
|
-
/** Durable consumer name. Required for persistence across restarts */
|
|
176
|
-
consumer: string;
|
|
177
|
-
/** Array of stream names to consume from */
|
|
178
|
-
streams: string[];
|
|
179
|
-
/** Glob pattern to discover event handlers */
|
|
180
|
-
discover: string;
|
|
181
|
-
/** Where to start consuming from on first subscription. @default 'new' */
|
|
182
|
-
startFrom?: 'all' | 'new' | 'last' | Date;
|
|
183
|
-
/** Max number of messages to buffer for processing @default 100 */
|
|
184
|
-
maxMessages?: number;
|
|
185
|
-
/** Ack wait timeout in milliseconds @default 30000 */
|
|
186
|
-
ackWait?: number;
|
|
187
|
-
/** Max redelivery attempts @default 3 */
|
|
188
|
-
maxDeliver?: number;
|
|
189
|
-
/** Idempotency store for deduplication */
|
|
190
|
-
idempotencyStore?: IdempotencyStore | false;
|
|
191
|
-
/** TTL for idempotency records in milliseconds @default 86400000 */
|
|
192
|
-
idempotencyTtl?: number;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Consume CloudEvents from multiple JetStream streams with a single connection.
|
|
196
|
-
* More efficient than calling consumeJetStreamEvents multiple times.
|
|
197
|
-
*
|
|
198
|
-
* @example
|
|
199
|
-
* ```typescript
|
|
200
|
-
* await consumeJetStreamStreams({
|
|
201
|
-
* streams: ['ORDERS', 'CUSTOMERS'],
|
|
202
|
-
* consumer: 'notifications',
|
|
203
|
-
* discover: `./src/events/**\/*.handler.ts`,
|
|
204
|
-
* })
|
|
205
|
-
* ```
|
|
206
|
-
*/
|
|
207
|
-
export declare function consumeJetStreamStreams(options: JetStreamStreamsConsumerOptions): Promise<ConsumerMessages[]>;
|
|
208
|
-
/**
|
|
209
|
-
* Alias for ensureJetStreamStreams - shorter name
|
|
210
|
-
* @see ensureJetStreamStreams
|
|
211
|
-
*/
|
|
212
|
-
export declare const ensureJetStreams: typeof ensureJetStreamStreams;
|
|
213
|
-
/**
|
|
214
|
-
* Alias for consumeJetStreamStreams - shorter name
|
|
215
|
-
* @see consumeJetStreamStreams
|
|
216
|
-
*/
|
|
217
|
-
export declare const consumeJetStreams: typeof consumeJetStreamStreams;
|