@relaybus/core 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-3OHMEMZA.cjs → chunk-J76M7XTS.cjs} +127 -9
- package/dist/chunk-J76M7XTS.cjs.map +1 -0
- package/dist/{chunk-WS274DL3.js → chunk-NOR5JHVN.js} +121 -9
- package/dist/chunk-NOR5JHVN.js.map +1 -0
- package/dist/index.cjs +2232 -1898
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +82 -475
- package/dist/index.d.ts +82 -475
- package/dist/index.js +2259 -1931
- package/dist/index.js.map +1 -1
- package/dist/internal/index.cjs +335 -117
- package/dist/internal/index.cjs.map +1 -1
- package/dist/internal/index.d.cts +269 -2
- package/dist/internal/index.d.ts +269 -2
- package/dist/internal/index.js +293 -101
- package/dist/internal/index.js.map +1 -1
- package/dist/transport-BlfzIBZD.d.cts +535 -0
- package/dist/transport-BlfzIBZD.d.ts +535 -0
- package/package.json +1 -1
- package/dist/chunk-3OHMEMZA.cjs.map +0 -1
- package/dist/chunk-WS274DL3.js.map +0 -1
- package/dist/event-DCRTuYKI.d.cts +0 -142
- package/dist/event-DCRTuYKI.d.ts +0 -142
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/internal/field-extractors.ts","../../src/internal/cloudevents.ts","../../src/internal/json-envelope.ts"],"names":["ConfigurationError","assertEventType"],"mappings":"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","file":"index.cjs","sourcesContent":["import { ConfigurationError } from '../errors.js';\nimport type { EventHeaders } from '../event.js';\n\n/**\n * Reads one header of an incoming message, for the `type`, `id`, `key` or\n * `source` option of {@link plainJsonDecoder}. Header names are compared\n * exactly (Kafka and AMQP header names are case-sensitive). Returns undefined when the\n * header is absent, so the decoder falls back to its default.\n *\n * ```ts\n * plainJsonDecoder({ type: fromHeader('event-type'), id: fromHeader('message-id') })\n * ```\n */\nexport function fromHeader(\n name: string,\n): (message: { readonly headers: EventHeaders }) => string | undefined {\n if (name.length === 0) {\n throw new ConfigurationError('fromHeader needs a header name');\n }\n return (message) => (Object.hasOwn(message.headers, name) ? message.headers[name] : undefined);\n}\n\n/**\n * Reads a field of the JSON payload by a dotted path (`'meta.eventType'`), for\n * the `type`, `id`, `key` or `source` option of {@link plainJsonDecoder}. A\n * string is returned as is and a safe integer as its decimal text (numeric ids\n * are common). Anything else returns undefined so the decoder falls back to its\n * default: a missing field, and also a fraction or an integer beyond 2^53, which\n * JSON parsing may already have rounded, so two different ids could collide.\n *\n * ```ts\n * plainJsonDecoder({ type: fromPayloadField('eventType'), key: fromPayloadField('order.id') })\n * ```\n */\nexport function fromPayloadField(\n path: string,\n): (message: { readonly payload: unknown }) => string | undefined {\n const segments = path.split('.');\n if (segments.some((segment) => segment.length === 0)) {\n throw new ConfigurationError(\n `fromPayloadField needs a dotted path of non-empty names, received '${path}'`,\n );\n }\n return (message) => {\n let value = message.payload;\n for (const segment of segments) {\n if (typeof value !== 'object' || value === null || !Object.hasOwn(value, segment)) {\n return undefined;\n }\n value = (value as Record<string, unknown>)[segment];\n }\n if (typeof value === 'string') {\n return value;\n }\n return Number.isSafeInteger(value) ? String(value) : undefined;\n };\n}\n","import { assertEventType, type EventEnvelope } from '../event.js';\n\n/** The media type of a content type, without parameters and lower-cased; undefined for anything but a string. */\nexport function mediaTypeOf(contentType: unknown): string | undefined {\n return typeof contentType === 'string'\n ? contentType.split(';')[0]!.trim().toLowerCase()\n : undefined;\n}\n\nexport function isJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Readers of structured CloudEvent attributes that fail with the error of the calling transport. */\nexport interface CloudEventReaders {\n readonly optionalAttribute: (body: Record<string, unknown>, name: string) => string | undefined;\n readonly requiredAttribute: (body: Record<string, unknown>, name: string) => string;\n readonly assertValidType: (type: string, label: string) => void;\n readonly assertJsonDataContentType: (dataContentType: string | undefined) => void;\n}\n\nexport function createCloudEventReaders(invalid: (reason: string) => Error): CloudEventReaders {\n const optionalAttribute = (body: Record<string, unknown>, name: string): string | undefined => {\n const value = body[name];\n if (value !== undefined && typeof value !== 'string') {\n throw invalid(`Attribute '${name}' must be a string`);\n }\n return value;\n };\n return {\n optionalAttribute,\n requiredAttribute: (body, name) => {\n const value = optionalAttribute(body, name);\n if (value === undefined || value.length === 0) {\n throw invalid(`Attribute '${name}' is missing or empty`);\n }\n return value;\n },\n assertValidType: (type, label) => {\n try {\n assertEventType(type);\n } catch (error) {\n throw invalid(`${label} is not a valid event type: ${(error as Error).message}`);\n }\n },\n assertJsonDataContentType: (dataContentType) => {\n const mediaType = mediaTypeOf(dataContentType);\n if (\n mediaType !== undefined &&\n mediaType !== 'application/json' &&\n mediaType !== 'text/json' &&\n !mediaType.endsWith('+json')\n ) {\n throw invalid(`datacontenttype must be JSON, received '${dataContentType}'`);\n }\n },\n };\n}\n\n/**\n * The JSON text of a CloudEvents 1.0 structured-mode event: the attributes (the key as `subject`,\n * correlation and causation ids as extension attributes), then `data`, the already serialized\n * payload, so the payload is serialized only once.\n */\nexport function writeStructuredCloudEvent(\n envelope: EventEnvelope,\n { time, data }: { readonly time: string; readonly data: string },\n): string {\n const attributes = {\n specversion: '1.0',\n id: envelope.id,\n type: envelope.type,\n source: envelope.source,\n time,\n datacontenttype: 'application/json',\n ...(envelope.key === null ? {} : { subject: envelope.key }),\n ...(envelope.correlationId === null ? {} : { correlationid: envelope.correlationId }),\n ...(envelope.causationId === null ? {} : { causationid: envelope.causationId }),\n };\n return `${JSON.stringify(attributes).slice(0, -1)},\"data\":${data}}`;\n}\n","import { ConfigurationError } from '../errors.js';\nimport { assertEventType, type EventEnvelope, type EventHeaders } from '../event.js';\nimport { isJsonObject } from './cloudevents.js';\n\n/**\n * A field of the JSON body, by dotted path: `'eventName'`, `'meta.correlationId'`. A segment that\n * is a whole number indexes an array: `'messageType.0'` is the first element of `messageType`.\n */\nexport type BodyField = { readonly body: string };\n/** A message header (Kafka record header, AMQP message header), by exact name. */\nexport type HeaderField = { readonly header: string };\n/** Where one envelope value lives on the wire. */\nexport type WireField = BodyField | HeaderField;\n/** The one event type every message of the route carries: written nowhere, used for every message read. */\nexport type FixedType = { readonly fixed: string };\n\ntype MappingFields<TField extends WireField, TTransportId extends string> = {\n /** Where the event type lives, or the one type of the route. Required. */\n readonly type: TField | FixedType;\n /**\n * Where the event id lives, or the transport's own message identity (see the transport's\n * mapping type). Required, so the inbox dedup key is always a deliberate choice. A message\n * whose mapped id is missing is malformed.\n */\n readonly id: TField | TTransportId;\n /** Ordering key. Default: the transport's own (the Kafka record key; none on RabbitMQ). */\n readonly key?: TField;\n /** Producing service. Default: the transport's own (Kafka topic; RabbitMQ `appId`, else the routing key). */\n readonly source?: TField;\n /** RFC 3339 time. Default: the transport's own (Kafka record timestamp; RabbitMQ `timestamp`, seconds). */\n readonly occurredAt?: TField;\n readonly correlationId?: TField;\n readonly causationId?: TField;\n /** Media type written with the message. Default `application/json`. Not checked on read. */\n readonly contentType?: string;\n};\n\n/**\n * A JSON object that wraps the payload with event metadata, such as\n * `{ \"eventName\": ..., \"messageId\": ..., \"data\": {...}, \"meta\": {...} }`.\n * Each value lives at a body path or in a header.\n */\nexport type BodyEnvelopeMapping<TTransportId extends string> = MappingFields<\n WireField,\n TTransportId\n> & {\n /** Body path of the payload. Required. */\n readonly payload: BodyField;\n /**\n * Event headers: a body path holding an object of strings, or `'message-headers'` (default),\n * every message header that no other field maps.\n */\n readonly headers?: BodyField | 'message-headers';\n};\n\n/**\n * The body is the payload itself, as a plain JSON producer writes it; every other value lives in\n * a header, so body paths are a compile error here.\n */\nexport type PayloadOnlyMapping<TTransportId extends string> = MappingFields<\n HeaderField,\n TTransportId\n> & {\n readonly payload: 'whole-body';\n /** Event headers: every message header that no other field maps. */\n readonly headers?: 'message-headers';\n};\n\n/** Where every envelope value lives in a JSON message. `type`, `id` and `payload` are required. */\nexport type JsonEnvelopeMapping<TTransportId extends string> =\n BodyEnvelopeMapping<TTransportId> | PayloadOnlyMapping<TTransportId>;\n\n/** A JSON message: the parsed body and the text headers. */\nexport type JsonWireMessage = { readonly body: unknown; readonly headers: EventHeaders };\n\n/** The values read from a message. An absent optional value is left to the transport's default. */\nexport type JsonEnvelopeFields = {\n readonly id?: string;\n readonly type: string;\n readonly payload: unknown;\n readonly key?: string;\n readonly source?: string;\n readonly headers: EventHeaders;\n readonly correlationId: string | null;\n readonly causationId: string | null;\n readonly occurredAt?: Date;\n};\n\n/** The errors of the calling transport. */\nexport type JsonEnvelopeFailures = {\n /** For a message that cannot be read: it goes to the invalid-message path. */\n readonly invalid: (reason: string) => Error;\n /** For an event that cannot be written: never retried. */\n readonly unencodable: (reason: string) => Error;\n};\n\n/** Writes and reads one mapping. Created once per codec; both methods are pure. */\nexport interface JsonEnvelopeFormat {\n /** The mapped headers and the body; the id is left out when the transport supplies it. */\n write(envelope: EventEnvelope): JsonWireMessage;\n read(message: JsonWireMessage): JsonEnvelopeFields;\n}\n\ntype Location =\n | { readonly label: string; readonly header: string }\n | { readonly label: string; readonly path: readonly string[] };\n\ntype OptionalName = 'key' | 'source' | 'occurredAt' | 'correlationId' | 'causationId';\nconst OPTIONAL_NAMES: readonly OptionalName[] = [\n 'key',\n 'source',\n 'occurredAt',\n 'correlationId',\n 'causationId',\n];\n\ntype Plan = {\n readonly type: Location | FixedType;\n /** Undefined when the transport supplies the id. */\n readonly id: Location | undefined;\n readonly optional: Readonly<Partial<Record<OptionalName, Location>>>;\n /** Undefined when the payload is the whole body. */\n readonly payload: readonly string[] | undefined;\n /** Undefined when event headers are the unmapped message headers. */\n readonly headers: readonly string[] | undefined;\n readonly mappedHeaders: ReadonlySet<string>;\n};\n\n/** RFC 3339 years have four digits. */\nconst MAXIMUM_RFC3339_YEAR = 9999;\nconst RFC3339_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$/i;\nconst ARRAY_INDEX = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Compiles `mapping` once. `transportIds` lists the transport's own id strategies.\n *\n * @throws ConfigurationError for a mapping that is incomplete, names a header twice, nests one\n * body path inside another or mixes array indexes and names under one body field.\n */\nexport function createJsonEnvelopeFormat(\n mapping: JsonEnvelopeMapping<string>,\n {\n transportIds,\n failures,\n }: { readonly transportIds: readonly string[]; readonly failures: JsonEnvelopeFailures },\n): JsonEnvelopeFormat {\n const plan = compile(mapping, transportIds);\n return {\n write: (envelope) => writeMessage(envelope, { plan, failures }),\n read: (message) => readMessage(message, { plan, failures }),\n };\n}\n\nfunction compile(mapping: JsonEnvelopeMapping<string>, transportIds: readonly string[]): Plan {\n if (!isJsonObject(mapping)) {\n throw new ConfigurationError('jsonEnvelope needs a mapping object');\n }\n const optional: Partial<Record<OptionalName, Location>> = {};\n for (const name of OPTIONAL_NAMES) {\n const field = mapping[name];\n if (field !== undefined) {\n optional[name] = toLocation(field, name);\n }\n }\n const plan: Plan = {\n type: compileType(mapping.type),\n id: compileId(mapping.id, transportIds),\n optional,\n payload: compilePayload(mapping.payload),\n headers: compileHeaders(mapping.headers),\n mappedHeaders: new Set(),\n };\n return assertDisjoint(plan);\n}\n\nfunction compileType(type: unknown): Location | FixedType {\n if (isJsonObject(type) && typeof type['fixed'] === 'string') {\n assertEventType(type['fixed']);\n return { fixed: type['fixed'] };\n }\n if (type === undefined) {\n throw new ConfigurationError('jsonEnvelope needs a type: { body }, { header } or { fixed }');\n }\n return toLocation(type, 'type');\n}\n\nfunction compileId(id: unknown, transportIds: readonly string[]): Location | undefined {\n if (typeof id === 'string' && transportIds.includes(id)) {\n return undefined;\n }\n if (!isJsonObject(id)) {\n throw new ConfigurationError(\n `jsonEnvelope needs an id: { body }, { header } or one of ${transportIds.map((name) => `'${name}'`).join(', ')}`,\n );\n }\n return toLocation(id, 'id');\n}\n\nfunction compilePayload(payload: unknown): readonly string[] | undefined {\n if (payload === 'whole-body') {\n return undefined;\n }\n if (!isJsonObject(payload) || typeof payload['body'] !== 'string') {\n throw new ConfigurationError(\n \"jsonEnvelope needs a payload: { body: '<path>' } or 'whole-body'\",\n );\n }\n return toPath(payload['body'], 'payload');\n}\n\nfunction compileHeaders(headers: unknown): readonly string[] | undefined {\n if (headers === undefined || headers === 'message-headers') {\n return undefined;\n }\n if (!isJsonObject(headers) || typeof headers['body'] !== 'string') {\n throw new ConfigurationError(\n \"jsonEnvelope headers must be { body: '<path>' } or 'message-headers'\",\n );\n }\n return toPath(headers['body'], 'headers');\n}\n\nfunction toLocation(field: unknown, label: string): Location {\n if (isJsonObject(field) && typeof field['header'] === 'string' && field['header'].length > 0) {\n return { label, header: field['header'] };\n }\n if (isJsonObject(field) && typeof field['body'] === 'string') {\n return { label, path: toPath(field['body'], label) };\n }\n throw new ConfigurationError(\n `jsonEnvelope ${label} must be { body: '<path>' } or { header: '<name>' }`,\n );\n}\n\nfunction toPath(path: string, label: string): readonly string[] {\n const segments = path.split('.');\n if (segments.some((segment) => segment.length === 0)) {\n throw new ConfigurationError(\n `jsonEnvelope ${label} needs a dotted path of non-empty names, received '${path}'`,\n );\n }\n return segments;\n}\n\n/** Collects the mapped headers and refuses overlapping locations, which would overwrite each other. */\nfunction assertDisjoint(plan: Plan): Plan {\n const locations = [plan.type, plan.id, ...Object.values(plan.optional)].filter(\n (location): location is Location => location !== undefined && !('fixed' in location),\n );\n const headers = locations.flatMap((location) => ('header' in location ? [location.header] : []));\n const duplicate = headers.find((name, index) => headers.indexOf(name) !== index);\n if (duplicate !== undefined) {\n throw new ConfigurationError(`jsonEnvelope maps header '${duplicate}' twice`);\n }\n const paths = [\n ...locations.flatMap((location) => ('path' in location ? [location.path] : [])),\n ...[plan.payload, plan.headers].filter((path) => path !== undefined),\n ];\n assertNoNestedPaths(paths);\n return { ...plan, mappedHeaders: new Set(headers) };\n}\n\nfunction assertNoNestedPaths(paths: readonly (readonly string[])[]): void {\n paths.forEach((path, index) => {\n for (const other of paths.slice(index + 1)) {\n assertCompatiblePaths(path, other);\n }\n });\n}\n\n/** Two body paths must part ways, and where they do, both index an array or both name a field. */\nfunction assertCompatiblePaths(path: readonly string[], other: readonly string[]): void {\n const parting = path.findIndex((segment, position) => segment !== other[position]);\n const both = `'${path.join('.')}' and '${other.join('.')}'`;\n if (parting === -1 || parting === other.length) {\n throw new ConfigurationError(`jsonEnvelope body paths ${both} overlap`);\n }\n if (ARRAY_INDEX.test(path[parting]!) !== ARRAY_INDEX.test(other[parting]!)) {\n throw new ConfigurationError(`jsonEnvelope body paths ${both} mix an array index and a name`);\n }\n}\n\ntype Context = { readonly plan: Plan; readonly failures: JsonEnvelopeFailures };\n\nfunction writeMessage(envelope: EventEnvelope, { plan, failures }: Context): JsonWireMessage {\n const root: Record<string, unknown> = {};\n const headers: [string, string][] = [];\n const put = (location: Location, value: string): void => {\n if ('header' in location) {\n headers.push([location.header, value]);\n } else {\n setAt(root, { path: location.path, value });\n }\n };\n if ('fixed' in plan.type) {\n if (envelope.type !== plan.type.fixed) {\n throw failures.unencodable(\n `Event ${envelope.id} has type '${envelope.type}', but this route carries only '${plan.type.fixed}'`,\n );\n }\n } else {\n put(plan.type, envelope.type);\n }\n if (plan.id !== undefined) {\n put(plan.id, envelope.id);\n }\n for (const [name, value] of optionalValues(envelope, failures)) {\n const location = plan.optional[name];\n if (location !== undefined && value !== null) {\n put(location, value);\n }\n }\n return {\n body: writeBody(envelope, { plan, root }),\n headers: Object.fromEntries([...eventHeaderEntries(envelope, { plan, failures }), ...headers]),\n };\n}\n\nfunction optionalValues(\n envelope: EventEnvelope,\n failures: JsonEnvelopeFailures,\n): [OptionalName, string | null][] {\n return [\n ['key', envelope.key],\n ['source', envelope.source],\n ['occurredAt', formatTime(envelope, failures)],\n ['correlationId', envelope.correlationId],\n ['causationId', envelope.causationId],\n ];\n}\n\nfunction writeBody(\n envelope: EventEnvelope,\n { plan, root }: { readonly plan: Plan; readonly root: Record<string, unknown> },\n): unknown {\n if (plan.payload === undefined) {\n return envelope.payload;\n }\n setAt(root, { path: plan.payload, value: envelope.payload });\n if (plan.headers !== undefined) {\n setAt(root, {\n path: plan.headers,\n value: Object.fromEntries(Object.entries(envelope.headers)),\n });\n }\n return root;\n}\n\n/** The event headers that travel as message headers; a name a mapped field uses is refused. */\nfunction eventHeaderEntries(\n envelope: EventEnvelope,\n { plan, failures }: Context,\n): [string, string][] {\n if (plan.headers !== undefined) {\n return [];\n }\n const entries = Object.entries(envelope.headers);\n const taken = entries.find(([name]) => plan.mappedHeaders.has(name));\n if (taken !== undefined) {\n throw failures.unencodable(\n `Event ${envelope.id} has a header '${taken[0]}', which the mapping uses for another field`,\n );\n }\n return entries;\n}\n\nfunction formatTime(envelope: EventEnvelope, failures: JsonEnvelopeFailures): string {\n const year = envelope.occurredAt.getUTCFullYear();\n if (Number.isNaN(year) || year < 0 || year > MAXIMUM_RFC3339_YEAR) {\n throw failures.unencodable(\n `Event ${envelope.id} has an occurredAt that is not an RFC 3339 instant (invalid date or year outside 0..9999)`,\n );\n }\n return envelope.occurredAt.toISOString();\n}\n\n/** Sets a value at a path, creating objects (arrays before an index segment) as own properties. */\nfunction setAt(\n root: Record<string, unknown>,\n { path, value }: { readonly path: readonly string[]; readonly value: unknown },\n): void {\n let container = root;\n for (const [index, segment] of path.slice(0, -1).entries()) {\n if (!Object.hasOwn(container, segment)) {\n defineValue(container, {\n name: segment,\n value: ARRAY_INDEX.test(path[index + 1]!) ? [] : {},\n });\n }\n container = container[segment] as Record<string, unknown>;\n }\n defineValue(container, { name: path.at(-1)!, value });\n}\n\n/** defineProperty, because assigning `__proto__` would set the prototype instead of a field. */\nfunction defineValue(\n target: Record<string, unknown>,\n { name, value }: { readonly name: string; readonly value: unknown },\n): void {\n Object.defineProperty(target, name, {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n}\n\nfunction readMessage(message: JsonWireMessage, context: Context): JsonEnvelopeFields {\n const { plan, failures } = context;\n if (plan.payload !== undefined && !isJsonObject(message.body)) {\n throw failures.invalid('The message body must be a JSON object');\n }\n const read = (location: Location | undefined): string | undefined =>\n location === undefined ? undefined : readText(message, { location, failures });\n const fields: Record<string, unknown> = {\n id:\n plan.id === undefined\n ? undefined\n : requireText(read(plan.id), { location: plan.id, failures }),\n type: readType(message, context),\n payload: readPayload(message.body, context),\n key: read(plan.optional.key),\n source: read(plan.optional.source),\n headers: readEventHeaders(message, plan),\n correlationId: read(plan.optional.correlationId) ?? null,\n causationId: read(plan.optional.causationId) ?? null,\n occurredAt: readTime(read(plan.optional.occurredAt), failures),\n };\n return Object.fromEntries(\n Object.entries(fields).filter((entry) => entry[1] !== undefined),\n ) as JsonEnvelopeFields;\n}\n\nfunction readType(message: JsonWireMessage, { plan, failures }: Context): string {\n if ('fixed' in plan.type) {\n return plan.type.fixed;\n }\n const location = plan.type;\n const type = requireText(readText(message, { location, failures }), { location, failures });\n try {\n assertEventType(type);\n } catch (error) {\n throw failures.invalid(`The event type is not a valid event type: ${(error as Error).message}`);\n }\n return type;\n}\n\nfunction readPayload(body: unknown, { plan, failures }: Context): unknown {\n if (plan.payload === undefined) {\n return body;\n }\n const payload = valueAt(body, plan.payload);\n if (payload === undefined) {\n throw failures.invalid(`The message has no payload at '${plan.payload.join('.')}'`);\n }\n return payload;\n}\n\nfunction readEventHeaders(message: JsonWireMessage, plan: Plan): EventHeaders {\n if (plan.headers === undefined) {\n return Object.fromEntries(\n Object.entries(message.headers).filter(([name]) => !plan.mappedHeaders.has(name)),\n );\n }\n const headers = valueAt(message.body, plan.headers);\n return isJsonObject(headers)\n ? Object.fromEntries(\n Object.entries(headers).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string',\n ),\n )\n : {};\n}\n\nfunction readTime(text: string | undefined, failures: JsonEnvelopeFailures): Date | undefined {\n if (text === undefined) {\n return undefined;\n }\n const time = new Date(text);\n if (!RFC3339_PATTERN.test(text) || Number.isNaN(time.getTime())) {\n throw failures.invalid(`The event time is not an RFC 3339 timestamp: '${text}'`);\n }\n return time;\n}\n\n/** A string, or a safe integer as its decimal text; undefined when absent, null or empty. */\nfunction readText(\n message: JsonWireMessage,\n { location, failures }: { readonly location: Location; readonly failures: JsonEnvelopeFailures },\n): string | undefined {\n const value =\n 'header' in location\n ? Object.hasOwn(message.headers, location.header)\n ? message.headers[location.header]\n : undefined\n : valueAt(message.body, location.path);\n if (value === undefined || value === null || value === '') {\n return undefined;\n }\n if (typeof value === 'string') {\n return value;\n }\n if (typeof value === 'number' && Number.isSafeInteger(value)) {\n return String(value);\n }\n throw failures.invalid(`The ${location.label} at ${describe(location)} must be a string`);\n}\n\nfunction requireText(\n value: string | undefined,\n { location, failures }: { readonly location: Location; readonly failures: JsonEnvelopeFailures },\n): string {\n if (value === undefined) {\n throw failures.invalid(`The message has no ${location.label} at ${describe(location)}`);\n }\n return value;\n}\n\nfunction describe(location: Location): string {\n return 'header' in location ? `header '${location.header}'` : `'${location.path.join('.')}'`;\n}\n\nfunction valueAt(body: unknown, path: readonly string[]): unknown {\n let value = body;\n for (const segment of path) {\n if (typeof value !== 'object' || value === null || !Object.hasOwn(value, segment)) {\n return undefined;\n }\n value = (value as Record<string, unknown>)[segment];\n }\n return value;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/internal/validation.ts","../../src/internal/field-extractors.ts","../../src/internal/cloudevents.ts","../../src/internal/json-envelope-plan.ts","../../src/internal/json-envelope-read.ts","../../src/internal/json-envelope-write.ts","../../src/internal/json-envelope.ts","../../src/store-kit/handed-out-ledger.ts","../../src/store-kit/owner-serialized-claims.ts","../../src/transport-kit/decoded-event-reader.ts","../../src/transport-kit/subscribing-transport.ts","../../src/values/bounded-integer.ts","../../src/values/exponential-backoff.ts","../../src/values/lane-lease-token.ts","../../src/values/non-empty-text.ts"],"names":["PositiveInteger","ConfigurationError","assertEventType","DeliveryLeaseIdentity"],"mappings":";;;;;AAGO,SAAS,qBAAA,CAAsB,OAAe,IAAA,EAAsB;AACzE,EAAA,OAAOA,iCAAA,CAAgB,EAAA,CAAG,KAAA,EAAO,IAAI,CAAA;AACvC;;;ACQO,SAAS,WACd,IAAA,EACqE;AACrE,EAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,IAAA,MAAM,IAAIC,qCAAmB,gCAAgC,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,CAAC,OAAA,KAAa,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQ,OAAA,EAAS,IAAI,CAAA,GAAI,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA,GAAI,MAAA;AACtF;AAcO,SAAS,iBACd,IAAA,EACgE;AAChE,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC/B,EAAA,IAAI,SAAS,IAAA,CAAK,CAAC,YAAY,OAAA,CAAQ,MAAA,KAAW,CAAC,CAAA,EAAG;AACpD,IAAA,MAAM,IAAIA,oCAAA;AAAA,MACR,sEAAsE,IAAI,CAAA,CAAA;AAAA,KAC5E;AAAA,EACF;AACA,EAAA,OAAO,CAAC,OAAA,KAAY;AAClB,IAAA,IAAI,QAAQ,OAAA,CAAQ,OAAA;AACpB,IAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,MAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,CAAC,MAAA,CAAO,MAAA,CAAO,KAAA,EAAO,OAAO,CAAA,EAAG;AACjF,QAAA,OAAO,MAAA;AAAA,MACT;AACA,MAAA,KAAA,GAAS,MAAkC,OAAO,CAAA;AAAA,IACpD;AACA,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,OAAO,OAAO,aAAA,CAAc,KAAK,CAAA,GAAI,MAAA,CAAO,KAAK,CAAA,GAAI,MAAA;AAAA,EACvD,CAAA;AACF;;;ACrDO,SAAS,YAAY,WAAA,EAA0C;AACpE,EAAA,OAAO,OAAO,WAAA,KAAgB,QAAA,GAC1B,WAAA,CAAY,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,CAAG,IAAA,EAAK,CAAE,WAAA,EAAY,GAC9C,MAAA;AACN;AAEO,SAAS,aAAa,KAAA,EAAkD;AAC7E,EAAA,OAAO,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,CAAC,KAAA,CAAM,QAAQ,KAAK,CAAA;AAC5E;AAUO,SAAS,wBAAwB,OAAA,EAAuD;AAC7F,EAAA,MAAM,iBAAA,GAAoB,CAAC,IAAA,EAA+B,IAAA,KAAqC;AAC7F,IAAA,MAAM,KAAA,GAAQ,KAAK,IAAI,CAAA;AACvB,IAAA,IAAI,KAAA,KAAU,MAAA,IAAa,OAAO,KAAA,KAAU,QAAA,EAAU;AACpD,MAAA,MAAM,OAAA,CAAQ,CAAA,WAAA,EAAc,IAAI,CAAA,kBAAA,CAAoB,CAAA;AAAA,IACtD;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AACA,EAAA,OAAO;AAAA,IACL,iBAAA;AAAA,IACA,iBAAA,EAAmB,CAAC,IAAA,EAAM,IAAA,KAAS;AACjC,MAAA,MAAM,KAAA,GAAQ,iBAAA,CAAkB,IAAA,EAAM,IAAI,CAAA;AAC1C,MAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC7C,QAAA,MAAM,OAAA,CAAQ,CAAA,WAAA,EAAc,IAAI,CAAA,qBAAA,CAAuB,CAAA;AAAA,MACzD;AACA,MAAA,OAAO,KAAA;AAAA,IACT,CAAA;AAAA,IACA,eAAA,EAAiB,CAAC,IAAA,EAAM,KAAA,KAAU;AAChC,MAAA,IAAI;AACF,QAAAC,iCAAA,CAAgB,IAAI,CAAA;AAAA,MACtB,SAAS,KAAA,EAAO;AACd,QAAA,MAAM,QAAQ,CAAA,EAAG,KAAK,CAAA,4BAAA,EAAgC,KAAA,CAAgB,OAAO,CAAA,CAAE,CAAA;AAAA,MACjF;AAAA,IACF,CAAA;AAAA,IACA,yBAAA,EAA2B,CAAC,eAAA,KAAoB;AAC9C,MAAA,MAAM,SAAA,GAAY,YAAY,eAAe,CAAA;AAC7C,MAAA,IACE,SAAA,KAAc,MAAA,IACd,SAAA,KAAc,kBAAA,IACd,SAAA,KAAc,eACd,CAAC,SAAA,CAAU,QAAA,CAAS,OAAO,CAAA,EAC3B;AACA,QAAA,MAAM,OAAA,CAAQ,CAAA,wCAAA,EAA2C,eAAe,CAAA,CAAA,CAAG,CAAA;AAAA,MAC7E;AAAA,IACF;AAAA,GACF;AACF;AAOO,SAAS,yBAAA,CACd,QAAA,EACA,EAAE,IAAA,EAAM,MAAK,EACL;AACR,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,WAAA,EAAa,KAAA;AAAA,IACb,IAAI,QAAA,CAAS,EAAA;AAAA,IACb,MAAM,QAAA,CAAS,IAAA;AAAA,IACf,QAAQ,QAAA,CAAS,MAAA;AAAA,IACjB,IAAA;AAAA,IACA,eAAA,EAAiB,kBAAA;AAAA,IACjB,GAAI,SAAS,GAAA,KAAQ,IAAA,GAAO,EAAC,GAAI,EAAE,OAAA,EAAS,QAAA,CAAS,GAAA,EAAI;AAAA,IACzD,GAAI,SAAS,aAAA,KAAkB,IAAA,GAAO,EAAC,GAAI,EAAE,aAAA,EAAe,QAAA,CAAS,aAAA,EAAc;AAAA,IACnF,GAAI,SAAS,WAAA,KAAgB,IAAA,GAAO,EAAC,GAAI,EAAE,WAAA,EAAa,QAAA,CAAS,WAAA;AAAY,GAC/E;AACA,EAAA,OAAO,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU,UAAU,CAAA,CAAE,MAAM,CAAA,EAAG,EAAE,CAAC,CAAA,QAAA,EAAW,IAAI,CAAA,CAAA,CAAA;AAClE;;;ACpEO,IAAM,cAAA,GAA0C;AAAA,EACrD,KAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,eAAA;AAAA,EACA;AACF,CAAA;AAcO,IAAM,WAAA,GAAc,kBAAA;AAKpB,SAAS,OAAA,CACd,SACA,YAAA,EACM;AACN,EAAA,IAAI,CAAC,YAAA,CAAa,OAAO,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAID,qCAAmB,qCAAqC,CAAA;AAAA,EACpE;AACA,EAAA,MAAM,WAAoD,EAAC;AAC3D,EAAA,KAAA,MAAW,QAAQ,cAAA,EAAgB;AACjC,IAAA,MAAM,KAAA,GAAQ,QAAQ,IAAI,CAAA;AAC1B,IAAA,IAAI,UAAU,MAAA,EAAW;AACvB,MAAA,QAAA,CAAS,IAAI,CAAA,GAAI,UAAA,CAAW,KAAA,EAAO,IAAI,CAAA;AAAA,IACzC;AAAA,EACF;AACA,EAAA,MAAM,IAAA,GAAa;AAAA,IACjB,IAAA,EAAM,WAAA,CAAY,OAAA,CAAQ,IAAI,CAAA;AAAA,IAC9B,EAAA,EAAI,SAAA,CAAU,OAAA,CAAQ,EAAA,EAAI,YAAY,CAAA;AAAA,IACtC,QAAA;AAAA,IACA,OAAA,EAAS,cAAA,CAAe,OAAA,CAAQ,OAAO,CAAA;AAAA,IACvC,OAAA,EAAS,cAAA,CAAe,OAAA,CAAQ,OAAO,CAAA;AAAA,IACvC,aAAA,sBAAmB,GAAA;AAAI,GACzB;AACA,EAAA,OAAO,eAAe,IAAI,CAAA;AAC5B;AAEA,SAAS,YAAY,IAAA,EAAqC;AACxD,EAAA,IAAI,aAAa,IAAI,CAAA,IAAK,OAAO,IAAA,CAAK,OAAO,MAAM,QAAA,EAAU;AAC3D,IAAAC,iCAAA,CAAgB,IAAA,CAAK,OAAO,CAAC,CAAA;AAC7B,IAAA,OAAO,EAAE,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA,EAAE;AAAA,EAChC;AACA,EAAA,IAAI,SAAS,MAAA,EAAW;AACtB,IAAA,MAAM,IAAID,qCAAmB,8DAA8D,CAAA;AAAA,EAC7F;AACA,EAAA,OAAO,UAAA,CAAW,MAAM,MAAM,CAAA;AAChC;AAEA,SAAS,SAAA,CAAU,IAAa,YAAA,EAAuD;AACrF,EAAA,IAAI,OAAO,EAAA,KAAO,QAAA,IAAY,YAAA,CAAa,QAAA,CAAS,EAAE,CAAA,EAAG;AACvD,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,YAAA,CAAa,EAAE,CAAA,EAAG;AACrB,IAAA,MAAM,IAAIA,oCAAA;AAAA,MACR,CAAA,yDAAA,EAA4D,YAAA,CAAa,GAAA,CAAI,CAAC,IAAA,KAAS,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,CAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,KAChH;AAAA,EACF;AACA,EAAA,OAAO,UAAA,CAAW,IAAI,IAAI,CAAA;AAC5B;AAEA,SAAS,eAAe,OAAA,EAAiD;AACvE,EAAA,IAAI,YAAY,YAAA,EAAc;AAC5B,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,aAAa,OAAO,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAM,MAAM,QAAA,EAAU;AACjE,IAAA,MAAM,IAAIA,oCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG,SAAS,CAAA;AAC1C;AAEA,SAAS,eAAe,OAAA,EAAiD;AACvE,EAAA,IAAI,OAAA,KAAY,MAAA,IAAa,OAAA,KAAY,iBAAA,EAAmB;AAC1D,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,aAAa,OAAO,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAM,MAAM,QAAA,EAAU;AACjE,IAAA,MAAM,IAAIA,oCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG,SAAS,CAAA;AAC1C;AAEA,SAAS,UAAA,CAAW,OAAgB,KAAA,EAAyB;AAC3D,EAAA,IAAI,YAAA,CAAa,KAAK,CAAA,IAAK,OAAO,KAAA,CAAM,QAAQ,CAAA,KAAM,QAAA,IAAY,KAAA,CAAM,QAAQ,CAAA,CAAE,MAAA,GAAS,CAAA,EAAG;AAC5F,IAAA,OAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,KAAA,CAAM,QAAQ,CAAA,EAAE;AAAA,EAC1C;AACA,EAAA,IAAI,aAAa,KAAK,CAAA,IAAK,OAAO,KAAA,CAAM,MAAM,MAAM,QAAA,EAAU;AAC5D,IAAA,OAAO,EAAE,OAAO,IAAA,EAAM,MAAA,CAAO,MAAM,MAAM,CAAA,EAAG,KAAK,CAAA,EAAE;AAAA,EACrD;AACA,EAAA,MAAM,IAAIA,oCAAA;AAAA,IACR,gBAAgB,KAAK,CAAA,mDAAA;AAAA,GACvB;AACF;AAEA,SAAS,MAAA,CAAO,MAAc,KAAA,EAAkC;AAC9D,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC/B,EAAA,IAAI,SAAS,IAAA,CAAK,CAAC,YAAY,OAAA,CAAQ,MAAA,KAAW,CAAC,CAAA,EAAG;AACpD,IAAA,MAAM,IAAIA,oCAAA;AAAA,MACR,CAAA,aAAA,EAAgB,KAAK,CAAA,mDAAA,EAAsD,IAAI,CAAA,CAAA;AAAA,KACjF;AAAA,EACF;AACA,EAAA,OAAO,QAAA;AACT;AAGA,SAAS,eAAe,IAAA,EAAkB;AACxC,EAAA,MAAM,SAAA,GAAY,CAAC,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,EAAA,EAAI,GAAG,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAC,CAAA,CAAE,MAAA;AAAA,IACtE,CAAC,QAAA,KAAmC,QAAA,KAAa,MAAA,IAAa,EAAE,OAAA,IAAW,QAAA;AAAA,GAC7E;AACA,EAAA,MAAM,OAAA,GAAU,SAAA,CAAU,OAAA,CAAQ,CAAC,QAAA,KAAc,QAAA,IAAY,QAAA,GAAW,CAAC,QAAA,CAAS,MAAM,CAAA,GAAI,EAAG,CAAA;AAC/F,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,IAAA,CAAK,CAAC,IAAA,EAAM,UAAU,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA,KAAM,KAAK,CAAA;AAC/E,EAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,IAAA,MAAM,IAAIA,oCAAA,CAAmB,CAAA,0BAAA,EAA6B,SAAS,CAAA,OAAA,CAAS,CAAA;AAAA,EAC9E;AACA,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,GAAG,SAAA,CAAU,OAAA,CAAQ,CAAC,QAAA,KAAc,MAAA,IAAU,QAAA,GAAW,CAAC,QAAA,CAAS,IAAI,CAAA,GAAI,EAAG,CAAA;AAAA,IAC9E,GAAG,CAAC,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,OAAO,CAAA,CAAE,MAAA,CAAO,CAAC,IAAA,KAAS,IAAA,KAAS,MAAS;AAAA,GACrE;AACA,EAAA,mBAAA,CAAoB,KAAK,CAAA;AACzB,EAAA,OAAO,EAAE,GAAG,IAAA,EAAM,eAAe,IAAI,GAAA,CAAI,OAAO,CAAA,EAAE;AACpD;AAEA,SAAS,oBAAoB,KAAA,EAA6C;AACxE,EAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,IAAA,EAAM,KAAA,KAAU;AAC7B,IAAA,KAAA,MAAW,KAAA,IAAS,KAAA,CAAM,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAA,EAAG;AAC1C,MAAA,qBAAA,CAAsB,MAAM,KAAK,CAAA;AAAA,IACnC;AAAA,EACF,CAAC,CAAA;AACH;AAGA,SAAS,qBAAA,CAAsB,MAAyB,KAAA,EAAgC;AACtF,EAAA,MAAM,OAAA,GAAU,KAAK,SAAA,CAAU,CAAC,SAAS,QAAA,KAAa,OAAA,KAAY,KAAA,CAAM,QAAQ,CAAC,CAAA;AACjF,EAAA,MAAM,IAAA,GAAO,CAAA,CAAA,EAAI,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAA,OAAA,EAAU,KAAA,CAAM,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA;AACxD,EAAA,IAAI,OAAA,KAAY,EAAA,IAAM,OAAA,KAAY,KAAA,CAAM,MAAA,EAAQ;AAC9C,IAAA,MAAM,IAAIA,oCAAA,CAAmB,CAAA,wBAAA,EAA2B,IAAI,CAAA,QAAA,CAAU,CAAA;AAAA,EACxE;AACA,EAAA,IAAI,WAAA,CAAY,IAAA,CAAK,IAAA,CAAK,OAAO,CAAE,CAAA,KAAM,WAAA,CAAY,IAAA,CAAK,KAAA,CAAM,OAAO,CAAE,CAAA,EAAG;AAC1E,IAAA,MAAM,IAAIA,oCAAA,CAAmB,CAAA,wBAAA,EAA2B,IAAI,CAAA,8BAAA,CAAgC,CAAA;AAAA,EAC9F;AACF;;;AChKA,IAAM,eAAA,GAAkB,uEAAA;AAEjB,SAAS,WAAA,CAAY,SAA0B,OAAA,EAAsC;AAC1F,EAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAS,GAAI,OAAA;AAC3B,EAAA,IAAI,KAAK,OAAA,KAAY,MAAA,IAAa,CAAC,YAAA,CAAa,OAAA,CAAQ,IAAI,CAAA,EAAG;AAC7D,IAAA,MAAM,QAAA,CAAS,QAAQ,wCAAwC,CAAA;AAAA,EACjE;AACA,EAAA,MAAM,IAAA,GAAO,CAAC,QAAA,KACZ,QAAA,KAAa,MAAA,GAAY,MAAA,GAAY,QAAA,CAAS,OAAA,EAAS,EAAE,QAAA,EAAU,QAAA,EAAU,CAAA;AAC/E,EAAA,MAAM,MAAA,GAAkC;AAAA,IACtC,EAAA,EACE,IAAA,CAAK,EAAA,KAAO,MAAA,GACR,SACA,WAAA,CAAY,IAAA,CAAK,IAAA,CAAK,EAAE,GAAG,EAAE,QAAA,EAAU,IAAA,CAAK,EAAA,EAAI,UAAU,CAAA;AAAA,IAChE,IAAA,EAAM,QAAA,CAAS,OAAA,EAAS,OAAO,CAAA;AAAA,IAC/B,OAAA,EAAS,WAAA,CAAY,OAAA,CAAQ,IAAA,EAAM,OAAO,CAAA;AAAA,IAC1C,GAAA,EAAK,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA;AAAA,IAC3B,MAAA,EAAQ,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA;AAAA,IACjC,OAAA,EAAS,gBAAA,CAAiB,OAAA,EAAS,IAAI,CAAA;AAAA,IACvC,aAAA,EAAe,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,aAAa,CAAA,IAAK,IAAA;AAAA,IACpD,WAAA,EAAa,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,WAAW,CAAA,IAAK,IAAA;AAAA,IAChD,YAAY,QAAA,CAAS,IAAA,CAAK,KAAK,QAAA,CAAS,UAAU,GAAG,QAAQ;AAAA,GAC/D;AACA,EAAA,OAAO,MAAA,CAAO,WAAA;AAAA,IACZ,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,CAAE,MAAA,CAAO,CAAC,KAAA,KAAU,KAAA,CAAM,CAAC,CAAA,KAAM,MAAS;AAAA,GACjE;AACF;AAEA,SAAS,QAAA,CAAS,OAAA,EAA0B,EAAE,IAAA,EAAM,UAAS,EAAoB;AAC/E,EAAA,IAAI,OAAA,IAAW,KAAK,IAAA,EAAM;AACxB,IAAA,OAAO,KAAK,IAAA,CAAK,KAAA;AAAA,EACnB;AACA,EAAA,MAAM,WAAW,IAAA,CAAK,IAAA;AACtB,EAAA,MAAM,IAAA,GAAO,WAAA,CAAY,QAAA,CAAS,OAAA,EAAS,EAAE,QAAA,EAAU,QAAA,EAAU,CAAA,EAAG,EAAE,QAAA,EAAU,QAAA,EAAU,CAAA;AAC1F,EAAA,IAAI;AACF,IAAAC,iCAAA,CAAgB,IAAI,CAAA;AAAA,EACtB,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,QAAA,CAAS,OAAA,CAAQ,CAAA,0CAAA,EAA8C,KAAA,CAAgB,OAAO,CAAA,CAAE,CAAA;AAAA,EAChG;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,WAAA,CAAY,IAAA,EAAe,EAAE,IAAA,EAAM,UAAS,EAAqB;AACxE,EAAA,IAAI,IAAA,CAAK,YAAY,MAAA,EAAW;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,IAAA,EAAM,IAAA,CAAK,OAAO,CAAA;AAC1C,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,MAAM,QAAA,CAAS,QAAQ,CAAA,+BAAA,EAAkC,IAAA,CAAK,QAAQ,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,EACpF;AACA,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,gBAAA,CAAiB,SAA0B,IAAA,EAA0B;AAC5E,EAAA,IAAI,IAAA,CAAK,YAAY,MAAA,EAAW;AAC9B,IAAA,OAAO,MAAA,CAAO,WAAA;AAAA,MACZ,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,OAAO,EAAE,MAAA,CAAO,CAAC,CAAC,IAAI,MAAM,CAAC,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,IAAI,CAAC;AAAA,KAClF;AAAA,EACF;AACA,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,IAAA,EAAM,KAAK,OAAO,CAAA;AAClD,EAAA,OAAO,YAAA,CAAa,OAAO,CAAA,GACvB,MAAA,CAAO,WAAA;AAAA,IACL,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,CAAE,MAAA;AAAA,MACtB,CAAC,KAAA,KAAqC,OAAO,KAAA,CAAM,CAAC,CAAA,KAAM;AAAA;AAC5D,MAEF,EAAC;AACP;AAEA,SAAS,QAAA,CAAS,MAA0B,QAAA,EAAkD;AAC5F,EAAA,IAAI,SAAS,MAAA,EAAW;AACtB,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,IAAI,CAAA;AAC1B,EAAA,IAAI,CAAC,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA,IAAK,OAAO,KAAA,CAAM,IAAA,CAAK,OAAA,EAAS,CAAA,EAAG;AAC/D,IAAA,MAAM,QAAA,CAAS,OAAA,CAAQ,CAAA,8CAAA,EAAiD,IAAI,CAAA,CAAA,CAAG,CAAA;AAAA,EACjF;AACA,EAAA,OAAO,IAAA;AACT;AAGA,SAAS,QAAA,CACP,OAAA,EACA,EAAE,QAAA,EAAU,UAAS,EACD;AACpB,EAAA,MAAM,KAAA,GACJ,YAAY,QAAA,GACR,MAAA,CAAO,OAAO,OAAA,CAAQ,OAAA,EAAS,SAAS,MAAM,CAAA,GAC5C,QAAQ,OAAA,CAAQ,QAAA,CAAS,MAAM,CAAA,GAC/B,MAAA,GACF,QAAQ,OAAA,CAAQ,IAAA,EAAM,SAAS,IAAI,CAAA;AACzC,EAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,IAAQ,UAAU,EAAA,EAAI;AACzD,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,MAAA,CAAO,aAAA,CAAc,KAAK,CAAA,EAAG;AAC5D,IAAA,OAAO,OAAO,KAAK,CAAA;AAAA,EACrB;AACA,EAAA,MAAM,QAAA,CAAS,QAAQ,CAAA,IAAA,EAAO,QAAA,CAAS,KAAK,CAAA,IAAA,EAAO,QAAA,CAAS,QAAQ,CAAC,CAAA,iBAAA,CAAmB,CAAA;AAC1F;AAEA,SAAS,WAAA,CACP,KAAA,EACA,EAAE,QAAA,EAAU,UAAS,EACb;AACR,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,MAAM,QAAA,CAAS,QAAQ,CAAA,mBAAA,EAAsB,QAAA,CAAS,KAAK,CAAA,IAAA,EAAO,QAAA,CAAS,QAAQ,CAAC,CAAA,CAAE,CAAA;AAAA,EACxF;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,SAAS,QAAA,EAA4B;AAC5C,EAAA,OAAO,QAAA,IAAY,QAAA,GAAW,CAAA,QAAA,EAAW,QAAA,CAAS,MAAM,CAAA,CAAA,CAAA,GAAM,CAAA,CAAA,EAAI,QAAA,CAAS,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA;AAC3F;AAEA,SAAS,OAAA,CAAQ,MAAe,IAAA,EAAkC;AAChE,EAAA,IAAI,KAAA,GAAQ,IAAA;AACZ,EAAA,KAAA,MAAW,WAAW,IAAA,EAAM;AAC1B,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,CAAC,MAAA,CAAO,MAAA,CAAO,KAAA,EAAO,OAAO,CAAA,EAAG;AACjF,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,KAAA,GAAS,MAAkC,OAAO,CAAA;AAAA,EACpD;AACA,EAAA,OAAO,KAAA;AACT;;;ACxHA,IAAM,oBAAA,GAAuB,IAAA;AAEtB,SAAS,YAAA,CACd,QAAA,EACA,EAAE,IAAA,EAAM,UAAS,EACA;AACjB,EAAA,MAAM,OAAgC,EAAC;AACvC,EAAA,MAAM,UAA8B,EAAC;AACrC,EAAA,MAAM,GAAA,GAAM,CAAC,QAAA,EAAoB,KAAA,KAAwB;AACvD,IAAA,IAAI,YAAY,QAAA,EAAU;AACxB,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAC,QAAA,CAAS,MAAA,EAAQ,KAAK,CAAC,CAAA;AAAA,IACvC,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,MAAM,EAAE,IAAA,EAAM,QAAA,CAAS,IAAA,EAAM,OAAO,CAAA;AAAA,IAC5C;AAAA,EACF,CAAA;AACA,EAAA,IAAI,OAAA,IAAW,KAAK,IAAA,EAAM;AACxB,IAAA,IAAI,QAAA,CAAS,IAAA,KAAS,IAAA,CAAK,IAAA,CAAK,KAAA,EAAO;AACrC,MAAA,MAAM,QAAA,CAAS,WAAA;AAAA,QACb,CAAA,MAAA,EAAS,SAAS,EAAE,CAAA,WAAA,EAAc,SAAS,IAAI,CAAA,gCAAA,EAAmC,IAAA,CAAK,IAAA,CAAK,KAAK,CAAA,CAAA;AAAA,OACnG;AAAA,IACF;AAAA,EACF,CAAA,MAAO;AACL,IAAA,GAAA,CAAI,IAAA,CAAK,IAAA,EAAM,QAAA,CAAS,IAAI,CAAA;AAAA,EAC9B;AACA,EAAA,IAAI,IAAA,CAAK,OAAO,MAAA,EAAW;AACzB,IAAA,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,QAAA,CAAS,EAAE,CAAA;AAAA,EAC1B;AACA,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,KAAK,KAAK,cAAA,CAAe,QAAA,EAAU,QAAQ,CAAA,EAAG;AAC9D,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA;AACnC,IAAA,IAAI,QAAA,KAAa,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AAC5C,MAAA,GAAA,CAAI,UAAU,KAAK,CAAA;AAAA,IACrB;AAAA,EACF;AACA,EAAA,OAAO;AAAA,IACL,MAAM,SAAA,CAAU,QAAA,EAAU,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,IACxC,OAAA,EAAS,MAAA,CAAO,WAAA,CAAY,CAAC,GAAG,kBAAA,CAAmB,QAAA,EAAU,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA,EAAG,GAAG,OAAO,CAAC;AAAA,GAC/F;AACF;AAEA,SAAS,cAAA,CACP,UACA,QAAA,EACiC;AACjC,EAAA,OAAO;AAAA,IACL,CAAC,KAAA,EAAO,QAAA,CAAS,GAAG,CAAA;AAAA,IACpB,CAAC,QAAA,EAAU,QAAA,CAAS,MAAM,CAAA;AAAA,IAC1B,CAAC,YAAA,EAAc,UAAA,CAAW,QAAA,EAAU,QAAQ,CAAC,CAAA;AAAA,IAC7C,CAAC,eAAA,EAAiB,QAAA,CAAS,aAAa,CAAA;AAAA,IACxC,CAAC,aAAA,EAAe,QAAA,CAAS,WAAW;AAAA,GACtC;AACF;AAEA,SAAS,SAAA,CACP,QAAA,EACA,EAAE,IAAA,EAAM,MAAK,EACJ;AACT,EAAA,IAAI,IAAA,CAAK,YAAY,MAAA,EAAW;AAC9B,IAAA,OAAO,QAAA,CAAS,OAAA;AAAA,EAClB;AACA,EAAA,KAAA,CAAM,IAAA,EAAM,EAAE,IAAA,EAAM,IAAA,CAAK,SAAS,KAAA,EAAO,QAAA,CAAS,SAAS,CAAA;AAC3D,EAAA,IAAI,IAAA,CAAK,YAAY,MAAA,EAAW;AAC9B,IAAA,KAAA,CAAM,IAAA,EAAM;AAAA,MACV,MAAM,IAAA,CAAK,OAAA;AAAA,MACX,OAAO,MAAA,CAAO,WAAA,CAAY,OAAO,OAAA,CAAQ,QAAA,CAAS,OAAO,CAAC;AAAA,KAC3D,CAAA;AAAA,EACH;AACA,EAAA,OAAO,IAAA;AACT;AAGA,SAAS,kBAAA,CACP,QAAA,EACA,EAAE,IAAA,EAAM,UAAS,EACG;AACpB,EAAA,IAAI,IAAA,CAAK,YAAY,MAAA,EAAW;AAC9B,IAAA,OAAO,EAAC;AAAA,EACV;AACA,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,QAAA,CAAS,OAAO,CAAA;AAC/C,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAC,IAAI,CAAA,KAAM,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,IAAI,CAAC,CAAA;AACnE,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,MAAM,QAAA,CAAS,WAAA;AAAA,MACb,SAAS,QAAA,CAAS,EAAE,CAAA,eAAA,EAAkB,KAAA,CAAM,CAAC,CAAC,CAAA,2CAAA;AAAA,KAChD;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,UAAA,CAAW,UAAyB,QAAA,EAAwC;AACnF,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,UAAA,CAAW,cAAA,EAAe;AAChD,EAAA,IAAI,OAAO,KAAA,CAAM,IAAI,KAAK,IAAA,GAAO,CAAA,IAAK,OAAO,oBAAA,EAAsB;AACjE,IAAA,MAAM,QAAA,CAAS,WAAA;AAAA,MACb,CAAA,MAAA,EAAS,SAAS,EAAE,CAAA,yFAAA;AAAA,KACtB;AAAA,EACF;AACA,EAAA,OAAO,QAAA,CAAS,WAAW,WAAA,EAAY;AACzC;AAGA,SAAS,KAAA,CACP,IAAA,EACA,EAAE,IAAA,EAAM,OAAM,EACR;AACN,EAAA,IAAI,SAAA,GAAY,IAAA;AAChB,EAAA,KAAA,MAAW,CAAC,KAAA,EAAO,OAAO,CAAA,IAAK,IAAA,CAAK,MAAM,CAAA,EAAG,EAAE,CAAA,CAAE,OAAA,EAAQ,EAAG;AAC1D,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,OAAO,CAAA,EAAG;AACtC,MAAA,WAAA,CAAY,SAAA,EAAW;AAAA,QACrB,IAAA,EAAM,OAAA;AAAA,QACN,KAAA,EAAO,WAAA,CAAY,IAAA,CAAK,IAAA,CAAK,KAAA,GAAQ,CAAC,CAAE,CAAA,GAAI,EAAC,GAAI;AAAC,OACnD,CAAA;AAAA,IACH;AACA,IAAA,SAAA,GAAY,UAAU,OAAO,CAAA;AAAA,EAC/B;AACA,EAAA,WAAA,CAAY,SAAA,EAAW,EAAE,IAAA,EAAM,IAAA,CAAK,GAAG,EAAE,CAAA,EAAI,OAAO,CAAA;AACtD;AAGA,SAAS,WAAA,CACP,MAAA,EACA,EAAE,IAAA,EAAM,OAAM,EACR;AACN,EAAA,MAAA,CAAO,cAAA,CAAe,QAAQ,IAAA,EAAM;AAAA,IAClC,KAAA;AAAA,IACA,UAAA,EAAY,IAAA;AAAA,IACZ,QAAA,EAAU,IAAA;AAAA,IACV,YAAA,EAAc;AAAA,GACf,CAAA;AACH;;;AC7BO,SAAS,yBACd,OAAA,EACA;AAAA,EACE,YAAA;AAAA,EACA;AACF,CAAA,EACoB;AACpB,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,OAAA,EAAS,YAAY,CAAA;AAC1C,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,CAAC,QAAA,KAAa,YAAA,CAAa,UAAU,EAAE,IAAA,EAAM,UAAU,CAAA;AAAA,IAC9D,IAAA,EAAM,CAAC,OAAA,KAAY,WAAA,CAAY,SAAS,EAAE,IAAA,EAAM,UAAU;AAAA,GAC5D;AACF;;;AC5GO,IAAM,kBAAN,MAAqD;AAAA,EACjD,QAAA,uBAAe,GAAA,EAAoB;AAAA,EAE5C,QAAA,CAAS,OAAuB,KAAA,EAAqB;AACnD,IAAA,IAAA,CAAK,QAAA,CAAS,IAAIC,uCAAA,CAAsB,EAAA,CAAG,MAAM,UAAA,EAAY,KAAA,CAAM,UAAU,CAAA,EAAG,KAAK,CAAA;AAAA,EACvF;AAAA;AAAA,EAGA,IAAI,QAAA,EAA2B;AAC7B,IAAA,OAAO,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA;AAAA,EACnC;AAAA,EAEA,OAAO,KAAA,EAA6B;AAClC,IAAA,IAAA,CAAK,QAAA,CAAS,OAAOA,uCAAA,CAAsB,EAAA,CAAG,MAAM,UAAA,EAAY,KAAA,CAAM,UAAU,CAAC,CAAA;AAAA,EACnF;AAAA;AAAA,EAGA,YAAY,OAAA,EAA6D;AACvE,IAAA,KAAA,MAAW,CAAC,QAAA,EAAU,KAAK,CAAA,IAAK,KAAK,QAAA,EAAU;AAC7C,MAAA,IAAI,OAAA,CAAQ,KAAA,EAAO,QAAQ,CAAA,EAAG;AAC5B,QAAA,IAAA,CAAK,QAAA,CAAS,OAAO,QAAQ,CAAA;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,UAAU,KAAA,EAAyB;AACjC,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,QAAA,CAAS,MAAA,EAAQ,CAAA,CAAE,MAAA,CAAO,CAAC,KAAA,KAAU,KAAA,CAAM,KAAA,KAAU,KAAK,CAAA;AAAA,EAC5E;AACF;;;AClCO,IAAe,wBAAf,MAAqC;AAAA;AAAA,EAEjC,OAAA,uBAAc,GAAA,EAA2B;AAAA,EAElD,MAAM,OAAA,EAAmD;AACvD,IAAA,IAAI,IAAA,CAAK,aAAA,CAAc,OAAO,CAAA,EAAG;AAC/B,MAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,EAAE,CAAA;AAAA,IAC3B;AACA,IAAA,OAAO,IAAA,CAAK,YAAY,OAAA,CAAQ,UAAA,EAAY,MAAM,IAAA,CAAK,WAAA,CAAY,OAAO,CAAC,CAAA;AAAA,EAC7E;AAAA;AAAA,EAGU,cAAc,OAAA,EAAgC;AACtD,IAAA,OAAO,QAAQ,QAAA,CAAS,MAAA,KAAW,CAAA,IAAK,EAAE,QAAQ,KAAA,GAAQ,CAAA,CAAA;AAAA,EAC5D;AAAA,EAKA,WAAA,CAAe,OAAe,IAAA,EAAoC;AAChE,IAAA,MAAM,WAAW,IAAA,CAAK,OAAA,CAAQ,IAAI,KAAK,CAAA,IAAK,QAAQ,OAAA,EAAQ;AAC5D,IAAA,MAAM,GAAA,GAAM,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AACpC,IAAA,MAAM,OAAO,GAAA,CAAI,IAAA;AAAA,MACf,MAAM,MAAA;AAAA,MACN,MAAM;AAAA,KACR;AACA,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,KAAA,EAAO,IAAI,CAAA;AAC5B,IAAA,KAAK,IAAA,CAAK,KAAK,MAAM;AACnB,MAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,KAAK,MAAM,IAAA,EAAM;AACpC,QAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,KAAK,CAAA;AAAA,MAC3B;AAAA,IACF,CAAC,CAAA;AACD,IAAA,OAAO,GAAA;AAAA,EACT;AACF;;;ACnBO,SAAS,iBAAiB,KAAA,EAAsB;AACrD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,UAAU,KAAA,EAAO;AAClE,IAAA,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAA,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AAAA,EAC9C;AACF;AAOO,IAAe,qBAAf,MAAoD;AAAA;AAAA;AAAA;AAAA;AAAA,EAKzD,QAAA,CAAS,SAAkB,OAAA,EAAkC;AAC3D,IAAA,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,OAAA,KAAY,IAAA,EAAM;AACnD,MAAA,MAAM,IAAA,CAAK,QAAQ,uDAAuD,CAAA;AAAA,IAC5E;AACA,IAAA,IAAI,UAAU,OAAA,EAAS;AACrB,MAAA,gBAAA,CAAiB,OAAO,CAAA;AACxB,MAAA,MAAM,IAAA,CAAK,QAAQ,uDAAuD,CAAA;AAAA,IAC5E;AACA,IAAA,MAAM,KAAA,GAAQ,OAAA;AACd,IAAA,OAAO;AAAA,MACL,IAAI,KAAA,CAAM,EAAA;AAAA,MACV,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,MAAA,EAAQ,KAAA,CAAM,MAAA,IAAU,IAAA,CAAK,cAAc,OAAO,CAAA;AAAA,MAClD,GAAA,EAAK,MAAM,GAAA,KAAQ,MAAA,GAAY,KAAK,UAAA,CAAW,OAAO,IAAI,KAAA,CAAM,GAAA;AAAA,MAChE,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,OAAA,EAAS,KAAA,CAAM,OAAA,IAAW,EAAC;AAAA,MAC3B,aAAA,EAAe,MAAM,aAAA,IAAiB,IAAA;AAAA,MACtC,WAAA,EAAa,MAAM,WAAA,IAAe,IAAA;AAAA,MAClC,UAAA,EAAY,KAAA,CAAM,UAAA,IAAc,IAAA,CAAK,YAAY,OAAO;AAAA,KAC1D;AAAA,EACF;AAAA;AAAA,EAGA,IAAA,CACE,MAAA,EACA,EAAE,KAAA,EAAO,MAAK,EACM;AACpB,IAAA,MAAM,QAAiB,OAAO,MAAA,KAAW,UAAA,GAAa,MAAA,CAAO,KAAK,CAAA,GAAI,MAAA;AACtE,IAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AACzC,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,MAAA,gBAAA,CAAiB,KAAK,CAAA;AACtB,MAAA,MAAM,KAAK,OAAA,CAAQ,CAAA,IAAA,EAAO,IAAI,CAAA,iBAAA,EAAoB,OAAO,KAAK,CAAA,mBAAA,CAAqB,CAAA;AAAA,IACrF;AACA,IAAA,OAAO,KAAA,CAAM,MAAA,KAAW,CAAA,GAAI,MAAA,GAAY,KAAA;AAAA,EAC1C;AAUF;;;AClEO,IAAe,uBAAf,MAAyD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS9D,SAAA,CACE,YAAA,EACA,SAAA,EACA,KAAA,EACe;AACf,IAAA,OAAO,KAAK,gBAAA,CAAiB,EAAE,YAAA,EAAc,SAAA,EAAW,OAAO,CAAA;AAAA,EACjE;AAUF;;;ACnCO,IAAe,iBAAf,MAA8B;AAAA;AAAA,EAEnC,OAAO,EAAA,CAAG,KAAA,EAAe,EAAE,IAAA,EAAM,OAAA,EAAS,SAAQ,EAA0B;AAC1E,IAAA,IAAI,CAAC,OAAO,SAAA,CAAU,KAAK,KAAK,KAAA,GAAQ,OAAA,IAAW,QAAQ,OAAA,EAAS;AAClE,MAAA,MAAM,IAAIF,oCAAA;AAAA,QACR,GAAG,IAAI,CAAA,yBAAA,EAA4B,OAAO,CAAA,IAAA,EAAO,OAAO,cAAc,KAAK,CAAA;AAAA,OAC7E;AAAA,IACF;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AACF;;;AChBO,IAAM,qBAAN,MAAyB;AAAA,EACrB,SAAA;AAAA,EACA,KAAA;AAAA,EAET,WAAA,CAAY,EAAE,SAAA,EAAW,KAAA,EAAM,EAA2D;AACxF,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAAA,EACf;AAAA;AAAA,EAGA,SAAS,OAAA,EAAyB;AAChC,IAAA,OAAO,IAAA,CAAK,IAAI,IAAA,CAAK,SAAA,GAAY,MAAM,OAAA,GAAU,CAAA,CAAA,EAAI,KAAK,KAAK,CAAA;AAAA,EACjE;AACF;;;ACAA,IAAM,WAAA,GAAc,CAAA;AAOb,IAAM,uBAAN,MAA2B;AAAA,EACvB,QAAA;AAAA,EACA,UAAA;AAAA,EAET,YAAY,MAAA,EAA8B;AACxC,IAAA,IAAA,CAAK,aAAa,MAAA,CAAO,SAAA;AACzB,IAAA,IAAA,CAAK,WAAW,IAAI,MAAA;AAAA,MAClB,WAAW,WAAW,CAAA,UAAA,EAAa,OAAO,WAAW,CAAA,UAAA,EAAa,OAAO,YAAY,CAAA,GAAA;AAAA,KACvF;AAAA,EACF;AAAA,EAEA,MAAA,CACE,IAAA,EACA,EAAE,KAAA,EAAO,QAAO,EACR;AACR,IAAA,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAK,IAAI,MAAM,CAAA,CAAA;AAAA,EACnC;AAAA;AAAA,EAGA,MAAM,KAAA,EAAgD;AACpD,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,KAAK,CAAA;AACtC,IAAA,IAAI,KAAA,KAAU,QAAQ,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA,IAAK,KAAK,UAAA,EAAY;AACzD,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,OAAO,EAAE,IAAA,EAAM,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA,EAAG,KAAA,EAAO,KAAA,CAAM,CAAC,GAAI,MAAA,EAAQ,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA,EAAE;AAAA,EAC9E;AACF;;;AC/CO,IAAe,YAAA,GAAf,MAAe,aAAA,CAAa;AAAA,EACjC,OAAO,EAAA,CAAG,KAAA,EAAe,IAAA,EAAsB;AAC7C,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,MAAA,MAAM,IAAIA,oCAAA,CAAmB,CAAA,EAAG,IAAI,CAAA,kBAAA,CAAoB,CAAA;AAAA,IAC1D;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA,EAGA,OAAO,QAAA,CAAS,KAAA,EAA2B,IAAA,EAAkC;AAC3E,IAAA,OAAO,UAAU,MAAA,GAAY,MAAA,GAAY,aAAA,CAAa,EAAA,CAAG,OAAO,IAAI,CAAA;AAAA,EACtE;AACF","file":"index.cjs","sourcesContent":["import { PositiveInteger } from '../values/positive-integer.js';\n\n/** Returns `value` when it is an integer of at least 1, else throws a {@link ConfigurationError} naming the option. */\nexport function assertPositiveInteger(value: number, name: string): number {\n return PositiveInteger.of(value, name);\n}\n","import { ConfigurationError } from '../errors.js';\nimport type { EventHeaders } from '../event.js';\n\n/**\n * Reads one header of an incoming message, for the `type`, `id`, `key` or\n * `source` option of {@link plainJsonDecoder}. Header names are compared\n * exactly (Kafka and AMQP header names are case-sensitive). Returns undefined when the\n * header is absent, so the decoder falls back to its default.\n *\n * ```ts\n * plainJsonDecoder({ type: fromHeader('event-type'), id: fromHeader('message-id') })\n * ```\n */\nexport function fromHeader(\n name: string,\n): (message: { readonly headers: EventHeaders }) => string | undefined {\n if (name.length === 0) {\n throw new ConfigurationError('fromHeader needs a header name');\n }\n return (message) => (Object.hasOwn(message.headers, name) ? message.headers[name] : undefined);\n}\n\n/**\n * Reads a field of the JSON payload by a dotted path (`'meta.eventType'`), for\n * the `type`, `id`, `key` or `source` option of {@link plainJsonDecoder}. A\n * string is returned as is and a safe integer as its decimal text (numeric ids\n * are common). Anything else returns undefined so the decoder falls back to its\n * default: a missing field, and also a fraction or an integer beyond 2^53, which\n * JSON parsing may already have rounded, so two different ids could collide.\n *\n * ```ts\n * plainJsonDecoder({ type: fromPayloadField('eventType'), key: fromPayloadField('order.id') })\n * ```\n */\nexport function fromPayloadField(\n path: string,\n): (message: { readonly payload: unknown }) => string | undefined {\n const segments = path.split('.');\n if (segments.some((segment) => segment.length === 0)) {\n throw new ConfigurationError(\n `fromPayloadField needs a dotted path of non-empty names, received '${path}'`,\n );\n }\n return (message) => {\n let value = message.payload;\n for (const segment of segments) {\n if (typeof value !== 'object' || value === null || !Object.hasOwn(value, segment)) {\n return undefined;\n }\n value = (value as Record<string, unknown>)[segment];\n }\n if (typeof value === 'string') {\n return value;\n }\n return Number.isSafeInteger(value) ? String(value) : undefined;\n };\n}\n","import { assertEventType, type EventEnvelope } from '../event.js';\n\n/** The media type of a content type, without parameters and lower-cased; undefined for anything but a string. */\nexport function mediaTypeOf(contentType: unknown): string | undefined {\n return typeof contentType === 'string'\n ? contentType.split(';')[0]!.trim().toLowerCase()\n : undefined;\n}\n\nexport function isJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Readers of structured CloudEvent attributes that fail with the error of the calling transport. */\nexport interface CloudEventReaders {\n readonly optionalAttribute: (body: Record<string, unknown>, name: string) => string | undefined;\n readonly requiredAttribute: (body: Record<string, unknown>, name: string) => string;\n readonly assertValidType: (type: string, label: string) => void;\n readonly assertJsonDataContentType: (dataContentType: string | undefined) => void;\n}\n\nexport function createCloudEventReaders(invalid: (reason: string) => Error): CloudEventReaders {\n const optionalAttribute = (body: Record<string, unknown>, name: string): string | undefined => {\n const value = body[name];\n if (value !== undefined && typeof value !== 'string') {\n throw invalid(`Attribute '${name}' must be a string`);\n }\n return value;\n };\n return {\n optionalAttribute,\n requiredAttribute: (body, name) => {\n const value = optionalAttribute(body, name);\n if (value === undefined || value.length === 0) {\n throw invalid(`Attribute '${name}' is missing or empty`);\n }\n return value;\n },\n assertValidType: (type, label) => {\n try {\n assertEventType(type);\n } catch (error) {\n throw invalid(`${label} is not a valid event type: ${(error as Error).message}`);\n }\n },\n assertJsonDataContentType: (dataContentType) => {\n const mediaType = mediaTypeOf(dataContentType);\n if (\n mediaType !== undefined &&\n mediaType !== 'application/json' &&\n mediaType !== 'text/json' &&\n !mediaType.endsWith('+json')\n ) {\n throw invalid(`datacontenttype must be JSON, received '${dataContentType}'`);\n }\n },\n };\n}\n\n/**\n * The JSON text of a CloudEvents 1.0 structured-mode event: the attributes (the key as `subject`,\n * correlation and causation ids as extension attributes), then `data`, the already serialized\n * payload, so the payload is serialized only once.\n */\nexport function writeStructuredCloudEvent(\n envelope: EventEnvelope,\n { time, data }: { readonly time: string; readonly data: string },\n): string {\n const attributes = {\n specversion: '1.0',\n id: envelope.id,\n type: envelope.type,\n source: envelope.source,\n time,\n datacontenttype: 'application/json',\n ...(envelope.key === null ? {} : { subject: envelope.key }),\n ...(envelope.correlationId === null ? {} : { correlationid: envelope.correlationId }),\n ...(envelope.causationId === null ? {} : { causationid: envelope.causationId }),\n };\n return `${JSON.stringify(attributes).slice(0, -1)},\"data\":${data}}`;\n}\n","import { ConfigurationError } from '../errors.js';\nimport { assertEventType } from '../event.js';\nimport { isJsonObject } from './cloudevents.js';\nimport type { FixedType, JsonEnvelopeFailures, JsonEnvelopeMapping } from './json-envelope.js';\n\n// Compiling a jsonEnvelope mapping into the plan that writing and reading follow.\n\nexport type Location =\n | { readonly label: string; readonly header: string }\n | { readonly label: string; readonly path: readonly string[] };\n\nexport type OptionalName = 'key' | 'source' | 'occurredAt' | 'correlationId' | 'causationId';\nexport const OPTIONAL_NAMES: readonly OptionalName[] = [\n 'key',\n 'source',\n 'occurredAt',\n 'correlationId',\n 'causationId',\n];\n\nexport type Plan = {\n readonly type: Location | FixedType;\n /** Undefined when the transport supplies the id. */\n readonly id: Location | undefined;\n readonly optional: Readonly<Partial<Record<OptionalName, Location>>>;\n /** Undefined when the payload is the whole body. */\n readonly payload: readonly string[] | undefined;\n /** Undefined when event headers are the unmapped message headers. */\n readonly headers: readonly string[] | undefined;\n readonly mappedHeaders: ReadonlySet<string>;\n};\n\nexport const ARRAY_INDEX = /^(?:0|[1-9]\\d*)$/;\n\n/** A compiled mapping with the errors of the calling transport. */\nexport type Context = { readonly plan: Plan; readonly failures: JsonEnvelopeFailures };\n\nexport function compile(\n mapping: JsonEnvelopeMapping<string>,\n transportIds: readonly string[],\n): Plan {\n if (!isJsonObject(mapping)) {\n throw new ConfigurationError('jsonEnvelope needs a mapping object');\n }\n const optional: Partial<Record<OptionalName, Location>> = {};\n for (const name of OPTIONAL_NAMES) {\n const field = mapping[name];\n if (field !== undefined) {\n optional[name] = toLocation(field, name);\n }\n }\n const plan: Plan = {\n type: compileType(mapping.type),\n id: compileId(mapping.id, transportIds),\n optional,\n payload: compilePayload(mapping.payload),\n headers: compileHeaders(mapping.headers),\n mappedHeaders: new Set(),\n };\n return assertDisjoint(plan);\n}\n\nfunction compileType(type: unknown): Location | FixedType {\n if (isJsonObject(type) && typeof type['fixed'] === 'string') {\n assertEventType(type['fixed']);\n return { fixed: type['fixed'] };\n }\n if (type === undefined) {\n throw new ConfigurationError('jsonEnvelope needs a type: { body }, { header } or { fixed }');\n }\n return toLocation(type, 'type');\n}\n\nfunction compileId(id: unknown, transportIds: readonly string[]): Location | undefined {\n if (typeof id === 'string' && transportIds.includes(id)) {\n return undefined;\n }\n if (!isJsonObject(id)) {\n throw new ConfigurationError(\n `jsonEnvelope needs an id: { body }, { header } or one of ${transportIds.map((name) => `'${name}'`).join(', ')}`,\n );\n }\n return toLocation(id, 'id');\n}\n\nfunction compilePayload(payload: unknown): readonly string[] | undefined {\n if (payload === 'whole-body') {\n return undefined;\n }\n if (!isJsonObject(payload) || typeof payload['body'] !== 'string') {\n throw new ConfigurationError(\n \"jsonEnvelope needs a payload: { body: '<path>' } or 'whole-body'\",\n );\n }\n return toPath(payload['body'], 'payload');\n}\n\nfunction compileHeaders(headers: unknown): readonly string[] | undefined {\n if (headers === undefined || headers === 'message-headers') {\n return undefined;\n }\n if (!isJsonObject(headers) || typeof headers['body'] !== 'string') {\n throw new ConfigurationError(\n \"jsonEnvelope headers must be { body: '<path>' } or 'message-headers'\",\n );\n }\n return toPath(headers['body'], 'headers');\n}\n\nfunction toLocation(field: unknown, label: string): Location {\n if (isJsonObject(field) && typeof field['header'] === 'string' && field['header'].length > 0) {\n return { label, header: field['header'] };\n }\n if (isJsonObject(field) && typeof field['body'] === 'string') {\n return { label, path: toPath(field['body'], label) };\n }\n throw new ConfigurationError(\n `jsonEnvelope ${label} must be { body: '<path>' } or { header: '<name>' }`,\n );\n}\n\nfunction toPath(path: string, label: string): readonly string[] {\n const segments = path.split('.');\n if (segments.some((segment) => segment.length === 0)) {\n throw new ConfigurationError(\n `jsonEnvelope ${label} needs a dotted path of non-empty names, received '${path}'`,\n );\n }\n return segments;\n}\n\n/** Collects the mapped headers and refuses overlapping locations, which would overwrite each other. */\nfunction assertDisjoint(plan: Plan): Plan {\n const locations = [plan.type, plan.id, ...Object.values(plan.optional)].filter(\n (location): location is Location => location !== undefined && !('fixed' in location),\n );\n const headers = locations.flatMap((location) => ('header' in location ? [location.header] : []));\n const duplicate = headers.find((name, index) => headers.indexOf(name) !== index);\n if (duplicate !== undefined) {\n throw new ConfigurationError(`jsonEnvelope maps header '${duplicate}' twice`);\n }\n const paths = [\n ...locations.flatMap((location) => ('path' in location ? [location.path] : [])),\n ...[plan.payload, plan.headers].filter((path) => path !== undefined),\n ];\n assertNoNestedPaths(paths);\n return { ...plan, mappedHeaders: new Set(headers) };\n}\n\nfunction assertNoNestedPaths(paths: readonly (readonly string[])[]): void {\n paths.forEach((path, index) => {\n for (const other of paths.slice(index + 1)) {\n assertCompatiblePaths(path, other);\n }\n });\n}\n\n/** Two body paths must part ways, and where they do, both index an array or both name a field. */\nfunction assertCompatiblePaths(path: readonly string[], other: readonly string[]): void {\n const parting = path.findIndex((segment, position) => segment !== other[position]);\n const both = `'${path.join('.')}' and '${other.join('.')}'`;\n if (parting === -1 || parting === other.length) {\n throw new ConfigurationError(`jsonEnvelope body paths ${both} overlap`);\n }\n if (ARRAY_INDEX.test(path[parting]!) !== ARRAY_INDEX.test(other[parting]!)) {\n throw new ConfigurationError(`jsonEnvelope body paths ${both} mix an array index and a name`);\n }\n}\n","import { assertEventType, type EventHeaders } from '../event.js';\nimport { isJsonObject } from './cloudevents.js';\nimport type { JsonEnvelopeFailures, JsonEnvelopeFields, JsonWireMessage } from './json-envelope.js';\nimport type { Context, Location, Plan } from './json-envelope-plan.js';\n\n// Reading the envelope fields of a JSON message by a compiled mapping.\n\nconst RFC3339_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$/i;\n\nexport function readMessage(message: JsonWireMessage, context: Context): JsonEnvelopeFields {\n const { plan, failures } = context;\n if (plan.payload !== undefined && !isJsonObject(message.body)) {\n throw failures.invalid('The message body must be a JSON object');\n }\n const read = (location: Location | undefined): string | undefined =>\n location === undefined ? undefined : readText(message, { location, failures });\n const fields: Record<string, unknown> = {\n id:\n plan.id === undefined\n ? undefined\n : requireText(read(plan.id), { location: plan.id, failures }),\n type: readType(message, context),\n payload: readPayload(message.body, context),\n key: read(plan.optional.key),\n source: read(plan.optional.source),\n headers: readEventHeaders(message, plan),\n correlationId: read(plan.optional.correlationId) ?? null,\n causationId: read(plan.optional.causationId) ?? null,\n occurredAt: readTime(read(plan.optional.occurredAt), failures),\n };\n return Object.fromEntries(\n Object.entries(fields).filter((entry) => entry[1] !== undefined),\n ) as JsonEnvelopeFields;\n}\n\nfunction readType(message: JsonWireMessage, { plan, failures }: Context): string {\n if ('fixed' in plan.type) {\n return plan.type.fixed;\n }\n const location = plan.type;\n const type = requireText(readText(message, { location, failures }), { location, failures });\n try {\n assertEventType(type);\n } catch (error) {\n throw failures.invalid(`The event type is not a valid event type: ${(error as Error).message}`);\n }\n return type;\n}\n\nfunction readPayload(body: unknown, { plan, failures }: Context): unknown {\n if (plan.payload === undefined) {\n return body;\n }\n const payload = valueAt(body, plan.payload);\n if (payload === undefined) {\n throw failures.invalid(`The message has no payload at '${plan.payload.join('.')}'`);\n }\n return payload;\n}\n\nfunction readEventHeaders(message: JsonWireMessage, plan: Plan): EventHeaders {\n if (plan.headers === undefined) {\n return Object.fromEntries(\n Object.entries(message.headers).filter(([name]) => !plan.mappedHeaders.has(name)),\n );\n }\n const headers = valueAt(message.body, plan.headers);\n return isJsonObject(headers)\n ? Object.fromEntries(\n Object.entries(headers).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string',\n ),\n )\n : {};\n}\n\nfunction readTime(text: string | undefined, failures: JsonEnvelopeFailures): Date | undefined {\n if (text === undefined) {\n return undefined;\n }\n const time = new Date(text);\n if (!RFC3339_PATTERN.test(text) || Number.isNaN(time.getTime())) {\n throw failures.invalid(`The event time is not an RFC 3339 timestamp: '${text}'`);\n }\n return time;\n}\n\n/** A string, or a safe integer as its decimal text; undefined when absent, null or empty. */\nfunction readText(\n message: JsonWireMessage,\n { location, failures }: { readonly location: Location; readonly failures: JsonEnvelopeFailures },\n): string | undefined {\n const value =\n 'header' in location\n ? Object.hasOwn(message.headers, location.header)\n ? message.headers[location.header]\n : undefined\n : valueAt(message.body, location.path);\n if (value === undefined || value === null || value === '') {\n return undefined;\n }\n if (typeof value === 'string') {\n return value;\n }\n if (typeof value === 'number' && Number.isSafeInteger(value)) {\n return String(value);\n }\n throw failures.invalid(`The ${location.label} at ${describe(location)} must be a string`);\n}\n\nfunction requireText(\n value: string | undefined,\n { location, failures }: { readonly location: Location; readonly failures: JsonEnvelopeFailures },\n): string {\n if (value === undefined) {\n throw failures.invalid(`The message has no ${location.label} at ${describe(location)}`);\n }\n return value;\n}\n\nfunction describe(location: Location): string {\n return 'header' in location ? `header '${location.header}'` : `'${location.path.join('.')}'`;\n}\n\nfunction valueAt(body: unknown, path: readonly string[]): unknown {\n let value = body;\n for (const segment of path) {\n if (typeof value !== 'object' || value === null || !Object.hasOwn(value, segment)) {\n return undefined;\n }\n value = (value as Record<string, unknown>)[segment];\n }\n return value;\n}\n","import type { EventEnvelope } from '../event.js';\nimport type { JsonEnvelopeFailures, JsonWireMessage } from './json-envelope.js';\nimport {\n ARRAY_INDEX,\n type Context,\n type Location,\n type OptionalName,\n type Plan,\n} from './json-envelope-plan.js';\n\n// Writing an envelope as a JSON message by a compiled mapping.\n\n/** RFC 3339 years have four digits. */\nconst MAXIMUM_RFC3339_YEAR = 9999;\n\nexport function writeMessage(\n envelope: EventEnvelope,\n { plan, failures }: Context,\n): JsonWireMessage {\n const root: Record<string, unknown> = {};\n const headers: [string, string][] = [];\n const put = (location: Location, value: string): void => {\n if ('header' in location) {\n headers.push([location.header, value]);\n } else {\n setAt(root, { path: location.path, value });\n }\n };\n if ('fixed' in plan.type) {\n if (envelope.type !== plan.type.fixed) {\n throw failures.unencodable(\n `Event ${envelope.id} has type '${envelope.type}', but this route carries only '${plan.type.fixed}'`,\n );\n }\n } else {\n put(plan.type, envelope.type);\n }\n if (plan.id !== undefined) {\n put(plan.id, envelope.id);\n }\n for (const [name, value] of optionalValues(envelope, failures)) {\n const location = plan.optional[name];\n if (location !== undefined && value !== null) {\n put(location, value);\n }\n }\n return {\n body: writeBody(envelope, { plan, root }),\n headers: Object.fromEntries([...eventHeaderEntries(envelope, { plan, failures }), ...headers]),\n };\n}\n\nfunction optionalValues(\n envelope: EventEnvelope,\n failures: JsonEnvelopeFailures,\n): [OptionalName, string | null][] {\n return [\n ['key', envelope.key],\n ['source', envelope.source],\n ['occurredAt', formatTime(envelope, failures)],\n ['correlationId', envelope.correlationId],\n ['causationId', envelope.causationId],\n ];\n}\n\nfunction writeBody(\n envelope: EventEnvelope,\n { plan, root }: { readonly plan: Plan; readonly root: Record<string, unknown> },\n): unknown {\n if (plan.payload === undefined) {\n return envelope.payload;\n }\n setAt(root, { path: plan.payload, value: envelope.payload });\n if (plan.headers !== undefined) {\n setAt(root, {\n path: plan.headers,\n value: Object.fromEntries(Object.entries(envelope.headers)),\n });\n }\n return root;\n}\n\n/** The event headers that travel as message headers; a name a mapped field uses is refused. */\nfunction eventHeaderEntries(\n envelope: EventEnvelope,\n { plan, failures }: Context,\n): [string, string][] {\n if (plan.headers !== undefined) {\n return [];\n }\n const entries = Object.entries(envelope.headers);\n const taken = entries.find(([name]) => plan.mappedHeaders.has(name));\n if (taken !== undefined) {\n throw failures.unencodable(\n `Event ${envelope.id} has a header '${taken[0]}', which the mapping uses for another field`,\n );\n }\n return entries;\n}\n\nfunction formatTime(envelope: EventEnvelope, failures: JsonEnvelopeFailures): string {\n const year = envelope.occurredAt.getUTCFullYear();\n if (Number.isNaN(year) || year < 0 || year > MAXIMUM_RFC3339_YEAR) {\n throw failures.unencodable(\n `Event ${envelope.id} has an occurredAt that is not an RFC 3339 instant (invalid date or year outside 0..9999)`,\n );\n }\n return envelope.occurredAt.toISOString();\n}\n\n/** Sets a value at a path, creating objects (arrays before an index segment) as own properties. */\nfunction setAt(\n root: Record<string, unknown>,\n { path, value }: { readonly path: readonly string[]; readonly value: unknown },\n): void {\n let container = root;\n for (const [index, segment] of path.slice(0, -1).entries()) {\n if (!Object.hasOwn(container, segment)) {\n defineValue(container, {\n name: segment,\n value: ARRAY_INDEX.test(path[index + 1]!) ? [] : {},\n });\n }\n container = container[segment] as Record<string, unknown>;\n }\n defineValue(container, { name: path.at(-1)!, value });\n}\n\n/** defineProperty, because assigning `__proto__` would set the prototype instead of a field. */\nfunction defineValue(\n target: Record<string, unknown>,\n { name, value }: { readonly name: string; readonly value: unknown },\n): void {\n Object.defineProperty(target, name, {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n}\n","import type { EventEnvelope, EventHeaders } from '../event.js';\nimport { compile } from './json-envelope-plan.js';\nimport { readMessage } from './json-envelope-read.js';\nimport { writeMessage } from './json-envelope-write.js';\n\n/**\n * A field of the JSON body, by dotted path: `'eventName'`, `'meta.correlationId'`. A segment that\n * is a whole number indexes an array: `'messageType.0'` is the first element of `messageType`.\n */\nexport type BodyField = { readonly body: string };\n/** A message header (Kafka record header, AMQP message header), by exact name. */\nexport type HeaderField = { readonly header: string };\n/** Where one envelope value lives on the wire. */\nexport type WireField = BodyField | HeaderField;\n/** The one event type every message of the route carries: written nowhere, used for every message read. */\nexport type FixedType = { readonly fixed: string };\n\ntype MappingFields<TField extends WireField, TTransportId extends string> = {\n /** Where the event type lives, or the one type of the route. Required. */\n readonly type: TField | FixedType;\n /**\n * Where the event id lives, or the transport's own message identity (see the transport's\n * mapping type). Required, so the inbox dedup key is always a deliberate choice. A message\n * whose mapped id is missing is malformed.\n */\n readonly id: TField | TTransportId;\n /** Ordering key. Default: the transport's own (the Kafka record key; none on RabbitMQ). */\n readonly key?: TField;\n /** Producing service. Default: the transport's own (Kafka topic; RabbitMQ `appId`, else the routing key). */\n readonly source?: TField;\n /** RFC 3339 time. Default: the transport's own (Kafka record timestamp; RabbitMQ `timestamp`, seconds). */\n readonly occurredAt?: TField;\n readonly correlationId?: TField;\n readonly causationId?: TField;\n /** Media type written with the message. Default `application/json`. Not checked on read. */\n readonly contentType?: string;\n};\n\n/**\n * A JSON object that wraps the payload with event metadata, such as\n * `{ \"eventName\": ..., \"messageId\": ..., \"data\": {...}, \"meta\": {...} }`.\n * Each value lives at a body path or in a header.\n */\nexport type BodyEnvelopeMapping<TTransportId extends string> = MappingFields<\n WireField,\n TTransportId\n> & {\n /** Body path of the payload. Required. */\n readonly payload: BodyField;\n /**\n * Event headers: a body path holding an object of strings, or `'message-headers'` (default),\n * every message header that no other field maps.\n */\n readonly headers?: BodyField | 'message-headers';\n};\n\n/**\n * The body is the payload itself, as a plain JSON producer writes it; every other value lives in\n * a header, so body paths are a compile error here.\n */\nexport type PayloadOnlyMapping<TTransportId extends string> = MappingFields<\n HeaderField,\n TTransportId\n> & {\n readonly payload: 'whole-body';\n /** Event headers: every message header that no other field maps. */\n readonly headers?: 'message-headers';\n};\n\n/** Where every envelope value lives in a JSON message. `type`, `id` and `payload` are required. */\nexport type JsonEnvelopeMapping<TTransportId extends string> =\n BodyEnvelopeMapping<TTransportId> | PayloadOnlyMapping<TTransportId>;\n\n/** A JSON message: the parsed body and the text headers. */\nexport type JsonWireMessage = { readonly body: unknown; readonly headers: EventHeaders };\n\n/** The values read from a message. An absent optional value is left to the transport's default. */\nexport type JsonEnvelopeFields = {\n readonly id?: string;\n readonly type: string;\n readonly payload: unknown;\n readonly key?: string;\n readonly source?: string;\n readonly headers: EventHeaders;\n readonly correlationId: string | null;\n readonly causationId: string | null;\n readonly occurredAt?: Date;\n};\n\n/** The errors of the calling transport. */\nexport type JsonEnvelopeFailures = {\n /** For a message that cannot be read: it goes to the invalid-message path. */\n readonly invalid: (reason: string) => Error;\n /** For an event that cannot be written: never retried. */\n readonly unencodable: (reason: string) => Error;\n};\n\n/** Writes and reads one mapping. Created once per codec; both methods are pure. */\nexport interface JsonEnvelopeFormat {\n /** The mapped headers and the body; the id is left out when the transport supplies it. */\n write(envelope: EventEnvelope): JsonWireMessage;\n read(message: JsonWireMessage): JsonEnvelopeFields;\n}\n\n/**\n * Compiles `mapping` once. `transportIds` lists the transport's own id strategies.\n *\n * @throws ConfigurationError for a mapping that is incomplete, names a header twice, nests one\n * body path inside another or mixes array indexes and names under one body field.\n */\nexport function createJsonEnvelopeFormat(\n mapping: JsonEnvelopeMapping<string>,\n {\n transportIds,\n failures,\n }: { readonly transportIds: readonly string[]; readonly failures: JsonEnvelopeFailures },\n): JsonEnvelopeFormat {\n const plan = compile(mapping, transportIds);\n return {\n write: (envelope) => writeMessage(envelope, { plan, failures }),\n read: (message) => readMessage(message, { plan, failures }),\n };\n}\n","import type { LeaseReference } from '../event-store.js';\nimport { DeliveryLeaseIdentity } from '../values/delivery-lease-identity.js';\n\n/** What a ledger remembers of a claim: at least who it was handed to and which delivery. */\nexport interface HandedOutEntry {\n readonly owner: string;\n readonly deliveryId: string;\n}\n\n/**\n * The claims a store instance handed out and has not seen settled, keyed by\n * {@link DeliveryLeaseIdentity} (delivery id and exact lease token). After a failed claim the\n * store keeps exactly these listed as running and gives the rest back.\n */\nexport class HandedOutLedger<TEntry extends HandedOutEntry> {\n readonly #entries = new Map<string, TEntry>();\n\n register(lease: LeaseReference, entry: TEntry): void {\n this.#entries.set(DeliveryLeaseIdentity.of(lease.deliveryId, lease.leaseToken), entry);\n }\n\n /** Whether the claim with this identity ({@link DeliveryLeaseIdentity.of}) is handed out. */\n has(identity: string): boolean {\n return this.#entries.has(identity);\n }\n\n forget(lease: LeaseReference): void {\n this.#entries.delete(DeliveryLeaseIdentity.of(lease.deliveryId, lease.leaseToken));\n }\n\n /** Forgets every entry `settled` says is settled. */\n forgetWhere(settled: (entry: TEntry, identity: string) => boolean): void {\n for (const [identity, entry] of this.#entries) {\n if (settled(entry, identity)) {\n this.#entries.delete(identity);\n }\n }\n }\n\n /** The entries handed out to `owner`. */\n entriesOf(owner: string): TEntry[] {\n return [...this.#entries.values()].filter((entry) => entry.owner === owner);\n }\n}\n","import type { ClaimRequest, ClaimedDelivery } from '../event-store.js';\n\n/**\n * The claim skeleton of the database stores: a request for no handlers or no deliveries claims\n * nothing, and the claims of one owner run one after the other. Claims of one owner read the same\n * held lanes and the same bookkeeping of what was handed out, so they must not overlap (the\n * dispatcher claims one batch at a time anyway; `runOnce` next to a running dispatcher is what\n * this guards against). A store supplies only {@link OwnerSerializedClaims.claimInTurn}.\n */\nexport abstract class OwnerSerializedClaims {\n /** The last claim of each owner still running; the next one waits for it. */\n readonly #queues = new Map<string, Promise<void>>();\n\n claim(request: ClaimRequest): Promise<ClaimedDelivery[]> {\n if (this.claimsNothing(request)) {\n return Promise.resolve([]);\n }\n return this.#serialized(request.leaseOwner, () => this.claimInTurn(request));\n }\n\n /** Whether the request cannot claim anything: no handlers, or a limit that is not above 0. */\n protected claimsNothing(request: ClaimRequest): boolean {\n return request.handlers.length === 0 || !(request.limit > 0);\n }\n\n /** Claims for `request` once the earlier claims of its owner settled. */\n protected abstract claimInTurn(request: ClaimRequest): Promise<ClaimedDelivery[]>;\n\n #serialized<T>(owner: string, work: () => Promise<T>): Promise<T> {\n const previous = this.#queues.get(owner) ?? Promise.resolve();\n const run = previous.then(work, work);\n const tail = run.then(\n () => undefined,\n () => undefined,\n );\n this.#queues.set(owner, tail);\n void tail.then(() => {\n if (this.#queues.get(owner) === tail) {\n this.#queues.delete(owner);\n }\n });\n return run;\n }\n}\n","import type { EventEnvelope, EventHeaders } from '../event.js';\n\n/** The event a transport's decoder extracted from a message; see the transport's `DecodedEvent`. */\nexport interface DecodedEventFields {\n readonly id: string;\n readonly type: string;\n readonly payload: unknown;\n readonly source?: string;\n readonly key?: string | null;\n readonly headers?: EventHeaders;\n readonly correlationId?: string | null;\n readonly causationId?: string | null;\n readonly occurredAt?: Date;\n}\n\n/** A fixed value, or an extractor that reads it from a plain message. */\nexport type TextOption<TPlain, TValue extends string | null> =\n TValue | ((message: TPlain) => TValue | undefined) | undefined;\n\n/**\n * Observes the rejection of a promise an async decoder or extractor returned by\n * mistake: the value is refused as malformed, and an unobserved rejection would\n * otherwise crash the process.\n */\nexport function observeRejection(value: unknown): void {\n if (typeof value === 'object' && value !== null && 'then' in value) {\n Promise.resolve(value).catch(() => undefined);\n }\n}\n\n/**\n * The inbound plumbing a transport shares with every other: completing what a user decoder\n * returned and reading the extractor options of a plain JSON decoder. A transport supplies only its\n * malformed-message error and the defaults its messages carry (source, key, time).\n */\nexport abstract class DecodedEventReader<TMessage, TPlain> {\n /**\n * Fills the fields a decoder left out and guards against a decoder that returned no object,\n * which would otherwise surface as a retried `TypeError` instead of a malformed message.\n */\n complete(decoded: unknown, message: TMessage): EventEnvelope {\n if (typeof decoded !== 'object' || decoded === null) {\n throw this.invalid('The decoder must return an event object synchronously');\n }\n if ('then' in decoded) {\n observeRejection(decoded);\n throw this.invalid('The decoder must return an event object synchronously');\n }\n const event = decoded as DecodedEventFields;\n return {\n id: event.id,\n type: event.type,\n source: event.source ?? this.defaultSource(message),\n key: event.key === undefined ? this.defaultKey(message) : event.key,\n payload: event.payload,\n headers: event.headers ?? {},\n correlationId: event.correlationId ?? null,\n causationId: event.causationId ?? null,\n occurredAt: event.occurredAt ?? this.defaultTime(message),\n };\n }\n\n /** The text an option gives for `plain`; undefined when it gives none or `''`. */\n text<TValue extends string | null>(\n option: TextOption<TPlain, TValue>,\n { plain, name }: { readonly plain: TPlain; readonly name: string },\n ): string | undefined {\n const value: unknown = typeof option === 'function' ? option(plain) : option;\n if (value === undefined || value === null) {\n return undefined;\n }\n if (typeof value !== 'string') {\n observeRejection(value);\n throw this.invalid(`The ${name} option returned ${typeof value}, expected a string`);\n }\n return value.length === 0 ? undefined : value;\n }\n\n /** The error of a malformed message, which the transport dead-letters instead of retrying. */\n abstract invalid(reason: string): Error;\n\n protected abstract defaultSource(message: TMessage): string;\n\n protected abstract defaultKey(message: TMessage): string | null;\n\n protected abstract defaultTime(message: TMessage): Date;\n}\n","import type { EventEnvelope } from '../event.js';\nimport type { CloseOptions } from '../event-store.js';\nimport type {\n Transport,\n TransportMessageHandler,\n TransportSubscriptionHooks,\n} from '../transport.js';\n\n/** One subscription of a transport: what it consumes and where the messages go. */\nexport interface TransportSubscription {\n readonly destinations: readonly string[];\n readonly onMessage: TransportMessageHandler;\n readonly hooks: TransportSubscriptionHooks | undefined;\n}\n\n/**\n * The skeleton of a broker transport that publishes and subscribes: the {@link Transport} port\n * with its subscribe signature in one place. A transport supplies how it publishes, opens its one\n * subscription, reports readiness and closes.\n */\nexport abstract class SubscribingTransport implements Transport {\n abstract readonly name: string;\n abstract readonly system: string;\n\n /**\n * Subscribes to `destinations`. Not async itself: the subscription's own promise is returned\n * as it is, so its checks reject rather than throw.\n */\n // eslint-disable-next-line relaybus/max-two-params -- the Transport.subscribe signature\n subscribe(\n destinations: readonly string[],\n onMessage: TransportMessageHandler,\n hooks?: TransportSubscriptionHooks,\n ): Promise<void> {\n return this.openSubscription({ destinations, onMessage, hooks });\n }\n\n abstract publish(envelope: EventEnvelope, destination: string): Promise<void>;\n\n abstract isReady(): boolean;\n\n abstract close(options?: CloseOptions): Promise<void>;\n\n /** Opens the transport's one subscription; rejects when it cannot. */\n protected abstract openSubscription(subscription: TransportSubscription): Promise<void>;\n}\n","import { ConfigurationError } from '../errors.js';\n\n/** The range a {@link BoundedInteger} option allows. */\nexport interface IntegerBounds {\n readonly name: string;\n readonly minimum: number;\n readonly maximum: number;\n}\n\n/** An integer option with fixed lower and upper bounds. */\nexport abstract class BoundedInteger {\n /** Returns `value` when it is an integer within the bounds, else throws a {@link ConfigurationError}. */\n static of(value: number, { name, minimum, maximum }: IntegerBounds): number {\n if (!Number.isInteger(value) || value < minimum || value > maximum) {\n throw new ConfigurationError(\n `${name} must be an integer from ${minimum} to ${maximum}, received ${value}`,\n );\n }\n return value;\n }\n}\n","/**\n * Delays that double with every attempt, from `initialMs` up to `maxMs`: the first retry waits\n * `initialMs`, the second twice that, and so on. Without jitter, for in-process retries.\n */\nexport class ExponentialBackoff {\n readonly initialMs: number;\n readonly maxMs: number;\n\n constructor({ initialMs, maxMs }: { readonly initialMs: number; readonly maxMs: number }) {\n this.initialMs = initialMs;\n this.maxMs = maxMs;\n }\n\n /** The delay after failed attempt `attempt` (1-based). */\n delayFor(attempt: number): number {\n return Math.min(this.initialMs * 2 ** (attempt - 1), this.maxMs);\n }\n}\n","/** The claim a lane lease token names, as written in the token. */\nexport interface LaneLeaseTokenParts {\n readonly lane: number;\n /** The lane's epoch, as decimal text: PostgreSQL epochs exceed the safe integers. */\n readonly epoch: string;\n /** The claim generation of the delivery. */\n readonly claims: number;\n}\n\n/** How many digits each part of a token may have, and how many lanes there are. */\nexport interface LaneLeaseTokenLimits {\n readonly laneCount: number;\n readonly epochDigits: number;\n readonly claimsDigits: number;\n}\n\n/** Largest number of digits of a lane number. */\nconst LANE_DIGITS = 3;\n\n/**\n * The fencing token of a claim in a lane-leased store: `<lane>:<epoch>:<claims>`. Every state\n * change checks the lane epoch and the delivery's claim generation it names. A store creates one\n * format with its own digit limits and parses only the tokens it can have issued.\n */\nexport class LaneLeaseTokenFormat {\n readonly #pattern: RegExp;\n readonly #laneCount: number;\n\n constructor(limits: LaneLeaseTokenLimits) {\n this.#laneCount = limits.laneCount;\n this.#pattern = new RegExp(\n `^(\\\\d{1,${LANE_DIGITS}}):(\\\\d{1,${limits.epochDigits}}):(\\\\d{1,${limits.claimsDigits}})$`,\n );\n }\n\n format(\n lane: number,\n { epoch, claims }: { readonly epoch: string | number; readonly claims: number },\n ): string {\n return `${lane}:${epoch}:${claims}`;\n }\n\n /** The parts of `token`; undefined when the store cannot have issued it. */\n parse(token: string): LaneLeaseTokenParts | undefined {\n const match = this.#pattern.exec(token);\n if (match === null || Number(match[1]) >= this.#laneCount) {\n return undefined;\n }\n return { lane: Number(match[1]), epoch: match[2]!, claims: Number(match[3]) };\n }\n}\n","import { ConfigurationError } from '../errors.js';\n\n/** A text option that must not be empty: a name, an exchange, a queue. */\nexport abstract class NonEmptyText {\n static of(value: string, name: string): string {\n if (value.length === 0) {\n throw new ConfigurationError(`${name} must not be empty`);\n }\n return value;\n }\n\n /** Like {@link NonEmptyText.of}, for an option that may be left out. */\n static optional(value: string | undefined, name: string): string | undefined {\n return value === undefined ? undefined : NonEmptyText.of(value, name);\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { b as EventHeaders, E as EventEnvelope, h as Clock, L as LeaseReference, d as ErrorInfo, j as ClaimRequest, C as ClaimedDelivery, T as Transport, U as TransportMessageHandler, V as TransportSubscriptionHooks, p as CloseOptions, D as Duration } from '../transport-BlfzIBZD.cjs';
|
|
2
2
|
|
|
3
3
|
/** Returns `value` when it is an integer of at least 1, else throws a {@link ConfigurationError} naming the option. */
|
|
4
4
|
declare function assertPositiveInteger(value: number, name: string): number;
|
|
@@ -168,4 +168,271 @@ declare function createJsonEnvelopeFormat(mapping: JsonEnvelopeMapping<string>,
|
|
|
168
168
|
readonly failures: JsonEnvelopeFailures;
|
|
169
169
|
}): JsonEnvelopeFormat;
|
|
170
170
|
|
|
171
|
-
|
|
171
|
+
/** What a ledger remembers of a claim: at least who it was handed to and which delivery. */
|
|
172
|
+
interface HandedOutEntry {
|
|
173
|
+
readonly owner: string;
|
|
174
|
+
readonly deliveryId: string;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* The claims a store instance handed out and has not seen settled, keyed by
|
|
178
|
+
* {@link DeliveryLeaseIdentity} (delivery id and exact lease token). After a failed claim the
|
|
179
|
+
* store keeps exactly these listed as running and gives the rest back.
|
|
180
|
+
*/
|
|
181
|
+
declare class HandedOutLedger<TEntry extends HandedOutEntry> {
|
|
182
|
+
#private;
|
|
183
|
+
register(lease: LeaseReference, entry: TEntry): void;
|
|
184
|
+
/** Whether the claim with this identity ({@link DeliveryLeaseIdentity.of}) is handed out. */
|
|
185
|
+
has(identity: string): boolean;
|
|
186
|
+
forget(lease: LeaseReference): void;
|
|
187
|
+
/** Forgets every entry `settled` says is settled. */
|
|
188
|
+
forgetWhere(settled: (entry: TEntry, identity: string) => boolean): void;
|
|
189
|
+
/** The entries handed out to `owner`. */
|
|
190
|
+
entriesOf(owner: string): TEntry[];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** How a claim ends without completing: retried later, given back, or dead-lettered. */
|
|
194
|
+
type SettlementChange = {
|
|
195
|
+
readonly kind: 'reschedule';
|
|
196
|
+
readonly availableAt: Date;
|
|
197
|
+
readonly error: ErrorInfo;
|
|
198
|
+
readonly now: Date;
|
|
199
|
+
} | {
|
|
200
|
+
readonly kind: 'release';
|
|
201
|
+
readonly now: Date;
|
|
202
|
+
} | {
|
|
203
|
+
readonly kind: 'bury';
|
|
204
|
+
readonly error: ErrorInfo;
|
|
205
|
+
readonly now: Date;
|
|
206
|
+
};
|
|
207
|
+
/** A change of the claim a lease names. */
|
|
208
|
+
type LeaseChange = {
|
|
209
|
+
readonly lease: LeaseReference;
|
|
210
|
+
readonly change: SettlementChange;
|
|
211
|
+
};
|
|
212
|
+
/** A lease renewal; `now` for a store that records when it happened. */
|
|
213
|
+
type LeaseExtension = {
|
|
214
|
+
readonly lease: LeaseReference;
|
|
215
|
+
readonly leaseExpiresAt: Date;
|
|
216
|
+
readonly now?: Date;
|
|
217
|
+
};
|
|
218
|
+
/**
|
|
219
|
+
* What a store answers about a lease: at once when it answers from memory, later when it asks a
|
|
220
|
+
* database. Answering at once keeps the in-memory store as fast (in microtasks) as it always was.
|
|
221
|
+
*/
|
|
222
|
+
type StoreAnswer = boolean | Promise<boolean>;
|
|
223
|
+
/**
|
|
224
|
+
* The fenced settlement skeleton every event store shares: find the claim a lease names (a lease
|
|
225
|
+
* this store cannot have issued, or whose claim ended, is not held and changes nothing), apply the
|
|
226
|
+
* change fenced by the lease, then forget the lease as handed out once the store answered.
|
|
227
|
+
* A store supplies only how it finds a held claim, how it writes a change and a renewal, and its
|
|
228
|
+
* bookkeeping of handed-out leases.
|
|
229
|
+
*/
|
|
230
|
+
declare abstract class LeaseSettlement<THeld> {
|
|
231
|
+
#private;
|
|
232
|
+
/** Renews the lease when it is still held; false otherwise. */
|
|
233
|
+
extendLease(extension: LeaseExtension): StoreAnswer;
|
|
234
|
+
/**
|
|
235
|
+
* Applies `change` when the lease is still held. Once the store answered (either way) the lease
|
|
236
|
+
* is forgotten as handed out; when the write throws it stays registered, since the caller may
|
|
237
|
+
* retry with the same lease.
|
|
238
|
+
*/
|
|
239
|
+
changeClaim(request: LeaseChange): StoreAnswer;
|
|
240
|
+
/** The claim `lease` names, when this store issued the lease; undefined otherwise. */
|
|
241
|
+
protected abstract findHeld(lease: LeaseReference): THeld | undefined;
|
|
242
|
+
protected abstract writeChange(held: THeld, request: LeaseChange): StoreAnswer;
|
|
243
|
+
protected abstract writeExtension(held: THeld, extension: LeaseExtension): StoreAnswer;
|
|
244
|
+
/** Drops `lease` from the store's handed-out bookkeeping; nothing for a store that keeps none. */
|
|
245
|
+
protected abstract forgetHandedOut(lease: LeaseReference): void;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* The claim skeleton of the database stores: a request for no handlers or no deliveries claims
|
|
250
|
+
* nothing, and the claims of one owner run one after the other. Claims of one owner read the same
|
|
251
|
+
* held lanes and the same bookkeeping of what was handed out, so they must not overlap (the
|
|
252
|
+
* dispatcher claims one batch at a time anyway; `runOnce` next to a running dispatcher is what
|
|
253
|
+
* this guards against). A store supplies only {@link OwnerSerializedClaims.claimInTurn}.
|
|
254
|
+
*/
|
|
255
|
+
declare abstract class OwnerSerializedClaims {
|
|
256
|
+
#private;
|
|
257
|
+
claim(request: ClaimRequest): Promise<ClaimedDelivery[]>;
|
|
258
|
+
/** Whether the request cannot claim anything: no handlers, or a limit that is not above 0. */
|
|
259
|
+
protected claimsNothing(request: ClaimRequest): boolean;
|
|
260
|
+
/** Claims for `request` once the earlier claims of its owner settled. */
|
|
261
|
+
protected abstract claimInTurn(request: ClaimRequest): Promise<ClaimedDelivery[]>;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/** The event a transport's decoder extracted from a message; see the transport's `DecodedEvent`. */
|
|
265
|
+
interface DecodedEventFields {
|
|
266
|
+
readonly id: string;
|
|
267
|
+
readonly type: string;
|
|
268
|
+
readonly payload: unknown;
|
|
269
|
+
readonly source?: string;
|
|
270
|
+
readonly key?: string | null;
|
|
271
|
+
readonly headers?: EventHeaders;
|
|
272
|
+
readonly correlationId?: string | null;
|
|
273
|
+
readonly causationId?: string | null;
|
|
274
|
+
readonly occurredAt?: Date;
|
|
275
|
+
}
|
|
276
|
+
/** A fixed value, or an extractor that reads it from a plain message. */
|
|
277
|
+
type TextOption<TPlain, TValue extends string | null> = TValue | ((message: TPlain) => TValue | undefined) | undefined;
|
|
278
|
+
/**
|
|
279
|
+
* Observes the rejection of a promise an async decoder or extractor returned by
|
|
280
|
+
* mistake: the value is refused as malformed, and an unobserved rejection would
|
|
281
|
+
* otherwise crash the process.
|
|
282
|
+
*/
|
|
283
|
+
declare function observeRejection(value: unknown): void;
|
|
284
|
+
/**
|
|
285
|
+
* The inbound plumbing a transport shares with every other: completing what a user decoder
|
|
286
|
+
* returned and reading the extractor options of a plain JSON decoder. A transport supplies only its
|
|
287
|
+
* malformed-message error and the defaults its messages carry (source, key, time).
|
|
288
|
+
*/
|
|
289
|
+
declare abstract class DecodedEventReader<TMessage, TPlain> {
|
|
290
|
+
/**
|
|
291
|
+
* Fills the fields a decoder left out and guards against a decoder that returned no object,
|
|
292
|
+
* which would otherwise surface as a retried `TypeError` instead of a malformed message.
|
|
293
|
+
*/
|
|
294
|
+
complete(decoded: unknown, message: TMessage): EventEnvelope;
|
|
295
|
+
/** The text an option gives for `plain`; undefined when it gives none or `''`. */
|
|
296
|
+
text<TValue extends string | null>(option: TextOption<TPlain, TValue>, { plain, name }: {
|
|
297
|
+
readonly plain: TPlain;
|
|
298
|
+
readonly name: string;
|
|
299
|
+
}): string | undefined;
|
|
300
|
+
/** The error of a malformed message, which the transport dead-letters instead of retrying. */
|
|
301
|
+
abstract invalid(reason: string): Error;
|
|
302
|
+
protected abstract defaultSource(message: TMessage): string;
|
|
303
|
+
protected abstract defaultKey(message: TMessage): string | null;
|
|
304
|
+
protected abstract defaultTime(message: TMessage): Date;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/** One subscription of a transport: what it consumes and where the messages go. */
|
|
308
|
+
interface TransportSubscription {
|
|
309
|
+
readonly destinations: readonly string[];
|
|
310
|
+
readonly onMessage: TransportMessageHandler;
|
|
311
|
+
readonly hooks: TransportSubscriptionHooks | undefined;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* The skeleton of a broker transport that publishes and subscribes: the {@link Transport} port
|
|
315
|
+
* with its subscribe signature in one place. A transport supplies how it publishes, opens its one
|
|
316
|
+
* subscription, reports readiness and closes.
|
|
317
|
+
*/
|
|
318
|
+
declare abstract class SubscribingTransport implements Transport {
|
|
319
|
+
abstract readonly name: string;
|
|
320
|
+
abstract readonly system: string;
|
|
321
|
+
/**
|
|
322
|
+
* Subscribes to `destinations`. Not async itself: the subscription's own promise is returned
|
|
323
|
+
* as it is, so its checks reject rather than throw.
|
|
324
|
+
*/
|
|
325
|
+
subscribe(destinations: readonly string[], onMessage: TransportMessageHandler, hooks?: TransportSubscriptionHooks): Promise<void>;
|
|
326
|
+
abstract publish(envelope: EventEnvelope, destination: string): Promise<void>;
|
|
327
|
+
abstract isReady(): boolean;
|
|
328
|
+
abstract close(options?: CloseOptions): Promise<void>;
|
|
329
|
+
/** Opens the transport's one subscription; rejects when it cannot. */
|
|
330
|
+
protected abstract openSubscription(subscription: TransportSubscription): Promise<void>;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Two identifiers joined into one map or set key, such as an event id and a handler id, or a
|
|
335
|
+
* handler id and an ordering key. The NUL separator keeps `('a:b', 'c')` and `('a', 'b:c')` apart.
|
|
336
|
+
* Keys are plain strings, so they cost nothing more than the template literal they replace.
|
|
337
|
+
*/
|
|
338
|
+
declare abstract class CompositeKey {
|
|
339
|
+
static of(first: string, second: string): string;
|
|
340
|
+
/** The start every key of `first` shares, to find them all by prefix. */
|
|
341
|
+
static startOf(first: string): string;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/** The range a {@link BoundedInteger} option allows. */
|
|
345
|
+
interface IntegerBounds {
|
|
346
|
+
readonly name: string;
|
|
347
|
+
readonly minimum: number;
|
|
348
|
+
readonly maximum: number;
|
|
349
|
+
}
|
|
350
|
+
/** An integer option with fixed lower and upper bounds. */
|
|
351
|
+
declare abstract class BoundedInteger {
|
|
352
|
+
/** Returns `value` when it is an integer within the bounds, else throws a {@link ConfigurationError}. */
|
|
353
|
+
static of(value: number, { name, minimum, maximum }: IntegerBounds): number;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Identifies one claim of a delivery: the delivery id with the exact lease token it was handed out
|
|
358
|
+
* with. Two claims of the same delivery (an expired one and the current one) have different
|
|
359
|
+
* identities, so bookkeeping of the older can never replace or remove the newer one's.
|
|
360
|
+
*/
|
|
361
|
+
declare abstract class DeliveryLeaseIdentity {
|
|
362
|
+
static of(deliveryId: string, leaseToken: string): string;
|
|
363
|
+
/** The start of the identity of every claim of `deliveryId`. */
|
|
364
|
+
static prefixOf(deliveryId: string): string;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Delays that double with every attempt, from `initialMs` up to `maxMs`: the first retry waits
|
|
369
|
+
* `initialMs`, the second twice that, and so on. Without jitter, for in-process retries.
|
|
370
|
+
*/
|
|
371
|
+
declare class ExponentialBackoff {
|
|
372
|
+
readonly initialMs: number;
|
|
373
|
+
readonly maxMs: number;
|
|
374
|
+
constructor({ initialMs, maxMs }: {
|
|
375
|
+
readonly initialMs: number;
|
|
376
|
+
readonly maxMs: number;
|
|
377
|
+
});
|
|
378
|
+
/** The delay after failed attempt `attempt` (1-based). */
|
|
379
|
+
delayFor(attempt: number): number;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/** The claim a lane lease token names, as written in the token. */
|
|
383
|
+
interface LaneLeaseTokenParts {
|
|
384
|
+
readonly lane: number;
|
|
385
|
+
/** The lane's epoch, as decimal text: PostgreSQL epochs exceed the safe integers. */
|
|
386
|
+
readonly epoch: string;
|
|
387
|
+
/** The claim generation of the delivery. */
|
|
388
|
+
readonly claims: number;
|
|
389
|
+
}
|
|
390
|
+
/** How many digits each part of a token may have, and how many lanes there are. */
|
|
391
|
+
interface LaneLeaseTokenLimits {
|
|
392
|
+
readonly laneCount: number;
|
|
393
|
+
readonly epochDigits: number;
|
|
394
|
+
readonly claimsDigits: number;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* The fencing token of a claim in a lane-leased store: `<lane>:<epoch>:<claims>`. Every state
|
|
398
|
+
* change checks the lane epoch and the delivery's claim generation it names. A store creates one
|
|
399
|
+
* format with its own digit limits and parses only the tokens it can have issued.
|
|
400
|
+
*/
|
|
401
|
+
declare class LaneLeaseTokenFormat {
|
|
402
|
+
#private;
|
|
403
|
+
constructor(limits: LaneLeaseTokenLimits);
|
|
404
|
+
format(lane: number, { epoch, claims }: {
|
|
405
|
+
readonly epoch: string | number;
|
|
406
|
+
readonly claims: number;
|
|
407
|
+
}): string;
|
|
408
|
+
/** The parts of `token`; undefined when the store cannot have issued it. */
|
|
409
|
+
parse(token: string): LaneLeaseTokenParts | undefined;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* A configured length of time, converted once from a {@link Duration} option. Each factory names
|
|
414
|
+
* the option, so its refusal says which one was wrong.
|
|
415
|
+
*/
|
|
416
|
+
declare abstract class Milliseconds {
|
|
417
|
+
/** Zero or more milliseconds. */
|
|
418
|
+
static of(value: Duration, name: string): number;
|
|
419
|
+
/** More than zero milliseconds: a wait, a timeout or an age that must pass at all. */
|
|
420
|
+
static positive(value: Duration, name: string): number;
|
|
421
|
+
/** A duration that drives a timer: more than zero, and no longer than timers can represent. */
|
|
422
|
+
static forTimer(value: Duration, name: string): number;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/** A text option that must not be empty: a name, an exchange, a queue. */
|
|
426
|
+
declare abstract class NonEmptyText {
|
|
427
|
+
static of(value: string, name: string): string;
|
|
428
|
+
/** Like {@link NonEmptyText.of}, for an option that may be left out. */
|
|
429
|
+
static optional(value: string | undefined, name: string): string | undefined;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/** A count option that must be a whole number of at least 1: a batch size, attempts, a limit. */
|
|
433
|
+
declare abstract class PositiveInteger {
|
|
434
|
+
/** Returns `value` when it is an integer of at least 1, else throws a {@link ConfigurationError} naming the option. */
|
|
435
|
+
static of(value: number, name: string): number;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
export { type BodyEnvelopeMapping, type BodyField, BoundedInteger, type CancelTimer, type CloudEventReaders, CompositeKey, type DecodedEventFields, DecodedEventReader, DeliveryLeaseIdentity, ExponentialBackoff, type FixedType, type HandedOutEntry, HandedOutLedger, type HeaderField, type IntegerBounds, type JsonEnvelopeFailures, type JsonEnvelopeFields, type JsonEnvelopeFormat, type JsonEnvelopeMapping, type JsonWireMessage, LaneLeaseTokenFormat, type LaneLeaseTokenLimits, type LaneLeaseTokenParts, type LeaseChange, type LeaseExtension, LeaseSettlement, Milliseconds, NonEmptyText, OwnerSerializedClaims, type PayloadOnlyMapping, PositiveInteger, type ScheduledTask, type SettlementChange, SubscribingTransport, type TextOption, type TransportSubscription, type WireField, assertPositiveInteger, createCloudEventReaders, createJsonEnvelopeFormat, fromHeader, fromPayloadField, isJsonObject, mediaTypeOf, observeRejection, schedule, sleep, writeStructuredCloudEvent };
|