@orion-js/echoes 4.5.3 → 4.5.4

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.
@@ -2,6 +2,8 @@ import type { EchoesEventTransportName, EchoesReceivedEvent, PublishOptions } fr
2
2
  export interface EventSubscriptionDefinition {
3
3
  topic: string;
4
4
  attemptsBeforeDeadLetter?: number;
5
+ ordered?: boolean;
6
+ configVersion?: number;
5
7
  }
6
8
  export interface EventTransportStartOptions {
7
9
  consume: boolean;
package/dist/index.cjs CHANGED
@@ -755,7 +755,9 @@ var EventBus = class {
755
755
  }
756
756
  const subscriptions = Object.entries(this.echoes).filter(([, echo2]) => echo2.type === "event").map(([topic, echo2]) => ({
757
757
  topic,
758
- attemptsBeforeDeadLetter: echo2.attemptsBeforeDeadLetter
758
+ attemptsBeforeDeadLetter: echo2.attemptsBeforeDeadLetter,
759
+ ordered: echo2.ordered,
760
+ configVersion: echo2.configVersion
759
761
  }));
760
762
  try {
761
763
  for (const name of selected) {
@@ -845,7 +847,7 @@ var PulseManager = class {
845
847
  (definition) => this.pulse.subscribe(
846
848
  definition.topic,
847
849
  (event) => options.onEvent(this.createReceivedEvent(event)),
848
- this.getSubscribeOptions(subscription, definition.attemptsBeforeDeadLetter)
850
+ this.getSubscribeOptions(subscription, definition)
849
851
  )
850
852
  )
851
853
  );
@@ -864,10 +866,12 @@ var PulseManager = class {
864
866
  await ((_a = this.pulse) == null ? void 0 : _a.close());
865
867
  this.subscriptions = [];
866
868
  }
867
- getSubscribeOptions(defaults = {}, attemptsBeforeDeadLetter) {
869
+ getSubscribeOptions(defaults = {}, definition) {
868
870
  return {
869
871
  ...defaults,
870
- ...attemptsBeforeDeadLetter === void 0 ? {} : { maxRetries: attemptsBeforeDeadLetter }
872
+ ...definition.ordered === void 0 ? {} : { ordered: definition.ordered },
873
+ ...definition.configVersion === void 0 ? {} : { configVersion: definition.configVersion },
874
+ ...definition.attemptsBeforeDeadLetter === void 0 ? {} : { maxRetries: definition.attemptsBeforeDeadLetter }
871
875
  };
872
876
  }
873
877
  createReceivedEvent(event) {
@@ -1028,6 +1032,8 @@ var echo = function createNewEcho(options) {
1028
1032
  params: options.params,
1029
1033
  returns: options.returns,
1030
1034
  attemptsBeforeDeadLetter: options.type === "event" ? options.attemptsBeforeDeadLetter : void 0,
1035
+ ordered: options.type === "event" ? options.ordered : void 0,
1036
+ configVersion: options.type === "event" ? options.configVersion : void 0,
1031
1037
  resolve,
1032
1038
  onEvent,
1033
1039
  onMessage: async (messageData) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/publish/index.ts","../src/echo/deserialize.ts","../src/publish/serialize.ts","../src/runtime.ts","../src/errors.ts","../src/request/getSignature.ts","../src/request/getPassword.ts","../src/request/getURL.ts","../src/request/makeRequest.ts","../src/request/index.ts","../src/startService/KafkaManager.ts","../src/events/EventBus.ts","../src/events/PulseManager.ts","../src/events/createEventBus.ts","../src/requestsHandler/checkSignature.ts","../src/requestsHandler/getEcho.ts","../src/requestsHandler/index.ts","../src/startService/index.ts","../src/echo/index.ts","../src/schema.ts","../src/service/index.ts"],"sourcesContent":["import publish from './publish'\nimport request from './request'\nimport startService, {stopService} from './startService'\n\nexport * from './echo'\nexport * from './errors'\nexport * from './runtime'\nexport * from './schema'\nexport * from './service'\nexport * from './types'\n\nexport {publish, startService, stopService, request}\n","import {EchoesConfigHandler} from './types'\n\nconst config: EchoesConfigHandler = {}\n\nexport default config\n","import config from '../config'\nimport {PublishOptions} from '../types'\n\n/**\n * Publish\n */\nexport default async function publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!config.eventBus) {\n throw new Error('You must initialize echoes configuration to use publish')\n }\n\n return await config.eventBus.publish(options)\n}\n","export default function (serializedJavascript: string): any {\n try {\n return eval('(' + serializedJavascript + ')')\n } catch (error) {\n throw new Error('Error deserializing echo message')\n }\n}\n","import serialize from 'serialize-javascript'\n\nfunction clonePropertyDescriptor(\n descriptor: PropertyDescriptor,\n references: WeakMap<object, any>,\n): PropertyDescriptor {\n // The copy only exists for serialization. Making properties configurable lets\n // ignoreFunction remove methods even when the caller passed a frozen object.\n const clonedDescriptor = {...descriptor, configurable: true}\n if ('value' in clonedDescriptor) {\n clonedDescriptor.value = cloneForSerialization(clonedDescriptor.value, references)\n }\n return clonedDescriptor\n}\n\nfunction copyOwnProperties(\n source: object,\n target: object,\n references: WeakMap<object, any>,\n shouldCopy: (key: PropertyKey) => boolean = () => true,\n) {\n for (const key of Reflect.ownKeys(source)) {\n if (!shouldCopy(key)) continue\n const descriptor = Object.getOwnPropertyDescriptor(source, key)\n if (!descriptor) continue\n Object.defineProperty(target, key, clonePropertyDescriptor(descriptor, references))\n }\n}\n\nfunction preserveCustomToJSON(source: object, target: object, references: WeakMap<object, any>) {\n const toJSON = (source as any).toJSON\n if (typeof toJSON !== 'function') return\n\n Object.defineProperty(target, 'toJSON', {\n configurable: true,\n enumerable: false,\n writable: true,\n value(key: string) {\n return cloneForSerialization(toJSON.call(source, key), references)\n },\n })\n}\n\nfunction cloneArrayBufferView<T extends ArrayBufferView>(\n value: T,\n references: WeakMap<object, any>,\n): T {\n const sourceBuffer = value.buffer\n let clonedBuffer = references.get(sourceBuffer) as ArrayBufferLike | undefined\n const shouldCopyBufferProperties = !clonedBuffer\n\n if (!clonedBuffer) {\n clonedBuffer = sourceBuffer.slice(0)\n references.set(sourceBuffer, clonedBuffer)\n }\n\n const clone =\n value instanceof DataView\n ? new DataView(clonedBuffer, value.byteOffset, value.byteLength)\n : new (value.constructor as any)(clonedBuffer, value.byteOffset, (value as any).length)\n\n references.set(value, clone)\n if (shouldCopyBufferProperties) {\n copyOwnProperties(sourceBuffer, clonedBuffer, references)\n }\n\n // Numeric indexes already exist on typed arrays. Preserve any additional own\n // properties because serialize-javascript includes them in the wire payload.\n copyOwnProperties(value, clone, references, key => {\n if (typeof key !== 'string') return true\n const index = Number(key)\n return !(\n Number.isInteger(index) &&\n index >= 0 &&\n index < (value as any).length &&\n String(index) === key\n )\n })\n return clone as T\n}\n\nfunction cloneForSerialization<T>(value: T, references = new WeakMap<object, any>()): T {\n if (value === null || (typeof value !== 'object' && typeof value !== 'function')) return value\n if (typeof value === 'function') return value\n\n const source = value as object\n if (references.has(source)) return references.get(source)\n\n if (value instanceof Date) {\n const clone = new Date(value.getTime())\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n return clone as T\n }\n\n if (value instanceof RegExp) {\n const clone = new RegExp(value.source, value.flags)\n clone.lastIndex = value.lastIndex\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n return clone as T\n }\n\n if (value instanceof Map) {\n const clone = new Map()\n references.set(source, clone)\n for (const [key, entry] of value) {\n Map.prototype.set.call(\n clone,\n cloneForSerialization(key, references),\n cloneForSerialization(entry, references),\n )\n }\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n return clone as T\n }\n\n if (value instanceof Set) {\n const clone = new Set()\n references.set(source, clone)\n for (const entry of value) {\n Set.prototype.add.call(clone, cloneForSerialization(entry, references))\n }\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n return clone as T\n }\n\n if (value instanceof URL) {\n const clone = new URL(value.toString())\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n return clone as T\n }\n\n if (Buffer.isBuffer(value)) {\n const clone = Buffer.from(value)\n references.set(source, clone)\n return clone as T\n }\n\n if (ArrayBuffer.isView(value)) {\n return cloneArrayBufferView(value, references) as T\n }\n\n if (\n value instanceof ArrayBuffer ||\n (typeof SharedArrayBuffer !== 'undefined' && value instanceof SharedArrayBuffer)\n ) {\n const clone = value.slice(0)\n references.set(source, clone)\n copyOwnProperties(value, clone, references)\n return clone as T\n }\n\n if (Array.isArray(value)) {\n const clone = new Array(value.length)\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n copyOwnProperties(value, clone, references, key => key !== 'length')\n return clone as T\n }\n\n const clone = Object.create(Object.getPrototypeOf(value))\n references.set(source, clone)\n copyOwnProperties(value, clone, references)\n preserveCustomToJSON(source, clone, references)\n return clone\n}\n\nexport default function (data: any): string {\n const serialized = serialize(cloneForSerialization(data), {ignoreFunction: true})\n return serialized\n}\n","import {AsyncLocalStorage} from 'node:async_hooks'\nimport {randomUUID} from 'node:crypto'\nimport {type EchoesErrorInfo, EchoesUserError, EchoesValidationError} from './errors'\n\nexport interface EchoesLogger {\n debug(message: string, metadata?: unknown): void\n info(message: string, metadata?: unknown): void\n warn(message: string, metadata?: unknown): void\n error(message: string, metadata?: unknown): void\n}\n\nexport interface EchoesSchemaAdapter {\n clean<T = unknown>(schema: unknown, value: unknown): T | Promise<T>\n parse<T = unknown>(schema: unknown, value: unknown): T | Promise<T>\n}\n\nexport interface EchoesExecutionContext {\n contextId?: string\n controllerType: 'echo'\n echoName: string\n params?: unknown\n}\n\nexport interface EchoesRequestHandlerDefinition {\n method: 'post'\n path: string\n bodyLimit: string\n handle(body: unknown): Promise<unknown>\n}\n\nexport type EchoesRequestHandlerRegistrar = (\n definition: EchoesRequestHandlerDefinition,\n) => void | Promise<void>\n\nexport interface EchoesRuntimeAdapter {\n schema?: EchoesSchemaAdapter\n logger?: EchoesLogger\n registerRequestHandler?: EchoesRequestHandlerRegistrar\n decorateService?(target: Function, context: ClassDecoratorContext): void\n getInstance?<T extends object>(target: new (...args: any[]) => T): T\n runWithContext?<T>(context: EchoesExecutionContext, callback: () => T | Promise<T>): Promise<T>\n createValidationError?(info: EchoesErrorInfo): Error\n createUserError?(info: EchoesErrorInfo): Error\n}\n\nconst defaultLogger: EchoesLogger = {\n debug: (message, metadata) =>\n metadata === undefined ? console.debug(message) : console.debug(message, metadata),\n info: (message, metadata) =>\n metadata === undefined ? console.info(message) : console.info(message, metadata),\n warn: (message, metadata) =>\n metadata === undefined ? console.warn(message) : console.warn(message, metadata),\n error: (message, metadata) =>\n metadata === undefined ? console.error(message) : console.error(message, metadata),\n}\n\nlet runtime: EchoesRuntimeAdapter = {}\nconst contextStorage = new AsyncLocalStorage<EchoesExecutionContext & {contextId: string}>()\n\n/**\n * Installs framework integrations without coupling Echoes to a framework.\n * The returned function restores the previous adapter, which is useful in tests.\n */\nexport function configureEchoesRuntime(adapter: EchoesRuntimeAdapter): () => void {\n const previous = runtime\n runtime = {...runtime, ...adapter}\n return () => {\n runtime = previous\n }\n}\n\nexport function getEchoesRuntime(): EchoesRuntimeAdapter {\n return runtime\n}\n\nexport function getEchoesLogger(): EchoesLogger {\n return runtime.logger || defaultLogger\n}\n\nexport function getEchoesContext(): (EchoesExecutionContext & {contextId: string}) | undefined {\n return contextStorage.getStore()\n}\n\nexport async function runWithEchoesContext<T>(\n context: EchoesExecutionContext,\n callback: () => T | Promise<T>,\n): Promise<T> {\n const contextWithId = {contextId: context.contextId || randomUUID(), ...context}\n return await contextStorage.run(contextWithId, async () => {\n if (runtime.runWithContext) {\n return await runtime.runWithContext(contextWithId, callback)\n }\n return await callback()\n })\n}\n\nfunction isSimpleSchemaLike(schema: unknown): schema is {\n clean(value: unknown, options?: Record<string, unknown>): unknown\n validate(value: unknown): unknown\n} {\n return (\n !!schema &&\n typeof schema === 'object' &&\n typeof (schema as any).clean === 'function' &&\n typeof (schema as any).validate === 'function'\n )\n}\n\nfunction cloneValue<T>(value: T): T {\n if (value === null || typeof value !== 'object') return value\n if (value instanceof Date) return new Date(value.getTime()) as T\n if (Buffer.isBuffer(value)) return Buffer.from(value) as T\n if (Array.isArray(value)) return value.map(cloneValue) as T\n const prototype = Object.getPrototypeOf(value)\n if (prototype !== Object.prototype && prototype !== null) return value\n\n const result: Record<string, unknown> = {}\n for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n result[key] = cloneValue(child)\n }\n return result as T\n}\n\nasync function cleanSimpleSchema<T>(\n schema: {\n clean(value: unknown, options?: Record<string, unknown>): unknown\n validate(value: unknown): unknown\n },\n value: unknown,\n): Promise<T> {\n const cloned = cloneValue(value)\n return (await schema.clean(cloned, {mutate: false})) as T\n}\n\nexport async function cleanEchoesSchema<T>(schema: unknown, value: unknown): Promise<T> {\n if (isSimpleSchemaLike(schema)) {\n return await cleanSimpleSchema<T>(schema, value)\n }\n if (runtime.schema) {\n return await runtime.schema.clean<T>(schema, value)\n }\n throw new Error(\n 'Echoes received a schema it cannot execute. Use a SimpleSchema-compatible object or configure an Echoes schema adapter.',\n )\n}\n\nexport async function parseEchoesSchema<T>(schema: unknown, value: unknown): Promise<T> {\n if (isSimpleSchemaLike(schema)) {\n const cleaned = await cleanSimpleSchema<T>(schema, value)\n await schema.validate(cleaned)\n return cleaned\n }\n if (runtime.schema) {\n return await runtime.schema.parse<T>(schema, value)\n }\n throw new Error(\n 'Echoes received a schema it cannot execute. Use a SimpleSchema-compatible object or configure an Echoes schema adapter.',\n )\n}\n\nexport function createEchoesValidationError(info: EchoesErrorInfo): Error {\n return runtime.createValidationError\n ? runtime.createValidationError(info)\n : new EchoesValidationError(info.validationErrors || {}, info.labels)\n}\n\nexport function createEchoesUserError(info: EchoesErrorInfo): Error {\n return runtime.createUserError\n ? runtime.createUserError(info)\n : new EchoesUserError(info.error, info.message, info.extra)\n}\n","export interface EchoesErrorInfo {\n error: string\n message: string\n extra?: any\n validationErrors?: Record<string, string>\n labels?: Record<string, string>\n}\n\nexport class EchoesUserError extends Error {\n readonly isEchoesError = true\n readonly isOrionError = true\n readonly isUserError = true\n readonly code: string\n readonly extra: any\n\n constructor(code: string, message?: string, extra?: any) {\n if (!message) {\n message = code\n code = 'error'\n }\n super(message)\n this.name = 'EchoesUserError'\n this.code = code\n this.extra = extra\n }\n\n getInfo(): EchoesErrorInfo {\n return {error: this.code, message: this.message, extra: this.extra}\n }\n}\n\nexport class EchoesValidationError extends Error {\n readonly isEchoesError = true\n readonly isOrionError = true\n readonly isValidationError = true\n readonly code = 'validationError'\n readonly validationErrors: Record<string, string>\n readonly labels: Record<string, string>\n\n constructor(validationErrors: Record<string, string>, labels: Record<string, string> = {}) {\n const printableErrors = Object.entries(validationErrors)\n .map(([key, value]) => `${key}: ${value}`)\n .join(', ')\n super(`Validation Error: {${printableErrors}}`)\n this.name = 'EchoesValidationError'\n this.validationErrors = validationErrors\n this.labels = Object.fromEntries(\n Object.keys(validationErrors)\n .filter(key => labels[key])\n .map(key => [key, labels[key]]),\n )\n }\n\n getInfo(): EchoesErrorInfo {\n return {\n error: this.code,\n message: 'Validation Error',\n validationErrors: this.validationErrors,\n labels: this.labels,\n }\n }\n}\n","import {createHmac} from 'node:crypto'\nimport {getEchoesPassword} from './getPassword'\n\nexport default function (_body: any): string {\n const password = getEchoesPassword()\n // Keep the legacy Echoes wire signature. jssha treated the object passed by\n // Echoes as an empty TEXT payload, so changing this would break mixed versions.\n return createHmac('sha1', password || '')\n .update('')\n .digest('hex')\n}\n","import config from '../config'\nimport {getEchoesLogger} from '../runtime'\n\nexport function getEchoesPassword() {\n const secret = config?.requests?.key || process.env.echoes_password || process.env.ECHOES_PASSWORD\n if (!secret) {\n getEchoesLogger().warn(\n 'Warning: no secret key found for echoes requests. Init echoes or set the env var \"echoes_password\" or process.env.ECHOES_PASSWORD',\n )\n }\n\n return secret\n}\n","import config from '../config'\n\nexport default function (serviceName: string): string {\n if (serviceName.startsWith('http')) return serviceName\n\n const url = config?.requests?.services?.[serviceName]\n\n if (!url) {\n throw new Error(`No URL found in echoes config for service ${serviceName}`)\n }\n\n return url\n}\n","import http from 'node:http'\nimport https from 'node:https'\nimport {RequestMaker} from '../types'\n\nasync function executeWithRetries<T>(\n callback: () => Promise<T>,\n retries = 0,\n delayMs = 200,\n): Promise<T> {\n try {\n return await callback()\n } catch (error) {\n if (retries <= 0) throw error\n await new Promise(resolve => setTimeout(resolve, delayMs))\n return await executeWithRetries(callback, retries - 1, delayMs)\n }\n}\n\nasync function postJSON(\n urlValue: string,\n data: unknown,\n timeout?: number,\n redirectsRemaining = 5,\n): Promise<{statusCode: number; data: object}> {\n const url = new URL(urlValue)\n const body = JSON.stringify(data)\n const transport = url.protocol === 'https:' ? https : http\n\n return await new Promise((resolve, reject) => {\n const request = transport.request(\n url,\n {\n method: 'POST',\n headers: {\n 'User-Agent': 'Orionjs-Echoes/1.1',\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(body),\n },\n },\n response => {\n const chunks: Buffer[] = []\n const statusCode = response.statusCode || 0\n if (statusCode >= 300 && statusCode < 400 && response.headers.location) {\n response.resume()\n if (redirectsRemaining <= 0) {\n reject(new Error('Echoes request exceeded the redirect limit'))\n return\n }\n resolve(\n postJSON(\n new URL(response.headers.location, url).toString(),\n data,\n timeout,\n redirectsRemaining - 1,\n ),\n )\n return\n }\n\n response.on('data', chunk => chunks.push(Buffer.from(chunk)))\n response.on('end', () => {\n try {\n const responseBody = Buffer.concat(chunks).toString('utf8')\n if (statusCode < 200 || statusCode >= 300) {\n reject(new Error(`Request failed with status code ${statusCode}`))\n return\n }\n resolve({\n statusCode,\n data: responseBody ? JSON.parse(responseBody) : {},\n })\n } catch (error) {\n reject(error)\n }\n })\n },\n )\n\n request.on('error', reject)\n if (timeout) {\n request.setTimeout(timeout, () => {\n request.destroy(new Error(`Echoes request timed out after ${timeout}ms`))\n })\n }\n request.end(body)\n })\n}\n\nexport const makeRequest: RequestMaker = async options => {\n return await executeWithRetries(\n () => postJSON(options.url, options.data, options.timeout),\n options.retries || 0,\n )\n}\n","import config from '../config'\nimport deserialize from '../echo/deserialize'\nimport serialize from '../publish/serialize'\nimport {createEchoesUserError, createEchoesValidationError} from '../runtime'\nimport type {\n MakeRequestParams,\n RequestHandlerResponse,\n RequestMaker,\n RequestOptions,\n} from '../types'\nimport getSignature from './getSignature'\nimport getURL from './getURL'\nimport {makeRequest} from './makeRequest'\n\nexport default async function request<TData = any, TParams = any>(\n options: RequestOptions<TParams>,\n): Promise<TData> {\n const {method, service, params} = options\n const serializedParams = serialize(params)\n const date = new Date()\n const body = {method, service, serializedParams, date}\n const signature = getSignature(body)\n\n try {\n const requestMaker: RequestMaker = config?.requests?.makeRequest || makeRequest\n const requestOptions: MakeRequestParams = {\n url: getURL(service),\n retries: options.retries,\n timeout: options.timeout,\n data: {\n body,\n signature,\n },\n }\n const result = await requestMaker(requestOptions)\n\n if (result.statusCode !== 200) {\n throw new Error(`Wrong status code ${result.statusCode}`)\n }\n\n const data: RequestHandlerResponse = result.data\n\n if (data.error) {\n const info = data.errorInfo\n if (info) {\n if (data.isValidationError) {\n throw createEchoesValidationError(info)\n }\n if (data.isUserError) {\n throw createEchoesUserError(info)\n }\n }\n\n throw new Error(`${data.error}`)\n }\n\n const response = deserialize(data.result)\n return response\n } catch (error) {\n const caught = error as any\n if (caught.isOrionError || caught.isEchoesError) throw caught\n\n throw new Error(`Echoes request network error calling ${service}/${method}: ${caught.message}`)\n }\n}\n","import {randomUUID} from 'node:crypto'\nimport deserialize from '../echo/deserialize'\nimport type {\n EventSubscriptionDefinition,\n EventTransport,\n EventTransportStartOptions,\n} from '../events/EventTransport'\nimport serialize from '../publish/serialize'\nimport {getEchoesLogger} from '../runtime'\nimport type {\n EchoesKafkaEventsConfig,\n EchoesKafkaMessagePayload,\n EchoesReceivedEvent,\n PublishOptions,\n} from '../types'\n\nconst HEARTBEAT_INTERVAL_SECONDS = 5\nconst CHECK_JOIN_CONSUMER_INTERVAL_SECONDS = 30\nconst DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY = 4\nconst DEFAULT_MEMBERS_TO_PARTITIONS_RATIO = 1\n\n/**\n * Kafka event transport. It retains the existing consumer-group and retry behavior.\n */\nclass KafkaManager implements EventTransport {\n readonly name = 'kafka' as const\n\n private kafka?: any\n private readonly options: EchoesKafkaEventsConfig\n private producer?: any\n private consumer?: any\n private topics: string[] = []\n private subscriptions = new Map<string, EventSubscriptionDefinition>()\n private onEvent?: (event: EchoesReceivedEvent) => Promise<void>\n private consumerStarted = false\n private producerConnected = false\n private interval?: NodeJS.Timeout\n\n constructor(options: EchoesKafkaEventsConfig) {\n this.options = options\n }\n\n async start(options: EventTransportStartOptions) {\n let kafkaModule: typeof import('kafkajs')\n try {\n kafkaModule = await import('kafkajs')\n } catch (error) {\n const wrapped = new Error(\n 'Echoes Kafka transport requires kafkajs to be installed in the application',\n )\n ;(wrapped as any).cause = error\n throw wrapped\n }\n this.kafka = new kafkaModule.Kafka(this.options.client as any)\n\n this.onEvent = options.onEvent\n this.subscriptions = new Map(\n options.subscriptions.map(subscription => [subscription.topic, subscription]),\n )\n this.topics = options.subscriptions.map(subscription => subscription.topic)\n\n // Kafka retries and DLQ publishing use a producer even on consumer-only servers.\n if (options.publish || options.consume) {\n this.producer = this.kafka.producer(this.options.producer)\n await this.producer.connect()\n this.producerConnected = true\n }\n\n if (!options.consume || this.topics.length === 0) return\n if (!this.options.consumer?.groupId) {\n throw new Error('Echoes Kafka consumers require consumer.groupId')\n }\n\n this.consumer = this.kafka.consumer(this.options.consumer)\n this.consumerStarted = await this.conditionalStart()\n if (this.consumerStarted) return\n\n getEchoesLogger().info('Echoes: Delaying consumer group join, waiting for conditions to be met')\n this.interval = setInterval(async () => {\n this.consumerStarted = await this.conditionalStart()\n if (this.consumerStarted) clearInterval(this.interval)\n }, CHECK_JOIN_CONSUMER_INTERVAL_SECONDS * 1000)\n }\n\n async publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!this.producer || !this.producerConnected) {\n throw new Error('Echoes Kafka producer is not connected')\n }\n\n return await this.producer.send({\n acks: options.acks,\n timeout: options.timeout,\n topic: options.topic,\n messages: [\n {\n value: serialize({params: options.params}),\n headers: {\n 'echoes-event-id': randomUUID(),\n },\n },\n ],\n })\n }\n\n async close() {\n const logger = getEchoesLogger()\n logger.warn('Echoes: Stopping Kafka transport')\n if (this.interval) clearInterval(this.interval)\n await Promise.all([\n this.consumer?.disconnect(),\n this.producerConnected ? this.producer?.disconnect() : undefined,\n ])\n this.consumerStarted = false\n this.producerConnected = false\n }\n\n private async checkJoinConsumerGroupConditions(): Promise<boolean> {\n const logger = getEchoesLogger()\n const admin = this.kafka.admin()\n try {\n await admin.connect()\n const groupId = this.options.consumer.groupId\n const groupDescriptions = await admin.describeGroups([groupId])\n const group = groupDescriptions.groups[0]\n if (group.state === 'Empty') {\n logger.info(`Echoes: Consumer group ${groupId} is empty, joining`)\n return true\n }\n const topicsMetadata = await admin.fetchTopicMetadata({topics: this.topics})\n const totalPartitions = topicsMetadata.topics.reduce(\n (acc, topic) => acc + topic.partitions.length,\n 0,\n )\n logger.info(\n `Echoes: Consumer group ${groupId} has ${group.members.length} members and ${totalPartitions} partitions`,\n )\n const partitionsRatio =\n this.options.membersToPartitionsRatio || DEFAULT_MEMBERS_TO_PARTITIONS_RATIO\n const partitionsThreshold = Math.ceil(totalPartitions * partitionsRatio)\n if (partitionsThreshold > group.members.length) {\n logger.info(\n `Echoes: Consumer group ${groupId} has room for more members ${group.members.length}/${partitionsThreshold}, joining`,\n )\n return true\n }\n return false\n } catch (error) {\n logger.error('Echoes: Error checking consumer group conditions, join', {error})\n return true\n } finally {\n await admin.disconnect().catch(error => {\n logger.error('Echoes: Error disconnecting admin client', {error})\n })\n }\n }\n\n private async joinConsumerGroup() {\n await this.consumer.connect()\n await this.consumer.subscribe({topics: this.topics})\n await this.consumer.run({\n partitionsConsumedConcurrently:\n this.options.partitionsConsumedConcurrently || DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY,\n eachMessage: params => this.handleMessage(params),\n })\n }\n\n private async conditionalStart(): Promise<boolean> {\n if (await this.checkJoinConsumerGroupConditions()) {\n await this.joinConsumerGroup()\n return true\n }\n return false\n }\n\n private async handleMessage(params: EchoesKafkaMessagePayload) {\n const logger = getEchoesLogger()\n const subscription = this.subscriptions.get(params.topic)\n if (!subscription) {\n logger.warn(`Echoes: Received a message for an unknown topic: ${params.topic}, ignoring it`)\n return\n }\n\n let intervalsCount = 0\n const heartbeatInterval = setInterval(async () => {\n await params.heartbeat().catch(error => {\n logger.warn(`Echoes: Error sending heartbeat: ${error.message}`)\n })\n intervalsCount++\n if ((intervalsCount * HEARTBEAT_INTERVAL_SECONDS) % 30 === 0) {\n logger.warn(\n `Echoes: Event is taking too long to process: ${params.topic} ${intervalsCount * HEARTBEAT_INTERVAL_SECONDS}s`,\n )\n }\n }, HEARTBEAT_INTERVAL_SECONDS * 1000)\n\n try {\n const event = this.createReceivedEvent(params)\n await this.onEvent(event)\n } catch (error) {\n try {\n await this.handleRetries(subscription, params, error as Error)\n } catch (retryError) {\n logger.error('Echoes: error processing a message', {\n error: retryError,\n topic: params.topic,\n })\n throw retryError\n }\n } finally {\n clearInterval(heartbeatInterval)\n }\n }\n\n private createReceivedEvent(params: EchoesKafkaMessagePayload): EchoesReceivedEvent {\n const {message, topic, partition} = params\n if (!message.value) {\n throw new Error(`Echoes received an empty Kafka message for ${topic}`)\n }\n const data = deserialize(message.value.toString())\n const retries = Number.parseInt(message.headers?.retries?.toString() || '0', 10)\n const timestamp = Number.parseInt(message.timestamp || '', 10)\n\n return {\n id:\n message.headers?.['echoes-event-id']?.toString() ||\n `kafka:${topic}:${partition}:${message.offset}`,\n topic,\n data,\n transport: 'kafka',\n headers: message.headers,\n createdAt: Number.isFinite(timestamp) ? new Date(timestamp) : new Date(),\n attempt: retries + 1,\n context: params,\n }\n }\n\n private async handleRetries(\n subscription: EventSubscriptionDefinition,\n params: EchoesKafkaMessagePayload,\n error: Error,\n ) {\n const logger = getEchoesLogger()\n const {message, topic} = params\n const retries = Number.parseInt(message?.headers?.retries?.toString() || '0', 10)\n if (\n subscription.attemptsBeforeDeadLetter === undefined ||\n subscription.attemptsBeforeDeadLetter === null\n ) {\n throw error\n }\n const maxRetries = subscription.attemptsBeforeDeadLetter || 0\n const exceededMaxRetries = retries >= maxRetries\n const nextTopic = exceededMaxRetries ? `DLQ-${topic}` : topic\n if (!message.value) throw error\n await this.producer.send({\n topic: nextTopic,\n messages: [\n {\n value: message.value.toString(),\n headers: {\n ...message.headers,\n retries: String(retries + 1),\n error: error.message,\n },\n },\n ],\n })\n\n if (exceededMaxRetries) {\n logger.error(\n 'Echoes: a message has reached the maximum number of retries, sending it to DLQ',\n {topic: nextTopic},\n )\n } else {\n logger.warn('Echoes: a retryable message failed', {error, topic: nextTopic})\n }\n }\n}\n\nexport default KafkaManager\n","import {getEchoesLogger} from '../runtime'\nimport type {\n EchoesEventTransportName,\n EchoesMap,\n EchoesReceivedEvent,\n PublishOptions,\n} from '../types'\nimport type {EventSubscriptionDefinition, EventTransport} from './EventTransport'\n\nexport interface EventBusOptions {\n echoes: EchoesMap\n transports: Partial<Record<EchoesEventTransportName, EventTransport>>\n consumeFrom: EchoesEventTransportName[]\n publishTo?: EchoesEventTransportName\n}\n\nexport default class EventBus {\n private readonly echoes: EchoesMap\n private readonly transports: Partial<Record<EchoesEventTransportName, EventTransport>>\n private readonly consumeFrom: EchoesEventTransportName[]\n private readonly publishTo?: EchoesEventTransportName\n private readonly startedTransports: EventTransport[] = []\n private started = false\n private closed = false\n\n constructor(options: EventBusOptions) {\n this.echoes = options.echoes\n this.transports = options.transports\n this.consumeFrom = [...new Set(options.consumeFrom)]\n this.publishTo = options.publishTo\n }\n\n async start() {\n if (this.started) return\n\n const selected = new Set(this.consumeFrom)\n if (this.publishTo) selected.add(this.publishTo)\n\n for (const name of selected) {\n if (!this.transports[name]) {\n throw new Error(`Echoes event transport \"${name}\" is selected but not configured`)\n }\n }\n\n const subscriptions: EventSubscriptionDefinition[] = Object.entries(this.echoes)\n .filter(([, echo]) => echo.type === 'event')\n .map(([topic, echo]) => ({\n topic,\n attemptsBeforeDeadLetter: echo.attemptsBeforeDeadLetter,\n }))\n\n try {\n for (const name of selected) {\n const transport = this.transports[name]\n this.startedTransports.push(transport)\n await transport.start({\n consume: this.consumeFrom.includes(name),\n publish: this.publishTo === name,\n subscriptions,\n onEvent: event => this.handleEvent(event),\n })\n }\n this.started = true\n } catch (error) {\n await this.close().catch(() => undefined)\n throw error\n }\n }\n\n async publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!this.started) {\n throw new Error('You must initialize echoes configuration to use publish')\n }\n if (!this.publishTo) {\n throw new Error('Echoes does not have a publish transport configured')\n }\n\n return await this.transports[this.publishTo].publish(options)\n }\n\n async close() {\n if (this.closed) return\n this.closed = true\n await Promise.all(this.startedTransports.map(transport => transport.close()))\n }\n\n private async handleEvent(event: EchoesReceivedEvent) {\n const logger = getEchoesLogger()\n const echo = this.echoes[event.topic]\n if (!echo || echo.type !== 'event') {\n logger.warn(`Echoes: Received a message for an unknown topic: ${event.topic}, ignoring it`)\n return\n }\n\n // Preserve the exact legacy Kafka entrypoint for custom EchoType implementations.\n if (event.transport === 'kafka' && event.context) {\n await echo.onMessage(event.context as any)\n return\n }\n\n if (echo.onEvent) {\n await echo.onEvent(event)\n return\n }\n\n await echo.resolve(event.data.params, {\n ...(event.context || {}),\n transport: event.transport,\n eventId: event.id,\n topic: event.topic,\n headers: event.headers,\n createdAt: event.createdAt,\n attempt: event.attempt,\n data: event.data,\n })\n }\n}\n","import type {\n EchoesEventPayload,\n EchoesPulseEventsConfig,\n EchoesReceivedEvent,\n PublishOptions,\n} from '../types'\nimport type {EventTransport, EventTransportStartOptions} from './EventTransport'\n\ntype PulseSubscribeOptions = NonNullable<EchoesPulseEventsConfig['subscription']>\n\ninterface PulseReceivedEvent {\n id: string\n topic: string\n data: EchoesEventPayload\n headers?: Record<string, unknown>\n createdAt: Date\n attempt: number\n}\n\nexport default class PulseManager implements EventTransport {\n readonly name = 'pulse' as const\n\n private readonly options: EchoesPulseEventsConfig\n private pulse?: any\n private subscriptions: Array<{unsubscribe(): Promise<void>}> = []\n\n constructor(options: EchoesPulseEventsConfig) {\n this.options = options\n }\n\n async start(options: EventTransportStartOptions) {\n let pulseModule: any\n try {\n pulseModule = await import('@orion-js/pulse')\n } catch (error) {\n const wrapped = new Error(\n 'Echoes Pulse transport requires @orion-js/pulse to be installed in the application',\n )\n ;(wrapped as any).cause = error\n throw wrapped\n }\n\n const {subscription, ...connectOptions} = this.options\n this.pulse = pulseModule.connect(connectOptions)\n await this.pulse.awaitConnection()\n\n if (!options.consume) return\n\n this.subscriptions = await Promise.all(\n options.subscriptions.map(definition =>\n this.pulse.subscribe(\n definition.topic,\n event => options.onEvent(this.createReceivedEvent(event)),\n this.getSubscribeOptions(subscription, definition.attemptsBeforeDeadLetter),\n ),\n ),\n )\n }\n\n async publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!this.pulse) {\n throw new Error('Echoes Pulse client is not connected')\n }\n\n return await this.pulse.publish({\n topic: options.topic,\n data: {params: options.params},\n })\n }\n\n async close() {\n await this.pulse?.close()\n this.subscriptions = []\n }\n\n private getSubscribeOptions(\n defaults: PulseSubscribeOptions = {},\n attemptsBeforeDeadLetter?: number,\n ): PulseSubscribeOptions {\n return {\n ...defaults,\n ...(attemptsBeforeDeadLetter === undefined ? {} : {maxRetries: attemptsBeforeDeadLetter}),\n }\n }\n\n private createReceivedEvent(event: PulseReceivedEvent): EchoesReceivedEvent {\n return {\n id: event.id,\n topic: event.topic,\n data: event.data,\n transport: 'pulse',\n headers: event.headers,\n createdAt: event.createdAt,\n attempt: event.attempt,\n context: event,\n }\n }\n}\n","import KafkaManager from '../startService/KafkaManager'\nimport type {\n EchoesEventTransportName,\n EchoesKafkaEventsConfig,\n EchoesOptions,\n EchoesPulseEventsConfig,\n} from '../types'\nimport EventBus from './EventBus'\nimport type {EventTransport} from './EventTransport'\nimport PulseManager from './PulseManager'\n\nexport interface ResolvedEventsConfig {\n kafka?: EchoesKafkaEventsConfig\n pulse?: EchoesPulseEventsConfig\n consumeFrom: EchoesEventTransportName[]\n publishTo?: EchoesEventTransportName\n}\n\nexport function resolveEventsConfig(options: EchoesOptions): ResolvedEventsConfig | undefined {\n const legacyKafka = options.client\n ? {\n client: options.client,\n producer: options.producer,\n consumer: options.consumer,\n readTopicsFromBeginning: options.readTopicsFromBeginning,\n partitionsConsumedConcurrently: options.partitionsConsumedConcurrently,\n membersToPartitionsRatio: options.membersToPartitionsRatio,\n }\n : undefined\n\n const kafka = options.events?.kafka || legacyKafka\n const pulse = options.events?.pulse\n\n if (!kafka && !pulse && !options.events) return undefined\n\n const defaultTransport: EchoesEventTransportName | undefined = kafka\n ? 'kafka'\n : pulse\n ? 'pulse'\n : undefined\n\n return {\n kafka,\n pulse,\n consumeFrom: options.events?.consumeFrom || (defaultTransport ? [defaultTransport] : []),\n publishTo: options.events?.publishTo || defaultTransport,\n }\n}\n\nexport default function createEventBus(options: EchoesOptions) {\n const resolved = resolveEventsConfig(options)\n if (!resolved) return undefined\n\n const transports: Partial<Record<EchoesEventTransportName, EventTransport>> = {}\n if (resolved.kafka) transports.kafka = new KafkaManager(resolved.kafka)\n if (resolved.pulse) transports.pulse = new PulseManager(resolved.pulse)\n\n return new EventBus({\n echoes: options.echoes,\n transports,\n consumeFrom: resolved.consumeFrom,\n publishTo: resolved.publishTo,\n })\n}\n","import getSignature from '../request/getSignature'\n\nexport default function (body: any, signature: string) {\n const generatedSignature = getSignature(body)\n if (generatedSignature !== signature) {\n throw new Error('Echoes invalid signature')\n }\n}\n","import config from '../config'\n\nexport default function (method: string) {\n const echo = config.echoes[method]\n\n if (!echo) {\n throw new Error(`Echo named ${method} not found in this service`)\n }\n\n if (echo.type !== 'request') {\n throw new Error(`Echo named ${method} is not of type request`)\n }\n\n return echo\n}\n","import serialize from '../publish/serialize'\nimport {getEchoesLogger} from '../runtime'\nimport {EchoesOptions} from '../types'\nimport checkSignature from './checkSignature'\nimport getEcho from './getEcho'\n\nexport default (options: EchoesOptions) =>\n ({\n method: 'post',\n path: options.requests.handlerPath || '/echoes-services',\n bodyLimit: '10mb',\n async handle(requestBody: any) {\n try {\n const {body, signature} = requestBody\n\n checkSignature(body, signature)\n\n const {method, serializedParams} = body\n\n const echo = getEcho(method)\n const result = await echo.onRequest(serializedParams)\n\n return {result: serialize(result)}\n } catch (error) {\n const caught = error as any\n if (!caught.getInfo) {\n getEchoesLogger().error('Error at echo requests handler:', {error: caught})\n }\n\n return {\n error: caught.message,\n errorInfo: caught.getInfo ? caught.getInfo() : null,\n isValidationError: !!caught.isValidationError,\n isUserError: !!caught.isUserError,\n }\n }\n },\n }) as const\n","import config from '../config'\nimport createEventBus from '../events/createEventBus'\nimport EventBus from '../events/EventBus'\nimport requestsHandler from '../requestsHandler'\nimport {getEchoesLogger, getEchoesRuntime} from '../runtime'\nimport {EchoesOptions} from '../types'\n\nlet eventBus: EventBus = null\n\nexport default async function startService(options: EchoesOptions) {\n config.echoes = options.echoes\n\n if (options.requests) {\n config.requests = options.requests\n const registerHandler =\n options.requests.registerHandler || getEchoesRuntime().registerRequestHandler\n if (!registerHandler) {\n throw new Error(\n 'Echoes requests require requests.registerHandler in standalone servers. Orion applications can import @orion-js/echoes-orion once during startup.',\n )\n }\n await registerHandler(requestsHandler(options))\n }\n\n const nextEventBus = createEventBus(options)\n if (nextEventBus) {\n await nextEventBus.start()\n eventBus = nextEventBus\n config.eventBus = eventBus\n }\n}\n\nexport async function stopService() {\n if (eventBus) {\n const logger = getEchoesLogger()\n logger.info('Stopping Echoes...')\n await eventBus.close()\n eventBus = null\n config.eventBus = undefined\n logger.info('Echoes stopped')\n }\n}\n","import {cleanEchoesSchema, parseEchoesSchema} from '../runtime'\nimport type {EchoesSchema, InferEchoesSchema} from '../schema'\nimport {\n EchoConfig,\n EchoEventConfig,\n EchoesKafkaMessagePayload,\n EchoesReceivedEvent,\n EchoRequestConfig,\n EchoType,\n} from '../types'\nimport deserialize from './deserialize'\n\n/**\n * @deprecated Use createEchoRequest and createEchoEvent instead\n */\nconst echo = function createNewEcho<\n TParamsSchema extends EchoesSchema,\n TReturnsSchema extends EchoesSchema,\n TEchoType extends 'event' | 'request',\n>(\n options: EchoConfig<TParamsSchema, TReturnsSchema, TEchoType>,\n): EchoType<TParamsSchema, TReturnsSchema, TEchoType> {\n const resolve = async (params: InferEchoesSchema<TParamsSchema>, context: any) => {\n const cleaned = options.params\n ? await parseEchoesSchema<InferEchoesSchema<TParamsSchema>>(options.params, params)\n : (params ?? ({} as InferEchoesSchema<TParamsSchema>))\n\n const result = await options.resolve(cleaned, context)\n\n if (options.returns) {\n return await cleanEchoesSchema<InferEchoesSchema<TReturnsSchema>>(options.returns, result)\n }\n\n return result\n }\n\n const onEvent = async (event: EchoesReceivedEvent) => {\n const context = {\n ...(event.context || {}),\n transport: event.transport,\n eventId: event.id,\n topic: event.topic,\n headers: event.headers,\n createdAt: event.createdAt,\n attempt: event.attempt,\n data: event.data,\n }\n\n await resolve(event.data.params, context)\n }\n\n return {\n type: options.type,\n params: options.params,\n returns: options.returns,\n attemptsBeforeDeadLetter:\n options.type === 'event' ? options.attemptsBeforeDeadLetter : undefined,\n resolve,\n onEvent,\n onMessage: async (messageData: EchoesKafkaMessagePayload) => {\n const {message} = messageData\n if (!message.value) {\n throw new Error(`Echoes received an empty Kafka message for ${messageData.topic}`)\n }\n\n const data = deserialize(message.value.toString())\n const retries = Number.parseInt(message.headers?.retries?.toString() || '0', 10)\n const timestamp = Number(message.timestamp)\n const createdAt = Number.isFinite(timestamp) ? new Date(timestamp) : new Date()\n const eventId =\n message.headers?.['echoes-event-id']?.toString() ||\n `kafka:${messageData.topic}:${messageData.partition}:${message.offset}`\n\n await onEvent({\n id: eventId,\n topic: messageData.topic,\n data,\n transport: 'kafka',\n headers: message.headers,\n createdAt,\n attempt: retries + 1,\n context: messageData,\n })\n },\n onRequest: async (serializedParams: string) => {\n const context = {}\n const params = deserialize(serializedParams)\n\n return await resolve(params, context)\n },\n }\n}\n\nexport function createEchoRequest<\n TParamsSchema extends EchoesSchema,\n TReturnsSchema extends EchoesSchema,\n>(\n options: EchoRequestConfig<TParamsSchema, TReturnsSchema>,\n): EchoType<TParamsSchema, TReturnsSchema, 'request'> {\n return echo({...options, type: 'request'})\n}\nexport function createEchoEvent<\n TParamsSchema extends EchoesSchema,\n TReturnsSchema extends EchoesSchema,\n>(\n options: EchoEventConfig<TParamsSchema, TReturnsSchema>,\n): EchoType<TParamsSchema, TReturnsSchema, 'event'> {\n return echo({...options, type: 'event' as any})\n}\n\nexport {echo}\n","export type EchoesSchema = unknown\n\ntype InferFieldType<T> = T extends {__tsFieldType: infer U}\n ? U\n : T extends 'string' | 'ID' | 'email'\n ? string\n : T extends 'date'\n ? Date\n : T extends 'integer' | 'number'\n ? number\n : T extends 'boolean'\n ? boolean\n : T extends 'blackbox'\n ? Record<string, any>\n : T extends 'any'\n ? any\n : T extends String | StringConstructor\n ? string\n : T extends Number | NumberConstructor\n ? number\n : T extends Boolean | BooleanConstructor\n ? boolean\n : T extends Date | DateConstructor\n ? Date\n : T extends Array<infer U>\n ? InferFieldType<U>[]\n : T extends Record<string, any>\n ? InferObjectSchema<T>\n : T\n\ntype NodeIsOptional<T> = T extends {optional: true} ? true : false\n\ntype InferObjectSchema<T extends Record<string, any>> = {\n -readonly [K in keyof T as NodeIsOptional<T[K]> extends true ? never : K]: InferEchoesSchema<\n T[K] extends {type: infer U} ? U : T[K]\n >\n} & {\n -readonly [K in keyof T as NodeIsOptional<T[K]> extends true ? K : never]?: InferEchoesSchema<\n T[K] extends {type: infer U} ? U : T[K]\n >\n}\n\ntype IsObjectSchema<T> =\n T extends Record<string, any>\n ? keyof {\n [K in keyof T as T[K] extends {type: any} ? K : never]: T[K]\n } extends never\n ? false\n : true\n : false\n\ntype AbstractClass<T = any> = abstract new (...args: any[]) => T\n\n/**\n * Infers the value represented by Orion-style schema declarations without\n * requiring @orion-js/schema to be installed.\n */\nexport type InferEchoesSchema<T> = T extends {__echoesType: infer U}\n ? U\n : T extends {__tsFieldType: infer U}\n ? U\n : T extends {__isModel: true; type: infer U}\n ? U extends Record<string, any>\n ? InferObjectSchema<U>\n : InferFieldType<U>\n : T extends StringConstructor\n ? string\n : T extends NumberConstructor\n ? number\n : T extends BooleanConstructor\n ? boolean\n : T extends DateConstructor\n ? Date\n : T extends AbstractClass<infer U>\n ? U\n : IsObjectSchema<T> extends true\n ? T extends Record<string, any>\n ? InferObjectSchema<T>\n : never\n : InferFieldType<T>\n\n/**\n * Adds compile-time value information to a runtime schema such as SimpleSchema.\n * It returns the same object and has no runtime cost.\n */\nexport function typedEchoesSchema<TValue, TSchema extends object = object>(\n schema: TSchema,\n): TSchema & {readonly __echoesType: TValue} {\n return schema as TSchema & {readonly __echoesType: TValue}\n}\n","import {createEchoEvent, createEchoRequest} from '../echo'\nimport {getEchoesRuntime, runWithEchoesContext} from '../runtime'\nimport {EchoConfig, EchoesMap} from '../types'\n\nexport interface EchoesPropertyDescriptor extends Omit<PropertyDecorator, 'value'> {\n value?: EchoConfig<any, any>['resolve']\n}\n// Define metadata storage using WeakMaps\nconst serviceMetadata = new WeakMap<any, {_serviceType: string}>()\nconst echoesMetadata = new WeakMap<any, Record<string, any>>()\nconst echoEntriesByClass = new Map<Function, Record<string, (instance: any) => any>>()\nconst standaloneInstances = new WeakMap<Function, any>()\nlet pendingEchoEntries: Record<string, (instance: any) => any> = {}\n\nexport function Echoes() {\n return (target: any, context: ClassDecoratorContext<any>) => {\n getEchoesRuntime().decorateService?.(target, context)\n serviceMetadata.set(target, {_serviceType: 'echoes'})\n\n if (Object.keys(pendingEchoEntries).length > 0) {\n echoEntriesByClass.set(target, pendingEchoEntries)\n pendingEchoEntries = {}\n }\n }\n}\n\nexport function EchoEvent(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EchoEvent(\n options?: Omit<EchoConfig<any, any>, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EchoEvent(options = {}) {\n return (method: any, context: ClassMethodDecoratorContext | ClassFieldDecoratorContext) => {\n const propertyKey = String(context.name)\n\n if (context.kind === 'method') {\n pendingEchoEntries[propertyKey] = (instance: any) => {\n const originalResolve = instance[propertyKey].bind(instance)\n return createEchoEvent({\n ...options,\n resolve: async (params, contextData) => {\n return await runWithEchoesContext(\n {\n controllerType: 'echo',\n echoName: propertyKey,\n params,\n },\n async () => {\n return await originalResolve(params, contextData)\n },\n )\n },\n })\n }\n }\n\n if (context.kind === 'field') {\n pendingEchoEntries[propertyKey] = (instance: any) => instance[propertyKey]\n }\n\n return method\n }\n}\n\nexport function EchoRequest(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EchoRequest(\n options?: Omit<EchoConfig<any, any>, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EchoRequest(options = {}) {\n return (method: any, context: ClassMethodDecoratorContext | ClassFieldDecoratorContext) => {\n const propertyKey = String(context.name)\n\n if (context.kind === 'method') {\n pendingEchoEntries[propertyKey] = (instance: any) => {\n const originalResolve = instance[propertyKey].bind(instance)\n return createEchoRequest({\n ...options,\n resolve: async (params, contextData) => {\n return await runWithEchoesContext(\n {\n controllerType: 'echo',\n echoName: propertyKey,\n params,\n },\n async () => {\n return await originalResolve(params, contextData)\n },\n )\n },\n })\n }\n }\n\n if (context.kind === 'field') {\n pendingEchoEntries[propertyKey] = (instance: any) => instance[propertyKey]\n }\n\n return method\n }\n}\n\nfunction initializeEchoesIfNeeded(instance: any) {\n if (echoesMetadata.has(instance)) return\n const entries = echoEntriesByClass.get(instance.constructor) || {}\n const echoes: Record<string, any> = {}\n for (const [key, setup] of Object.entries(entries)) {\n echoes[key] = setup(instance)\n }\n echoesMetadata.set(instance, echoes)\n}\n\nexport function getServiceEchoes(target: any): EchoesMap {\n let instance: any\n if (typeof target !== 'function') {\n instance = target\n } else if (getEchoesRuntime().getInstance) {\n instance = getEchoesRuntime().getInstance(target)\n } else {\n instance = standaloneInstances.get(target)\n if (!instance) {\n instance = new target()\n standaloneInstances.set(target, instance)\n }\n }\n\n if (!serviceMetadata.has(instance.constructor)) {\n throw new Error('You must pass a class decorated with @Echoes to getServiceEchoes')\n }\n\n const instanceMetadata = serviceMetadata.get(instance.constructor)\n if (instanceMetadata._serviceType !== 'echoes') {\n throw new Error('You must pass a class decorated with @Echoes to getServiceEchoes')\n }\n\n initializeEchoesIfNeeded(instance)\n\n const echoesMap = echoesMetadata.get(instance) || {}\n\n return echoesMap\n}\n"],"mappings":"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","names":["clone","serialize","import_node_crypto","https","http","request","import_node_crypto","echo","echo","echo"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/publish/index.ts","../src/echo/deserialize.ts","../src/publish/serialize.ts","../src/runtime.ts","../src/errors.ts","../src/request/getSignature.ts","../src/request/getPassword.ts","../src/request/getURL.ts","../src/request/makeRequest.ts","../src/request/index.ts","../src/startService/KafkaManager.ts","../src/events/EventBus.ts","../src/events/PulseManager.ts","../src/events/createEventBus.ts","../src/requestsHandler/checkSignature.ts","../src/requestsHandler/getEcho.ts","../src/requestsHandler/index.ts","../src/startService/index.ts","../src/echo/index.ts","../src/schema.ts","../src/service/index.ts"],"sourcesContent":["import publish from './publish'\nimport request from './request'\nimport startService, {stopService} from './startService'\n\nexport * from './echo'\nexport * from './errors'\nexport * from './runtime'\nexport * from './schema'\nexport * from './service'\nexport * from './types'\n\nexport {publish, startService, stopService, request}\n","import {EchoesConfigHandler} from './types'\n\nconst config: EchoesConfigHandler = {}\n\nexport default config\n","import config from '../config'\nimport {PublishOptions} from '../types'\n\n/**\n * Publish\n */\nexport default async function publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!config.eventBus) {\n throw new Error('You must initialize echoes configuration to use publish')\n }\n\n return await config.eventBus.publish(options)\n}\n","export default function (serializedJavascript: string): any {\n try {\n return eval('(' + serializedJavascript + ')')\n } catch (error) {\n throw new Error('Error deserializing echo message')\n }\n}\n","import serialize from 'serialize-javascript'\n\nfunction clonePropertyDescriptor(\n descriptor: PropertyDescriptor,\n references: WeakMap<object, any>,\n): PropertyDescriptor {\n // The copy only exists for serialization. Making properties configurable lets\n // ignoreFunction remove methods even when the caller passed a frozen object.\n const clonedDescriptor = {...descriptor, configurable: true}\n if ('value' in clonedDescriptor) {\n clonedDescriptor.value = cloneForSerialization(clonedDescriptor.value, references)\n }\n return clonedDescriptor\n}\n\nfunction copyOwnProperties(\n source: object,\n target: object,\n references: WeakMap<object, any>,\n shouldCopy: (key: PropertyKey) => boolean = () => true,\n) {\n for (const key of Reflect.ownKeys(source)) {\n if (!shouldCopy(key)) continue\n const descriptor = Object.getOwnPropertyDescriptor(source, key)\n if (!descriptor) continue\n Object.defineProperty(target, key, clonePropertyDescriptor(descriptor, references))\n }\n}\n\nfunction preserveCustomToJSON(source: object, target: object, references: WeakMap<object, any>) {\n const toJSON = (source as any).toJSON\n if (typeof toJSON !== 'function') return\n\n Object.defineProperty(target, 'toJSON', {\n configurable: true,\n enumerable: false,\n writable: true,\n value(key: string) {\n return cloneForSerialization(toJSON.call(source, key), references)\n },\n })\n}\n\nfunction cloneArrayBufferView<T extends ArrayBufferView>(\n value: T,\n references: WeakMap<object, any>,\n): T {\n const sourceBuffer = value.buffer\n let clonedBuffer = references.get(sourceBuffer) as ArrayBufferLike | undefined\n const shouldCopyBufferProperties = !clonedBuffer\n\n if (!clonedBuffer) {\n clonedBuffer = sourceBuffer.slice(0)\n references.set(sourceBuffer, clonedBuffer)\n }\n\n const clone =\n value instanceof DataView\n ? new DataView(clonedBuffer, value.byteOffset, value.byteLength)\n : new (value.constructor as any)(clonedBuffer, value.byteOffset, (value as any).length)\n\n references.set(value, clone)\n if (shouldCopyBufferProperties) {\n copyOwnProperties(sourceBuffer, clonedBuffer, references)\n }\n\n // Numeric indexes already exist on typed arrays. Preserve any additional own\n // properties because serialize-javascript includes them in the wire payload.\n copyOwnProperties(value, clone, references, key => {\n if (typeof key !== 'string') return true\n const index = Number(key)\n return !(\n Number.isInteger(index) &&\n index >= 0 &&\n index < (value as any).length &&\n String(index) === key\n )\n })\n return clone as T\n}\n\nfunction cloneForSerialization<T>(value: T, references = new WeakMap<object, any>()): T {\n if (value === null || (typeof value !== 'object' && typeof value !== 'function')) return value\n if (typeof value === 'function') return value\n\n const source = value as object\n if (references.has(source)) return references.get(source)\n\n if (value instanceof Date) {\n const clone = new Date(value.getTime())\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n return clone as T\n }\n\n if (value instanceof RegExp) {\n const clone = new RegExp(value.source, value.flags)\n clone.lastIndex = value.lastIndex\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n return clone as T\n }\n\n if (value instanceof Map) {\n const clone = new Map()\n references.set(source, clone)\n for (const [key, entry] of value) {\n Map.prototype.set.call(\n clone,\n cloneForSerialization(key, references),\n cloneForSerialization(entry, references),\n )\n }\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n return clone as T\n }\n\n if (value instanceof Set) {\n const clone = new Set()\n references.set(source, clone)\n for (const entry of value) {\n Set.prototype.add.call(clone, cloneForSerialization(entry, references))\n }\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n return clone as T\n }\n\n if (value instanceof URL) {\n const clone = new URL(value.toString())\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n return clone as T\n }\n\n if (Buffer.isBuffer(value)) {\n const clone = Buffer.from(value)\n references.set(source, clone)\n return clone as T\n }\n\n if (ArrayBuffer.isView(value)) {\n return cloneArrayBufferView(value, references) as T\n }\n\n if (\n value instanceof ArrayBuffer ||\n (typeof SharedArrayBuffer !== 'undefined' && value instanceof SharedArrayBuffer)\n ) {\n const clone = value.slice(0)\n references.set(source, clone)\n copyOwnProperties(value, clone, references)\n return clone as T\n }\n\n if (Array.isArray(value)) {\n const clone = new Array(value.length)\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n copyOwnProperties(value, clone, references, key => key !== 'length')\n return clone as T\n }\n\n const clone = Object.create(Object.getPrototypeOf(value))\n references.set(source, clone)\n copyOwnProperties(value, clone, references)\n preserveCustomToJSON(source, clone, references)\n return clone\n}\n\nexport default function (data: any): string {\n const serialized = serialize(cloneForSerialization(data), {ignoreFunction: true})\n return serialized\n}\n","import {AsyncLocalStorage} from 'node:async_hooks'\nimport {randomUUID} from 'node:crypto'\nimport {type EchoesErrorInfo, EchoesUserError, EchoesValidationError} from './errors'\n\nexport interface EchoesLogger {\n debug(message: string, metadata?: unknown): void\n info(message: string, metadata?: unknown): void\n warn(message: string, metadata?: unknown): void\n error(message: string, metadata?: unknown): void\n}\n\nexport interface EchoesSchemaAdapter {\n clean<T = unknown>(schema: unknown, value: unknown): T | Promise<T>\n parse<T = unknown>(schema: unknown, value: unknown): T | Promise<T>\n}\n\nexport interface EchoesExecutionContext {\n contextId?: string\n controllerType: 'echo'\n echoName: string\n params?: unknown\n}\n\nexport interface EchoesRequestHandlerDefinition {\n method: 'post'\n path: string\n bodyLimit: string\n handle(body: unknown): Promise<unknown>\n}\n\nexport type EchoesRequestHandlerRegistrar = (\n definition: EchoesRequestHandlerDefinition,\n) => void | Promise<void>\n\nexport interface EchoesRuntimeAdapter {\n schema?: EchoesSchemaAdapter\n logger?: EchoesLogger\n registerRequestHandler?: EchoesRequestHandlerRegistrar\n decorateService?(target: Function, context: ClassDecoratorContext): void\n getInstance?<T extends object>(target: new (...args: any[]) => T): T\n runWithContext?<T>(context: EchoesExecutionContext, callback: () => T | Promise<T>): Promise<T>\n createValidationError?(info: EchoesErrorInfo): Error\n createUserError?(info: EchoesErrorInfo): Error\n}\n\nconst defaultLogger: EchoesLogger = {\n debug: (message, metadata) =>\n metadata === undefined ? console.debug(message) : console.debug(message, metadata),\n info: (message, metadata) =>\n metadata === undefined ? console.info(message) : console.info(message, metadata),\n warn: (message, metadata) =>\n metadata === undefined ? console.warn(message) : console.warn(message, metadata),\n error: (message, metadata) =>\n metadata === undefined ? console.error(message) : console.error(message, metadata),\n}\n\nlet runtime: EchoesRuntimeAdapter = {}\nconst contextStorage = new AsyncLocalStorage<EchoesExecutionContext & {contextId: string}>()\n\n/**\n * Installs framework integrations without coupling Echoes to a framework.\n * The returned function restores the previous adapter, which is useful in tests.\n */\nexport function configureEchoesRuntime(adapter: EchoesRuntimeAdapter): () => void {\n const previous = runtime\n runtime = {...runtime, ...adapter}\n return () => {\n runtime = previous\n }\n}\n\nexport function getEchoesRuntime(): EchoesRuntimeAdapter {\n return runtime\n}\n\nexport function getEchoesLogger(): EchoesLogger {\n return runtime.logger || defaultLogger\n}\n\nexport function getEchoesContext(): (EchoesExecutionContext & {contextId: string}) | undefined {\n return contextStorage.getStore()\n}\n\nexport async function runWithEchoesContext<T>(\n context: EchoesExecutionContext,\n callback: () => T | Promise<T>,\n): Promise<T> {\n const contextWithId = {contextId: context.contextId || randomUUID(), ...context}\n return await contextStorage.run(contextWithId, async () => {\n if (runtime.runWithContext) {\n return await runtime.runWithContext(contextWithId, callback)\n }\n return await callback()\n })\n}\n\nfunction isSimpleSchemaLike(schema: unknown): schema is {\n clean(value: unknown, options?: Record<string, unknown>): unknown\n validate(value: unknown): unknown\n} {\n return (\n !!schema &&\n typeof schema === 'object' &&\n typeof (schema as any).clean === 'function' &&\n typeof (schema as any).validate === 'function'\n )\n}\n\nfunction cloneValue<T>(value: T): T {\n if (value === null || typeof value !== 'object') return value\n if (value instanceof Date) return new Date(value.getTime()) as T\n if (Buffer.isBuffer(value)) return Buffer.from(value) as T\n if (Array.isArray(value)) return value.map(cloneValue) as T\n const prototype = Object.getPrototypeOf(value)\n if (prototype !== Object.prototype && prototype !== null) return value\n\n const result: Record<string, unknown> = {}\n for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n result[key] = cloneValue(child)\n }\n return result as T\n}\n\nasync function cleanSimpleSchema<T>(\n schema: {\n clean(value: unknown, options?: Record<string, unknown>): unknown\n validate(value: unknown): unknown\n },\n value: unknown,\n): Promise<T> {\n const cloned = cloneValue(value)\n return (await schema.clean(cloned, {mutate: false})) as T\n}\n\nexport async function cleanEchoesSchema<T>(schema: unknown, value: unknown): Promise<T> {\n if (isSimpleSchemaLike(schema)) {\n return await cleanSimpleSchema<T>(schema, value)\n }\n if (runtime.schema) {\n return await runtime.schema.clean<T>(schema, value)\n }\n throw new Error(\n 'Echoes received a schema it cannot execute. Use a SimpleSchema-compatible object or configure an Echoes schema adapter.',\n )\n}\n\nexport async function parseEchoesSchema<T>(schema: unknown, value: unknown): Promise<T> {\n if (isSimpleSchemaLike(schema)) {\n const cleaned = await cleanSimpleSchema<T>(schema, value)\n await schema.validate(cleaned)\n return cleaned\n }\n if (runtime.schema) {\n return await runtime.schema.parse<T>(schema, value)\n }\n throw new Error(\n 'Echoes received a schema it cannot execute. Use a SimpleSchema-compatible object or configure an Echoes schema adapter.',\n )\n}\n\nexport function createEchoesValidationError(info: EchoesErrorInfo): Error {\n return runtime.createValidationError\n ? runtime.createValidationError(info)\n : new EchoesValidationError(info.validationErrors || {}, info.labels)\n}\n\nexport function createEchoesUserError(info: EchoesErrorInfo): Error {\n return runtime.createUserError\n ? runtime.createUserError(info)\n : new EchoesUserError(info.error, info.message, info.extra)\n}\n","export interface EchoesErrorInfo {\n error: string\n message: string\n extra?: any\n validationErrors?: Record<string, string>\n labels?: Record<string, string>\n}\n\nexport class EchoesUserError extends Error {\n readonly isEchoesError = true\n readonly isOrionError = true\n readonly isUserError = true\n readonly code: string\n readonly extra: any\n\n constructor(code: string, message?: string, extra?: any) {\n if (!message) {\n message = code\n code = 'error'\n }\n super(message)\n this.name = 'EchoesUserError'\n this.code = code\n this.extra = extra\n }\n\n getInfo(): EchoesErrorInfo {\n return {error: this.code, message: this.message, extra: this.extra}\n }\n}\n\nexport class EchoesValidationError extends Error {\n readonly isEchoesError = true\n readonly isOrionError = true\n readonly isValidationError = true\n readonly code = 'validationError'\n readonly validationErrors: Record<string, string>\n readonly labels: Record<string, string>\n\n constructor(validationErrors: Record<string, string>, labels: Record<string, string> = {}) {\n const printableErrors = Object.entries(validationErrors)\n .map(([key, value]) => `${key}: ${value}`)\n .join(', ')\n super(`Validation Error: {${printableErrors}}`)\n this.name = 'EchoesValidationError'\n this.validationErrors = validationErrors\n this.labels = Object.fromEntries(\n Object.keys(validationErrors)\n .filter(key => labels[key])\n .map(key => [key, labels[key]]),\n )\n }\n\n getInfo(): EchoesErrorInfo {\n return {\n error: this.code,\n message: 'Validation Error',\n validationErrors: this.validationErrors,\n labels: this.labels,\n }\n }\n}\n","import {createHmac} from 'node:crypto'\nimport {getEchoesPassword} from './getPassword'\n\nexport default function (_body: any): string {\n const password = getEchoesPassword()\n // Keep the legacy Echoes wire signature. jssha treated the object passed by\n // Echoes as an empty TEXT payload, so changing this would break mixed versions.\n return createHmac('sha1', password || '')\n .update('')\n .digest('hex')\n}\n","import config from '../config'\nimport {getEchoesLogger} from '../runtime'\n\nexport function getEchoesPassword() {\n const secret = config?.requests?.key || process.env.echoes_password || process.env.ECHOES_PASSWORD\n if (!secret) {\n getEchoesLogger().warn(\n 'Warning: no secret key found for echoes requests. Init echoes or set the env var \"echoes_password\" or process.env.ECHOES_PASSWORD',\n )\n }\n\n return secret\n}\n","import config from '../config'\n\nexport default function (serviceName: string): string {\n if (serviceName.startsWith('http')) return serviceName\n\n const url = config?.requests?.services?.[serviceName]\n\n if (!url) {\n throw new Error(`No URL found in echoes config for service ${serviceName}`)\n }\n\n return url\n}\n","import http from 'node:http'\nimport https from 'node:https'\nimport {RequestMaker} from '../types'\n\nasync function executeWithRetries<T>(\n callback: () => Promise<T>,\n retries = 0,\n delayMs = 200,\n): Promise<T> {\n try {\n return await callback()\n } catch (error) {\n if (retries <= 0) throw error\n await new Promise(resolve => setTimeout(resolve, delayMs))\n return await executeWithRetries(callback, retries - 1, delayMs)\n }\n}\n\nasync function postJSON(\n urlValue: string,\n data: unknown,\n timeout?: number,\n redirectsRemaining = 5,\n): Promise<{statusCode: number; data: object}> {\n const url = new URL(urlValue)\n const body = JSON.stringify(data)\n const transport = url.protocol === 'https:' ? https : http\n\n return await new Promise((resolve, reject) => {\n const request = transport.request(\n url,\n {\n method: 'POST',\n headers: {\n 'User-Agent': 'Orionjs-Echoes/1.1',\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(body),\n },\n },\n response => {\n const chunks: Buffer[] = []\n const statusCode = response.statusCode || 0\n if (statusCode >= 300 && statusCode < 400 && response.headers.location) {\n response.resume()\n if (redirectsRemaining <= 0) {\n reject(new Error('Echoes request exceeded the redirect limit'))\n return\n }\n resolve(\n postJSON(\n new URL(response.headers.location, url).toString(),\n data,\n timeout,\n redirectsRemaining - 1,\n ),\n )\n return\n }\n\n response.on('data', chunk => chunks.push(Buffer.from(chunk)))\n response.on('end', () => {\n try {\n const responseBody = Buffer.concat(chunks).toString('utf8')\n if (statusCode < 200 || statusCode >= 300) {\n reject(new Error(`Request failed with status code ${statusCode}`))\n return\n }\n resolve({\n statusCode,\n data: responseBody ? JSON.parse(responseBody) : {},\n })\n } catch (error) {\n reject(error)\n }\n })\n },\n )\n\n request.on('error', reject)\n if (timeout) {\n request.setTimeout(timeout, () => {\n request.destroy(new Error(`Echoes request timed out after ${timeout}ms`))\n })\n }\n request.end(body)\n })\n}\n\nexport const makeRequest: RequestMaker = async options => {\n return await executeWithRetries(\n () => postJSON(options.url, options.data, options.timeout),\n options.retries || 0,\n )\n}\n","import config from '../config'\nimport deserialize from '../echo/deserialize'\nimport serialize from '../publish/serialize'\nimport {createEchoesUserError, createEchoesValidationError} from '../runtime'\nimport type {\n MakeRequestParams,\n RequestHandlerResponse,\n RequestMaker,\n RequestOptions,\n} from '../types'\nimport getSignature from './getSignature'\nimport getURL from './getURL'\nimport {makeRequest} from './makeRequest'\n\nexport default async function request<TData = any, TParams = any>(\n options: RequestOptions<TParams>,\n): Promise<TData> {\n const {method, service, params} = options\n const serializedParams = serialize(params)\n const date = new Date()\n const body = {method, service, serializedParams, date}\n const signature = getSignature(body)\n\n try {\n const requestMaker: RequestMaker = config?.requests?.makeRequest || makeRequest\n const requestOptions: MakeRequestParams = {\n url: getURL(service),\n retries: options.retries,\n timeout: options.timeout,\n data: {\n body,\n signature,\n },\n }\n const result = await requestMaker(requestOptions)\n\n if (result.statusCode !== 200) {\n throw new Error(`Wrong status code ${result.statusCode}`)\n }\n\n const data: RequestHandlerResponse = result.data\n\n if (data.error) {\n const info = data.errorInfo\n if (info) {\n if (data.isValidationError) {\n throw createEchoesValidationError(info)\n }\n if (data.isUserError) {\n throw createEchoesUserError(info)\n }\n }\n\n throw new Error(`${data.error}`)\n }\n\n const response = deserialize(data.result)\n return response\n } catch (error) {\n const caught = error as any\n if (caught.isOrionError || caught.isEchoesError) throw caught\n\n throw new Error(`Echoes request network error calling ${service}/${method}: ${caught.message}`)\n }\n}\n","import {randomUUID} from 'node:crypto'\nimport deserialize from '../echo/deserialize'\nimport type {\n EventSubscriptionDefinition,\n EventTransport,\n EventTransportStartOptions,\n} from '../events/EventTransport'\nimport serialize from '../publish/serialize'\nimport {getEchoesLogger} from '../runtime'\nimport type {\n EchoesKafkaEventsConfig,\n EchoesKafkaMessagePayload,\n EchoesReceivedEvent,\n PublishOptions,\n} from '../types'\n\nconst HEARTBEAT_INTERVAL_SECONDS = 5\nconst CHECK_JOIN_CONSUMER_INTERVAL_SECONDS = 30\nconst DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY = 4\nconst DEFAULT_MEMBERS_TO_PARTITIONS_RATIO = 1\n\n/**\n * Kafka event transport. It retains the existing consumer-group and retry behavior.\n */\nclass KafkaManager implements EventTransport {\n readonly name = 'kafka' as const\n\n private kafka?: any\n private readonly options: EchoesKafkaEventsConfig\n private producer?: any\n private consumer?: any\n private topics: string[] = []\n private subscriptions = new Map<string, EventSubscriptionDefinition>()\n private onEvent?: (event: EchoesReceivedEvent) => Promise<void>\n private consumerStarted = false\n private producerConnected = false\n private interval?: NodeJS.Timeout\n\n constructor(options: EchoesKafkaEventsConfig) {\n this.options = options\n }\n\n async start(options: EventTransportStartOptions) {\n let kafkaModule: typeof import('kafkajs')\n try {\n kafkaModule = await import('kafkajs')\n } catch (error) {\n const wrapped = new Error(\n 'Echoes Kafka transport requires kafkajs to be installed in the application',\n )\n ;(wrapped as any).cause = error\n throw wrapped\n }\n this.kafka = new kafkaModule.Kafka(this.options.client as any)\n\n this.onEvent = options.onEvent\n this.subscriptions = new Map(\n options.subscriptions.map(subscription => [subscription.topic, subscription]),\n )\n this.topics = options.subscriptions.map(subscription => subscription.topic)\n\n // Kafka retries and DLQ publishing use a producer even on consumer-only servers.\n if (options.publish || options.consume) {\n this.producer = this.kafka.producer(this.options.producer)\n await this.producer.connect()\n this.producerConnected = true\n }\n\n if (!options.consume || this.topics.length === 0) return\n if (!this.options.consumer?.groupId) {\n throw new Error('Echoes Kafka consumers require consumer.groupId')\n }\n\n this.consumer = this.kafka.consumer(this.options.consumer)\n this.consumerStarted = await this.conditionalStart()\n if (this.consumerStarted) return\n\n getEchoesLogger().info('Echoes: Delaying consumer group join, waiting for conditions to be met')\n this.interval = setInterval(async () => {\n this.consumerStarted = await this.conditionalStart()\n if (this.consumerStarted) clearInterval(this.interval)\n }, CHECK_JOIN_CONSUMER_INTERVAL_SECONDS * 1000)\n }\n\n async publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!this.producer || !this.producerConnected) {\n throw new Error('Echoes Kafka producer is not connected')\n }\n\n return await this.producer.send({\n acks: options.acks,\n timeout: options.timeout,\n topic: options.topic,\n messages: [\n {\n value: serialize({params: options.params}),\n headers: {\n 'echoes-event-id': randomUUID(),\n },\n },\n ],\n })\n }\n\n async close() {\n const logger = getEchoesLogger()\n logger.warn('Echoes: Stopping Kafka transport')\n if (this.interval) clearInterval(this.interval)\n await Promise.all([\n this.consumer?.disconnect(),\n this.producerConnected ? this.producer?.disconnect() : undefined,\n ])\n this.consumerStarted = false\n this.producerConnected = false\n }\n\n private async checkJoinConsumerGroupConditions(): Promise<boolean> {\n const logger = getEchoesLogger()\n const admin = this.kafka.admin()\n try {\n await admin.connect()\n const groupId = this.options.consumer.groupId\n const groupDescriptions = await admin.describeGroups([groupId])\n const group = groupDescriptions.groups[0]\n if (group.state === 'Empty') {\n logger.info(`Echoes: Consumer group ${groupId} is empty, joining`)\n return true\n }\n const topicsMetadata = await admin.fetchTopicMetadata({topics: this.topics})\n const totalPartitions = topicsMetadata.topics.reduce(\n (acc, topic) => acc + topic.partitions.length,\n 0,\n )\n logger.info(\n `Echoes: Consumer group ${groupId} has ${group.members.length} members and ${totalPartitions} partitions`,\n )\n const partitionsRatio =\n this.options.membersToPartitionsRatio || DEFAULT_MEMBERS_TO_PARTITIONS_RATIO\n const partitionsThreshold = Math.ceil(totalPartitions * partitionsRatio)\n if (partitionsThreshold > group.members.length) {\n logger.info(\n `Echoes: Consumer group ${groupId} has room for more members ${group.members.length}/${partitionsThreshold}, joining`,\n )\n return true\n }\n return false\n } catch (error) {\n logger.error('Echoes: Error checking consumer group conditions, join', {error})\n return true\n } finally {\n await admin.disconnect().catch(error => {\n logger.error('Echoes: Error disconnecting admin client', {error})\n })\n }\n }\n\n private async joinConsumerGroup() {\n await this.consumer.connect()\n await this.consumer.subscribe({topics: this.topics})\n await this.consumer.run({\n partitionsConsumedConcurrently:\n this.options.partitionsConsumedConcurrently || DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY,\n eachMessage: params => this.handleMessage(params),\n })\n }\n\n private async conditionalStart(): Promise<boolean> {\n if (await this.checkJoinConsumerGroupConditions()) {\n await this.joinConsumerGroup()\n return true\n }\n return false\n }\n\n private async handleMessage(params: EchoesKafkaMessagePayload) {\n const logger = getEchoesLogger()\n const subscription = this.subscriptions.get(params.topic)\n if (!subscription) {\n logger.warn(`Echoes: Received a message for an unknown topic: ${params.topic}, ignoring it`)\n return\n }\n\n let intervalsCount = 0\n const heartbeatInterval = setInterval(async () => {\n await params.heartbeat().catch(error => {\n logger.warn(`Echoes: Error sending heartbeat: ${error.message}`)\n })\n intervalsCount++\n if ((intervalsCount * HEARTBEAT_INTERVAL_SECONDS) % 30 === 0) {\n logger.warn(\n `Echoes: Event is taking too long to process: ${params.topic} ${intervalsCount * HEARTBEAT_INTERVAL_SECONDS}s`,\n )\n }\n }, HEARTBEAT_INTERVAL_SECONDS * 1000)\n\n try {\n const event = this.createReceivedEvent(params)\n await this.onEvent(event)\n } catch (error) {\n try {\n await this.handleRetries(subscription, params, error as Error)\n } catch (retryError) {\n logger.error('Echoes: error processing a message', {\n error: retryError,\n topic: params.topic,\n })\n throw retryError\n }\n } finally {\n clearInterval(heartbeatInterval)\n }\n }\n\n private createReceivedEvent(params: EchoesKafkaMessagePayload): EchoesReceivedEvent {\n const {message, topic, partition} = params\n if (!message.value) {\n throw new Error(`Echoes received an empty Kafka message for ${topic}`)\n }\n const data = deserialize(message.value.toString())\n const retries = Number.parseInt(message.headers?.retries?.toString() || '0', 10)\n const timestamp = Number.parseInt(message.timestamp || '', 10)\n\n return {\n id:\n message.headers?.['echoes-event-id']?.toString() ||\n `kafka:${topic}:${partition}:${message.offset}`,\n topic,\n data,\n transport: 'kafka',\n headers: message.headers,\n createdAt: Number.isFinite(timestamp) ? new Date(timestamp) : new Date(),\n attempt: retries + 1,\n context: params,\n }\n }\n\n private async handleRetries(\n subscription: EventSubscriptionDefinition,\n params: EchoesKafkaMessagePayload,\n error: Error,\n ) {\n const logger = getEchoesLogger()\n const {message, topic} = params\n const retries = Number.parseInt(message?.headers?.retries?.toString() || '0', 10)\n if (\n subscription.attemptsBeforeDeadLetter === undefined ||\n subscription.attemptsBeforeDeadLetter === null\n ) {\n throw error\n }\n const maxRetries = subscription.attemptsBeforeDeadLetter || 0\n const exceededMaxRetries = retries >= maxRetries\n const nextTopic = exceededMaxRetries ? `DLQ-${topic}` : topic\n if (!message.value) throw error\n await this.producer.send({\n topic: nextTopic,\n messages: [\n {\n value: message.value.toString(),\n headers: {\n ...message.headers,\n retries: String(retries + 1),\n error: error.message,\n },\n },\n ],\n })\n\n if (exceededMaxRetries) {\n logger.error(\n 'Echoes: a message has reached the maximum number of retries, sending it to DLQ',\n {topic: nextTopic},\n )\n } else {\n logger.warn('Echoes: a retryable message failed', {error, topic: nextTopic})\n }\n }\n}\n\nexport default KafkaManager\n","import {getEchoesLogger} from '../runtime'\nimport type {\n EchoesEventTransportName,\n EchoesMap,\n EchoesReceivedEvent,\n PublishOptions,\n} from '../types'\nimport type {EventSubscriptionDefinition, EventTransport} from './EventTransport'\n\nexport interface EventBusOptions {\n echoes: EchoesMap\n transports: Partial<Record<EchoesEventTransportName, EventTransport>>\n consumeFrom: EchoesEventTransportName[]\n publishTo?: EchoesEventTransportName\n}\n\nexport default class EventBus {\n private readonly echoes: EchoesMap\n private readonly transports: Partial<Record<EchoesEventTransportName, EventTransport>>\n private readonly consumeFrom: EchoesEventTransportName[]\n private readonly publishTo?: EchoesEventTransportName\n private readonly startedTransports: EventTransport[] = []\n private started = false\n private closed = false\n\n constructor(options: EventBusOptions) {\n this.echoes = options.echoes\n this.transports = options.transports\n this.consumeFrom = [...new Set(options.consumeFrom)]\n this.publishTo = options.publishTo\n }\n\n async start() {\n if (this.started) return\n\n const selected = new Set(this.consumeFrom)\n if (this.publishTo) selected.add(this.publishTo)\n\n for (const name of selected) {\n if (!this.transports[name]) {\n throw new Error(`Echoes event transport \"${name}\" is selected but not configured`)\n }\n }\n\n const subscriptions: EventSubscriptionDefinition[] = Object.entries(this.echoes)\n .filter(([, echo]) => echo.type === 'event')\n .map(([topic, echo]) => ({\n topic,\n attemptsBeforeDeadLetter: echo.attemptsBeforeDeadLetter,\n ordered: echo.ordered,\n configVersion: echo.configVersion,\n }))\n\n try {\n for (const name of selected) {\n const transport = this.transports[name]\n this.startedTransports.push(transport)\n await transport.start({\n consume: this.consumeFrom.includes(name),\n publish: this.publishTo === name,\n subscriptions,\n onEvent: event => this.handleEvent(event),\n })\n }\n this.started = true\n } catch (error) {\n await this.close().catch(() => undefined)\n throw error\n }\n }\n\n async publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!this.started) {\n throw new Error('You must initialize echoes configuration to use publish')\n }\n if (!this.publishTo) {\n throw new Error('Echoes does not have a publish transport configured')\n }\n\n return await this.transports[this.publishTo].publish(options)\n }\n\n async close() {\n if (this.closed) return\n this.closed = true\n await Promise.all(this.startedTransports.map(transport => transport.close()))\n }\n\n private async handleEvent(event: EchoesReceivedEvent) {\n const logger = getEchoesLogger()\n const echo = this.echoes[event.topic]\n if (!echo || echo.type !== 'event') {\n logger.warn(`Echoes: Received a message for an unknown topic: ${event.topic}, ignoring it`)\n return\n }\n\n // Preserve the exact legacy Kafka entrypoint for custom EchoType implementations.\n if (event.transport === 'kafka' && event.context) {\n await echo.onMessage(event.context as any)\n return\n }\n\n if (echo.onEvent) {\n await echo.onEvent(event)\n return\n }\n\n await echo.resolve(event.data.params, {\n ...(event.context || {}),\n transport: event.transport,\n eventId: event.id,\n topic: event.topic,\n headers: event.headers,\n createdAt: event.createdAt,\n attempt: event.attempt,\n data: event.data,\n })\n }\n}\n","import type {\n EchoesEventPayload,\n EchoesPulseEventsConfig,\n EchoesReceivedEvent,\n PublishOptions,\n} from '../types'\nimport type {EventTransport, EventTransportStartOptions} from './EventTransport'\n\ntype PulseSubscribeOptions = NonNullable<EchoesPulseEventsConfig['subscription']>\n\ninterface PulseReceivedEvent {\n id: string\n topic: string\n data: EchoesEventPayload\n headers?: Record<string, unknown>\n createdAt: Date\n attempt: number\n}\n\nexport default class PulseManager implements EventTransport {\n readonly name = 'pulse' as const\n\n private readonly options: EchoesPulseEventsConfig\n private pulse?: any\n private subscriptions: Array<{unsubscribe(): Promise<void>}> = []\n\n constructor(options: EchoesPulseEventsConfig) {\n this.options = options\n }\n\n async start(options: EventTransportStartOptions) {\n let pulseModule: any\n try {\n pulseModule = await import('@orion-js/pulse')\n } catch (error) {\n const wrapped = new Error(\n 'Echoes Pulse transport requires @orion-js/pulse to be installed in the application',\n )\n ;(wrapped as any).cause = error\n throw wrapped\n }\n\n const {subscription, ...connectOptions} = this.options\n this.pulse = pulseModule.connect(connectOptions)\n await this.pulse.awaitConnection()\n\n if (!options.consume) return\n\n this.subscriptions = await Promise.all(\n options.subscriptions.map(definition =>\n this.pulse.subscribe(\n definition.topic,\n event => options.onEvent(this.createReceivedEvent(event)),\n this.getSubscribeOptions(subscription, definition),\n ),\n ),\n )\n }\n\n async publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!this.pulse) {\n throw new Error('Echoes Pulse client is not connected')\n }\n\n return await this.pulse.publish({\n topic: options.topic,\n data: {params: options.params},\n })\n }\n\n async close() {\n await this.pulse?.close()\n this.subscriptions = []\n }\n\n private getSubscribeOptions(\n defaults: PulseSubscribeOptions = {},\n definition: EventTransportStartOptions['subscriptions'][number],\n ): PulseSubscribeOptions {\n return {\n ...defaults,\n ...(definition.ordered === undefined ? {} : {ordered: definition.ordered}),\n ...(definition.configVersion === undefined ? {} : {configVersion: definition.configVersion}),\n ...(definition.attemptsBeforeDeadLetter === undefined\n ? {}\n : {maxRetries: definition.attemptsBeforeDeadLetter}),\n }\n }\n\n private createReceivedEvent(event: PulseReceivedEvent): EchoesReceivedEvent {\n return {\n id: event.id,\n topic: event.topic,\n data: event.data,\n transport: 'pulse',\n headers: event.headers,\n createdAt: event.createdAt,\n attempt: event.attempt,\n context: event,\n }\n }\n}\n","import KafkaManager from '../startService/KafkaManager'\nimport type {\n EchoesEventTransportName,\n EchoesKafkaEventsConfig,\n EchoesOptions,\n EchoesPulseEventsConfig,\n} from '../types'\nimport EventBus from './EventBus'\nimport type {EventTransport} from './EventTransport'\nimport PulseManager from './PulseManager'\n\nexport interface ResolvedEventsConfig {\n kafka?: EchoesKafkaEventsConfig\n pulse?: EchoesPulseEventsConfig\n consumeFrom: EchoesEventTransportName[]\n publishTo?: EchoesEventTransportName\n}\n\nexport function resolveEventsConfig(options: EchoesOptions): ResolvedEventsConfig | undefined {\n const legacyKafka = options.client\n ? {\n client: options.client,\n producer: options.producer,\n consumer: options.consumer,\n readTopicsFromBeginning: options.readTopicsFromBeginning,\n partitionsConsumedConcurrently: options.partitionsConsumedConcurrently,\n membersToPartitionsRatio: options.membersToPartitionsRatio,\n }\n : undefined\n\n const kafka = options.events?.kafka || legacyKafka\n const pulse = options.events?.pulse\n\n if (!kafka && !pulse && !options.events) return undefined\n\n const defaultTransport: EchoesEventTransportName | undefined = kafka\n ? 'kafka'\n : pulse\n ? 'pulse'\n : undefined\n\n return {\n kafka,\n pulse,\n consumeFrom: options.events?.consumeFrom || (defaultTransport ? [defaultTransport] : []),\n publishTo: options.events?.publishTo || defaultTransport,\n }\n}\n\nexport default function createEventBus(options: EchoesOptions) {\n const resolved = resolveEventsConfig(options)\n if (!resolved) return undefined\n\n const transports: Partial<Record<EchoesEventTransportName, EventTransport>> = {}\n if (resolved.kafka) transports.kafka = new KafkaManager(resolved.kafka)\n if (resolved.pulse) transports.pulse = new PulseManager(resolved.pulse)\n\n return new EventBus({\n echoes: options.echoes,\n transports,\n consumeFrom: resolved.consumeFrom,\n publishTo: resolved.publishTo,\n })\n}\n","import getSignature from '../request/getSignature'\n\nexport default function (body: any, signature: string) {\n const generatedSignature = getSignature(body)\n if (generatedSignature !== signature) {\n throw new Error('Echoes invalid signature')\n }\n}\n","import config from '../config'\n\nexport default function (method: string) {\n const echo = config.echoes[method]\n\n if (!echo) {\n throw new Error(`Echo named ${method} not found in this service`)\n }\n\n if (echo.type !== 'request') {\n throw new Error(`Echo named ${method} is not of type request`)\n }\n\n return echo\n}\n","import serialize from '../publish/serialize'\nimport {getEchoesLogger} from '../runtime'\nimport {EchoesOptions} from '../types'\nimport checkSignature from './checkSignature'\nimport getEcho from './getEcho'\n\nexport default (options: EchoesOptions) =>\n ({\n method: 'post',\n path: options.requests.handlerPath || '/echoes-services',\n bodyLimit: '10mb',\n async handle(requestBody: any) {\n try {\n const {body, signature} = requestBody\n\n checkSignature(body, signature)\n\n const {method, serializedParams} = body\n\n const echo = getEcho(method)\n const result = await echo.onRequest(serializedParams)\n\n return {result: serialize(result)}\n } catch (error) {\n const caught = error as any\n if (!caught.getInfo) {\n getEchoesLogger().error('Error at echo requests handler:', {error: caught})\n }\n\n return {\n error: caught.message,\n errorInfo: caught.getInfo ? caught.getInfo() : null,\n isValidationError: !!caught.isValidationError,\n isUserError: !!caught.isUserError,\n }\n }\n },\n }) as const\n","import config from '../config'\nimport createEventBus from '../events/createEventBus'\nimport EventBus from '../events/EventBus'\nimport requestsHandler from '../requestsHandler'\nimport {getEchoesLogger, getEchoesRuntime} from '../runtime'\nimport {EchoesOptions} from '../types'\n\nlet eventBus: EventBus = null\n\nexport default async function startService(options: EchoesOptions) {\n config.echoes = options.echoes\n\n if (options.requests) {\n config.requests = options.requests\n const registerHandler =\n options.requests.registerHandler || getEchoesRuntime().registerRequestHandler\n if (!registerHandler) {\n throw new Error(\n 'Echoes requests require requests.registerHandler in standalone servers. Orion applications can import @orion-js/echoes-orion once during startup.',\n )\n }\n await registerHandler(requestsHandler(options))\n }\n\n const nextEventBus = createEventBus(options)\n if (nextEventBus) {\n await nextEventBus.start()\n eventBus = nextEventBus\n config.eventBus = eventBus\n }\n}\n\nexport async function stopService() {\n if (eventBus) {\n const logger = getEchoesLogger()\n logger.info('Stopping Echoes...')\n await eventBus.close()\n eventBus = null\n config.eventBus = undefined\n logger.info('Echoes stopped')\n }\n}\n","import {cleanEchoesSchema, parseEchoesSchema} from '../runtime'\nimport type {EchoesSchema, InferEchoesSchema} from '../schema'\nimport {\n EchoConfig,\n EchoEventConfig,\n EchoesKafkaMessagePayload,\n EchoesReceivedEvent,\n EchoRequestConfig,\n EchoType,\n} from '../types'\nimport deserialize from './deserialize'\n\n/**\n * @deprecated Use createEchoRequest and createEchoEvent instead\n */\nconst echo = function createNewEcho<\n TParamsSchema extends EchoesSchema,\n TReturnsSchema extends EchoesSchema,\n TEchoType extends 'event' | 'request',\n>(\n options: EchoConfig<TParamsSchema, TReturnsSchema, TEchoType>,\n): EchoType<TParamsSchema, TReturnsSchema, TEchoType> {\n const resolve = async (params: InferEchoesSchema<TParamsSchema>, context: any) => {\n const cleaned = options.params\n ? await parseEchoesSchema<InferEchoesSchema<TParamsSchema>>(options.params, params)\n : (params ?? ({} as InferEchoesSchema<TParamsSchema>))\n\n const result = await options.resolve(cleaned, context)\n\n if (options.returns) {\n return await cleanEchoesSchema<InferEchoesSchema<TReturnsSchema>>(options.returns, result)\n }\n\n return result\n }\n\n const onEvent = async (event: EchoesReceivedEvent) => {\n const context = {\n ...(event.context || {}),\n transport: event.transport,\n eventId: event.id,\n topic: event.topic,\n headers: event.headers,\n createdAt: event.createdAt,\n attempt: event.attempt,\n data: event.data,\n }\n\n await resolve(event.data.params, context)\n }\n\n return {\n type: options.type,\n params: options.params,\n returns: options.returns,\n attemptsBeforeDeadLetter:\n options.type === 'event' ? options.attemptsBeforeDeadLetter : undefined,\n ordered:\n options.type === 'event'\n ? (options as EchoEventConfig<TParamsSchema, TReturnsSchema>).ordered\n : undefined,\n configVersion:\n options.type === 'event'\n ? (options as EchoEventConfig<TParamsSchema, TReturnsSchema>).configVersion\n : undefined,\n resolve,\n onEvent,\n onMessage: async (messageData: EchoesKafkaMessagePayload) => {\n const {message} = messageData\n if (!message.value) {\n throw new Error(`Echoes received an empty Kafka message for ${messageData.topic}`)\n }\n\n const data = deserialize(message.value.toString())\n const retries = Number.parseInt(message.headers?.retries?.toString() || '0', 10)\n const timestamp = Number(message.timestamp)\n const createdAt = Number.isFinite(timestamp) ? new Date(timestamp) : new Date()\n const eventId =\n message.headers?.['echoes-event-id']?.toString() ||\n `kafka:${messageData.topic}:${messageData.partition}:${message.offset}`\n\n await onEvent({\n id: eventId,\n topic: messageData.topic,\n data,\n transport: 'kafka',\n headers: message.headers,\n createdAt,\n attempt: retries + 1,\n context: messageData,\n })\n },\n onRequest: async (serializedParams: string) => {\n const context = {}\n const params = deserialize(serializedParams)\n\n return await resolve(params, context)\n },\n }\n}\n\nexport function createEchoRequest<\n TParamsSchema extends EchoesSchema,\n TReturnsSchema extends EchoesSchema,\n>(\n options: EchoRequestConfig<TParamsSchema, TReturnsSchema>,\n): EchoType<TParamsSchema, TReturnsSchema, 'request'> {\n return echo({...options, type: 'request'})\n}\nexport function createEchoEvent<\n TParamsSchema extends EchoesSchema,\n TReturnsSchema extends EchoesSchema,\n>(\n options: EchoEventConfig<TParamsSchema, TReturnsSchema>,\n): EchoType<TParamsSchema, TReturnsSchema, 'event'> {\n return echo({...options, type: 'event' as any})\n}\n\nexport {echo}\n","export type EchoesSchema = unknown\n\ntype InferFieldType<T> = T extends {__tsFieldType: infer U}\n ? U\n : T extends 'string' | 'ID' | 'email'\n ? string\n : T extends 'date'\n ? Date\n : T extends 'integer' | 'number'\n ? number\n : T extends 'boolean'\n ? boolean\n : T extends 'blackbox'\n ? Record<string, any>\n : T extends 'any'\n ? any\n : T extends String | StringConstructor\n ? string\n : T extends Number | NumberConstructor\n ? number\n : T extends Boolean | BooleanConstructor\n ? boolean\n : T extends Date | DateConstructor\n ? Date\n : T extends Array<infer U>\n ? InferFieldType<U>[]\n : T extends Record<string, any>\n ? InferObjectSchema<T>\n : T\n\ntype NodeIsOptional<T> = T extends {optional: true} ? true : false\n\ntype InferObjectSchema<T extends Record<string, any>> = {\n -readonly [K in keyof T as NodeIsOptional<T[K]> extends true ? never : K]: InferEchoesSchema<\n T[K] extends {type: infer U} ? U : T[K]\n >\n} & {\n -readonly [K in keyof T as NodeIsOptional<T[K]> extends true ? K : never]?: InferEchoesSchema<\n T[K] extends {type: infer U} ? U : T[K]\n >\n}\n\ntype IsObjectSchema<T> =\n T extends Record<string, any>\n ? keyof {\n [K in keyof T as T[K] extends {type: any} ? K : never]: T[K]\n } extends never\n ? false\n : true\n : false\n\ntype AbstractClass<T = any> = abstract new (...args: any[]) => T\n\n/**\n * Infers the value represented by Orion-style schema declarations without\n * requiring @orion-js/schema to be installed.\n */\nexport type InferEchoesSchema<T> = T extends {__echoesType: infer U}\n ? U\n : T extends {__tsFieldType: infer U}\n ? U\n : T extends {__isModel: true; type: infer U}\n ? U extends Record<string, any>\n ? InferObjectSchema<U>\n : InferFieldType<U>\n : T extends StringConstructor\n ? string\n : T extends NumberConstructor\n ? number\n : T extends BooleanConstructor\n ? boolean\n : T extends DateConstructor\n ? Date\n : T extends AbstractClass<infer U>\n ? U\n : IsObjectSchema<T> extends true\n ? T extends Record<string, any>\n ? InferObjectSchema<T>\n : never\n : InferFieldType<T>\n\n/**\n * Adds compile-time value information to a runtime schema such as SimpleSchema.\n * It returns the same object and has no runtime cost.\n */\nexport function typedEchoesSchema<TValue, TSchema extends object = object>(\n schema: TSchema,\n): TSchema & {readonly __echoesType: TValue} {\n return schema as TSchema & {readonly __echoesType: TValue}\n}\n","import {createEchoEvent, createEchoRequest} from '../echo'\nimport {getEchoesRuntime, runWithEchoesContext} from '../runtime'\nimport {EchoConfig, EchoesMap} from '../types'\n\nexport interface EchoesPropertyDescriptor extends Omit<PropertyDecorator, 'value'> {\n value?: EchoConfig<any, any>['resolve']\n}\n// Define metadata storage using WeakMaps\nconst serviceMetadata = new WeakMap<any, {_serviceType: string}>()\nconst echoesMetadata = new WeakMap<any, Record<string, any>>()\nconst echoEntriesByClass = new Map<Function, Record<string, (instance: any) => any>>()\nconst standaloneInstances = new WeakMap<Function, any>()\nlet pendingEchoEntries: Record<string, (instance: any) => any> = {}\n\nexport function Echoes() {\n return (target: any, context: ClassDecoratorContext<any>) => {\n getEchoesRuntime().decorateService?.(target, context)\n serviceMetadata.set(target, {_serviceType: 'echoes'})\n\n if (Object.keys(pendingEchoEntries).length > 0) {\n echoEntriesByClass.set(target, pendingEchoEntries)\n pendingEchoEntries = {}\n }\n }\n}\n\nexport function EchoEvent(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EchoEvent(\n options?: Omit<EchoConfig<any, any>, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EchoEvent(options = {}) {\n return (method: any, context: ClassMethodDecoratorContext | ClassFieldDecoratorContext) => {\n const propertyKey = String(context.name)\n\n if (context.kind === 'method') {\n pendingEchoEntries[propertyKey] = (instance: any) => {\n const originalResolve = instance[propertyKey].bind(instance)\n return createEchoEvent({\n ...options,\n resolve: async (params, contextData) => {\n return await runWithEchoesContext(\n {\n controllerType: 'echo',\n echoName: propertyKey,\n params,\n },\n async () => {\n return await originalResolve(params, contextData)\n },\n )\n },\n })\n }\n }\n\n if (context.kind === 'field') {\n pendingEchoEntries[propertyKey] = (instance: any) => instance[propertyKey]\n }\n\n return method\n }\n}\n\nexport function EchoRequest(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EchoRequest(\n options?: Omit<EchoConfig<any, any>, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EchoRequest(options = {}) {\n return (method: any, context: ClassMethodDecoratorContext | ClassFieldDecoratorContext) => {\n const propertyKey = String(context.name)\n\n if (context.kind === 'method') {\n pendingEchoEntries[propertyKey] = (instance: any) => {\n const originalResolve = instance[propertyKey].bind(instance)\n return createEchoRequest({\n ...options,\n resolve: async (params, contextData) => {\n return await runWithEchoesContext(\n {\n controllerType: 'echo',\n echoName: propertyKey,\n params,\n },\n async () => {\n return await originalResolve(params, contextData)\n },\n )\n },\n })\n }\n }\n\n if (context.kind === 'field') {\n pendingEchoEntries[propertyKey] = (instance: any) => instance[propertyKey]\n }\n\n return method\n }\n}\n\nfunction initializeEchoesIfNeeded(instance: any) {\n if (echoesMetadata.has(instance)) return\n const entries = echoEntriesByClass.get(instance.constructor) || {}\n const echoes: Record<string, any> = {}\n for (const [key, setup] of Object.entries(entries)) {\n echoes[key] = setup(instance)\n }\n echoesMetadata.set(instance, echoes)\n}\n\nexport function getServiceEchoes(target: any): EchoesMap {\n let instance: any\n if (typeof target !== 'function') {\n instance = target\n } else if (getEchoesRuntime().getInstance) {\n instance = getEchoesRuntime().getInstance(target)\n } else {\n instance = standaloneInstances.get(target)\n if (!instance) {\n instance = new target()\n standaloneInstances.set(target, instance)\n }\n }\n\n if (!serviceMetadata.has(instance.constructor)) {\n throw new Error('You must pass a class decorated with @Echoes to getServiceEchoes')\n }\n\n const instanceMetadata = serviceMetadata.get(instance.constructor)\n if (instanceMetadata._serviceType !== 'echoes') {\n throw new Error('You must pass a class decorated with @Echoes to getServiceEchoes')\n }\n\n initializeEchoesIfNeeded(instance)\n\n const echoesMap = echoesMetadata.get(instance) || {}\n\n return echoesMap\n}\n"],"mappings":"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","names":["clone","serialize","import_node_crypto","https","http","request","import_node_crypto","echo","echo","echo"]}
package/dist/index.js CHANGED
@@ -698,7 +698,9 @@ var EventBus = class {
698
698
  }
699
699
  const subscriptions = Object.entries(this.echoes).filter(([, echo2]) => echo2.type === "event").map(([topic, echo2]) => ({
700
700
  topic,
701
- attemptsBeforeDeadLetter: echo2.attemptsBeforeDeadLetter
701
+ attemptsBeforeDeadLetter: echo2.attemptsBeforeDeadLetter,
702
+ ordered: echo2.ordered,
703
+ configVersion: echo2.configVersion
702
704
  }));
703
705
  try {
704
706
  for (const name of selected) {
@@ -788,7 +790,7 @@ var PulseManager = class {
788
790
  (definition) => this.pulse.subscribe(
789
791
  definition.topic,
790
792
  (event) => options.onEvent(this.createReceivedEvent(event)),
791
- this.getSubscribeOptions(subscription, definition.attemptsBeforeDeadLetter)
793
+ this.getSubscribeOptions(subscription, definition)
792
794
  )
793
795
  )
794
796
  );
@@ -807,10 +809,12 @@ var PulseManager = class {
807
809
  await ((_a = this.pulse) == null ? void 0 : _a.close());
808
810
  this.subscriptions = [];
809
811
  }
810
- getSubscribeOptions(defaults = {}, attemptsBeforeDeadLetter) {
812
+ getSubscribeOptions(defaults = {}, definition) {
811
813
  return {
812
814
  ...defaults,
813
- ...attemptsBeforeDeadLetter === void 0 ? {} : { maxRetries: attemptsBeforeDeadLetter }
815
+ ...definition.ordered === void 0 ? {} : { ordered: definition.ordered },
816
+ ...definition.configVersion === void 0 ? {} : { configVersion: definition.configVersion },
817
+ ...definition.attemptsBeforeDeadLetter === void 0 ? {} : { maxRetries: definition.attemptsBeforeDeadLetter }
814
818
  };
815
819
  }
816
820
  createReceivedEvent(event) {
@@ -971,6 +975,8 @@ var echo = function createNewEcho(options) {
971
975
  params: options.params,
972
976
  returns: options.returns,
973
977
  attemptsBeforeDeadLetter: options.type === "event" ? options.attemptsBeforeDeadLetter : void 0,
978
+ ordered: options.type === "event" ? options.ordered : void 0,
979
+ configVersion: options.type === "event" ? options.configVersion : void 0,
974
980
  resolve,
975
981
  onEvent,
976
982
  onMessage: async (messageData) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/publish/index.ts","../src/echo/deserialize.ts","../src/publish/serialize.ts","../src/runtime.ts","../src/errors.ts","../src/request/getSignature.ts","../src/request/getPassword.ts","../src/request/getURL.ts","../src/request/makeRequest.ts","../src/request/index.ts","../src/startService/KafkaManager.ts","../src/events/EventBus.ts","../src/events/PulseManager.ts","../src/events/createEventBus.ts","../src/requestsHandler/checkSignature.ts","../src/requestsHandler/getEcho.ts","../src/requestsHandler/index.ts","../src/startService/index.ts","../src/echo/index.ts","../src/schema.ts","../src/service/index.ts"],"sourcesContent":["import {EchoesConfigHandler} from './types'\n\nconst config: EchoesConfigHandler = {}\n\nexport default config\n","import config from '../config'\nimport {PublishOptions} from '../types'\n\n/**\n * Publish\n */\nexport default async function publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!config.eventBus) {\n throw new Error('You must initialize echoes configuration to use publish')\n }\n\n return await config.eventBus.publish(options)\n}\n","export default function (serializedJavascript: string): any {\n try {\n return eval('(' + serializedJavascript + ')')\n } catch (error) {\n throw new Error('Error deserializing echo message')\n }\n}\n","import serialize from 'serialize-javascript'\n\nfunction clonePropertyDescriptor(\n descriptor: PropertyDescriptor,\n references: WeakMap<object, any>,\n): PropertyDescriptor {\n // The copy only exists for serialization. Making properties configurable lets\n // ignoreFunction remove methods even when the caller passed a frozen object.\n const clonedDescriptor = {...descriptor, configurable: true}\n if ('value' in clonedDescriptor) {\n clonedDescriptor.value = cloneForSerialization(clonedDescriptor.value, references)\n }\n return clonedDescriptor\n}\n\nfunction copyOwnProperties(\n source: object,\n target: object,\n references: WeakMap<object, any>,\n shouldCopy: (key: PropertyKey) => boolean = () => true,\n) {\n for (const key of Reflect.ownKeys(source)) {\n if (!shouldCopy(key)) continue\n const descriptor = Object.getOwnPropertyDescriptor(source, key)\n if (!descriptor) continue\n Object.defineProperty(target, key, clonePropertyDescriptor(descriptor, references))\n }\n}\n\nfunction preserveCustomToJSON(source: object, target: object, references: WeakMap<object, any>) {\n const toJSON = (source as any).toJSON\n if (typeof toJSON !== 'function') return\n\n Object.defineProperty(target, 'toJSON', {\n configurable: true,\n enumerable: false,\n writable: true,\n value(key: string) {\n return cloneForSerialization(toJSON.call(source, key), references)\n },\n })\n}\n\nfunction cloneArrayBufferView<T extends ArrayBufferView>(\n value: T,\n references: WeakMap<object, any>,\n): T {\n const sourceBuffer = value.buffer\n let clonedBuffer = references.get(sourceBuffer) as ArrayBufferLike | undefined\n const shouldCopyBufferProperties = !clonedBuffer\n\n if (!clonedBuffer) {\n clonedBuffer = sourceBuffer.slice(0)\n references.set(sourceBuffer, clonedBuffer)\n }\n\n const clone =\n value instanceof DataView\n ? new DataView(clonedBuffer, value.byteOffset, value.byteLength)\n : new (value.constructor as any)(clonedBuffer, value.byteOffset, (value as any).length)\n\n references.set(value, clone)\n if (shouldCopyBufferProperties) {\n copyOwnProperties(sourceBuffer, clonedBuffer, references)\n }\n\n // Numeric indexes already exist on typed arrays. Preserve any additional own\n // properties because serialize-javascript includes them in the wire payload.\n copyOwnProperties(value, clone, references, key => {\n if (typeof key !== 'string') return true\n const index = Number(key)\n return !(\n Number.isInteger(index) &&\n index >= 0 &&\n index < (value as any).length &&\n String(index) === key\n )\n })\n return clone as T\n}\n\nfunction cloneForSerialization<T>(value: T, references = new WeakMap<object, any>()): T {\n if (value === null || (typeof value !== 'object' && typeof value !== 'function')) return value\n if (typeof value === 'function') return value\n\n const source = value as object\n if (references.has(source)) return references.get(source)\n\n if (value instanceof Date) {\n const clone = new Date(value.getTime())\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n return clone as T\n }\n\n if (value instanceof RegExp) {\n const clone = new RegExp(value.source, value.flags)\n clone.lastIndex = value.lastIndex\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n return clone as T\n }\n\n if (value instanceof Map) {\n const clone = new Map()\n references.set(source, clone)\n for (const [key, entry] of value) {\n Map.prototype.set.call(\n clone,\n cloneForSerialization(key, references),\n cloneForSerialization(entry, references),\n )\n }\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n return clone as T\n }\n\n if (value instanceof Set) {\n const clone = new Set()\n references.set(source, clone)\n for (const entry of value) {\n Set.prototype.add.call(clone, cloneForSerialization(entry, references))\n }\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n return clone as T\n }\n\n if (value instanceof URL) {\n const clone = new URL(value.toString())\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n return clone as T\n }\n\n if (Buffer.isBuffer(value)) {\n const clone = Buffer.from(value)\n references.set(source, clone)\n return clone as T\n }\n\n if (ArrayBuffer.isView(value)) {\n return cloneArrayBufferView(value, references) as T\n }\n\n if (\n value instanceof ArrayBuffer ||\n (typeof SharedArrayBuffer !== 'undefined' && value instanceof SharedArrayBuffer)\n ) {\n const clone = value.slice(0)\n references.set(source, clone)\n copyOwnProperties(value, clone, references)\n return clone as T\n }\n\n if (Array.isArray(value)) {\n const clone = new Array(value.length)\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n copyOwnProperties(value, clone, references, key => key !== 'length')\n return clone as T\n }\n\n const clone = Object.create(Object.getPrototypeOf(value))\n references.set(source, clone)\n copyOwnProperties(value, clone, references)\n preserveCustomToJSON(source, clone, references)\n return clone\n}\n\nexport default function (data: any): string {\n const serialized = serialize(cloneForSerialization(data), {ignoreFunction: true})\n return serialized\n}\n","import {AsyncLocalStorage} from 'node:async_hooks'\nimport {randomUUID} from 'node:crypto'\nimport {type EchoesErrorInfo, EchoesUserError, EchoesValidationError} from './errors'\n\nexport interface EchoesLogger {\n debug(message: string, metadata?: unknown): void\n info(message: string, metadata?: unknown): void\n warn(message: string, metadata?: unknown): void\n error(message: string, metadata?: unknown): void\n}\n\nexport interface EchoesSchemaAdapter {\n clean<T = unknown>(schema: unknown, value: unknown): T | Promise<T>\n parse<T = unknown>(schema: unknown, value: unknown): T | Promise<T>\n}\n\nexport interface EchoesExecutionContext {\n contextId?: string\n controllerType: 'echo'\n echoName: string\n params?: unknown\n}\n\nexport interface EchoesRequestHandlerDefinition {\n method: 'post'\n path: string\n bodyLimit: string\n handle(body: unknown): Promise<unknown>\n}\n\nexport type EchoesRequestHandlerRegistrar = (\n definition: EchoesRequestHandlerDefinition,\n) => void | Promise<void>\n\nexport interface EchoesRuntimeAdapter {\n schema?: EchoesSchemaAdapter\n logger?: EchoesLogger\n registerRequestHandler?: EchoesRequestHandlerRegistrar\n decorateService?(target: Function, context: ClassDecoratorContext): void\n getInstance?<T extends object>(target: new (...args: any[]) => T): T\n runWithContext?<T>(context: EchoesExecutionContext, callback: () => T | Promise<T>): Promise<T>\n createValidationError?(info: EchoesErrorInfo): Error\n createUserError?(info: EchoesErrorInfo): Error\n}\n\nconst defaultLogger: EchoesLogger = {\n debug: (message, metadata) =>\n metadata === undefined ? console.debug(message) : console.debug(message, metadata),\n info: (message, metadata) =>\n metadata === undefined ? console.info(message) : console.info(message, metadata),\n warn: (message, metadata) =>\n metadata === undefined ? console.warn(message) : console.warn(message, metadata),\n error: (message, metadata) =>\n metadata === undefined ? console.error(message) : console.error(message, metadata),\n}\n\nlet runtime: EchoesRuntimeAdapter = {}\nconst contextStorage = new AsyncLocalStorage<EchoesExecutionContext & {contextId: string}>()\n\n/**\n * Installs framework integrations without coupling Echoes to a framework.\n * The returned function restores the previous adapter, which is useful in tests.\n */\nexport function configureEchoesRuntime(adapter: EchoesRuntimeAdapter): () => void {\n const previous = runtime\n runtime = {...runtime, ...adapter}\n return () => {\n runtime = previous\n }\n}\n\nexport function getEchoesRuntime(): EchoesRuntimeAdapter {\n return runtime\n}\n\nexport function getEchoesLogger(): EchoesLogger {\n return runtime.logger || defaultLogger\n}\n\nexport function getEchoesContext(): (EchoesExecutionContext & {contextId: string}) | undefined {\n return contextStorage.getStore()\n}\n\nexport async function runWithEchoesContext<T>(\n context: EchoesExecutionContext,\n callback: () => T | Promise<T>,\n): Promise<T> {\n const contextWithId = {contextId: context.contextId || randomUUID(), ...context}\n return await contextStorage.run(contextWithId, async () => {\n if (runtime.runWithContext) {\n return await runtime.runWithContext(contextWithId, callback)\n }\n return await callback()\n })\n}\n\nfunction isSimpleSchemaLike(schema: unknown): schema is {\n clean(value: unknown, options?: Record<string, unknown>): unknown\n validate(value: unknown): unknown\n} {\n return (\n !!schema &&\n typeof schema === 'object' &&\n typeof (schema as any).clean === 'function' &&\n typeof (schema as any).validate === 'function'\n )\n}\n\nfunction cloneValue<T>(value: T): T {\n if (value === null || typeof value !== 'object') return value\n if (value instanceof Date) return new Date(value.getTime()) as T\n if (Buffer.isBuffer(value)) return Buffer.from(value) as T\n if (Array.isArray(value)) return value.map(cloneValue) as T\n const prototype = Object.getPrototypeOf(value)\n if (prototype !== Object.prototype && prototype !== null) return value\n\n const result: Record<string, unknown> = {}\n for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n result[key] = cloneValue(child)\n }\n return result as T\n}\n\nasync function cleanSimpleSchema<T>(\n schema: {\n clean(value: unknown, options?: Record<string, unknown>): unknown\n validate(value: unknown): unknown\n },\n value: unknown,\n): Promise<T> {\n const cloned = cloneValue(value)\n return (await schema.clean(cloned, {mutate: false})) as T\n}\n\nexport async function cleanEchoesSchema<T>(schema: unknown, value: unknown): Promise<T> {\n if (isSimpleSchemaLike(schema)) {\n return await cleanSimpleSchema<T>(schema, value)\n }\n if (runtime.schema) {\n return await runtime.schema.clean<T>(schema, value)\n }\n throw new Error(\n 'Echoes received a schema it cannot execute. Use a SimpleSchema-compatible object or configure an Echoes schema adapter.',\n )\n}\n\nexport async function parseEchoesSchema<T>(schema: unknown, value: unknown): Promise<T> {\n if (isSimpleSchemaLike(schema)) {\n const cleaned = await cleanSimpleSchema<T>(schema, value)\n await schema.validate(cleaned)\n return cleaned\n }\n if (runtime.schema) {\n return await runtime.schema.parse<T>(schema, value)\n }\n throw new Error(\n 'Echoes received a schema it cannot execute. Use a SimpleSchema-compatible object or configure an Echoes schema adapter.',\n )\n}\n\nexport function createEchoesValidationError(info: EchoesErrorInfo): Error {\n return runtime.createValidationError\n ? runtime.createValidationError(info)\n : new EchoesValidationError(info.validationErrors || {}, info.labels)\n}\n\nexport function createEchoesUserError(info: EchoesErrorInfo): Error {\n return runtime.createUserError\n ? runtime.createUserError(info)\n : new EchoesUserError(info.error, info.message, info.extra)\n}\n","export interface EchoesErrorInfo {\n error: string\n message: string\n extra?: any\n validationErrors?: Record<string, string>\n labels?: Record<string, string>\n}\n\nexport class EchoesUserError extends Error {\n readonly isEchoesError = true\n readonly isOrionError = true\n readonly isUserError = true\n readonly code: string\n readonly extra: any\n\n constructor(code: string, message?: string, extra?: any) {\n if (!message) {\n message = code\n code = 'error'\n }\n super(message)\n this.name = 'EchoesUserError'\n this.code = code\n this.extra = extra\n }\n\n getInfo(): EchoesErrorInfo {\n return {error: this.code, message: this.message, extra: this.extra}\n }\n}\n\nexport class EchoesValidationError extends Error {\n readonly isEchoesError = true\n readonly isOrionError = true\n readonly isValidationError = true\n readonly code = 'validationError'\n readonly validationErrors: Record<string, string>\n readonly labels: Record<string, string>\n\n constructor(validationErrors: Record<string, string>, labels: Record<string, string> = {}) {\n const printableErrors = Object.entries(validationErrors)\n .map(([key, value]) => `${key}: ${value}`)\n .join(', ')\n super(`Validation Error: {${printableErrors}}`)\n this.name = 'EchoesValidationError'\n this.validationErrors = validationErrors\n this.labels = Object.fromEntries(\n Object.keys(validationErrors)\n .filter(key => labels[key])\n .map(key => [key, labels[key]]),\n )\n }\n\n getInfo(): EchoesErrorInfo {\n return {\n error: this.code,\n message: 'Validation Error',\n validationErrors: this.validationErrors,\n labels: this.labels,\n }\n }\n}\n","import {createHmac} from 'node:crypto'\nimport {getEchoesPassword} from './getPassword'\n\nexport default function (_body: any): string {\n const password = getEchoesPassword()\n // Keep the legacy Echoes wire signature. jssha treated the object passed by\n // Echoes as an empty TEXT payload, so changing this would break mixed versions.\n return createHmac('sha1', password || '')\n .update('')\n .digest('hex')\n}\n","import config from '../config'\nimport {getEchoesLogger} from '../runtime'\n\nexport function getEchoesPassword() {\n const secret = config?.requests?.key || process.env.echoes_password || process.env.ECHOES_PASSWORD\n if (!secret) {\n getEchoesLogger().warn(\n 'Warning: no secret key found for echoes requests. Init echoes or set the env var \"echoes_password\" or process.env.ECHOES_PASSWORD',\n )\n }\n\n return secret\n}\n","import config from '../config'\n\nexport default function (serviceName: string): string {\n if (serviceName.startsWith('http')) return serviceName\n\n const url = config?.requests?.services?.[serviceName]\n\n if (!url) {\n throw new Error(`No URL found in echoes config for service ${serviceName}`)\n }\n\n return url\n}\n","import http from 'node:http'\nimport https from 'node:https'\nimport {RequestMaker} from '../types'\n\nasync function executeWithRetries<T>(\n callback: () => Promise<T>,\n retries = 0,\n delayMs = 200,\n): Promise<T> {\n try {\n return await callback()\n } catch (error) {\n if (retries <= 0) throw error\n await new Promise(resolve => setTimeout(resolve, delayMs))\n return await executeWithRetries(callback, retries - 1, delayMs)\n }\n}\n\nasync function postJSON(\n urlValue: string,\n data: unknown,\n timeout?: number,\n redirectsRemaining = 5,\n): Promise<{statusCode: number; data: object}> {\n const url = new URL(urlValue)\n const body = JSON.stringify(data)\n const transport = url.protocol === 'https:' ? https : http\n\n return await new Promise((resolve, reject) => {\n const request = transport.request(\n url,\n {\n method: 'POST',\n headers: {\n 'User-Agent': 'Orionjs-Echoes/1.1',\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(body),\n },\n },\n response => {\n const chunks: Buffer[] = []\n const statusCode = response.statusCode || 0\n if (statusCode >= 300 && statusCode < 400 && response.headers.location) {\n response.resume()\n if (redirectsRemaining <= 0) {\n reject(new Error('Echoes request exceeded the redirect limit'))\n return\n }\n resolve(\n postJSON(\n new URL(response.headers.location, url).toString(),\n data,\n timeout,\n redirectsRemaining - 1,\n ),\n )\n return\n }\n\n response.on('data', chunk => chunks.push(Buffer.from(chunk)))\n response.on('end', () => {\n try {\n const responseBody = Buffer.concat(chunks).toString('utf8')\n if (statusCode < 200 || statusCode >= 300) {\n reject(new Error(`Request failed with status code ${statusCode}`))\n return\n }\n resolve({\n statusCode,\n data: responseBody ? JSON.parse(responseBody) : {},\n })\n } catch (error) {\n reject(error)\n }\n })\n },\n )\n\n request.on('error', reject)\n if (timeout) {\n request.setTimeout(timeout, () => {\n request.destroy(new Error(`Echoes request timed out after ${timeout}ms`))\n })\n }\n request.end(body)\n })\n}\n\nexport const makeRequest: RequestMaker = async options => {\n return await executeWithRetries(\n () => postJSON(options.url, options.data, options.timeout),\n options.retries || 0,\n )\n}\n","import config from '../config'\nimport deserialize from '../echo/deserialize'\nimport serialize from '../publish/serialize'\nimport {createEchoesUserError, createEchoesValidationError} from '../runtime'\nimport type {\n MakeRequestParams,\n RequestHandlerResponse,\n RequestMaker,\n RequestOptions,\n} from '../types'\nimport getSignature from './getSignature'\nimport getURL from './getURL'\nimport {makeRequest} from './makeRequest'\n\nexport default async function request<TData = any, TParams = any>(\n options: RequestOptions<TParams>,\n): Promise<TData> {\n const {method, service, params} = options\n const serializedParams = serialize(params)\n const date = new Date()\n const body = {method, service, serializedParams, date}\n const signature = getSignature(body)\n\n try {\n const requestMaker: RequestMaker = config?.requests?.makeRequest || makeRequest\n const requestOptions: MakeRequestParams = {\n url: getURL(service),\n retries: options.retries,\n timeout: options.timeout,\n data: {\n body,\n signature,\n },\n }\n const result = await requestMaker(requestOptions)\n\n if (result.statusCode !== 200) {\n throw new Error(`Wrong status code ${result.statusCode}`)\n }\n\n const data: RequestHandlerResponse = result.data\n\n if (data.error) {\n const info = data.errorInfo\n if (info) {\n if (data.isValidationError) {\n throw createEchoesValidationError(info)\n }\n if (data.isUserError) {\n throw createEchoesUserError(info)\n }\n }\n\n throw new Error(`${data.error}`)\n }\n\n const response = deserialize(data.result)\n return response\n } catch (error) {\n const caught = error as any\n if (caught.isOrionError || caught.isEchoesError) throw caught\n\n throw new Error(`Echoes request network error calling ${service}/${method}: ${caught.message}`)\n }\n}\n","import {randomUUID} from 'node:crypto'\nimport deserialize from '../echo/deserialize'\nimport type {\n EventSubscriptionDefinition,\n EventTransport,\n EventTransportStartOptions,\n} from '../events/EventTransport'\nimport serialize from '../publish/serialize'\nimport {getEchoesLogger} from '../runtime'\nimport type {\n EchoesKafkaEventsConfig,\n EchoesKafkaMessagePayload,\n EchoesReceivedEvent,\n PublishOptions,\n} from '../types'\n\nconst HEARTBEAT_INTERVAL_SECONDS = 5\nconst CHECK_JOIN_CONSUMER_INTERVAL_SECONDS = 30\nconst DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY = 4\nconst DEFAULT_MEMBERS_TO_PARTITIONS_RATIO = 1\n\n/**\n * Kafka event transport. It retains the existing consumer-group and retry behavior.\n */\nclass KafkaManager implements EventTransport {\n readonly name = 'kafka' as const\n\n private kafka?: any\n private readonly options: EchoesKafkaEventsConfig\n private producer?: any\n private consumer?: any\n private topics: string[] = []\n private subscriptions = new Map<string, EventSubscriptionDefinition>()\n private onEvent?: (event: EchoesReceivedEvent) => Promise<void>\n private consumerStarted = false\n private producerConnected = false\n private interval?: NodeJS.Timeout\n\n constructor(options: EchoesKafkaEventsConfig) {\n this.options = options\n }\n\n async start(options: EventTransportStartOptions) {\n let kafkaModule: typeof import('kafkajs')\n try {\n kafkaModule = await import('kafkajs')\n } catch (error) {\n const wrapped = new Error(\n 'Echoes Kafka transport requires kafkajs to be installed in the application',\n )\n ;(wrapped as any).cause = error\n throw wrapped\n }\n this.kafka = new kafkaModule.Kafka(this.options.client as any)\n\n this.onEvent = options.onEvent\n this.subscriptions = new Map(\n options.subscriptions.map(subscription => [subscription.topic, subscription]),\n )\n this.topics = options.subscriptions.map(subscription => subscription.topic)\n\n // Kafka retries and DLQ publishing use a producer even on consumer-only servers.\n if (options.publish || options.consume) {\n this.producer = this.kafka.producer(this.options.producer)\n await this.producer.connect()\n this.producerConnected = true\n }\n\n if (!options.consume || this.topics.length === 0) return\n if (!this.options.consumer?.groupId) {\n throw new Error('Echoes Kafka consumers require consumer.groupId')\n }\n\n this.consumer = this.kafka.consumer(this.options.consumer)\n this.consumerStarted = await this.conditionalStart()\n if (this.consumerStarted) return\n\n getEchoesLogger().info('Echoes: Delaying consumer group join, waiting for conditions to be met')\n this.interval = setInterval(async () => {\n this.consumerStarted = await this.conditionalStart()\n if (this.consumerStarted) clearInterval(this.interval)\n }, CHECK_JOIN_CONSUMER_INTERVAL_SECONDS * 1000)\n }\n\n async publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!this.producer || !this.producerConnected) {\n throw new Error('Echoes Kafka producer is not connected')\n }\n\n return await this.producer.send({\n acks: options.acks,\n timeout: options.timeout,\n topic: options.topic,\n messages: [\n {\n value: serialize({params: options.params}),\n headers: {\n 'echoes-event-id': randomUUID(),\n },\n },\n ],\n })\n }\n\n async close() {\n const logger = getEchoesLogger()\n logger.warn('Echoes: Stopping Kafka transport')\n if (this.interval) clearInterval(this.interval)\n await Promise.all([\n this.consumer?.disconnect(),\n this.producerConnected ? this.producer?.disconnect() : undefined,\n ])\n this.consumerStarted = false\n this.producerConnected = false\n }\n\n private async checkJoinConsumerGroupConditions(): Promise<boolean> {\n const logger = getEchoesLogger()\n const admin = this.kafka.admin()\n try {\n await admin.connect()\n const groupId = this.options.consumer.groupId\n const groupDescriptions = await admin.describeGroups([groupId])\n const group = groupDescriptions.groups[0]\n if (group.state === 'Empty') {\n logger.info(`Echoes: Consumer group ${groupId} is empty, joining`)\n return true\n }\n const topicsMetadata = await admin.fetchTopicMetadata({topics: this.topics})\n const totalPartitions = topicsMetadata.topics.reduce(\n (acc, topic) => acc + topic.partitions.length,\n 0,\n )\n logger.info(\n `Echoes: Consumer group ${groupId} has ${group.members.length} members and ${totalPartitions} partitions`,\n )\n const partitionsRatio =\n this.options.membersToPartitionsRatio || DEFAULT_MEMBERS_TO_PARTITIONS_RATIO\n const partitionsThreshold = Math.ceil(totalPartitions * partitionsRatio)\n if (partitionsThreshold > group.members.length) {\n logger.info(\n `Echoes: Consumer group ${groupId} has room for more members ${group.members.length}/${partitionsThreshold}, joining`,\n )\n return true\n }\n return false\n } catch (error) {\n logger.error('Echoes: Error checking consumer group conditions, join', {error})\n return true\n } finally {\n await admin.disconnect().catch(error => {\n logger.error('Echoes: Error disconnecting admin client', {error})\n })\n }\n }\n\n private async joinConsumerGroup() {\n await this.consumer.connect()\n await this.consumer.subscribe({topics: this.topics})\n await this.consumer.run({\n partitionsConsumedConcurrently:\n this.options.partitionsConsumedConcurrently || DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY,\n eachMessage: params => this.handleMessage(params),\n })\n }\n\n private async conditionalStart(): Promise<boolean> {\n if (await this.checkJoinConsumerGroupConditions()) {\n await this.joinConsumerGroup()\n return true\n }\n return false\n }\n\n private async handleMessage(params: EchoesKafkaMessagePayload) {\n const logger = getEchoesLogger()\n const subscription = this.subscriptions.get(params.topic)\n if (!subscription) {\n logger.warn(`Echoes: Received a message for an unknown topic: ${params.topic}, ignoring it`)\n return\n }\n\n let intervalsCount = 0\n const heartbeatInterval = setInterval(async () => {\n await params.heartbeat().catch(error => {\n logger.warn(`Echoes: Error sending heartbeat: ${error.message}`)\n })\n intervalsCount++\n if ((intervalsCount * HEARTBEAT_INTERVAL_SECONDS) % 30 === 0) {\n logger.warn(\n `Echoes: Event is taking too long to process: ${params.topic} ${intervalsCount * HEARTBEAT_INTERVAL_SECONDS}s`,\n )\n }\n }, HEARTBEAT_INTERVAL_SECONDS * 1000)\n\n try {\n const event = this.createReceivedEvent(params)\n await this.onEvent(event)\n } catch (error) {\n try {\n await this.handleRetries(subscription, params, error as Error)\n } catch (retryError) {\n logger.error('Echoes: error processing a message', {\n error: retryError,\n topic: params.topic,\n })\n throw retryError\n }\n } finally {\n clearInterval(heartbeatInterval)\n }\n }\n\n private createReceivedEvent(params: EchoesKafkaMessagePayload): EchoesReceivedEvent {\n const {message, topic, partition} = params\n if (!message.value) {\n throw new Error(`Echoes received an empty Kafka message for ${topic}`)\n }\n const data = deserialize(message.value.toString())\n const retries = Number.parseInt(message.headers?.retries?.toString() || '0', 10)\n const timestamp = Number.parseInt(message.timestamp || '', 10)\n\n return {\n id:\n message.headers?.['echoes-event-id']?.toString() ||\n `kafka:${topic}:${partition}:${message.offset}`,\n topic,\n data,\n transport: 'kafka',\n headers: message.headers,\n createdAt: Number.isFinite(timestamp) ? new Date(timestamp) : new Date(),\n attempt: retries + 1,\n context: params,\n }\n }\n\n private async handleRetries(\n subscription: EventSubscriptionDefinition,\n params: EchoesKafkaMessagePayload,\n error: Error,\n ) {\n const logger = getEchoesLogger()\n const {message, topic} = params\n const retries = Number.parseInt(message?.headers?.retries?.toString() || '0', 10)\n if (\n subscription.attemptsBeforeDeadLetter === undefined ||\n subscription.attemptsBeforeDeadLetter === null\n ) {\n throw error\n }\n const maxRetries = subscription.attemptsBeforeDeadLetter || 0\n const exceededMaxRetries = retries >= maxRetries\n const nextTopic = exceededMaxRetries ? `DLQ-${topic}` : topic\n if (!message.value) throw error\n await this.producer.send({\n topic: nextTopic,\n messages: [\n {\n value: message.value.toString(),\n headers: {\n ...message.headers,\n retries: String(retries + 1),\n error: error.message,\n },\n },\n ],\n })\n\n if (exceededMaxRetries) {\n logger.error(\n 'Echoes: a message has reached the maximum number of retries, sending it to DLQ',\n {topic: nextTopic},\n )\n } else {\n logger.warn('Echoes: a retryable message failed', {error, topic: nextTopic})\n }\n }\n}\n\nexport default KafkaManager\n","import {getEchoesLogger} from '../runtime'\nimport type {\n EchoesEventTransportName,\n EchoesMap,\n EchoesReceivedEvent,\n PublishOptions,\n} from '../types'\nimport type {EventSubscriptionDefinition, EventTransport} from './EventTransport'\n\nexport interface EventBusOptions {\n echoes: EchoesMap\n transports: Partial<Record<EchoesEventTransportName, EventTransport>>\n consumeFrom: EchoesEventTransportName[]\n publishTo?: EchoesEventTransportName\n}\n\nexport default class EventBus {\n private readonly echoes: EchoesMap\n private readonly transports: Partial<Record<EchoesEventTransportName, EventTransport>>\n private readonly consumeFrom: EchoesEventTransportName[]\n private readonly publishTo?: EchoesEventTransportName\n private readonly startedTransports: EventTransport[] = []\n private started = false\n private closed = false\n\n constructor(options: EventBusOptions) {\n this.echoes = options.echoes\n this.transports = options.transports\n this.consumeFrom = [...new Set(options.consumeFrom)]\n this.publishTo = options.publishTo\n }\n\n async start() {\n if (this.started) return\n\n const selected = new Set(this.consumeFrom)\n if (this.publishTo) selected.add(this.publishTo)\n\n for (const name of selected) {\n if (!this.transports[name]) {\n throw new Error(`Echoes event transport \"${name}\" is selected but not configured`)\n }\n }\n\n const subscriptions: EventSubscriptionDefinition[] = Object.entries(this.echoes)\n .filter(([, echo]) => echo.type === 'event')\n .map(([topic, echo]) => ({\n topic,\n attemptsBeforeDeadLetter: echo.attemptsBeforeDeadLetter,\n }))\n\n try {\n for (const name of selected) {\n const transport = this.transports[name]\n this.startedTransports.push(transport)\n await transport.start({\n consume: this.consumeFrom.includes(name),\n publish: this.publishTo === name,\n subscriptions,\n onEvent: event => this.handleEvent(event),\n })\n }\n this.started = true\n } catch (error) {\n await this.close().catch(() => undefined)\n throw error\n }\n }\n\n async publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!this.started) {\n throw new Error('You must initialize echoes configuration to use publish')\n }\n if (!this.publishTo) {\n throw new Error('Echoes does not have a publish transport configured')\n }\n\n return await this.transports[this.publishTo].publish(options)\n }\n\n async close() {\n if (this.closed) return\n this.closed = true\n await Promise.all(this.startedTransports.map(transport => transport.close()))\n }\n\n private async handleEvent(event: EchoesReceivedEvent) {\n const logger = getEchoesLogger()\n const echo = this.echoes[event.topic]\n if (!echo || echo.type !== 'event') {\n logger.warn(`Echoes: Received a message for an unknown topic: ${event.topic}, ignoring it`)\n return\n }\n\n // Preserve the exact legacy Kafka entrypoint for custom EchoType implementations.\n if (event.transport === 'kafka' && event.context) {\n await echo.onMessage(event.context as any)\n return\n }\n\n if (echo.onEvent) {\n await echo.onEvent(event)\n return\n }\n\n await echo.resolve(event.data.params, {\n ...(event.context || {}),\n transport: event.transport,\n eventId: event.id,\n topic: event.topic,\n headers: event.headers,\n createdAt: event.createdAt,\n attempt: event.attempt,\n data: event.data,\n })\n }\n}\n","import type {\n EchoesEventPayload,\n EchoesPulseEventsConfig,\n EchoesReceivedEvent,\n PublishOptions,\n} from '../types'\nimport type {EventTransport, EventTransportStartOptions} from './EventTransport'\n\ntype PulseSubscribeOptions = NonNullable<EchoesPulseEventsConfig['subscription']>\n\ninterface PulseReceivedEvent {\n id: string\n topic: string\n data: EchoesEventPayload\n headers?: Record<string, unknown>\n createdAt: Date\n attempt: number\n}\n\nexport default class PulseManager implements EventTransport {\n readonly name = 'pulse' as const\n\n private readonly options: EchoesPulseEventsConfig\n private pulse?: any\n private subscriptions: Array<{unsubscribe(): Promise<void>}> = []\n\n constructor(options: EchoesPulseEventsConfig) {\n this.options = options\n }\n\n async start(options: EventTransportStartOptions) {\n let pulseModule: any\n try {\n pulseModule = await import('@orion-js/pulse')\n } catch (error) {\n const wrapped = new Error(\n 'Echoes Pulse transport requires @orion-js/pulse to be installed in the application',\n )\n ;(wrapped as any).cause = error\n throw wrapped\n }\n\n const {subscription, ...connectOptions} = this.options\n this.pulse = pulseModule.connect(connectOptions)\n await this.pulse.awaitConnection()\n\n if (!options.consume) return\n\n this.subscriptions = await Promise.all(\n options.subscriptions.map(definition =>\n this.pulse.subscribe(\n definition.topic,\n event => options.onEvent(this.createReceivedEvent(event)),\n this.getSubscribeOptions(subscription, definition.attemptsBeforeDeadLetter),\n ),\n ),\n )\n }\n\n async publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!this.pulse) {\n throw new Error('Echoes Pulse client is not connected')\n }\n\n return await this.pulse.publish({\n topic: options.topic,\n data: {params: options.params},\n })\n }\n\n async close() {\n await this.pulse?.close()\n this.subscriptions = []\n }\n\n private getSubscribeOptions(\n defaults: PulseSubscribeOptions = {},\n attemptsBeforeDeadLetter?: number,\n ): PulseSubscribeOptions {\n return {\n ...defaults,\n ...(attemptsBeforeDeadLetter === undefined ? {} : {maxRetries: attemptsBeforeDeadLetter}),\n }\n }\n\n private createReceivedEvent(event: PulseReceivedEvent): EchoesReceivedEvent {\n return {\n id: event.id,\n topic: event.topic,\n data: event.data,\n transport: 'pulse',\n headers: event.headers,\n createdAt: event.createdAt,\n attempt: event.attempt,\n context: event,\n }\n }\n}\n","import KafkaManager from '../startService/KafkaManager'\nimport type {\n EchoesEventTransportName,\n EchoesKafkaEventsConfig,\n EchoesOptions,\n EchoesPulseEventsConfig,\n} from '../types'\nimport EventBus from './EventBus'\nimport type {EventTransport} from './EventTransport'\nimport PulseManager from './PulseManager'\n\nexport interface ResolvedEventsConfig {\n kafka?: EchoesKafkaEventsConfig\n pulse?: EchoesPulseEventsConfig\n consumeFrom: EchoesEventTransportName[]\n publishTo?: EchoesEventTransportName\n}\n\nexport function resolveEventsConfig(options: EchoesOptions): ResolvedEventsConfig | undefined {\n const legacyKafka = options.client\n ? {\n client: options.client,\n producer: options.producer,\n consumer: options.consumer,\n readTopicsFromBeginning: options.readTopicsFromBeginning,\n partitionsConsumedConcurrently: options.partitionsConsumedConcurrently,\n membersToPartitionsRatio: options.membersToPartitionsRatio,\n }\n : undefined\n\n const kafka = options.events?.kafka || legacyKafka\n const pulse = options.events?.pulse\n\n if (!kafka && !pulse && !options.events) return undefined\n\n const defaultTransport: EchoesEventTransportName | undefined = kafka\n ? 'kafka'\n : pulse\n ? 'pulse'\n : undefined\n\n return {\n kafka,\n pulse,\n consumeFrom: options.events?.consumeFrom || (defaultTransport ? [defaultTransport] : []),\n publishTo: options.events?.publishTo || defaultTransport,\n }\n}\n\nexport default function createEventBus(options: EchoesOptions) {\n const resolved = resolveEventsConfig(options)\n if (!resolved) return undefined\n\n const transports: Partial<Record<EchoesEventTransportName, EventTransport>> = {}\n if (resolved.kafka) transports.kafka = new KafkaManager(resolved.kafka)\n if (resolved.pulse) transports.pulse = new PulseManager(resolved.pulse)\n\n return new EventBus({\n echoes: options.echoes,\n transports,\n consumeFrom: resolved.consumeFrom,\n publishTo: resolved.publishTo,\n })\n}\n","import getSignature from '../request/getSignature'\n\nexport default function (body: any, signature: string) {\n const generatedSignature = getSignature(body)\n if (generatedSignature !== signature) {\n throw new Error('Echoes invalid signature')\n }\n}\n","import config from '../config'\n\nexport default function (method: string) {\n const echo = config.echoes[method]\n\n if (!echo) {\n throw new Error(`Echo named ${method} not found in this service`)\n }\n\n if (echo.type !== 'request') {\n throw new Error(`Echo named ${method} is not of type request`)\n }\n\n return echo\n}\n","import serialize from '../publish/serialize'\nimport {getEchoesLogger} from '../runtime'\nimport {EchoesOptions} from '../types'\nimport checkSignature from './checkSignature'\nimport getEcho from './getEcho'\n\nexport default (options: EchoesOptions) =>\n ({\n method: 'post',\n path: options.requests.handlerPath || '/echoes-services',\n bodyLimit: '10mb',\n async handle(requestBody: any) {\n try {\n const {body, signature} = requestBody\n\n checkSignature(body, signature)\n\n const {method, serializedParams} = body\n\n const echo = getEcho(method)\n const result = await echo.onRequest(serializedParams)\n\n return {result: serialize(result)}\n } catch (error) {\n const caught = error as any\n if (!caught.getInfo) {\n getEchoesLogger().error('Error at echo requests handler:', {error: caught})\n }\n\n return {\n error: caught.message,\n errorInfo: caught.getInfo ? caught.getInfo() : null,\n isValidationError: !!caught.isValidationError,\n isUserError: !!caught.isUserError,\n }\n }\n },\n }) as const\n","import config from '../config'\nimport createEventBus from '../events/createEventBus'\nimport EventBus from '../events/EventBus'\nimport requestsHandler from '../requestsHandler'\nimport {getEchoesLogger, getEchoesRuntime} from '../runtime'\nimport {EchoesOptions} from '../types'\n\nlet eventBus: EventBus = null\n\nexport default async function startService(options: EchoesOptions) {\n config.echoes = options.echoes\n\n if (options.requests) {\n config.requests = options.requests\n const registerHandler =\n options.requests.registerHandler || getEchoesRuntime().registerRequestHandler\n if (!registerHandler) {\n throw new Error(\n 'Echoes requests require requests.registerHandler in standalone servers. Orion applications can import @orion-js/echoes-orion once during startup.',\n )\n }\n await registerHandler(requestsHandler(options))\n }\n\n const nextEventBus = createEventBus(options)\n if (nextEventBus) {\n await nextEventBus.start()\n eventBus = nextEventBus\n config.eventBus = eventBus\n }\n}\n\nexport async function stopService() {\n if (eventBus) {\n const logger = getEchoesLogger()\n logger.info('Stopping Echoes...')\n await eventBus.close()\n eventBus = null\n config.eventBus = undefined\n logger.info('Echoes stopped')\n }\n}\n","import {cleanEchoesSchema, parseEchoesSchema} from '../runtime'\nimport type {EchoesSchema, InferEchoesSchema} from '../schema'\nimport {\n EchoConfig,\n EchoEventConfig,\n EchoesKafkaMessagePayload,\n EchoesReceivedEvent,\n EchoRequestConfig,\n EchoType,\n} from '../types'\nimport deserialize from './deserialize'\n\n/**\n * @deprecated Use createEchoRequest and createEchoEvent instead\n */\nconst echo = function createNewEcho<\n TParamsSchema extends EchoesSchema,\n TReturnsSchema extends EchoesSchema,\n TEchoType extends 'event' | 'request',\n>(\n options: EchoConfig<TParamsSchema, TReturnsSchema, TEchoType>,\n): EchoType<TParamsSchema, TReturnsSchema, TEchoType> {\n const resolve = async (params: InferEchoesSchema<TParamsSchema>, context: any) => {\n const cleaned = options.params\n ? await parseEchoesSchema<InferEchoesSchema<TParamsSchema>>(options.params, params)\n : (params ?? ({} as InferEchoesSchema<TParamsSchema>))\n\n const result = await options.resolve(cleaned, context)\n\n if (options.returns) {\n return await cleanEchoesSchema<InferEchoesSchema<TReturnsSchema>>(options.returns, result)\n }\n\n return result\n }\n\n const onEvent = async (event: EchoesReceivedEvent) => {\n const context = {\n ...(event.context || {}),\n transport: event.transport,\n eventId: event.id,\n topic: event.topic,\n headers: event.headers,\n createdAt: event.createdAt,\n attempt: event.attempt,\n data: event.data,\n }\n\n await resolve(event.data.params, context)\n }\n\n return {\n type: options.type,\n params: options.params,\n returns: options.returns,\n attemptsBeforeDeadLetter:\n options.type === 'event' ? options.attemptsBeforeDeadLetter : undefined,\n resolve,\n onEvent,\n onMessage: async (messageData: EchoesKafkaMessagePayload) => {\n const {message} = messageData\n if (!message.value) {\n throw new Error(`Echoes received an empty Kafka message for ${messageData.topic}`)\n }\n\n const data = deserialize(message.value.toString())\n const retries = Number.parseInt(message.headers?.retries?.toString() || '0', 10)\n const timestamp = Number(message.timestamp)\n const createdAt = Number.isFinite(timestamp) ? new Date(timestamp) : new Date()\n const eventId =\n message.headers?.['echoes-event-id']?.toString() ||\n `kafka:${messageData.topic}:${messageData.partition}:${message.offset}`\n\n await onEvent({\n id: eventId,\n topic: messageData.topic,\n data,\n transport: 'kafka',\n headers: message.headers,\n createdAt,\n attempt: retries + 1,\n context: messageData,\n })\n },\n onRequest: async (serializedParams: string) => {\n const context = {}\n const params = deserialize(serializedParams)\n\n return await resolve(params, context)\n },\n }\n}\n\nexport function createEchoRequest<\n TParamsSchema extends EchoesSchema,\n TReturnsSchema extends EchoesSchema,\n>(\n options: EchoRequestConfig<TParamsSchema, TReturnsSchema>,\n): EchoType<TParamsSchema, TReturnsSchema, 'request'> {\n return echo({...options, type: 'request'})\n}\nexport function createEchoEvent<\n TParamsSchema extends EchoesSchema,\n TReturnsSchema extends EchoesSchema,\n>(\n options: EchoEventConfig<TParamsSchema, TReturnsSchema>,\n): EchoType<TParamsSchema, TReturnsSchema, 'event'> {\n return echo({...options, type: 'event' as any})\n}\n\nexport {echo}\n","export type EchoesSchema = unknown\n\ntype InferFieldType<T> = T extends {__tsFieldType: infer U}\n ? U\n : T extends 'string' | 'ID' | 'email'\n ? string\n : T extends 'date'\n ? Date\n : T extends 'integer' | 'number'\n ? number\n : T extends 'boolean'\n ? boolean\n : T extends 'blackbox'\n ? Record<string, any>\n : T extends 'any'\n ? any\n : T extends String | StringConstructor\n ? string\n : T extends Number | NumberConstructor\n ? number\n : T extends Boolean | BooleanConstructor\n ? boolean\n : T extends Date | DateConstructor\n ? Date\n : T extends Array<infer U>\n ? InferFieldType<U>[]\n : T extends Record<string, any>\n ? InferObjectSchema<T>\n : T\n\ntype NodeIsOptional<T> = T extends {optional: true} ? true : false\n\ntype InferObjectSchema<T extends Record<string, any>> = {\n -readonly [K in keyof T as NodeIsOptional<T[K]> extends true ? never : K]: InferEchoesSchema<\n T[K] extends {type: infer U} ? U : T[K]\n >\n} & {\n -readonly [K in keyof T as NodeIsOptional<T[K]> extends true ? K : never]?: InferEchoesSchema<\n T[K] extends {type: infer U} ? U : T[K]\n >\n}\n\ntype IsObjectSchema<T> =\n T extends Record<string, any>\n ? keyof {\n [K in keyof T as T[K] extends {type: any} ? K : never]: T[K]\n } extends never\n ? false\n : true\n : false\n\ntype AbstractClass<T = any> = abstract new (...args: any[]) => T\n\n/**\n * Infers the value represented by Orion-style schema declarations without\n * requiring @orion-js/schema to be installed.\n */\nexport type InferEchoesSchema<T> = T extends {__echoesType: infer U}\n ? U\n : T extends {__tsFieldType: infer U}\n ? U\n : T extends {__isModel: true; type: infer U}\n ? U extends Record<string, any>\n ? InferObjectSchema<U>\n : InferFieldType<U>\n : T extends StringConstructor\n ? string\n : T extends NumberConstructor\n ? number\n : T extends BooleanConstructor\n ? boolean\n : T extends DateConstructor\n ? Date\n : T extends AbstractClass<infer U>\n ? U\n : IsObjectSchema<T> extends true\n ? T extends Record<string, any>\n ? InferObjectSchema<T>\n : never\n : InferFieldType<T>\n\n/**\n * Adds compile-time value information to a runtime schema such as SimpleSchema.\n * It returns the same object and has no runtime cost.\n */\nexport function typedEchoesSchema<TValue, TSchema extends object = object>(\n schema: TSchema,\n): TSchema & {readonly __echoesType: TValue} {\n return schema as TSchema & {readonly __echoesType: TValue}\n}\n","import {createEchoEvent, createEchoRequest} from '../echo'\nimport {getEchoesRuntime, runWithEchoesContext} from '../runtime'\nimport {EchoConfig, EchoesMap} from '../types'\n\nexport interface EchoesPropertyDescriptor extends Omit<PropertyDecorator, 'value'> {\n value?: EchoConfig<any, any>['resolve']\n}\n// Define metadata storage using WeakMaps\nconst serviceMetadata = new WeakMap<any, {_serviceType: string}>()\nconst echoesMetadata = new WeakMap<any, Record<string, any>>()\nconst echoEntriesByClass = new Map<Function, Record<string, (instance: any) => any>>()\nconst standaloneInstances = new WeakMap<Function, any>()\nlet pendingEchoEntries: Record<string, (instance: any) => any> = {}\n\nexport function Echoes() {\n return (target: any, context: ClassDecoratorContext<any>) => {\n getEchoesRuntime().decorateService?.(target, context)\n serviceMetadata.set(target, {_serviceType: 'echoes'})\n\n if (Object.keys(pendingEchoEntries).length > 0) {\n echoEntriesByClass.set(target, pendingEchoEntries)\n pendingEchoEntries = {}\n }\n }\n}\n\nexport function EchoEvent(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EchoEvent(\n options?: Omit<EchoConfig<any, any>, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EchoEvent(options = {}) {\n return (method: any, context: ClassMethodDecoratorContext | ClassFieldDecoratorContext) => {\n const propertyKey = String(context.name)\n\n if (context.kind === 'method') {\n pendingEchoEntries[propertyKey] = (instance: any) => {\n const originalResolve = instance[propertyKey].bind(instance)\n return createEchoEvent({\n ...options,\n resolve: async (params, contextData) => {\n return await runWithEchoesContext(\n {\n controllerType: 'echo',\n echoName: propertyKey,\n params,\n },\n async () => {\n return await originalResolve(params, contextData)\n },\n )\n },\n })\n }\n }\n\n if (context.kind === 'field') {\n pendingEchoEntries[propertyKey] = (instance: any) => instance[propertyKey]\n }\n\n return method\n }\n}\n\nexport function EchoRequest(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EchoRequest(\n options?: Omit<EchoConfig<any, any>, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EchoRequest(options = {}) {\n return (method: any, context: ClassMethodDecoratorContext | ClassFieldDecoratorContext) => {\n const propertyKey = String(context.name)\n\n if (context.kind === 'method') {\n pendingEchoEntries[propertyKey] = (instance: any) => {\n const originalResolve = instance[propertyKey].bind(instance)\n return createEchoRequest({\n ...options,\n resolve: async (params, contextData) => {\n return await runWithEchoesContext(\n {\n controllerType: 'echo',\n echoName: propertyKey,\n params,\n },\n async () => {\n return await originalResolve(params, contextData)\n },\n )\n },\n })\n }\n }\n\n if (context.kind === 'field') {\n pendingEchoEntries[propertyKey] = (instance: any) => instance[propertyKey]\n }\n\n return method\n }\n}\n\nfunction initializeEchoesIfNeeded(instance: any) {\n if (echoesMetadata.has(instance)) return\n const entries = echoEntriesByClass.get(instance.constructor) || {}\n const echoes: Record<string, any> = {}\n for (const [key, setup] of Object.entries(entries)) {\n echoes[key] = setup(instance)\n }\n echoesMetadata.set(instance, echoes)\n}\n\nexport function getServiceEchoes(target: any): EchoesMap {\n let instance: any\n if (typeof target !== 'function') {\n instance = target\n } else if (getEchoesRuntime().getInstance) {\n instance = getEchoesRuntime().getInstance(target)\n } else {\n instance = standaloneInstances.get(target)\n if (!instance) {\n instance = new target()\n standaloneInstances.set(target, instance)\n }\n }\n\n if (!serviceMetadata.has(instance.constructor)) {\n throw new Error('You must pass a class decorated with @Echoes to getServiceEchoes')\n }\n\n const instanceMetadata = serviceMetadata.get(instance.constructor)\n if (instanceMetadata._serviceType !== 'echoes') {\n throw new Error('You must pass a class decorated with @Echoes to getServiceEchoes')\n }\n\n initializeEchoesIfNeeded(instance)\n\n const echoesMap = echoesMetadata.get(instance) || {}\n\n return echoesMap\n}\n"],"mappings":"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","names":["clone","request","randomUUID","randomUUID","echo","echo","echo"]}
1
+ {"version":3,"sources":["../src/config.ts","../src/publish/index.ts","../src/echo/deserialize.ts","../src/publish/serialize.ts","../src/runtime.ts","../src/errors.ts","../src/request/getSignature.ts","../src/request/getPassword.ts","../src/request/getURL.ts","../src/request/makeRequest.ts","../src/request/index.ts","../src/startService/KafkaManager.ts","../src/events/EventBus.ts","../src/events/PulseManager.ts","../src/events/createEventBus.ts","../src/requestsHandler/checkSignature.ts","../src/requestsHandler/getEcho.ts","../src/requestsHandler/index.ts","../src/startService/index.ts","../src/echo/index.ts","../src/schema.ts","../src/service/index.ts"],"sourcesContent":["import {EchoesConfigHandler} from './types'\n\nconst config: EchoesConfigHandler = {}\n\nexport default config\n","import config from '../config'\nimport {PublishOptions} from '../types'\n\n/**\n * Publish\n */\nexport default async function publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!config.eventBus) {\n throw new Error('You must initialize echoes configuration to use publish')\n }\n\n return await config.eventBus.publish(options)\n}\n","export default function (serializedJavascript: string): any {\n try {\n return eval('(' + serializedJavascript + ')')\n } catch (error) {\n throw new Error('Error deserializing echo message')\n }\n}\n","import serialize from 'serialize-javascript'\n\nfunction clonePropertyDescriptor(\n descriptor: PropertyDescriptor,\n references: WeakMap<object, any>,\n): PropertyDescriptor {\n // The copy only exists for serialization. Making properties configurable lets\n // ignoreFunction remove methods even when the caller passed a frozen object.\n const clonedDescriptor = {...descriptor, configurable: true}\n if ('value' in clonedDescriptor) {\n clonedDescriptor.value = cloneForSerialization(clonedDescriptor.value, references)\n }\n return clonedDescriptor\n}\n\nfunction copyOwnProperties(\n source: object,\n target: object,\n references: WeakMap<object, any>,\n shouldCopy: (key: PropertyKey) => boolean = () => true,\n) {\n for (const key of Reflect.ownKeys(source)) {\n if (!shouldCopy(key)) continue\n const descriptor = Object.getOwnPropertyDescriptor(source, key)\n if (!descriptor) continue\n Object.defineProperty(target, key, clonePropertyDescriptor(descriptor, references))\n }\n}\n\nfunction preserveCustomToJSON(source: object, target: object, references: WeakMap<object, any>) {\n const toJSON = (source as any).toJSON\n if (typeof toJSON !== 'function') return\n\n Object.defineProperty(target, 'toJSON', {\n configurable: true,\n enumerable: false,\n writable: true,\n value(key: string) {\n return cloneForSerialization(toJSON.call(source, key), references)\n },\n })\n}\n\nfunction cloneArrayBufferView<T extends ArrayBufferView>(\n value: T,\n references: WeakMap<object, any>,\n): T {\n const sourceBuffer = value.buffer\n let clonedBuffer = references.get(sourceBuffer) as ArrayBufferLike | undefined\n const shouldCopyBufferProperties = !clonedBuffer\n\n if (!clonedBuffer) {\n clonedBuffer = sourceBuffer.slice(0)\n references.set(sourceBuffer, clonedBuffer)\n }\n\n const clone =\n value instanceof DataView\n ? new DataView(clonedBuffer, value.byteOffset, value.byteLength)\n : new (value.constructor as any)(clonedBuffer, value.byteOffset, (value as any).length)\n\n references.set(value, clone)\n if (shouldCopyBufferProperties) {\n copyOwnProperties(sourceBuffer, clonedBuffer, references)\n }\n\n // Numeric indexes already exist on typed arrays. Preserve any additional own\n // properties because serialize-javascript includes them in the wire payload.\n copyOwnProperties(value, clone, references, key => {\n if (typeof key !== 'string') return true\n const index = Number(key)\n return !(\n Number.isInteger(index) &&\n index >= 0 &&\n index < (value as any).length &&\n String(index) === key\n )\n })\n return clone as T\n}\n\nfunction cloneForSerialization<T>(value: T, references = new WeakMap<object, any>()): T {\n if (value === null || (typeof value !== 'object' && typeof value !== 'function')) return value\n if (typeof value === 'function') return value\n\n const source = value as object\n if (references.has(source)) return references.get(source)\n\n if (value instanceof Date) {\n const clone = new Date(value.getTime())\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n return clone as T\n }\n\n if (value instanceof RegExp) {\n const clone = new RegExp(value.source, value.flags)\n clone.lastIndex = value.lastIndex\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n return clone as T\n }\n\n if (value instanceof Map) {\n const clone = new Map()\n references.set(source, clone)\n for (const [key, entry] of value) {\n Map.prototype.set.call(\n clone,\n cloneForSerialization(key, references),\n cloneForSerialization(entry, references),\n )\n }\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n return clone as T\n }\n\n if (value instanceof Set) {\n const clone = new Set()\n references.set(source, clone)\n for (const entry of value) {\n Set.prototype.add.call(clone, cloneForSerialization(entry, references))\n }\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n return clone as T\n }\n\n if (value instanceof URL) {\n const clone = new URL(value.toString())\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n return clone as T\n }\n\n if (Buffer.isBuffer(value)) {\n const clone = Buffer.from(value)\n references.set(source, clone)\n return clone as T\n }\n\n if (ArrayBuffer.isView(value)) {\n return cloneArrayBufferView(value, references) as T\n }\n\n if (\n value instanceof ArrayBuffer ||\n (typeof SharedArrayBuffer !== 'undefined' && value instanceof SharedArrayBuffer)\n ) {\n const clone = value.slice(0)\n references.set(source, clone)\n copyOwnProperties(value, clone, references)\n return clone as T\n }\n\n if (Array.isArray(value)) {\n const clone = new Array(value.length)\n Object.setPrototypeOf(clone, Object.getPrototypeOf(value))\n references.set(source, clone)\n copyOwnProperties(value, clone, references, key => key !== 'length')\n return clone as T\n }\n\n const clone = Object.create(Object.getPrototypeOf(value))\n references.set(source, clone)\n copyOwnProperties(value, clone, references)\n preserveCustomToJSON(source, clone, references)\n return clone\n}\n\nexport default function (data: any): string {\n const serialized = serialize(cloneForSerialization(data), {ignoreFunction: true})\n return serialized\n}\n","import {AsyncLocalStorage} from 'node:async_hooks'\nimport {randomUUID} from 'node:crypto'\nimport {type EchoesErrorInfo, EchoesUserError, EchoesValidationError} from './errors'\n\nexport interface EchoesLogger {\n debug(message: string, metadata?: unknown): void\n info(message: string, metadata?: unknown): void\n warn(message: string, metadata?: unknown): void\n error(message: string, metadata?: unknown): void\n}\n\nexport interface EchoesSchemaAdapter {\n clean<T = unknown>(schema: unknown, value: unknown): T | Promise<T>\n parse<T = unknown>(schema: unknown, value: unknown): T | Promise<T>\n}\n\nexport interface EchoesExecutionContext {\n contextId?: string\n controllerType: 'echo'\n echoName: string\n params?: unknown\n}\n\nexport interface EchoesRequestHandlerDefinition {\n method: 'post'\n path: string\n bodyLimit: string\n handle(body: unknown): Promise<unknown>\n}\n\nexport type EchoesRequestHandlerRegistrar = (\n definition: EchoesRequestHandlerDefinition,\n) => void | Promise<void>\n\nexport interface EchoesRuntimeAdapter {\n schema?: EchoesSchemaAdapter\n logger?: EchoesLogger\n registerRequestHandler?: EchoesRequestHandlerRegistrar\n decorateService?(target: Function, context: ClassDecoratorContext): void\n getInstance?<T extends object>(target: new (...args: any[]) => T): T\n runWithContext?<T>(context: EchoesExecutionContext, callback: () => T | Promise<T>): Promise<T>\n createValidationError?(info: EchoesErrorInfo): Error\n createUserError?(info: EchoesErrorInfo): Error\n}\n\nconst defaultLogger: EchoesLogger = {\n debug: (message, metadata) =>\n metadata === undefined ? console.debug(message) : console.debug(message, metadata),\n info: (message, metadata) =>\n metadata === undefined ? console.info(message) : console.info(message, metadata),\n warn: (message, metadata) =>\n metadata === undefined ? console.warn(message) : console.warn(message, metadata),\n error: (message, metadata) =>\n metadata === undefined ? console.error(message) : console.error(message, metadata),\n}\n\nlet runtime: EchoesRuntimeAdapter = {}\nconst contextStorage = new AsyncLocalStorage<EchoesExecutionContext & {contextId: string}>()\n\n/**\n * Installs framework integrations without coupling Echoes to a framework.\n * The returned function restores the previous adapter, which is useful in tests.\n */\nexport function configureEchoesRuntime(adapter: EchoesRuntimeAdapter): () => void {\n const previous = runtime\n runtime = {...runtime, ...adapter}\n return () => {\n runtime = previous\n }\n}\n\nexport function getEchoesRuntime(): EchoesRuntimeAdapter {\n return runtime\n}\n\nexport function getEchoesLogger(): EchoesLogger {\n return runtime.logger || defaultLogger\n}\n\nexport function getEchoesContext(): (EchoesExecutionContext & {contextId: string}) | undefined {\n return contextStorage.getStore()\n}\n\nexport async function runWithEchoesContext<T>(\n context: EchoesExecutionContext,\n callback: () => T | Promise<T>,\n): Promise<T> {\n const contextWithId = {contextId: context.contextId || randomUUID(), ...context}\n return await contextStorage.run(contextWithId, async () => {\n if (runtime.runWithContext) {\n return await runtime.runWithContext(contextWithId, callback)\n }\n return await callback()\n })\n}\n\nfunction isSimpleSchemaLike(schema: unknown): schema is {\n clean(value: unknown, options?: Record<string, unknown>): unknown\n validate(value: unknown): unknown\n} {\n return (\n !!schema &&\n typeof schema === 'object' &&\n typeof (schema as any).clean === 'function' &&\n typeof (schema as any).validate === 'function'\n )\n}\n\nfunction cloneValue<T>(value: T): T {\n if (value === null || typeof value !== 'object') return value\n if (value instanceof Date) return new Date(value.getTime()) as T\n if (Buffer.isBuffer(value)) return Buffer.from(value) as T\n if (Array.isArray(value)) return value.map(cloneValue) as T\n const prototype = Object.getPrototypeOf(value)\n if (prototype !== Object.prototype && prototype !== null) return value\n\n const result: Record<string, unknown> = {}\n for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n result[key] = cloneValue(child)\n }\n return result as T\n}\n\nasync function cleanSimpleSchema<T>(\n schema: {\n clean(value: unknown, options?: Record<string, unknown>): unknown\n validate(value: unknown): unknown\n },\n value: unknown,\n): Promise<T> {\n const cloned = cloneValue(value)\n return (await schema.clean(cloned, {mutate: false})) as T\n}\n\nexport async function cleanEchoesSchema<T>(schema: unknown, value: unknown): Promise<T> {\n if (isSimpleSchemaLike(schema)) {\n return await cleanSimpleSchema<T>(schema, value)\n }\n if (runtime.schema) {\n return await runtime.schema.clean<T>(schema, value)\n }\n throw new Error(\n 'Echoes received a schema it cannot execute. Use a SimpleSchema-compatible object or configure an Echoes schema adapter.',\n )\n}\n\nexport async function parseEchoesSchema<T>(schema: unknown, value: unknown): Promise<T> {\n if (isSimpleSchemaLike(schema)) {\n const cleaned = await cleanSimpleSchema<T>(schema, value)\n await schema.validate(cleaned)\n return cleaned\n }\n if (runtime.schema) {\n return await runtime.schema.parse<T>(schema, value)\n }\n throw new Error(\n 'Echoes received a schema it cannot execute. Use a SimpleSchema-compatible object or configure an Echoes schema adapter.',\n )\n}\n\nexport function createEchoesValidationError(info: EchoesErrorInfo): Error {\n return runtime.createValidationError\n ? runtime.createValidationError(info)\n : new EchoesValidationError(info.validationErrors || {}, info.labels)\n}\n\nexport function createEchoesUserError(info: EchoesErrorInfo): Error {\n return runtime.createUserError\n ? runtime.createUserError(info)\n : new EchoesUserError(info.error, info.message, info.extra)\n}\n","export interface EchoesErrorInfo {\n error: string\n message: string\n extra?: any\n validationErrors?: Record<string, string>\n labels?: Record<string, string>\n}\n\nexport class EchoesUserError extends Error {\n readonly isEchoesError = true\n readonly isOrionError = true\n readonly isUserError = true\n readonly code: string\n readonly extra: any\n\n constructor(code: string, message?: string, extra?: any) {\n if (!message) {\n message = code\n code = 'error'\n }\n super(message)\n this.name = 'EchoesUserError'\n this.code = code\n this.extra = extra\n }\n\n getInfo(): EchoesErrorInfo {\n return {error: this.code, message: this.message, extra: this.extra}\n }\n}\n\nexport class EchoesValidationError extends Error {\n readonly isEchoesError = true\n readonly isOrionError = true\n readonly isValidationError = true\n readonly code = 'validationError'\n readonly validationErrors: Record<string, string>\n readonly labels: Record<string, string>\n\n constructor(validationErrors: Record<string, string>, labels: Record<string, string> = {}) {\n const printableErrors = Object.entries(validationErrors)\n .map(([key, value]) => `${key}: ${value}`)\n .join(', ')\n super(`Validation Error: {${printableErrors}}`)\n this.name = 'EchoesValidationError'\n this.validationErrors = validationErrors\n this.labels = Object.fromEntries(\n Object.keys(validationErrors)\n .filter(key => labels[key])\n .map(key => [key, labels[key]]),\n )\n }\n\n getInfo(): EchoesErrorInfo {\n return {\n error: this.code,\n message: 'Validation Error',\n validationErrors: this.validationErrors,\n labels: this.labels,\n }\n }\n}\n","import {createHmac} from 'node:crypto'\nimport {getEchoesPassword} from './getPassword'\n\nexport default function (_body: any): string {\n const password = getEchoesPassword()\n // Keep the legacy Echoes wire signature. jssha treated the object passed by\n // Echoes as an empty TEXT payload, so changing this would break mixed versions.\n return createHmac('sha1', password || '')\n .update('')\n .digest('hex')\n}\n","import config from '../config'\nimport {getEchoesLogger} from '../runtime'\n\nexport function getEchoesPassword() {\n const secret = config?.requests?.key || process.env.echoes_password || process.env.ECHOES_PASSWORD\n if (!secret) {\n getEchoesLogger().warn(\n 'Warning: no secret key found for echoes requests. Init echoes or set the env var \"echoes_password\" or process.env.ECHOES_PASSWORD',\n )\n }\n\n return secret\n}\n","import config from '../config'\n\nexport default function (serviceName: string): string {\n if (serviceName.startsWith('http')) return serviceName\n\n const url = config?.requests?.services?.[serviceName]\n\n if (!url) {\n throw new Error(`No URL found in echoes config for service ${serviceName}`)\n }\n\n return url\n}\n","import http from 'node:http'\nimport https from 'node:https'\nimport {RequestMaker} from '../types'\n\nasync function executeWithRetries<T>(\n callback: () => Promise<T>,\n retries = 0,\n delayMs = 200,\n): Promise<T> {\n try {\n return await callback()\n } catch (error) {\n if (retries <= 0) throw error\n await new Promise(resolve => setTimeout(resolve, delayMs))\n return await executeWithRetries(callback, retries - 1, delayMs)\n }\n}\n\nasync function postJSON(\n urlValue: string,\n data: unknown,\n timeout?: number,\n redirectsRemaining = 5,\n): Promise<{statusCode: number; data: object}> {\n const url = new URL(urlValue)\n const body = JSON.stringify(data)\n const transport = url.protocol === 'https:' ? https : http\n\n return await new Promise((resolve, reject) => {\n const request = transport.request(\n url,\n {\n method: 'POST',\n headers: {\n 'User-Agent': 'Orionjs-Echoes/1.1',\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(body),\n },\n },\n response => {\n const chunks: Buffer[] = []\n const statusCode = response.statusCode || 0\n if (statusCode >= 300 && statusCode < 400 && response.headers.location) {\n response.resume()\n if (redirectsRemaining <= 0) {\n reject(new Error('Echoes request exceeded the redirect limit'))\n return\n }\n resolve(\n postJSON(\n new URL(response.headers.location, url).toString(),\n data,\n timeout,\n redirectsRemaining - 1,\n ),\n )\n return\n }\n\n response.on('data', chunk => chunks.push(Buffer.from(chunk)))\n response.on('end', () => {\n try {\n const responseBody = Buffer.concat(chunks).toString('utf8')\n if (statusCode < 200 || statusCode >= 300) {\n reject(new Error(`Request failed with status code ${statusCode}`))\n return\n }\n resolve({\n statusCode,\n data: responseBody ? JSON.parse(responseBody) : {},\n })\n } catch (error) {\n reject(error)\n }\n })\n },\n )\n\n request.on('error', reject)\n if (timeout) {\n request.setTimeout(timeout, () => {\n request.destroy(new Error(`Echoes request timed out after ${timeout}ms`))\n })\n }\n request.end(body)\n })\n}\n\nexport const makeRequest: RequestMaker = async options => {\n return await executeWithRetries(\n () => postJSON(options.url, options.data, options.timeout),\n options.retries || 0,\n )\n}\n","import config from '../config'\nimport deserialize from '../echo/deserialize'\nimport serialize from '../publish/serialize'\nimport {createEchoesUserError, createEchoesValidationError} from '../runtime'\nimport type {\n MakeRequestParams,\n RequestHandlerResponse,\n RequestMaker,\n RequestOptions,\n} from '../types'\nimport getSignature from './getSignature'\nimport getURL from './getURL'\nimport {makeRequest} from './makeRequest'\n\nexport default async function request<TData = any, TParams = any>(\n options: RequestOptions<TParams>,\n): Promise<TData> {\n const {method, service, params} = options\n const serializedParams = serialize(params)\n const date = new Date()\n const body = {method, service, serializedParams, date}\n const signature = getSignature(body)\n\n try {\n const requestMaker: RequestMaker = config?.requests?.makeRequest || makeRequest\n const requestOptions: MakeRequestParams = {\n url: getURL(service),\n retries: options.retries,\n timeout: options.timeout,\n data: {\n body,\n signature,\n },\n }\n const result = await requestMaker(requestOptions)\n\n if (result.statusCode !== 200) {\n throw new Error(`Wrong status code ${result.statusCode}`)\n }\n\n const data: RequestHandlerResponse = result.data\n\n if (data.error) {\n const info = data.errorInfo\n if (info) {\n if (data.isValidationError) {\n throw createEchoesValidationError(info)\n }\n if (data.isUserError) {\n throw createEchoesUserError(info)\n }\n }\n\n throw new Error(`${data.error}`)\n }\n\n const response = deserialize(data.result)\n return response\n } catch (error) {\n const caught = error as any\n if (caught.isOrionError || caught.isEchoesError) throw caught\n\n throw new Error(`Echoes request network error calling ${service}/${method}: ${caught.message}`)\n }\n}\n","import {randomUUID} from 'node:crypto'\nimport deserialize from '../echo/deserialize'\nimport type {\n EventSubscriptionDefinition,\n EventTransport,\n EventTransportStartOptions,\n} from '../events/EventTransport'\nimport serialize from '../publish/serialize'\nimport {getEchoesLogger} from '../runtime'\nimport type {\n EchoesKafkaEventsConfig,\n EchoesKafkaMessagePayload,\n EchoesReceivedEvent,\n PublishOptions,\n} from '../types'\n\nconst HEARTBEAT_INTERVAL_SECONDS = 5\nconst CHECK_JOIN_CONSUMER_INTERVAL_SECONDS = 30\nconst DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY = 4\nconst DEFAULT_MEMBERS_TO_PARTITIONS_RATIO = 1\n\n/**\n * Kafka event transport. It retains the existing consumer-group and retry behavior.\n */\nclass KafkaManager implements EventTransport {\n readonly name = 'kafka' as const\n\n private kafka?: any\n private readonly options: EchoesKafkaEventsConfig\n private producer?: any\n private consumer?: any\n private topics: string[] = []\n private subscriptions = new Map<string, EventSubscriptionDefinition>()\n private onEvent?: (event: EchoesReceivedEvent) => Promise<void>\n private consumerStarted = false\n private producerConnected = false\n private interval?: NodeJS.Timeout\n\n constructor(options: EchoesKafkaEventsConfig) {\n this.options = options\n }\n\n async start(options: EventTransportStartOptions) {\n let kafkaModule: typeof import('kafkajs')\n try {\n kafkaModule = await import('kafkajs')\n } catch (error) {\n const wrapped = new Error(\n 'Echoes Kafka transport requires kafkajs to be installed in the application',\n )\n ;(wrapped as any).cause = error\n throw wrapped\n }\n this.kafka = new kafkaModule.Kafka(this.options.client as any)\n\n this.onEvent = options.onEvent\n this.subscriptions = new Map(\n options.subscriptions.map(subscription => [subscription.topic, subscription]),\n )\n this.topics = options.subscriptions.map(subscription => subscription.topic)\n\n // Kafka retries and DLQ publishing use a producer even on consumer-only servers.\n if (options.publish || options.consume) {\n this.producer = this.kafka.producer(this.options.producer)\n await this.producer.connect()\n this.producerConnected = true\n }\n\n if (!options.consume || this.topics.length === 0) return\n if (!this.options.consumer?.groupId) {\n throw new Error('Echoes Kafka consumers require consumer.groupId')\n }\n\n this.consumer = this.kafka.consumer(this.options.consumer)\n this.consumerStarted = await this.conditionalStart()\n if (this.consumerStarted) return\n\n getEchoesLogger().info('Echoes: Delaying consumer group join, waiting for conditions to be met')\n this.interval = setInterval(async () => {\n this.consumerStarted = await this.conditionalStart()\n if (this.consumerStarted) clearInterval(this.interval)\n }, CHECK_JOIN_CONSUMER_INTERVAL_SECONDS * 1000)\n }\n\n async publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!this.producer || !this.producerConnected) {\n throw new Error('Echoes Kafka producer is not connected')\n }\n\n return await this.producer.send({\n acks: options.acks,\n timeout: options.timeout,\n topic: options.topic,\n messages: [\n {\n value: serialize({params: options.params}),\n headers: {\n 'echoes-event-id': randomUUID(),\n },\n },\n ],\n })\n }\n\n async close() {\n const logger = getEchoesLogger()\n logger.warn('Echoes: Stopping Kafka transport')\n if (this.interval) clearInterval(this.interval)\n await Promise.all([\n this.consumer?.disconnect(),\n this.producerConnected ? this.producer?.disconnect() : undefined,\n ])\n this.consumerStarted = false\n this.producerConnected = false\n }\n\n private async checkJoinConsumerGroupConditions(): Promise<boolean> {\n const logger = getEchoesLogger()\n const admin = this.kafka.admin()\n try {\n await admin.connect()\n const groupId = this.options.consumer.groupId\n const groupDescriptions = await admin.describeGroups([groupId])\n const group = groupDescriptions.groups[0]\n if (group.state === 'Empty') {\n logger.info(`Echoes: Consumer group ${groupId} is empty, joining`)\n return true\n }\n const topicsMetadata = await admin.fetchTopicMetadata({topics: this.topics})\n const totalPartitions = topicsMetadata.topics.reduce(\n (acc, topic) => acc + topic.partitions.length,\n 0,\n )\n logger.info(\n `Echoes: Consumer group ${groupId} has ${group.members.length} members and ${totalPartitions} partitions`,\n )\n const partitionsRatio =\n this.options.membersToPartitionsRatio || DEFAULT_MEMBERS_TO_PARTITIONS_RATIO\n const partitionsThreshold = Math.ceil(totalPartitions * partitionsRatio)\n if (partitionsThreshold > group.members.length) {\n logger.info(\n `Echoes: Consumer group ${groupId} has room for more members ${group.members.length}/${partitionsThreshold}, joining`,\n )\n return true\n }\n return false\n } catch (error) {\n logger.error('Echoes: Error checking consumer group conditions, join', {error})\n return true\n } finally {\n await admin.disconnect().catch(error => {\n logger.error('Echoes: Error disconnecting admin client', {error})\n })\n }\n }\n\n private async joinConsumerGroup() {\n await this.consumer.connect()\n await this.consumer.subscribe({topics: this.topics})\n await this.consumer.run({\n partitionsConsumedConcurrently:\n this.options.partitionsConsumedConcurrently || DEFAULT_PARTITIONS_CONSUMED_CONCURRENTLY,\n eachMessage: params => this.handleMessage(params),\n })\n }\n\n private async conditionalStart(): Promise<boolean> {\n if (await this.checkJoinConsumerGroupConditions()) {\n await this.joinConsumerGroup()\n return true\n }\n return false\n }\n\n private async handleMessage(params: EchoesKafkaMessagePayload) {\n const logger = getEchoesLogger()\n const subscription = this.subscriptions.get(params.topic)\n if (!subscription) {\n logger.warn(`Echoes: Received a message for an unknown topic: ${params.topic}, ignoring it`)\n return\n }\n\n let intervalsCount = 0\n const heartbeatInterval = setInterval(async () => {\n await params.heartbeat().catch(error => {\n logger.warn(`Echoes: Error sending heartbeat: ${error.message}`)\n })\n intervalsCount++\n if ((intervalsCount * HEARTBEAT_INTERVAL_SECONDS) % 30 === 0) {\n logger.warn(\n `Echoes: Event is taking too long to process: ${params.topic} ${intervalsCount * HEARTBEAT_INTERVAL_SECONDS}s`,\n )\n }\n }, HEARTBEAT_INTERVAL_SECONDS * 1000)\n\n try {\n const event = this.createReceivedEvent(params)\n await this.onEvent(event)\n } catch (error) {\n try {\n await this.handleRetries(subscription, params, error as Error)\n } catch (retryError) {\n logger.error('Echoes: error processing a message', {\n error: retryError,\n topic: params.topic,\n })\n throw retryError\n }\n } finally {\n clearInterval(heartbeatInterval)\n }\n }\n\n private createReceivedEvent(params: EchoesKafkaMessagePayload): EchoesReceivedEvent {\n const {message, topic, partition} = params\n if (!message.value) {\n throw new Error(`Echoes received an empty Kafka message for ${topic}`)\n }\n const data = deserialize(message.value.toString())\n const retries = Number.parseInt(message.headers?.retries?.toString() || '0', 10)\n const timestamp = Number.parseInt(message.timestamp || '', 10)\n\n return {\n id:\n message.headers?.['echoes-event-id']?.toString() ||\n `kafka:${topic}:${partition}:${message.offset}`,\n topic,\n data,\n transport: 'kafka',\n headers: message.headers,\n createdAt: Number.isFinite(timestamp) ? new Date(timestamp) : new Date(),\n attempt: retries + 1,\n context: params,\n }\n }\n\n private async handleRetries(\n subscription: EventSubscriptionDefinition,\n params: EchoesKafkaMessagePayload,\n error: Error,\n ) {\n const logger = getEchoesLogger()\n const {message, topic} = params\n const retries = Number.parseInt(message?.headers?.retries?.toString() || '0', 10)\n if (\n subscription.attemptsBeforeDeadLetter === undefined ||\n subscription.attemptsBeforeDeadLetter === null\n ) {\n throw error\n }\n const maxRetries = subscription.attemptsBeforeDeadLetter || 0\n const exceededMaxRetries = retries >= maxRetries\n const nextTopic = exceededMaxRetries ? `DLQ-${topic}` : topic\n if (!message.value) throw error\n await this.producer.send({\n topic: nextTopic,\n messages: [\n {\n value: message.value.toString(),\n headers: {\n ...message.headers,\n retries: String(retries + 1),\n error: error.message,\n },\n },\n ],\n })\n\n if (exceededMaxRetries) {\n logger.error(\n 'Echoes: a message has reached the maximum number of retries, sending it to DLQ',\n {topic: nextTopic},\n )\n } else {\n logger.warn('Echoes: a retryable message failed', {error, topic: nextTopic})\n }\n }\n}\n\nexport default KafkaManager\n","import {getEchoesLogger} from '../runtime'\nimport type {\n EchoesEventTransportName,\n EchoesMap,\n EchoesReceivedEvent,\n PublishOptions,\n} from '../types'\nimport type {EventSubscriptionDefinition, EventTransport} from './EventTransport'\n\nexport interface EventBusOptions {\n echoes: EchoesMap\n transports: Partial<Record<EchoesEventTransportName, EventTransport>>\n consumeFrom: EchoesEventTransportName[]\n publishTo?: EchoesEventTransportName\n}\n\nexport default class EventBus {\n private readonly echoes: EchoesMap\n private readonly transports: Partial<Record<EchoesEventTransportName, EventTransport>>\n private readonly consumeFrom: EchoesEventTransportName[]\n private readonly publishTo?: EchoesEventTransportName\n private readonly startedTransports: EventTransport[] = []\n private started = false\n private closed = false\n\n constructor(options: EventBusOptions) {\n this.echoes = options.echoes\n this.transports = options.transports\n this.consumeFrom = [...new Set(options.consumeFrom)]\n this.publishTo = options.publishTo\n }\n\n async start() {\n if (this.started) return\n\n const selected = new Set(this.consumeFrom)\n if (this.publishTo) selected.add(this.publishTo)\n\n for (const name of selected) {\n if (!this.transports[name]) {\n throw new Error(`Echoes event transport \"${name}\" is selected but not configured`)\n }\n }\n\n const subscriptions: EventSubscriptionDefinition[] = Object.entries(this.echoes)\n .filter(([, echo]) => echo.type === 'event')\n .map(([topic, echo]) => ({\n topic,\n attemptsBeforeDeadLetter: echo.attemptsBeforeDeadLetter,\n ordered: echo.ordered,\n configVersion: echo.configVersion,\n }))\n\n try {\n for (const name of selected) {\n const transport = this.transports[name]\n this.startedTransports.push(transport)\n await transport.start({\n consume: this.consumeFrom.includes(name),\n publish: this.publishTo === name,\n subscriptions,\n onEvent: event => this.handleEvent(event),\n })\n }\n this.started = true\n } catch (error) {\n await this.close().catch(() => undefined)\n throw error\n }\n }\n\n async publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!this.started) {\n throw new Error('You must initialize echoes configuration to use publish')\n }\n if (!this.publishTo) {\n throw new Error('Echoes does not have a publish transport configured')\n }\n\n return await this.transports[this.publishTo].publish(options)\n }\n\n async close() {\n if (this.closed) return\n this.closed = true\n await Promise.all(this.startedTransports.map(transport => transport.close()))\n }\n\n private async handleEvent(event: EchoesReceivedEvent) {\n const logger = getEchoesLogger()\n const echo = this.echoes[event.topic]\n if (!echo || echo.type !== 'event') {\n logger.warn(`Echoes: Received a message for an unknown topic: ${event.topic}, ignoring it`)\n return\n }\n\n // Preserve the exact legacy Kafka entrypoint for custom EchoType implementations.\n if (event.transport === 'kafka' && event.context) {\n await echo.onMessage(event.context as any)\n return\n }\n\n if (echo.onEvent) {\n await echo.onEvent(event)\n return\n }\n\n await echo.resolve(event.data.params, {\n ...(event.context || {}),\n transport: event.transport,\n eventId: event.id,\n topic: event.topic,\n headers: event.headers,\n createdAt: event.createdAt,\n attempt: event.attempt,\n data: event.data,\n })\n }\n}\n","import type {\n EchoesEventPayload,\n EchoesPulseEventsConfig,\n EchoesReceivedEvent,\n PublishOptions,\n} from '../types'\nimport type {EventTransport, EventTransportStartOptions} from './EventTransport'\n\ntype PulseSubscribeOptions = NonNullable<EchoesPulseEventsConfig['subscription']>\n\ninterface PulseReceivedEvent {\n id: string\n topic: string\n data: EchoesEventPayload\n headers?: Record<string, unknown>\n createdAt: Date\n attempt: number\n}\n\nexport default class PulseManager implements EventTransport {\n readonly name = 'pulse' as const\n\n private readonly options: EchoesPulseEventsConfig\n private pulse?: any\n private subscriptions: Array<{unsubscribe(): Promise<void>}> = []\n\n constructor(options: EchoesPulseEventsConfig) {\n this.options = options\n }\n\n async start(options: EventTransportStartOptions) {\n let pulseModule: any\n try {\n pulseModule = await import('@orion-js/pulse')\n } catch (error) {\n const wrapped = new Error(\n 'Echoes Pulse transport requires @orion-js/pulse to be installed in the application',\n )\n ;(wrapped as any).cause = error\n throw wrapped\n }\n\n const {subscription, ...connectOptions} = this.options\n this.pulse = pulseModule.connect(connectOptions)\n await this.pulse.awaitConnection()\n\n if (!options.consume) return\n\n this.subscriptions = await Promise.all(\n options.subscriptions.map(definition =>\n this.pulse.subscribe(\n definition.topic,\n event => options.onEvent(this.createReceivedEvent(event)),\n this.getSubscribeOptions(subscription, definition),\n ),\n ),\n )\n }\n\n async publish<TParams = any>(options: PublishOptions<TParams>) {\n if (!this.pulse) {\n throw new Error('Echoes Pulse client is not connected')\n }\n\n return await this.pulse.publish({\n topic: options.topic,\n data: {params: options.params},\n })\n }\n\n async close() {\n await this.pulse?.close()\n this.subscriptions = []\n }\n\n private getSubscribeOptions(\n defaults: PulseSubscribeOptions = {},\n definition: EventTransportStartOptions['subscriptions'][number],\n ): PulseSubscribeOptions {\n return {\n ...defaults,\n ...(definition.ordered === undefined ? {} : {ordered: definition.ordered}),\n ...(definition.configVersion === undefined ? {} : {configVersion: definition.configVersion}),\n ...(definition.attemptsBeforeDeadLetter === undefined\n ? {}\n : {maxRetries: definition.attemptsBeforeDeadLetter}),\n }\n }\n\n private createReceivedEvent(event: PulseReceivedEvent): EchoesReceivedEvent {\n return {\n id: event.id,\n topic: event.topic,\n data: event.data,\n transport: 'pulse',\n headers: event.headers,\n createdAt: event.createdAt,\n attempt: event.attempt,\n context: event,\n }\n }\n}\n","import KafkaManager from '../startService/KafkaManager'\nimport type {\n EchoesEventTransportName,\n EchoesKafkaEventsConfig,\n EchoesOptions,\n EchoesPulseEventsConfig,\n} from '../types'\nimport EventBus from './EventBus'\nimport type {EventTransport} from './EventTransport'\nimport PulseManager from './PulseManager'\n\nexport interface ResolvedEventsConfig {\n kafka?: EchoesKafkaEventsConfig\n pulse?: EchoesPulseEventsConfig\n consumeFrom: EchoesEventTransportName[]\n publishTo?: EchoesEventTransportName\n}\n\nexport function resolveEventsConfig(options: EchoesOptions): ResolvedEventsConfig | undefined {\n const legacyKafka = options.client\n ? {\n client: options.client,\n producer: options.producer,\n consumer: options.consumer,\n readTopicsFromBeginning: options.readTopicsFromBeginning,\n partitionsConsumedConcurrently: options.partitionsConsumedConcurrently,\n membersToPartitionsRatio: options.membersToPartitionsRatio,\n }\n : undefined\n\n const kafka = options.events?.kafka || legacyKafka\n const pulse = options.events?.pulse\n\n if (!kafka && !pulse && !options.events) return undefined\n\n const defaultTransport: EchoesEventTransportName | undefined = kafka\n ? 'kafka'\n : pulse\n ? 'pulse'\n : undefined\n\n return {\n kafka,\n pulse,\n consumeFrom: options.events?.consumeFrom || (defaultTransport ? [defaultTransport] : []),\n publishTo: options.events?.publishTo || defaultTransport,\n }\n}\n\nexport default function createEventBus(options: EchoesOptions) {\n const resolved = resolveEventsConfig(options)\n if (!resolved) return undefined\n\n const transports: Partial<Record<EchoesEventTransportName, EventTransport>> = {}\n if (resolved.kafka) transports.kafka = new KafkaManager(resolved.kafka)\n if (resolved.pulse) transports.pulse = new PulseManager(resolved.pulse)\n\n return new EventBus({\n echoes: options.echoes,\n transports,\n consumeFrom: resolved.consumeFrom,\n publishTo: resolved.publishTo,\n })\n}\n","import getSignature from '../request/getSignature'\n\nexport default function (body: any, signature: string) {\n const generatedSignature = getSignature(body)\n if (generatedSignature !== signature) {\n throw new Error('Echoes invalid signature')\n }\n}\n","import config from '../config'\n\nexport default function (method: string) {\n const echo = config.echoes[method]\n\n if (!echo) {\n throw new Error(`Echo named ${method} not found in this service`)\n }\n\n if (echo.type !== 'request') {\n throw new Error(`Echo named ${method} is not of type request`)\n }\n\n return echo\n}\n","import serialize from '../publish/serialize'\nimport {getEchoesLogger} from '../runtime'\nimport {EchoesOptions} from '../types'\nimport checkSignature from './checkSignature'\nimport getEcho from './getEcho'\n\nexport default (options: EchoesOptions) =>\n ({\n method: 'post',\n path: options.requests.handlerPath || '/echoes-services',\n bodyLimit: '10mb',\n async handle(requestBody: any) {\n try {\n const {body, signature} = requestBody\n\n checkSignature(body, signature)\n\n const {method, serializedParams} = body\n\n const echo = getEcho(method)\n const result = await echo.onRequest(serializedParams)\n\n return {result: serialize(result)}\n } catch (error) {\n const caught = error as any\n if (!caught.getInfo) {\n getEchoesLogger().error('Error at echo requests handler:', {error: caught})\n }\n\n return {\n error: caught.message,\n errorInfo: caught.getInfo ? caught.getInfo() : null,\n isValidationError: !!caught.isValidationError,\n isUserError: !!caught.isUserError,\n }\n }\n },\n }) as const\n","import config from '../config'\nimport createEventBus from '../events/createEventBus'\nimport EventBus from '../events/EventBus'\nimport requestsHandler from '../requestsHandler'\nimport {getEchoesLogger, getEchoesRuntime} from '../runtime'\nimport {EchoesOptions} from '../types'\n\nlet eventBus: EventBus = null\n\nexport default async function startService(options: EchoesOptions) {\n config.echoes = options.echoes\n\n if (options.requests) {\n config.requests = options.requests\n const registerHandler =\n options.requests.registerHandler || getEchoesRuntime().registerRequestHandler\n if (!registerHandler) {\n throw new Error(\n 'Echoes requests require requests.registerHandler in standalone servers. Orion applications can import @orion-js/echoes-orion once during startup.',\n )\n }\n await registerHandler(requestsHandler(options))\n }\n\n const nextEventBus = createEventBus(options)\n if (nextEventBus) {\n await nextEventBus.start()\n eventBus = nextEventBus\n config.eventBus = eventBus\n }\n}\n\nexport async function stopService() {\n if (eventBus) {\n const logger = getEchoesLogger()\n logger.info('Stopping Echoes...')\n await eventBus.close()\n eventBus = null\n config.eventBus = undefined\n logger.info('Echoes stopped')\n }\n}\n","import {cleanEchoesSchema, parseEchoesSchema} from '../runtime'\nimport type {EchoesSchema, InferEchoesSchema} from '../schema'\nimport {\n EchoConfig,\n EchoEventConfig,\n EchoesKafkaMessagePayload,\n EchoesReceivedEvent,\n EchoRequestConfig,\n EchoType,\n} from '../types'\nimport deserialize from './deserialize'\n\n/**\n * @deprecated Use createEchoRequest and createEchoEvent instead\n */\nconst echo = function createNewEcho<\n TParamsSchema extends EchoesSchema,\n TReturnsSchema extends EchoesSchema,\n TEchoType extends 'event' | 'request',\n>(\n options: EchoConfig<TParamsSchema, TReturnsSchema, TEchoType>,\n): EchoType<TParamsSchema, TReturnsSchema, TEchoType> {\n const resolve = async (params: InferEchoesSchema<TParamsSchema>, context: any) => {\n const cleaned = options.params\n ? await parseEchoesSchema<InferEchoesSchema<TParamsSchema>>(options.params, params)\n : (params ?? ({} as InferEchoesSchema<TParamsSchema>))\n\n const result = await options.resolve(cleaned, context)\n\n if (options.returns) {\n return await cleanEchoesSchema<InferEchoesSchema<TReturnsSchema>>(options.returns, result)\n }\n\n return result\n }\n\n const onEvent = async (event: EchoesReceivedEvent) => {\n const context = {\n ...(event.context || {}),\n transport: event.transport,\n eventId: event.id,\n topic: event.topic,\n headers: event.headers,\n createdAt: event.createdAt,\n attempt: event.attempt,\n data: event.data,\n }\n\n await resolve(event.data.params, context)\n }\n\n return {\n type: options.type,\n params: options.params,\n returns: options.returns,\n attemptsBeforeDeadLetter:\n options.type === 'event' ? options.attemptsBeforeDeadLetter : undefined,\n ordered:\n options.type === 'event'\n ? (options as EchoEventConfig<TParamsSchema, TReturnsSchema>).ordered\n : undefined,\n configVersion:\n options.type === 'event'\n ? (options as EchoEventConfig<TParamsSchema, TReturnsSchema>).configVersion\n : undefined,\n resolve,\n onEvent,\n onMessage: async (messageData: EchoesKafkaMessagePayload) => {\n const {message} = messageData\n if (!message.value) {\n throw new Error(`Echoes received an empty Kafka message for ${messageData.topic}`)\n }\n\n const data = deserialize(message.value.toString())\n const retries = Number.parseInt(message.headers?.retries?.toString() || '0', 10)\n const timestamp = Number(message.timestamp)\n const createdAt = Number.isFinite(timestamp) ? new Date(timestamp) : new Date()\n const eventId =\n message.headers?.['echoes-event-id']?.toString() ||\n `kafka:${messageData.topic}:${messageData.partition}:${message.offset}`\n\n await onEvent({\n id: eventId,\n topic: messageData.topic,\n data,\n transport: 'kafka',\n headers: message.headers,\n createdAt,\n attempt: retries + 1,\n context: messageData,\n })\n },\n onRequest: async (serializedParams: string) => {\n const context = {}\n const params = deserialize(serializedParams)\n\n return await resolve(params, context)\n },\n }\n}\n\nexport function createEchoRequest<\n TParamsSchema extends EchoesSchema,\n TReturnsSchema extends EchoesSchema,\n>(\n options: EchoRequestConfig<TParamsSchema, TReturnsSchema>,\n): EchoType<TParamsSchema, TReturnsSchema, 'request'> {\n return echo({...options, type: 'request'})\n}\nexport function createEchoEvent<\n TParamsSchema extends EchoesSchema,\n TReturnsSchema extends EchoesSchema,\n>(\n options: EchoEventConfig<TParamsSchema, TReturnsSchema>,\n): EchoType<TParamsSchema, TReturnsSchema, 'event'> {\n return echo({...options, type: 'event' as any})\n}\n\nexport {echo}\n","export type EchoesSchema = unknown\n\ntype InferFieldType<T> = T extends {__tsFieldType: infer U}\n ? U\n : T extends 'string' | 'ID' | 'email'\n ? string\n : T extends 'date'\n ? Date\n : T extends 'integer' | 'number'\n ? number\n : T extends 'boolean'\n ? boolean\n : T extends 'blackbox'\n ? Record<string, any>\n : T extends 'any'\n ? any\n : T extends String | StringConstructor\n ? string\n : T extends Number | NumberConstructor\n ? number\n : T extends Boolean | BooleanConstructor\n ? boolean\n : T extends Date | DateConstructor\n ? Date\n : T extends Array<infer U>\n ? InferFieldType<U>[]\n : T extends Record<string, any>\n ? InferObjectSchema<T>\n : T\n\ntype NodeIsOptional<T> = T extends {optional: true} ? true : false\n\ntype InferObjectSchema<T extends Record<string, any>> = {\n -readonly [K in keyof T as NodeIsOptional<T[K]> extends true ? never : K]: InferEchoesSchema<\n T[K] extends {type: infer U} ? U : T[K]\n >\n} & {\n -readonly [K in keyof T as NodeIsOptional<T[K]> extends true ? K : never]?: InferEchoesSchema<\n T[K] extends {type: infer U} ? U : T[K]\n >\n}\n\ntype IsObjectSchema<T> =\n T extends Record<string, any>\n ? keyof {\n [K in keyof T as T[K] extends {type: any} ? K : never]: T[K]\n } extends never\n ? false\n : true\n : false\n\ntype AbstractClass<T = any> = abstract new (...args: any[]) => T\n\n/**\n * Infers the value represented by Orion-style schema declarations without\n * requiring @orion-js/schema to be installed.\n */\nexport type InferEchoesSchema<T> = T extends {__echoesType: infer U}\n ? U\n : T extends {__tsFieldType: infer U}\n ? U\n : T extends {__isModel: true; type: infer U}\n ? U extends Record<string, any>\n ? InferObjectSchema<U>\n : InferFieldType<U>\n : T extends StringConstructor\n ? string\n : T extends NumberConstructor\n ? number\n : T extends BooleanConstructor\n ? boolean\n : T extends DateConstructor\n ? Date\n : T extends AbstractClass<infer U>\n ? U\n : IsObjectSchema<T> extends true\n ? T extends Record<string, any>\n ? InferObjectSchema<T>\n : never\n : InferFieldType<T>\n\n/**\n * Adds compile-time value information to a runtime schema such as SimpleSchema.\n * It returns the same object and has no runtime cost.\n */\nexport function typedEchoesSchema<TValue, TSchema extends object = object>(\n schema: TSchema,\n): TSchema & {readonly __echoesType: TValue} {\n return schema as TSchema & {readonly __echoesType: TValue}\n}\n","import {createEchoEvent, createEchoRequest} from '../echo'\nimport {getEchoesRuntime, runWithEchoesContext} from '../runtime'\nimport {EchoConfig, EchoesMap} from '../types'\n\nexport interface EchoesPropertyDescriptor extends Omit<PropertyDecorator, 'value'> {\n value?: EchoConfig<any, any>['resolve']\n}\n// Define metadata storage using WeakMaps\nconst serviceMetadata = new WeakMap<any, {_serviceType: string}>()\nconst echoesMetadata = new WeakMap<any, Record<string, any>>()\nconst echoEntriesByClass = new Map<Function, Record<string, (instance: any) => any>>()\nconst standaloneInstances = new WeakMap<Function, any>()\nlet pendingEchoEntries: Record<string, (instance: any) => any> = {}\n\nexport function Echoes() {\n return (target: any, context: ClassDecoratorContext<any>) => {\n getEchoesRuntime().decorateService?.(target, context)\n serviceMetadata.set(target, {_serviceType: 'echoes'})\n\n if (Object.keys(pendingEchoEntries).length > 0) {\n echoEntriesByClass.set(target, pendingEchoEntries)\n pendingEchoEntries = {}\n }\n }\n}\n\nexport function EchoEvent(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EchoEvent(\n options?: Omit<EchoConfig<any, any>, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EchoEvent(options = {}) {\n return (method: any, context: ClassMethodDecoratorContext | ClassFieldDecoratorContext) => {\n const propertyKey = String(context.name)\n\n if (context.kind === 'method') {\n pendingEchoEntries[propertyKey] = (instance: any) => {\n const originalResolve = instance[propertyKey].bind(instance)\n return createEchoEvent({\n ...options,\n resolve: async (params, contextData) => {\n return await runWithEchoesContext(\n {\n controllerType: 'echo',\n echoName: propertyKey,\n params,\n },\n async () => {\n return await originalResolve(params, contextData)\n },\n )\n },\n })\n }\n }\n\n if (context.kind === 'field') {\n pendingEchoEntries[propertyKey] = (instance: any) => instance[propertyKey]\n }\n\n return method\n }\n}\n\nexport function EchoRequest(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EchoRequest(\n options?: Omit<EchoConfig<any, any>, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EchoRequest(options = {}) {\n return (method: any, context: ClassMethodDecoratorContext | ClassFieldDecoratorContext) => {\n const propertyKey = String(context.name)\n\n if (context.kind === 'method') {\n pendingEchoEntries[propertyKey] = (instance: any) => {\n const originalResolve = instance[propertyKey].bind(instance)\n return createEchoRequest({\n ...options,\n resolve: async (params, contextData) => {\n return await runWithEchoesContext(\n {\n controllerType: 'echo',\n echoName: propertyKey,\n params,\n },\n async () => {\n return await originalResolve(params, contextData)\n },\n )\n },\n })\n }\n }\n\n if (context.kind === 'field') {\n pendingEchoEntries[propertyKey] = (instance: any) => instance[propertyKey]\n }\n\n return method\n }\n}\n\nfunction initializeEchoesIfNeeded(instance: any) {\n if (echoesMetadata.has(instance)) return\n const entries = echoEntriesByClass.get(instance.constructor) || {}\n const echoes: Record<string, any> = {}\n for (const [key, setup] of Object.entries(entries)) {\n echoes[key] = setup(instance)\n }\n echoesMetadata.set(instance, echoes)\n}\n\nexport function getServiceEchoes(target: any): EchoesMap {\n let instance: any\n if (typeof target !== 'function') {\n instance = target\n } else if (getEchoesRuntime().getInstance) {\n instance = getEchoesRuntime().getInstance(target)\n } else {\n instance = standaloneInstances.get(target)\n if (!instance) {\n instance = new target()\n standaloneInstances.set(target, instance)\n }\n }\n\n if (!serviceMetadata.has(instance.constructor)) {\n throw new Error('You must pass a class decorated with @Echoes to getServiceEchoes')\n }\n\n const instanceMetadata = serviceMetadata.get(instance.constructor)\n if (instanceMetadata._serviceType !== 'echoes') {\n throw new Error('You must pass a class decorated with @Echoes to getServiceEchoes')\n }\n\n initializeEchoesIfNeeded(instance)\n\n const echoesMap = echoesMetadata.get(instance) || {}\n\n return echoesMap\n}\n"],"mappings":";AAEA,IAAM,SAA8B,CAAC;AAErC,IAAO,iBAAQ;;;ACEf,eAAO,QAA8C,SAAkC;AACrF,MAAI,CAAC,eAAO,UAAU;AACpB,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AAEA,SAAO,MAAM,eAAO,SAAS,QAAQ,OAAO;AAC9C;;;ACZe,SAAR,oBAAkB,sBAAmC;AAC1D,MAAI;AACF,WAAO,KAAK,MAAM,uBAAuB,GAAG;AAAA,EAC9C,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD;AACF;;;ACNA,OAAO,eAAe;AAEtB,SAAS,wBACP,YACA,YACoB;AAGpB,QAAM,mBAAmB,EAAC,GAAG,YAAY,cAAc,KAAI;AAC3D,MAAI,WAAW,kBAAkB;AAC/B,qBAAiB,QAAQ,sBAAsB,iBAAiB,OAAO,UAAU;AAAA,EACnF;AACA,SAAO;AACT;AAEA,SAAS,kBACP,QACA,QACA,YACA,aAA4C,MAAM,MAClD;AACA,aAAW,OAAO,QAAQ,QAAQ,MAAM,GAAG;AACzC,QAAI,CAAC,WAAW,GAAG,EAAG;AACtB,UAAM,aAAa,OAAO,yBAAyB,QAAQ,GAAG;AAC9D,QAAI,CAAC,WAAY;AACjB,WAAO,eAAe,QAAQ,KAAK,wBAAwB,YAAY,UAAU,CAAC;AAAA,EACpF;AACF;AAEA,SAAS,qBAAqB,QAAgB,QAAgB,YAAkC;AAC9F,QAAM,SAAU,OAAe;AAC/B,MAAI,OAAO,WAAW,WAAY;AAElC,SAAO,eAAe,QAAQ,UAAU;AAAA,IACtC,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,MAAM,KAAa;AACjB,aAAO,sBAAsB,OAAO,KAAK,QAAQ,GAAG,GAAG,UAAU;AAAA,IACnE;AAAA,EACF,CAAC;AACH;AAEA,SAAS,qBACP,OACA,YACG;AACH,QAAM,eAAe,MAAM;AAC3B,MAAI,eAAe,WAAW,IAAI,YAAY;AAC9C,QAAM,6BAA6B,CAAC;AAEpC,MAAI,CAAC,cAAc;AACjB,mBAAe,aAAa,MAAM,CAAC;AACnC,eAAW,IAAI,cAAc,YAAY;AAAA,EAC3C;AAEA,QAAM,QACJ,iBAAiB,WACb,IAAI,SAAS,cAAc,MAAM,YAAY,MAAM,UAAU,IAC7D,IAAK,MAAM,YAAoB,cAAc,MAAM,YAAa,MAAc,MAAM;AAE1F,aAAW,IAAI,OAAO,KAAK;AAC3B,MAAI,4BAA4B;AAC9B,sBAAkB,cAAc,cAAc,UAAU;AAAA,EAC1D;AAIA,oBAAkB,OAAO,OAAO,YAAY,SAAO;AACjD,QAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,UAAM,QAAQ,OAAO,GAAG;AACxB,WAAO,EACL,OAAO,UAAU,KAAK,KACtB,SAAS,KACT,QAAS,MAAc,UACvB,OAAO,KAAK,MAAM;AAAA,EAEtB,CAAC;AACD,SAAO;AACT;AAEA,SAAS,sBAAyB,OAAU,aAAa,oBAAI,QAAqB,GAAM;AACtF,MAAI,UAAU,QAAS,OAAO,UAAU,YAAY,OAAO,UAAU,WAAa,QAAO;AACzF,MAAI,OAAO,UAAU,WAAY,QAAO;AAExC,QAAM,SAAS;AACf,MAAI,WAAW,IAAI,MAAM,EAAG,QAAO,WAAW,IAAI,MAAM;AAExD,MAAI,iBAAiB,MAAM;AACzB,UAAMA,SAAQ,IAAI,KAAK,MAAM,QAAQ,CAAC;AACtC,WAAO,eAAeA,QAAO,OAAO,eAAe,KAAK,CAAC;AACzD,eAAW,IAAI,QAAQA,MAAK;AAC5B,WAAOA;AAAA,EACT;AAEA,MAAI,iBAAiB,QAAQ;AAC3B,UAAMA,SAAQ,IAAI,OAAO,MAAM,QAAQ,MAAM,KAAK;AAClD,IAAAA,OAAM,YAAY,MAAM;AACxB,WAAO,eAAeA,QAAO,OAAO,eAAe,KAAK,CAAC;AACzD,eAAW,IAAI,QAAQA,MAAK;AAC5B,WAAOA;AAAA,EACT;AAEA,MAAI,iBAAiB,KAAK;AACxB,UAAMA,SAAQ,oBAAI,IAAI;AACtB,eAAW,IAAI,QAAQA,MAAK;AAC5B,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO;AAChC,UAAI,UAAU,IAAI;AAAA,QAChBA;AAAA,QACA,sBAAsB,KAAK,UAAU;AAAA,QACrC,sBAAsB,OAAO,UAAU;AAAA,MACzC;AAAA,IACF;AACA,WAAO,eAAeA,QAAO,OAAO,eAAe,KAAK,CAAC;AACzD,WAAOA;AAAA,EACT;AAEA,MAAI,iBAAiB,KAAK;AACxB,UAAMA,SAAQ,oBAAI,IAAI;AACtB,eAAW,IAAI,QAAQA,MAAK;AAC5B,eAAW,SAAS,OAAO;AACzB,UAAI,UAAU,IAAI,KAAKA,QAAO,sBAAsB,OAAO,UAAU,CAAC;AAAA,IACxE;AACA,WAAO,eAAeA,QAAO,OAAO,eAAe,KAAK,CAAC;AACzD,WAAOA;AAAA,EACT;AAEA,MAAI,iBAAiB,KAAK;AACxB,UAAMA,SAAQ,IAAI,IAAI,MAAM,SAAS,CAAC;AACtC,WAAO,eAAeA,QAAO,OAAO,eAAe,KAAK,CAAC;AACzD,eAAW,IAAI,QAAQA,MAAK;AAC5B,WAAOA;AAAA,EACT;AAEA,MAAI,OAAO,SAAS,KAAK,GAAG;AAC1B,UAAMA,SAAQ,OAAO,KAAK,KAAK;AAC/B,eAAW,IAAI,QAAQA,MAAK;AAC5B,WAAOA;AAAA,EACT;AAEA,MAAI,YAAY,OAAO,KAAK,GAAG;AAC7B,WAAO,qBAAqB,OAAO,UAAU;AAAA,EAC/C;AAEA,MACE,iBAAiB,eAChB,OAAO,sBAAsB,eAAe,iBAAiB,mBAC9D;AACA,UAAMA,SAAQ,MAAM,MAAM,CAAC;AAC3B,eAAW,IAAI,QAAQA,MAAK;AAC5B,sBAAkB,OAAOA,QAAO,UAAU;AAC1C,WAAOA;AAAA,EACT;AAEA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,UAAMA,SAAQ,IAAI,MAAM,MAAM,MAAM;AACpC,WAAO,eAAeA,QAAO,OAAO,eAAe,KAAK,CAAC;AACzD,eAAW,IAAI,QAAQA,MAAK;AAC5B,sBAAkB,OAAOA,QAAO,YAAY,SAAO,QAAQ,QAAQ;AACnE,WAAOA;AAAA,EACT;AAEA,QAAM,QAAQ,OAAO,OAAO,OAAO,eAAe,KAAK,CAAC;AACxD,aAAW,IAAI,QAAQ,KAAK;AAC5B,oBAAkB,OAAO,OAAO,UAAU;AAC1C,uBAAqB,QAAQ,OAAO,UAAU;AAC9C,SAAO;AACT;AAEe,SAAR,kBAAkB,MAAmB;AAC1C,QAAM,aAAa,UAAU,sBAAsB,IAAI,GAAG,EAAC,gBAAgB,KAAI,CAAC;AAChF,SAAO;AACT;;;AC5KA,SAAQ,yBAAwB;AAChC,SAAQ,kBAAiB;;;ACOlB,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAChC,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EAET,YAAY,MAAc,SAAkB,OAAa;AACvD,QAAI,CAAC,SAAS;AACZ,gBAAU;AACV,aAAO;AAAA,IACT;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,UAA2B;AACzB,WAAO,EAAC,OAAO,KAAK,MAAM,SAAS,KAAK,SAAS,OAAO,KAAK,MAAK;AAAA,EACpE;AACF;AAEO,IAAM,wBAAN,cAAoC,MAAM;AAAA,EACtC,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EAET,YAAY,kBAA0C,SAAiC,CAAC,GAAG;AACzF,UAAM,kBAAkB,OAAO,QAAQ,gBAAgB,EACpD,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,KAAK,KAAK,EAAE,EACxC,KAAK,IAAI;AACZ,UAAM,sBAAsB,eAAe,GAAG;AAC9C,SAAK,OAAO;AACZ,SAAK,mBAAmB;AACxB,SAAK,SAAS,OAAO;AAAA,MACnB,OAAO,KAAK,gBAAgB,EACzB,OAAO,SAAO,OAAO,GAAG,CAAC,EACzB,IAAI,SAAO,CAAC,KAAK,OAAO,GAAG,CAAC,CAAC;AAAA,IAClC;AAAA,EACF;AAAA,EAEA,UAA2B;AACzB,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,SAAS;AAAA,MACT,kBAAkB,KAAK;AAAA,MACvB,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AACF;;;ADhBA,IAAM,gBAA8B;AAAA,EAClC,OAAO,CAAC,SAAS,aACf,aAAa,SAAY,QAAQ,MAAM,OAAO,IAAI,QAAQ,MAAM,SAAS,QAAQ;AAAA,EACnF,MAAM,CAAC,SAAS,aACd,aAAa,SAAY,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,SAAS,QAAQ;AAAA,EACjF,MAAM,CAAC,SAAS,aACd,aAAa,SAAY,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,SAAS,QAAQ;AAAA,EACjF,OAAO,CAAC,SAAS,aACf,aAAa,SAAY,QAAQ,MAAM,OAAO,IAAI,QAAQ,MAAM,SAAS,QAAQ;AACrF;AAEA,IAAI,UAAgC,CAAC;AACrC,IAAM,iBAAiB,IAAI,kBAAgE;AAMpF,SAAS,uBAAuB,SAA2C;AAChF,QAAM,WAAW;AACjB,YAAU,EAAC,GAAG,SAAS,GAAG,QAAO;AACjC,SAAO,MAAM;AACX,cAAU;AAAA,EACZ;AACF;AAEO,SAAS,mBAAyC;AACvD,SAAO;AACT;AAEO,SAAS,kBAAgC;AAC9C,SAAO,QAAQ,UAAU;AAC3B;AAEO,SAAS,mBAA+E;AAC7F,SAAO,eAAe,SAAS;AACjC;AAEA,eAAsB,qBACpB,SACA,UACY;AACZ,QAAM,gBAAgB,EAAC,WAAW,QAAQ,aAAa,WAAW,GAAG,GAAG,QAAO;AAC/E,SAAO,MAAM,eAAe,IAAI,eAAe,YAAY;AACzD,QAAI,QAAQ,gBAAgB;AAC1B,aAAO,MAAM,QAAQ,eAAe,eAAe,QAAQ;AAAA,IAC7D;AACA,WAAO,MAAM,SAAS;AAAA,EACxB,CAAC;AACH;AAEA,SAAS,mBAAmB,QAG1B;AACA,SACE,CAAC,CAAC,UACF,OAAO,WAAW,YAClB,OAAQ,OAAe,UAAU,cACjC,OAAQ,OAAe,aAAa;AAExC;AAEA,SAAS,WAAc,OAAa;AAClC,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,MAAI,iBAAiB,KAAM,QAAO,IAAI,KAAK,MAAM,QAAQ,CAAC;AAC1D,MAAI,OAAO,SAAS,KAAK,EAAG,QAAO,OAAO,KAAK,KAAK;AACpD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,UAAU;AACrD,QAAM,YAAY,OAAO,eAAe,KAAK;AAC7C,MAAI,cAAc,OAAO,aAAa,cAAc,KAAM,QAAO;AAEjE,QAAM,SAAkC,CAAC;AACzC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAgC,GAAG;AAC3E,WAAO,GAAG,IAAI,WAAW,KAAK;AAAA,EAChC;AACA,SAAO;AACT;AAEA,eAAe,kBACb,QAIA,OACY;AACZ,QAAM,SAAS,WAAW,KAAK;AAC/B,SAAQ,MAAM,OAAO,MAAM,QAAQ,EAAC,QAAQ,MAAK,CAAC;AACpD;AAEA,eAAsB,kBAAqB,QAAiB,OAA4B;AACtF,MAAI,mBAAmB,MAAM,GAAG;AAC9B,WAAO,MAAM,kBAAqB,QAAQ,KAAK;AAAA,EACjD;AACA,MAAI,QAAQ,QAAQ;AAClB,WAAO,MAAM,QAAQ,OAAO,MAAS,QAAQ,KAAK;AAAA,EACpD;AACA,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAEA,eAAsB,kBAAqB,QAAiB,OAA4B;AACtF,MAAI,mBAAmB,MAAM,GAAG;AAC9B,UAAM,UAAU,MAAM,kBAAqB,QAAQ,KAAK;AACxD,UAAM,OAAO,SAAS,OAAO;AAC7B,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,QAAQ;AAClB,WAAO,MAAM,QAAQ,OAAO,MAAS,QAAQ,KAAK;AAAA,EACpD;AACA,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAEO,SAAS,4BAA4B,MAA8B;AACxE,SAAO,QAAQ,wBACX,QAAQ,sBAAsB,IAAI,IAClC,IAAI,sBAAsB,KAAK,oBAAoB,CAAC,GAAG,KAAK,MAAM;AACxE;AAEO,SAAS,sBAAsB,MAA8B;AAClE,SAAO,QAAQ,kBACX,QAAQ,gBAAgB,IAAI,IAC5B,IAAI,gBAAgB,KAAK,OAAO,KAAK,SAAS,KAAK,KAAK;AAC9D;;;AE1KA,SAAQ,kBAAiB;;;ACGlB,SAAS,oBAAoB;AAHpC;AAIE,QAAM,WAAS,iDAAQ,aAAR,mBAAkB,QAAO,QAAQ,IAAI,mBAAmB,QAAQ,IAAI;AACnF,MAAI,CAAC,QAAQ;AACX,oBAAgB,EAAE;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;ADTe,SAAR,qBAAkB,OAAoB;AAC3C,QAAM,WAAW,kBAAkB;AAGnC,SAAO,WAAW,QAAQ,YAAY,EAAE,EACrC,OAAO,EAAE,EACT,OAAO,KAAK;AACjB;;;AERe,SAAR,eAAkB,aAA6B;AAFtD;AAGE,MAAI,YAAY,WAAW,MAAM,EAAG,QAAO;AAE3C,QAAM,OAAM,uDAAQ,aAAR,mBAAkB,aAAlB,mBAA6B;AAEzC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,6CAA6C,WAAW,EAAE;AAAA,EAC5E;AAEA,SAAO;AACT;;;ACZA,OAAO,UAAU;AACjB,OAAO,WAAW;AAGlB,eAAe,mBACb,UACA,UAAU,GACV,UAAU,KACE;AACZ,MAAI;AACF,WAAO,MAAM,SAAS;AAAA,EACxB,SAAS,OAAO;AACd,QAAI,WAAW,EAAG,OAAM;AACxB,UAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,OAAO,CAAC;AACzD,WAAO,MAAM,mBAAmB,UAAU,UAAU,GAAG,OAAO;AAAA,EAChE;AACF;AAEA,eAAe,SACb,UACA,MACA,SACA,qBAAqB,GACwB;AAC7C,QAAM,MAAM,IAAI,IAAI,QAAQ;AAC5B,QAAM,OAAO,KAAK,UAAU,IAAI;AAChC,QAAM,YAAY,IAAI,aAAa,WAAW,QAAQ;AAEtD,SAAO,MAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC5C,UAAMC,WAAU,UAAU;AAAA,MACxB;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,cAAc;AAAA,UACd,gBAAgB;AAAA,UAChB,kBAAkB,OAAO,WAAW,IAAI;AAAA,QAC1C;AAAA,MACF;AAAA,MACA,cAAY;AACV,cAAM,SAAmB,CAAC;AAC1B,cAAM,aAAa,SAAS,cAAc;AAC1C,YAAI,cAAc,OAAO,aAAa,OAAO,SAAS,QAAQ,UAAU;AACtE,mBAAS,OAAO;AAChB,cAAI,sBAAsB,GAAG;AAC3B,mBAAO,IAAI,MAAM,4CAA4C,CAAC;AAC9D;AAAA,UACF;AACA;AAAA,YACE;AAAA,cACE,IAAI,IAAI,SAAS,QAAQ,UAAU,GAAG,EAAE,SAAS;AAAA,cACjD;AAAA,cACA;AAAA,cACA,qBAAqB;AAAA,YACvB;AAAA,UACF;AACA;AAAA,QACF;AAEA,iBAAS,GAAG,QAAQ,WAAS,OAAO,KAAK,OAAO,KAAK,KAAK,CAAC,CAAC;AAC5D,iBAAS,GAAG,OAAO,MAAM;AACvB,cAAI;AACF,kBAAM,eAAe,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM;AAC1D,gBAAI,aAAa,OAAO,cAAc,KAAK;AACzC,qBAAO,IAAI,MAAM,mCAAmC,UAAU,EAAE,CAAC;AACjE;AAAA,YACF;AACA,oBAAQ;AAAA,cACN;AAAA,cACA,MAAM,eAAe,KAAK,MAAM,YAAY,IAAI,CAAC;AAAA,YACnD,CAAC;AAAA,UACH,SAAS,OAAO;AACd,mBAAO,KAAK;AAAA,UACd;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,IAAAA,SAAQ,GAAG,SAAS,MAAM;AAC1B,QAAI,SAAS;AACX,MAAAA,SAAQ,WAAW,SAAS,MAAM;AAChC,QAAAA,SAAQ,QAAQ,IAAI,MAAM,kCAAkC,OAAO,IAAI,CAAC;AAAA,MAC1E,CAAC;AAAA,IACH;AACA,IAAAA,SAAQ,IAAI,IAAI;AAAA,EAClB,CAAC;AACH;AAEO,IAAM,cAA4B,OAAM,YAAW;AACxD,SAAO,MAAM;AAAA,IACX,MAAM,SAAS,QAAQ,KAAK,QAAQ,MAAM,QAAQ,OAAO;AAAA,IACzD,QAAQ,WAAW;AAAA,EACrB;AACF;;;AC/EA,eAAO,QACL,SACgB;AAhBlB;AAiBE,QAAM,EAAC,QAAQ,SAAS,OAAM,IAAI;AAClC,QAAM,mBAAmB,kBAAU,MAAM;AACzC,QAAM,OAAO,oBAAI,KAAK;AACtB,QAAM,OAAO,EAAC,QAAQ,SAAS,kBAAkB,KAAI;AACrD,QAAM,YAAY,qBAAa,IAAI;AAEnC,MAAI;AACF,UAAM,iBAA6B,iDAAQ,aAAR,mBAAkB,gBAAe;AACpE,UAAM,iBAAoC;AAAA,MACxC,KAAK,eAAO,OAAO;AAAA,MACnB,SAAS,QAAQ;AAAA,MACjB,SAAS,QAAQ;AAAA,MACjB,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,UAAM,SAAS,MAAM,aAAa,cAAc;AAEhD,QAAI,OAAO,eAAe,KAAK;AAC7B,YAAM,IAAI,MAAM,qBAAqB,OAAO,UAAU,EAAE;AAAA,IAC1D;AAEA,UAAM,OAA+B,OAAO;AAE5C,QAAI,KAAK,OAAO;AACd,YAAM,OAAO,KAAK;AAClB,UAAI,MAAM;AACR,YAAI,KAAK,mBAAmB;AAC1B,gBAAM,4BAA4B,IAAI;AAAA,QACxC;AACA,YAAI,KAAK,aAAa;AACpB,gBAAM,sBAAsB,IAAI;AAAA,QAClC;AAAA,MACF;AAEA,YAAM,IAAI,MAAM,GAAG,KAAK,KAAK,EAAE;AAAA,IACjC;AAEA,UAAM,WAAW,oBAAY,KAAK,MAAM;AACxC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,SAAS;AACf,QAAI,OAAO,gBAAgB,OAAO,cAAe,OAAM;AAEvD,UAAM,IAAI,MAAM,wCAAwC,OAAO,IAAI,MAAM,KAAK,OAAO,OAAO,EAAE;AAAA,EAChG;AACF;;;AChEA,SAAQ,cAAAC,mBAAiB;AAgBzB,IAAM,6BAA6B;AACnC,IAAM,uCAAuC;AAC7C,IAAM,2CAA2C;AACjD,IAAM,sCAAsC;AAK5C,IAAM,eAAN,MAA6C;AAAA,EAClC,OAAO;AAAA,EAER;AAAA,EACS;AAAA,EACT;AAAA,EACA;AAAA,EACA,SAAmB,CAAC;AAAA,EACpB,gBAAgB,oBAAI,IAAyC;AAAA,EAC7D;AAAA,EACA,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB;AAAA,EAER,YAAY,SAAkC;AAC5C,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAM,MAAM,SAAqC;AA1CnD;AA2CI,QAAI;AACJ,QAAI;AACF,oBAAc,MAAM,OAAO,SAAS;AAAA,IACtC,SAAS,OAAO;AACd,YAAM,UAAU,IAAI;AAAA,QAClB;AAAA,MACF;AACC,MAAC,QAAgB,QAAQ;AAC1B,YAAM;AAAA,IACR;AACA,SAAK,QAAQ,IAAI,YAAY,MAAM,KAAK,QAAQ,MAAa;AAE7D,SAAK,UAAU,QAAQ;AACvB,SAAK,gBAAgB,IAAI;AAAA,MACvB,QAAQ,cAAc,IAAI,kBAAgB,CAAC,aAAa,OAAO,YAAY,CAAC;AAAA,IAC9E;AACA,SAAK,SAAS,QAAQ,cAAc,IAAI,kBAAgB,aAAa,KAAK;AAG1E,QAAI,QAAQ,WAAW,QAAQ,SAAS;AACtC,WAAK,WAAW,KAAK,MAAM,SAAS,KAAK,QAAQ,QAAQ;AACzD,YAAM,KAAK,SAAS,QAAQ;AAC5B,WAAK,oBAAoB;AAAA,IAC3B;AAEA,QAAI,CAAC,QAAQ,WAAW,KAAK,OAAO,WAAW,EAAG;AAClD,QAAI,GAAC,UAAK,QAAQ,aAAb,mBAAuB,UAAS;AACnC,YAAM,IAAI,MAAM,iDAAiD;AAAA,IACnE;AAEA,SAAK,WAAW,KAAK,MAAM,SAAS,KAAK,QAAQ,QAAQ;AACzD,SAAK,kBAAkB,MAAM,KAAK,iBAAiB;AACnD,QAAI,KAAK,gBAAiB;AAE1B,oBAAgB,EAAE,KAAK,wEAAwE;AAC/F,SAAK,WAAW,YAAY,YAAY;AACtC,WAAK,kBAAkB,MAAM,KAAK,iBAAiB;AACnD,UAAI,KAAK,gBAAiB,eAAc,KAAK,QAAQ;AAAA,IACvD,GAAG,uCAAuC,GAAI;AAAA,EAChD;AAAA,EAEA,MAAM,QAAuB,SAAkC;AAC7D,QAAI,CAAC,KAAK,YAAY,CAAC,KAAK,mBAAmB;AAC7C,YAAM,IAAI,MAAM,wCAAwC;AAAA,IAC1D;AAEA,WAAO,MAAM,KAAK,SAAS,KAAK;AAAA,MAC9B,MAAM,QAAQ;AAAA,MACd,SAAS,QAAQ;AAAA,MACjB,OAAO,QAAQ;AAAA,MACf,UAAU;AAAA,QACR;AAAA,UACE,OAAO,kBAAU,EAAC,QAAQ,QAAQ,OAAM,CAAC;AAAA,UACzC,SAAS;AAAA,YACP,mBAAmBC,YAAW;AAAA,UAChC;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,QAAQ;AAxGhB;AAyGI,UAAM,SAAS,gBAAgB;AAC/B,WAAO,KAAK,kCAAkC;AAC9C,QAAI,KAAK,SAAU,eAAc,KAAK,QAAQ;AAC9C,UAAM,QAAQ,IAAI;AAAA,OAChB,UAAK,aAAL,mBAAe;AAAA,MACf,KAAK,qBAAoB,UAAK,aAAL,mBAAe,eAAe;AAAA,IACzD,CAAC;AACD,SAAK,kBAAkB;AACvB,SAAK,oBAAoB;AAAA,EAC3B;AAAA,EAEA,MAAc,mCAAqD;AACjE,UAAM,SAAS,gBAAgB;AAC/B,UAAM,QAAQ,KAAK,MAAM,MAAM;AAC/B,QAAI;AACF,YAAM,MAAM,QAAQ;AACpB,YAAM,UAAU,KAAK,QAAQ,SAAS;AACtC,YAAM,oBAAoB,MAAM,MAAM,eAAe,CAAC,OAAO,CAAC;AAC9D,YAAM,QAAQ,kBAAkB,OAAO,CAAC;AACxC,UAAI,MAAM,UAAU,SAAS;AAC3B,eAAO,KAAK,0BAA0B,OAAO,oBAAoB;AACjE,eAAO;AAAA,MACT;AACA,YAAM,iBAAiB,MAAM,MAAM,mBAAmB,EAAC,QAAQ,KAAK,OAAM,CAAC;AAC3E,YAAM,kBAAkB,eAAe,OAAO;AAAA,QAC5C,CAAC,KAAK,UAAU,MAAM,MAAM,WAAW;AAAA,QACvC;AAAA,MACF;AACA,aAAO;AAAA,QACL,0BAA0B,OAAO,QAAQ,MAAM,QAAQ,MAAM,gBAAgB,eAAe;AAAA,MAC9F;AACA,YAAM,kBACJ,KAAK,QAAQ,4BAA4B;AAC3C,YAAM,sBAAsB,KAAK,KAAK,kBAAkB,eAAe;AACvE,UAAI,sBAAsB,MAAM,QAAQ,QAAQ;AAC9C,eAAO;AAAA,UACL,0BAA0B,OAAO,8BAA8B,MAAM,QAAQ,MAAM,IAAI,mBAAmB;AAAA,QAC5G;AACA,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,aAAO,MAAM,0DAA0D,EAAC,MAAK,CAAC;AAC9E,aAAO;AAAA,IACT,UAAE;AACA,YAAM,MAAM,WAAW,EAAE,MAAM,WAAS;AACtC,eAAO,MAAM,4CAA4C,EAAC,MAAK,CAAC;AAAA,MAClE,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAc,oBAAoB;AAChC,UAAM,KAAK,SAAS,QAAQ;AAC5B,UAAM,KAAK,SAAS,UAAU,EAAC,QAAQ,KAAK,OAAM,CAAC;AACnD,UAAM,KAAK,SAAS,IAAI;AAAA,MACtB,gCACE,KAAK,QAAQ,kCAAkC;AAAA,MACjD,aAAa,YAAU,KAAK,cAAc,MAAM;AAAA,IAClD,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,mBAAqC;AACjD,QAAI,MAAM,KAAK,iCAAiC,GAAG;AACjD,YAAM,KAAK,kBAAkB;AAC7B,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,cAAc,QAAmC;AAC7D,UAAM,SAAS,gBAAgB;AAC/B,UAAM,eAAe,KAAK,cAAc,IAAI,OAAO,KAAK;AACxD,QAAI,CAAC,cAAc;AACjB,aAAO,KAAK,oDAAoD,OAAO,KAAK,eAAe;AAC3F;AAAA,IACF;AAEA,QAAI,iBAAiB;AACrB,UAAM,oBAAoB,YAAY,YAAY;AAChD,YAAM,OAAO,UAAU,EAAE,MAAM,WAAS;AACtC,eAAO,KAAK,oCAAoC,MAAM,OAAO,EAAE;AAAA,MACjE,CAAC;AACD;AACA,UAAK,iBAAiB,6BAA8B,OAAO,GAAG;AAC5D,eAAO;AAAA,UACL,gDAAgD,OAAO,KAAK,IAAI,iBAAiB,0BAA0B;AAAA,QAC7G;AAAA,MACF;AAAA,IACF,GAAG,6BAA6B,GAAI;AAEpC,QAAI;AACF,YAAM,QAAQ,KAAK,oBAAoB,MAAM;AAC7C,YAAM,KAAK,QAAQ,KAAK;AAAA,IAC1B,SAAS,OAAO;AACd,UAAI;AACF,cAAM,KAAK,cAAc,cAAc,QAAQ,KAAc;AAAA,MAC/D,SAAS,YAAY;AACnB,eAAO,MAAM,sCAAsC;AAAA,UACjD,OAAO;AAAA,UACP,OAAO,OAAO;AAAA,QAChB,CAAC;AACD,cAAM;AAAA,MACR;AAAA,IACF,UAAE;AACA,oBAAc,iBAAiB;AAAA,IACjC;AAAA,EACF;AAAA,EAEQ,oBAAoB,QAAwD;AArNtF;AAsNI,UAAM,EAAC,SAAS,OAAO,UAAS,IAAI;AACpC,QAAI,CAAC,QAAQ,OAAO;AAClB,YAAM,IAAI,MAAM,8CAA8C,KAAK,EAAE;AAAA,IACvE;AACA,UAAM,OAAO,oBAAY,QAAQ,MAAM,SAAS,CAAC;AACjD,UAAM,UAAU,OAAO,WAAS,mBAAQ,YAAR,mBAAiB,YAAjB,mBAA0B,eAAc,KAAK,EAAE;AAC/E,UAAM,YAAY,OAAO,SAAS,QAAQ,aAAa,IAAI,EAAE;AAE7D,WAAO;AAAA,MACL,MACE,mBAAQ,YAAR,mBAAkB,uBAAlB,mBAAsC,eACtC,SAAS,KAAK,IAAI,SAAS,IAAI,QAAQ,MAAM;AAAA,MAC/C;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,SAAS,QAAQ;AAAA,MACjB,WAAW,OAAO,SAAS,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,oBAAI,KAAK;AAAA,MACvE,SAAS,UAAU;AAAA,MACnB,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,MAAc,cACZ,cACA,QACA,OACA;AAhPJ;AAiPI,UAAM,SAAS,gBAAgB;AAC/B,UAAM,EAAC,SAAS,MAAK,IAAI;AACzB,UAAM,UAAU,OAAO,WAAS,8CAAS,YAAT,mBAAkB,YAAlB,mBAA2B,eAAc,KAAK,EAAE;AAChF,QACE,aAAa,6BAA6B,UAC1C,aAAa,6BAA6B,MAC1C;AACA,YAAM;AAAA,IACR;AACA,UAAM,aAAa,aAAa,4BAA4B;AAC5D,UAAM,qBAAqB,WAAW;AACtC,UAAM,YAAY,qBAAqB,OAAO,KAAK,KAAK;AACxD,QAAI,CAAC,QAAQ,MAAO,OAAM;AAC1B,UAAM,KAAK,SAAS,KAAK;AAAA,MACvB,OAAO;AAAA,MACP,UAAU;AAAA,QACR;AAAA,UACE,OAAO,QAAQ,MAAM,SAAS;AAAA,UAC9B,SAAS;AAAA,YACP,GAAG,QAAQ;AAAA,YACX,SAAS,OAAO,UAAU,CAAC;AAAA,YAC3B,OAAO,MAAM;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI,oBAAoB;AACtB,aAAO;AAAA,QACL;AAAA,QACA,EAAC,OAAO,UAAS;AAAA,MACnB;AAAA,IACF,OAAO;AACL,aAAO,KAAK,sCAAsC,EAAC,OAAO,OAAO,UAAS,CAAC;AAAA,IAC7E;AAAA,EACF;AACF;AAEA,IAAO,uBAAQ;;;ACvQf,IAAqB,WAArB,MAA8B;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,oBAAsC,CAAC;AAAA,EAChD,UAAU;AAAA,EACV,SAAS;AAAA,EAEjB,YAAY,SAA0B;AACpC,SAAK,SAAS,QAAQ;AACtB,SAAK,aAAa,QAAQ;AAC1B,SAAK,cAAc,CAAC,GAAG,IAAI,IAAI,QAAQ,WAAW,CAAC;AACnD,SAAK,YAAY,QAAQ;AAAA,EAC3B;AAAA,EAEA,MAAM,QAAQ;AACZ,QAAI,KAAK,QAAS;AAElB,UAAM,WAAW,IAAI,IAAI,KAAK,WAAW;AACzC,QAAI,KAAK,UAAW,UAAS,IAAI,KAAK,SAAS;AAE/C,eAAW,QAAQ,UAAU;AAC3B,UAAI,CAAC,KAAK,WAAW,IAAI,GAAG;AAC1B,cAAM,IAAI,MAAM,2BAA2B,IAAI,kCAAkC;AAAA,MACnF;AAAA,IACF;AAEA,UAAM,gBAA+C,OAAO,QAAQ,KAAK,MAAM,EAC5E,OAAO,CAAC,CAAC,EAAEC,KAAI,MAAMA,MAAK,SAAS,OAAO,EAC1C,IAAI,CAAC,CAAC,OAAOA,KAAI,OAAO;AAAA,MACvB;AAAA,MACA,0BAA0BA,MAAK;AAAA,MAC/B,SAASA,MAAK;AAAA,MACd,eAAeA,MAAK;AAAA,IACtB,EAAE;AAEJ,QAAI;AACF,iBAAW,QAAQ,UAAU;AAC3B,cAAM,YAAY,KAAK,WAAW,IAAI;AACtC,aAAK,kBAAkB,KAAK,SAAS;AACrC,cAAM,UAAU,MAAM;AAAA,UACpB,SAAS,KAAK,YAAY,SAAS,IAAI;AAAA,UACvC,SAAS,KAAK,cAAc;AAAA,UAC5B;AAAA,UACA,SAAS,WAAS,KAAK,YAAY,KAAK;AAAA,QAC1C,CAAC;AAAA,MACH;AACA,WAAK,UAAU;AAAA,IACjB,SAAS,OAAO;AACd,YAAM,KAAK,MAAM,EAAE,MAAM,MAAM,MAAS;AACxC,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,QAAuB,SAAkC;AAC7D,QAAI,CAAC,KAAK,SAAS;AACjB,YAAM,IAAI,MAAM,yDAAyD;AAAA,IAC3E;AACA,QAAI,CAAC,KAAK,WAAW;AACnB,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AAEA,WAAO,MAAM,KAAK,WAAW,KAAK,SAAS,EAAE,QAAQ,OAAO;AAAA,EAC9D;AAAA,EAEA,MAAM,QAAQ;AACZ,QAAI,KAAK,OAAQ;AACjB,SAAK,SAAS;AACd,UAAM,QAAQ,IAAI,KAAK,kBAAkB,IAAI,eAAa,UAAU,MAAM,CAAC,CAAC;AAAA,EAC9E;AAAA,EAEA,MAAc,YAAY,OAA4B;AACpD,UAAM,SAAS,gBAAgB;AAC/B,UAAMA,QAAO,KAAK,OAAO,MAAM,KAAK;AACpC,QAAI,CAACA,SAAQA,MAAK,SAAS,SAAS;AAClC,aAAO,KAAK,oDAAoD,MAAM,KAAK,eAAe;AAC1F;AAAA,IACF;AAGA,QAAI,MAAM,cAAc,WAAW,MAAM,SAAS;AAChD,YAAMA,MAAK,UAAU,MAAM,OAAc;AACzC;AAAA,IACF;AAEA,QAAIA,MAAK,SAAS;AAChB,YAAMA,MAAK,QAAQ,KAAK;AACxB;AAAA,IACF;AAEA,UAAMA,MAAK,QAAQ,MAAM,KAAK,QAAQ;AAAA,MACpC,GAAI,MAAM,WAAW,CAAC;AAAA,MACtB,WAAW,MAAM;AAAA,MACjB,SAAS,MAAM;AAAA,MACf,OAAO,MAAM;AAAA,MACb,SAAS,MAAM;AAAA,MACf,WAAW,MAAM;AAAA,MACjB,SAAS,MAAM;AAAA,MACf,MAAM,MAAM;AAAA,IACd,CAAC;AAAA,EACH;AACF;;;ACnGA,IAAqB,eAArB,MAA4D;AAAA,EACjD,OAAO;AAAA,EAEC;AAAA,EACT;AAAA,EACA,gBAAuD,CAAC;AAAA,EAEhE,YAAY,SAAkC;AAC5C,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAM,MAAM,SAAqC;AAC/C,QAAI;AACJ,QAAI;AACF,oBAAc,MAAM,OAAO,iBAAiB;AAAA,IAC9C,SAAS,OAAO;AACd,YAAM,UAAU,IAAI;AAAA,QAClB;AAAA,MACF;AACC,MAAC,QAAgB,QAAQ;AAC1B,YAAM;AAAA,IACR;AAEA,UAAM,EAAC,cAAc,GAAG,eAAc,IAAI,KAAK;AAC/C,SAAK,QAAQ,YAAY,QAAQ,cAAc;AAC/C,UAAM,KAAK,MAAM,gBAAgB;AAEjC,QAAI,CAAC,QAAQ,QAAS;AAEtB,SAAK,gBAAgB,MAAM,QAAQ;AAAA,MACjC,QAAQ,cAAc;AAAA,QAAI,gBACxB,KAAK,MAAM;AAAA,UACT,WAAW;AAAA,UACX,WAAS,QAAQ,QAAQ,KAAK,oBAAoB,KAAK,CAAC;AAAA,UACxD,KAAK,oBAAoB,cAAc,UAAU;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,QAAuB,SAAkC;AAC7D,QAAI,CAAC,KAAK,OAAO;AACf,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AAEA,WAAO,MAAM,KAAK,MAAM,QAAQ;AAAA,MAC9B,OAAO,QAAQ;AAAA,MACf,MAAM,EAAC,QAAQ,QAAQ,OAAM;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,QAAQ;AAtEhB;AAuEI,YAAM,UAAK,UAAL,mBAAY;AAClB,SAAK,gBAAgB,CAAC;AAAA,EACxB;AAAA,EAEQ,oBACN,WAAkC,CAAC,GACnC,YACuB;AACvB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAI,WAAW,YAAY,SAAY,CAAC,IAAI,EAAC,SAAS,WAAW,QAAO;AAAA,MACxE,GAAI,WAAW,kBAAkB,SAAY,CAAC,IAAI,EAAC,eAAe,WAAW,cAAa;AAAA,MAC1F,GAAI,WAAW,6BAA6B,SACxC,CAAC,IACD,EAAC,YAAY,WAAW,yBAAwB;AAAA,IACtD;AAAA,EACF;AAAA,EAEQ,oBAAoB,OAAgD;AAC1E,WAAO;AAAA,MACL,IAAI,MAAM;AAAA,MACV,OAAO,MAAM;AAAA,MACb,MAAM,MAAM;AAAA,MACZ,WAAW;AAAA,MACX,SAAS,MAAM;AAAA,MACf,WAAW,MAAM;AAAA,MACjB,SAAS,MAAM;AAAA,MACf,SAAS;AAAA,IACX;AAAA,EACF;AACF;;;ACnFO,SAAS,oBAAoB,SAA0D;AAlB9F;AAmBE,QAAM,cAAc,QAAQ,SACxB;AAAA,IACE,QAAQ,QAAQ;AAAA,IAChB,UAAU,QAAQ;AAAA,IAClB,UAAU,QAAQ;AAAA,IAClB,yBAAyB,QAAQ;AAAA,IACjC,gCAAgC,QAAQ;AAAA,IACxC,0BAA0B,QAAQ;AAAA,EACpC,IACA;AAEJ,QAAM,UAAQ,aAAQ,WAAR,mBAAgB,UAAS;AACvC,QAAM,SAAQ,aAAQ,WAAR,mBAAgB;AAE9B,MAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,OAAQ,QAAO;AAEhD,QAAM,mBAAyD,QAC3D,UACA,QACE,UACA;AAEN,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,eAAa,aAAQ,WAAR,mBAAgB,iBAAgB,mBAAmB,CAAC,gBAAgB,IAAI,CAAC;AAAA,IACtF,aAAW,aAAQ,WAAR,mBAAgB,cAAa;AAAA,EAC1C;AACF;AAEe,SAAR,eAAgC,SAAwB;AAC7D,QAAM,WAAW,oBAAoB,OAAO;AAC5C,MAAI,CAAC,SAAU,QAAO;AAEtB,QAAM,aAAwE,CAAC;AAC/E,MAAI,SAAS,MAAO,YAAW,QAAQ,IAAI,qBAAa,SAAS,KAAK;AACtE,MAAI,SAAS,MAAO,YAAW,QAAQ,IAAI,aAAa,SAAS,KAAK;AAEtE,SAAO,IAAI,SAAS;AAAA,IAClB,QAAQ,QAAQ;AAAA,IAChB;AAAA,IACA,aAAa,SAAS;AAAA,IACtB,WAAW,SAAS;AAAA,EACtB,CAAC;AACH;;;AC7De,SAAR,uBAAkB,MAAW,WAAmB;AACrD,QAAM,qBAAqB,qBAAa,IAAI;AAC5C,MAAI,uBAAuB,WAAW;AACpC,UAAM,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AACF;;;ACLe,SAAR,gBAAkB,QAAgB;AACvC,QAAMC,QAAO,eAAO,OAAO,MAAM;AAEjC,MAAI,CAACA,OAAM;AACT,UAAM,IAAI,MAAM,cAAc,MAAM,4BAA4B;AAAA,EAClE;AAEA,MAAIA,MAAK,SAAS,WAAW;AAC3B,UAAM,IAAI,MAAM,cAAc,MAAM,yBAAyB;AAAA,EAC/D;AAEA,SAAOA;AACT;;;ACRA,IAAO,0BAAQ,CAAC,aACb;AAAA,EACC,QAAQ;AAAA,EACR,MAAM,QAAQ,SAAS,eAAe;AAAA,EACtC,WAAW;AAAA,EACX,MAAM,OAAO,aAAkB;AAC7B,QAAI;AACF,YAAM,EAAC,MAAM,UAAS,IAAI;AAE1B,6BAAe,MAAM,SAAS;AAE9B,YAAM,EAAC,QAAQ,iBAAgB,IAAI;AAEnC,YAAMC,QAAO,gBAAQ,MAAM;AAC3B,YAAM,SAAS,MAAMA,MAAK,UAAU,gBAAgB;AAEpD,aAAO,EAAC,QAAQ,kBAAU,MAAM,EAAC;AAAA,IACnC,SAAS,OAAO;AACd,YAAM,SAAS;AACf,UAAI,CAAC,OAAO,SAAS;AACnB,wBAAgB,EAAE,MAAM,mCAAmC,EAAC,OAAO,OAAM,CAAC;AAAA,MAC5E;AAEA,aAAO;AAAA,QACL,OAAO,OAAO;AAAA,QACd,WAAW,OAAO,UAAU,OAAO,QAAQ,IAAI;AAAA,QAC/C,mBAAmB,CAAC,CAAC,OAAO;AAAA,QAC5B,aAAa,CAAC,CAAC,OAAO;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACF;;;AC9BF,IAAI,WAAqB;AAEzB,eAAO,aAAoC,SAAwB;AACjE,iBAAO,SAAS,QAAQ;AAExB,MAAI,QAAQ,UAAU;AACpB,mBAAO,WAAW,QAAQ;AAC1B,UAAM,kBACJ,QAAQ,SAAS,mBAAmB,iBAAiB,EAAE;AACzD,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,UAAM,gBAAgB,wBAAgB,OAAO,CAAC;AAAA,EAChD;AAEA,QAAM,eAAe,eAAe,OAAO;AAC3C,MAAI,cAAc;AAChB,UAAM,aAAa,MAAM;AACzB,eAAW;AACX,mBAAO,WAAW;AAAA,EACpB;AACF;AAEA,eAAsB,cAAc;AAClC,MAAI,UAAU;AACZ,UAAM,SAAS,gBAAgB;AAC/B,WAAO,KAAK,oBAAoB;AAChC,UAAM,SAAS,MAAM;AACrB,eAAW;AACX,mBAAO,WAAW;AAClB,WAAO,KAAK,gBAAgB;AAAA,EAC9B;AACF;;;AC1BA,IAAM,OAAO,SAAS,cAKpB,SACoD;AACpD,QAAM,UAAU,OAAO,QAA0C,YAAiB;AAChF,UAAM,UAAU,QAAQ,SACpB,MAAM,kBAAoD,QAAQ,QAAQ,MAAM,IAC/E,UAAW,CAAC;AAEjB,UAAM,SAAS,MAAM,QAAQ,QAAQ,SAAS,OAAO;AAErD,QAAI,QAAQ,SAAS;AACnB,aAAO,MAAM,kBAAqD,QAAQ,SAAS,MAAM;AAAA,IAC3F;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,OAAO,UAA+B;AACpD,UAAM,UAAU;AAAA,MACd,GAAI,MAAM,WAAW,CAAC;AAAA,MACtB,WAAW,MAAM;AAAA,MACjB,SAAS,MAAM;AAAA,MACf,OAAO,MAAM;AAAA,MACb,SAAS,MAAM;AAAA,MACf,WAAW,MAAM;AAAA,MACjB,SAAS,MAAM;AAAA,MACf,MAAM,MAAM;AAAA,IACd;AAEA,UAAM,QAAQ,MAAM,KAAK,QAAQ,OAAO;AAAA,EAC1C;AAEA,SAAO;AAAA,IACL,MAAM,QAAQ;AAAA,IACd,QAAQ,QAAQ;AAAA,IAChB,SAAS,QAAQ;AAAA,IACjB,0BACE,QAAQ,SAAS,UAAU,QAAQ,2BAA2B;AAAA,IAChE,SACE,QAAQ,SAAS,UACZ,QAA2D,UAC5D;AAAA,IACN,eACE,QAAQ,SAAS,UACZ,QAA2D,gBAC5D;AAAA,IACN;AAAA,IACA;AAAA,IACA,WAAW,OAAO,gBAA2C;AAnEjE;AAoEM,YAAM,EAAC,QAAO,IAAI;AAClB,UAAI,CAAC,QAAQ,OAAO;AAClB,cAAM,IAAI,MAAM,8CAA8C,YAAY,KAAK,EAAE;AAAA,MACnF;AAEA,YAAM,OAAO,oBAAY,QAAQ,MAAM,SAAS,CAAC;AACjD,YAAM,UAAU,OAAO,WAAS,mBAAQ,YAAR,mBAAiB,YAAjB,mBAA0B,eAAc,KAAK,EAAE;AAC/E,YAAM,YAAY,OAAO,QAAQ,SAAS;AAC1C,YAAM,YAAY,OAAO,SAAS,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,oBAAI,KAAK;AAC9E,YAAM,YACJ,mBAAQ,YAAR,mBAAkB,uBAAlB,mBAAsC,eACtC,SAAS,YAAY,KAAK,IAAI,YAAY,SAAS,IAAI,QAAQ,MAAM;AAEvE,YAAM,QAAQ;AAAA,QACZ,IAAI;AAAA,QACJ,OAAO,YAAY;AAAA,QACnB;AAAA,QACA,WAAW;AAAA,QACX,SAAS,QAAQ;AAAA,QACjB;AAAA,QACA,SAAS,UAAU;AAAA,QACnB,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,IACA,WAAW,OAAO,qBAA6B;AAC7C,YAAM,UAAU,CAAC;AACjB,YAAM,SAAS,oBAAY,gBAAgB;AAE3C,aAAO,MAAM,QAAQ,QAAQ,OAAO;AAAA,IACtC;AAAA,EACF;AACF;AAEO,SAAS,kBAId,SACoD;AACpD,SAAO,KAAK,EAAC,GAAG,SAAS,MAAM,UAAS,CAAC;AAC3C;AACO,SAAS,gBAId,SACkD;AAClD,SAAO,KAAK,EAAC,GAAG,SAAS,MAAM,QAAc,CAAC;AAChD;;;AC/BO,SAAS,kBACd,QAC2C;AAC3C,SAAO;AACT;;;ACjFA,IAAM,kBAAkB,oBAAI,QAAqC;AACjE,IAAM,iBAAiB,oBAAI,QAAkC;AAC7D,IAAM,qBAAqB,oBAAI,IAAsD;AACrF,IAAM,sBAAsB,oBAAI,QAAuB;AACvD,IAAI,qBAA6D,CAAC;AAE3D,SAAS,SAAS;AACvB,SAAO,CAAC,QAAa,YAAwC;AAf/D;AAgBI,iCAAiB,GAAE,oBAAnB,4BAAqC,QAAQ;AAC7C,oBAAgB,IAAI,QAAQ,EAAC,cAAc,SAAQ,CAAC;AAEpD,QAAI,OAAO,KAAK,kBAAkB,EAAE,SAAS,GAAG;AAC9C,yBAAmB,IAAI,QAAQ,kBAAkB;AACjD,2BAAqB,CAAC;AAAA,IACxB;AAAA,EACF;AACF;AASO,SAAS,UAAU,UAAU,CAAC,GAAG;AACtC,SAAO,CAAC,QAAa,YAAsE;AACzF,UAAM,cAAc,OAAO,QAAQ,IAAI;AAEvC,QAAI,QAAQ,SAAS,UAAU;AAC7B,yBAAmB,WAAW,IAAI,CAAC,aAAkB;AACnD,cAAM,kBAAkB,SAAS,WAAW,EAAE,KAAK,QAAQ;AAC3D,eAAO,gBAAgB;AAAA,UACrB,GAAG;AAAA,UACH,SAAS,OAAO,QAAQ,gBAAgB;AACtC,mBAAO,MAAM;AAAA,cACX;AAAA,gBACE,gBAAgB;AAAA,gBAChB,UAAU;AAAA,gBACV;AAAA,cACF;AAAA,cACA,YAAY;AACV,uBAAO,MAAM,gBAAgB,QAAQ,WAAW;AAAA,cAClD;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS,SAAS;AAC5B,yBAAmB,WAAW,IAAI,CAAC,aAAkB,SAAS,WAAW;AAAA,IAC3E;AAEA,WAAO;AAAA,EACT;AACF;AASO,SAAS,YAAY,UAAU,CAAC,GAAG;AACxC,SAAO,CAAC,QAAa,YAAsE;AACzF,UAAM,cAAc,OAAO,QAAQ,IAAI;AAEvC,QAAI,QAAQ,SAAS,UAAU;AAC7B,yBAAmB,WAAW,IAAI,CAAC,aAAkB;AACnD,cAAM,kBAAkB,SAAS,WAAW,EAAE,KAAK,QAAQ;AAC3D,eAAO,kBAAkB;AAAA,UACvB,GAAG;AAAA,UACH,SAAS,OAAO,QAAQ,gBAAgB;AACtC,mBAAO,MAAM;AAAA,cACX;AAAA,gBACE,gBAAgB;AAAA,gBAChB,UAAU;AAAA,gBACV;AAAA,cACF;AAAA,cACA,YAAY;AACV,uBAAO,MAAM,gBAAgB,QAAQ,WAAW;AAAA,cAClD;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS,SAAS;AAC5B,yBAAmB,WAAW,IAAI,CAAC,aAAkB,SAAS,WAAW;AAAA,IAC3E;AAEA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,yBAAyB,UAAe;AAC/C,MAAI,eAAe,IAAI,QAAQ,EAAG;AAClC,QAAM,UAAU,mBAAmB,IAAI,SAAS,WAAW,KAAK,CAAC;AACjE,QAAM,SAA8B,CAAC;AACrC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,WAAO,GAAG,IAAI,MAAM,QAAQ;AAAA,EAC9B;AACA,iBAAe,IAAI,UAAU,MAAM;AACrC;AAEO,SAAS,iBAAiB,QAAwB;AACvD,MAAI;AACJ,MAAI,OAAO,WAAW,YAAY;AAChC,eAAW;AAAA,EACb,WAAW,iBAAiB,EAAE,aAAa;AACzC,eAAW,iBAAiB,EAAE,YAAY,MAAM;AAAA,EAClD,OAAO;AACL,eAAW,oBAAoB,IAAI,MAAM;AACzC,QAAI,CAAC,UAAU;AACb,iBAAW,IAAI,OAAO;AACtB,0BAAoB,IAAI,QAAQ,QAAQ;AAAA,IAC1C;AAAA,EACF;AAEA,MAAI,CAAC,gBAAgB,IAAI,SAAS,WAAW,GAAG;AAC9C,UAAM,IAAI,MAAM,kEAAkE;AAAA,EACpF;AAEA,QAAM,mBAAmB,gBAAgB,IAAI,SAAS,WAAW;AACjE,MAAI,iBAAiB,iBAAiB,UAAU;AAC9C,UAAM,IAAI,MAAM,kEAAkE;AAAA,EACpF;AAEA,2BAAyB,QAAQ;AAEjC,QAAM,YAAY,eAAe,IAAI,QAAQ,KAAK,CAAC;AAEnD,SAAO;AACT;","names":["clone","request","randomUUID","randomUUID","echo","echo","echo"]}
package/dist/types.d.ts CHANGED
@@ -9,6 +9,15 @@ export interface EchoRequestConfig<TParamsSchema extends EchoesSchema, TReturnsS
9
9
  export interface EchoEventConfig<TParamsSchema extends EchoesSchema, TReturnsSchema extends EchoesSchema> {
10
10
  params?: TParamsSchema;
11
11
  returns?: TReturnsSchema;
12
+ /**
13
+ * Pulse only. Overrides events.pulse.subscription.ordered for this topic listener.
14
+ * When neither value is configured, Pulse defaults to false.
15
+ */
16
+ ordered?: boolean;
17
+ /**
18
+ * Pulse only. Integer version for persisted subscription settings. Higher versions win.
19
+ */
20
+ configVersion?: number;
12
21
  resolve(params?: InferEchoesSchema<TParamsSchema>, context?: any): Promise<InferEchoesSchema<TReturnsSchema>>;
13
22
  attemptsBeforeDeadLetter?: number;
14
23
  }
@@ -19,6 +28,8 @@ export type EchoType<TParamsSchema extends EchoesSchema = any, TReturnsSchema ex
19
28
  params?: TParamsSchema;
20
29
  returns?: TReturnsSchema;
21
30
  attemptsBeforeDeadLetter?: number;
31
+ ordered?: boolean;
32
+ configVersion?: number;
22
33
  type: TEchoType;
23
34
  resolve(params?: InferEchoesSchema<TParamsSchema>, context?: any): Promise<InferEchoesSchema<TReturnsSchema>>;
24
35
  onEvent?(event: EchoesReceivedEvent): Promise<void>;
@@ -169,10 +180,12 @@ export interface EchoesPulseEventsConfig {
169
180
  onError?: (error: Error) => void;
170
181
  /**
171
182
  * Subscription defaults used by every Echoes event handled through Pulse.
172
- * attemptsBeforeDeadLetter overrides maxRetries per event when configured.
183
+ * Event-level ordered and attemptsBeforeDeadLetter override ordered and maxRetries
184
+ * respectively when configured.
173
185
  */
174
186
  subscription?: {
175
187
  ordered?: boolean;
188
+ configVersion?: number;
176
189
  offsetReset?: 'latest' | 'earliest';
177
190
  delivery?: 'at-least-once' | 'at-most-once';
178
191
  maxRetries?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orion-js/echoes",
3
- "version": "4.5.3",
3
+ "version": "4.5.4",
4
4
  "main": "./dist/index.cjs",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [
@@ -12,7 +12,7 @@
12
12
  "serialize-javascript": "^6.0.0"
13
13
  },
14
14
  "peerDependencies": {
15
- "@orion-js/pulse": "^4.5.4",
15
+ "@orion-js/pulse": "^4.5.9",
16
16
  "kafkajs": "^2.2.4"
17
17
  },
18
18
  "peerDependenciesMeta": {
@@ -24,7 +24,7 @@
24
24
  }
25
25
  },
26
26
  "devDependencies": {
27
- "@orion-js/pulse": "4.5.4",
27
+ "@orion-js/pulse": "4.5.9",
28
28
  "@types/node": "^18.0.0",
29
29
  "@types/supertest": "2.0.11",
30
30
  "kafkajs": "^2.2.4",