orpc-fn 0.4.0 → 0.5.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/README.md +146 -4
- package/dist/cli.js +37 -48
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +29 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +49 -0
- package/dist/client.js.map +1 -1
- package/dist/create-fn.d.ts.map +1 -1
- package/dist/create-fn.js +0 -1
- package/dist/create-fn.js.map +1 -1
- package/dist/hono.d.ts +12 -1
- package/dist/hono.d.ts.map +1 -1
- package/dist/hono.js +15 -1
- package/dist/hono.js.map +1 -1
- package/dist/live/fn-live.d.ts +1 -6
- package/dist/live/fn-live.d.ts.map +1 -1
- package/dist/live/fn-live.js +2 -18
- package/dist/live/fn-live.js.map +1 -1
- package/dist/live/index.d.ts +3 -1
- package/dist/live/index.d.ts.map +1 -1
- package/dist/live/index.js +2 -0
- package/dist/live/index.js.map +1 -1
- package/dist/live/invalidation-stream.d.ts +52 -0
- package/dist/live/invalidation-stream.d.ts.map +1 -0
- package/dist/live/invalidation-stream.js +98 -0
- package/dist/live/invalidation-stream.js.map +1 -0
- package/dist/live/ioredis.d.ts +1 -0
- package/dist/live/ioredis.d.ts.map +1 -1
- package/dist/live/ioredis.js +1 -0
- package/dist/live/ioredis.js.map +1 -1
- package/dist/live/memory.d.ts +2 -1
- package/dist/live/memory.d.ts.map +1 -1
- package/dist/live/memory.js +6 -1
- package/dist/live/memory.js.map +1 -1
- package/dist/live/pub-sub.d.ts +5 -0
- package/dist/live/pub-sub.d.ts.map +1 -1
- package/dist/live/pub-sub.js +16 -3
- package/dist/live/pub-sub.js.map +1 -1
- package/dist/live/redis-bun.d.ts +3 -0
- package/dist/live/redis-bun.d.ts.map +1 -1
- package/dist/live/redis-bun.js +1 -0
- package/dist/live/redis-bun.js.map +1 -1
- package/dist/live/redis.d.ts +4 -1
- package/dist/live/redis.d.ts.map +1 -1
- package/dist/live/redis.js +14 -2
- package/dist/live/redis.js.map +1 -1
- package/dist/live/scoped-change-bus.d.ts +45 -0
- package/dist/live/scoped-change-bus.d.ts.map +1 -0
- package/dist/live/scoped-change-bus.js +38 -0
- package/dist/live/scoped-change-bus.js.map +1 -0
- package/dist/live/transport.d.ts +11 -0
- package/dist/live/transport.d.ts.map +1 -1
- package/dist/live/transport.js.map +1 -1
- package/dist/procedure-cli.d.ts +25 -0
- package/dist/procedure-cli.d.ts.map +1 -0
- package/dist/procedure-cli.js +67 -0
- package/dist/procedure-cli.js.map +1 -0
- package/dist/react.d.ts +116 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +156 -0
- package/dist/react.js.map +1 -0
- package/dist/realtime.d.ts +114 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/realtime.js +316 -0
- package/dist/realtime.js.map +1 -0
- package/dist/vue/testing.d.ts +67 -0
- package/dist/vue/testing.d.ts.map +1 -0
- package/dist/vue/testing.js +225 -0
- package/dist/vue/testing.js.map +1 -0
- package/dist/vue.d.ts +211 -0
- package/dist/vue.d.ts.map +1 -0
- package/dist/vue.js +312 -0
- package/dist/vue.js.map +1 -0
- package/package.json +49 -3
- package/src/cli.ts +47 -57
- package/src/client.ts +57 -0
- package/src/create-fn.ts +0 -1
- package/src/hono.ts +22 -2
- package/src/live/fn-live.ts +3 -22
- package/src/live/index.ts +12 -1
- package/src/live/invalidation-stream.ts +142 -0
- package/src/live/ioredis.ts +2 -0
- package/src/live/memory.ts +11 -2
- package/src/live/pub-sub.ts +23 -2
- package/src/live/redis-bun.ts +3 -0
- package/src/live/redis.ts +33 -6
- package/src/live/scoped-change-bus.ts +98 -0
- package/src/live/transport.ts +12 -0
- package/src/procedure-cli.ts +99 -0
- package/src/react.ts +355 -0
- package/src/realtime.ts +416 -0
- package/src/vue/testing.ts +296 -0
- package/src/vue.ts +783 -0
package/dist/live/pub-sub.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pub-sub.js","sourceRoot":"","sources":["../../src/live/pub-sub.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Schema } from '@orpc/contract'\nimport { ORPCError } from '@orpc/server'\nimport type { ZodObject, ZodRawShape, ZodType, z } from 'zod'\nimport type { FnLogger } from '../logger.js'\nimport {\n\terrorAttributes,\n\terrorMessageOf,\n\ttype SpanLike,\n\ttype Tracing\n} from '../otel.js'\nimport type {\n\tGuardOptions,\n\tFnContext,\n\tFnDefinition,\n\tFnProcedure,\n\tFnRouteOptions,\n\tMaybePromise,\n\tProcedureKey,\n\tProcedureOption\n} from '../types.js'\nimport { decodeMessage, encodePayload } from './codec.js'\nimport { LIVE_GAP, positiveInteger, safely, waitFor } from './lifecycle.js'\nimport type {\n\tBacklogOptions,\n\tPubSubMessage,\n\tPubSubTransport\n} from './transport.js'\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Types\n//\n// Publishers pass an event schema's INPUT (`z.input`); subscribers, filters\n// and channel resolvers see its OUTPUT (`z.output`). The raw input travels on\n// the wire and every receiver parses it once.\n// ═══════════════════════════════════════════════════════════════════════════\n\n/** Any Zod object schema, including `.strict()`, `.passthrough()` and `.catchall()`. */\nexport type ObjectSchema = ZodObject<ZodRawShape, z.core.$ZodObjectConfig>\n\n/**\n * A static channel name, or one derived from (partial) subscriber input or\n * event data.\n */\nexport type ChannelDefinition<TInput, TEventData, TContext = unknown> =\n\t| string\n\t| {\n\t\t\tsubscribe: (params: { input: TInput; context: TContext }) => string\n\t\t\tpublish: (event: TEventData) => string\n\t }\n\t| ((\n\t\t\tparams: Partial<TInput> | Partial<TEventData>,\n\t\t\tcontext?: TContext\n\t ) => string)\n\n/** Decides whether one event reaches one subscriber. */\nexport type FilterFn<TInput, TEventData> = (params: {\n\tinput: TInput\n\tdata: TEventData\n}) => MaybePromise<boolean>\n\n/**\n * Checked when a subscription opens, before anything is sent. `true` allows\n * everyone; a function returns false (or throws) to refuse with FORBIDDEN.\n */\nexport type AuthFn<TInput, TContext> =\n\t| ((params: { input: TInput; ctx: TContext }) => MaybePromise<boolean>)\n\t| true\n\nexport type PublisherConfig = {\n\t/** Required name for tracing (e.g. 'chat.messages'). */\n\tname: string\n\t/**\n\t * Store recent events in a backlog list; new subscribers receive it before\n\t * live events. Default: false\n\t */\n\tuseBacklog?: boolean\n\t/** Maximum backlog items to keep (default: 50). */\n\tbacklogSize?: number\n\t/** Backlog TTL in seconds (default: 30). */\n\tbacklogTtl?: number\n\t/**\n\t * Also publish every payload to this channel (with its own backlog when\n\t * `useBacklog`). Subscribers still use `channel`. Equal to the primary\n\t * channel means no duplicate work.\n\t */\n\tmirrorChannel?: string\n}\n\n/** Per-definition overrides of the factory queue bounds. */\nexport type ChannelQueueOptions = {\n\tmaxQueueSize?: number\n\tmaxIngressSize?: number\n\tmaxReplaySize?: number\n}\n\n/** Synchronous observational events; failures cannot interrupt delivery. */\nexport type PubSubMetric = { name: string; channel: string } & (\n\t| {\n\t\t\ttype: 'queue'\n\t\t\tstage: 'ingress' | 'replay' | 'delivery'\n\t\t\tdepth: number\n\t\t\tlimit: number\n\t }\n\t| { type: 'drop'; stage: 'ingress' | 'replay' | 'delivery'; count: number }\n\t| { type: 'reconnect' }\n\t| { type: 'parseError'; stage: 'ingress' | 'replay'; error: unknown }\n)\n\nexport type PubSubOptions<\n\tTDef extends FnDefinition,\n\tTInputSchema extends ObjectSchema,\n\tTEventSchema extends ZodType,\n\tTKey extends ProcedureKey<TDef>\n> = PublisherConfig &\n\tChannelQueueOptions & {\n\t\tchannel: ChannelDefinition<\n\t\t\tz.output<TInputSchema>,\n\t\t\tz.output<TEventSchema>,\n\t\t\tFnContext<TDef, TKey>\n\t\t>\n\t\t/** What the subscriber provides. */\n\t\tinputSchema: TInputSchema\n\t\t/** What gets published. */\n\t\teventSchema: TEventSchema\n\t\tfilterFn?: FilterFn<z.output<TInputSchema>, z.output<TEventSchema>>\n\t\tauthFn?: AuthFn<z.output<TInputSchema>, FnContext<TDef, TKey>>\n\t\t/**\n\t\t * When a slow subscriber's queue overflows (drop-oldest), enqueue this\n\t\t * marker INSTEAD of the new event so the subscriber resyncs from its\n\t\t * cursor. A wholly dropped item leaves no per-item gap a consumer could\n\t\t * detect, so the marker is the only reliable live signal of loss. Return\n\t\t * null to skip.\n\t\t */\n\t\toverflowMarker?: (\n\t\t\tinput: z.output<TInputSchema>\n\t\t) => z.output<TEventSchema> | null\n\t\ttags?: TDef['tag'][]\n\t\tsummary?: string\n\t\tdescription?: string\n\t}\n\nexport type PubSub<\n\tTDef extends FnDefinition,\n\tTInputSchema extends ObjectSchema,\n\tTEventSchema extends ZodType,\n\tTKey extends ProcedureKey<TDef>\n> = {\n\tsubscribe: FnProcedure<\n\t\tTDef,\n\t\tTKey,\n\t\tTInputSchema,\n\t\tSchema<\n\t\t\tAsyncGenerator<z.output<TEventSchema>, void, unknown>,\n\t\t\tAsyncGenerator<z.output<TEventSchema>, void, unknown>\n\t\t>\n\t>\n\tpublish: (data: z.input<TEventSchema>) => Promise<void>\n\t/** Publish a batch in one atomic round-trip; items may target different channels. */\n\tpublishMany: (items: readonly z.input<TEventSchema>[]) => Promise<void>\n\tgetSubscriptionChannelName: (params: {\n\t\tinput: z.output<TInputSchema>\n\t\tcontext: FnContext<TDef, TKey>\n\t}) => string\n\tgetPublishChannelName: (event: z.output<TEventSchema>) => string\n\t/** @deprecated Prefer the separate required-input resolver methods. */\n\tgetChannelName: (\n\t\tparams: Partial<z.output<TInputSchema>> | Partial<z.output<TEventSchema>>,\n\t\tcontext?: FnContext<TDef, TKey>\n\t) => string\n}\n\nexport type CreatePubSub<TDef extends FnDefinition> = <\n\tTInputSchema extends ObjectSchema,\n\tTEventSchema extends ZodType,\n\tTKey extends ProcedureKey<TDef> = TDef['default']\n>(\n\toptions: PubSubOptions<TDef, TInputSchema, TEventSchema, NoInfer<TKey>> &\n\t\tGuardOptions<TDef['guards']> &\n\t\tPick<\n\t\t\tFnRouteOptions<TDef, TKey, z.output<TInputSchema>>,\n\t\t\t'meta' | 'guardResolvers'\n\t\t> &\n\t\t/** Which `procedures` builder the subscribe route uses. */ ProcedureOption<\n\t\t\tTDef,\n\t\t\tTKey\n\t\t>\n) => PubSub<TDef, TInputSchema, TEventSchema, TKey>\n\nexport type PublisherOptions<TEventSchema extends ZodType> = PublisherConfig & {\n\t/** Static channel name, or a resolver over (partial) parsed event data. */\n\tchannel: string | ((params: Partial<z.output<TEventSchema>>) => string)\n\teventSchema: TEventSchema\n}\n\nexport type Publisher<TEventSchema extends ZodType> = {\n\tpublish: (data: z.input<TEventSchema>) => Promise<void>\n\tpublishMany: (items: readonly z.input<TEventSchema>[]) => Promise<void>\n\tgetChannelName: (params: Partial<z.output<TEventSchema>>) => string\n}\n\n/**\n * Publish-only counterpart to `createPubSub`, for buses whose subscribe side\n * lives elsewhere (e.g. an `fnLive` route sharing the channel and schema).\n */\nexport type CreatePublisher = <TEventSchema extends ZodType>(\n\toptions: PublisherOptions<TEventSchema>\n) => Publisher<TEventSchema>\n\nexport type PubSubRuntimeOptions = {\n\t/** Queue depths, drops, successful reconnects and parse failures. */\n\tonMetric?: (event: PubSubMetric) => void\n\t/**\n\t * The broker, or a function creating it on first use so importing routes\n\t * opens no connection: `transport: () => bunRedisTransport(getRedis())`.\n\t */\n\ttransport: PubSubTransport | (() => PubSubTransport)\n\t/**\n\t * Called per event dropped from ingress, replay or delivery queues.\n\t * Delivery drops count events before subscriber filtering.\n\t */\n\tonDrop?: (count: number, info: { name: string; channel: string }) => void\n\t/** Per-subscriber queue bound before drop-oldest (default: 1000). */\n\tmaxQueueSize?: number\n\t/** Pending raw messages per channel, before asynchronous parsing. */\n\tmaxIngressSize?: number\n\t/** Buffered live messages during replay. */\n\tmaxReplaySize?: number\n\t/** Broker subscription and backlog wait bound (default 10000ms). */\n\tinitializationTimeoutMs?: number\n\t/** Applied to channels, mirrors and therefore backlog keys. */\n\tnamespace?: string\n\t/** Close this transport only when its ownership is explicitly transferred. */\n\townsTransport?: boolean\n}\n\n/** @internal */\nexport type LiveRuntimeOptions = {\n\tfn: (options: Record<string, unknown>) => import('@orpc/server').AnyProcedure\n\ttracing: Tracing\n\tcreateLogger: (scope: string, span: SpanLike | undefined) => FnLogger\n\tpubsub?: PubSubRuntimeOptions | undefined\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Bounded queue\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Bounded drop-oldest FIFO with \"one overflow marker per overflow episode\"\n * semantics.\n *\n * On the FIRST overflow of an episode the oldest message is dropped and the\n * marker from `createOverflowMarker` is enqueued INSTEAD of the new event - the\n * subscriber's resync-from-cursor recovers the loss. While that marker is still\n * queued, further overflows drop the oldest NON-marker message (the marker\n * itself is never displaced) and enqueue the new event WITHOUT a second marker:\n * the pending marker's resync already covers every drop that happens before it\n * is delivered. Without this dedupe a sustained overflow converges the whole\n * queue to markers - one full snapshot re-run per queued slot. Dequeuing the\n * marker ends the episode; the next overflow starts a fresh one.\n *\n * `createOverflowMarker` absent (or returning null) falls back to plain\n * drop-oldest with the new event enqueued.\n */\nexport function createBoundedEventQueue<T>(opts: {\n\tmaxSize: number\n\tcreateOverflowMarker?: () => T | null\n\t/** Called once per dropped message (metrics/counters). */\n\tonDrop?: () => void\n\tonDepth?: (depth: number) => void\n}) {\n\tpositiveInteger(opts.maxSize, 'maxSize')\n\tconst items: T[] = []\n\t// The queued marker while an overflow episode is open. Created once per\n\t// episode, so identity is the exact \"is this the pending marker?\" test.\n\tlet pendingOverflowMarker: T | null = null\n\n\treturn {\n\t\tget length() {\n\t\t\treturn items.length\n\t\t},\n\t\tenqueue(data: T): void {\n\t\t\ttry {\n\t\t\t\tif (items.length >= opts.maxSize) {\n\t\t\t\t\tif (pendingOverflowMarker !== null) {\n\t\t\t\t\t\t// Episode already signalled: drop the oldest non-marker message\n\t\t\t\t\t\t// and enqueue WITHOUT a second marker.\n\t\t\t\t\t\tconst dropIndex = items[0] === pendingOverflowMarker ? 1 : 0\n\t\t\t\t\t\tif (dropIndex >= items.length) {\n\t\t\t\t\t\t\t// Degenerate maxSize: the queue is just the pending marker, so\n\t\t\t\t\t\t\t// the new event is the drop - the marker's resync covers it.\n\t\t\t\t\t\t\tsafely(opts.onDrop)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\titems.splice(dropIndex, 1)\n\t\t\t\t\t\tsafely(opts.onDrop)\n\t\t\t\t\t\titems.push(data)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\titems.shift()\n\t\t\t\t\tsafely(opts.onDrop)\n\t\t\t\t\tconst marker = opts.createOverflowMarker?.() ?? null\n\t\t\t\t\tif (marker !== null) {\n\t\t\t\t\t\tpendingOverflowMarker = marker\n\t\t\t\t\t\titems.push(marker)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\titems.push(data)\n\t\t\t} finally {\n\t\t\t\tsafely(() => opts.onDepth?.(items.length))\n\t\t\t}\n\t\t},\n\t\tdequeue(): T | undefined {\n\t\t\tconst next = items.shift()\n\t\t\tsafely(() => opts.onDepth?.(items.length))\n\t\t\tif (next !== undefined && next === pendingOverflowMarker) {\n\t\t\t\tpendingOverflowMarker = null\n\t\t\t}\n\t\t\treturn next\n\t\t}\n\t}\n}\n\n/**\n * One subscriber's ordered, bounded delivery. Events wait in a bounded\n * drop-oldest queue (see {@link createBoundedEventQueue}) BEFORE the\n * subscriber's filter runs; the filter runs in order as the consumer reads,\n * so a slow async filter neither reorders events nor lets pending work grow\n * past `maxSize`. Overflow markers skip the filter.\n */\nexport function createSubscriberDelivery<T>(options: {\n\tmaxSize: number\n\taccept?: ((data: T) => MaybePromise<boolean>) | undefined\n\toverflowMarker?: (() => T | null) | undefined\n\tonFilterError: (error: unknown) => void\n\tonDrop: () => void\n\tonDepth?: (depth: number) => void\n}) {\n\ttype Item = { data: T; marker: boolean }\n\tconst queue = createBoundedEventQueue<Item>({\n\t\tmaxSize: options.maxSize,\n\t\tcreateOverflowMarker: () => {\n\t\t\tconst marker = options.overflowMarker?.() ?? null\n\t\t\treturn marker === null ? null : { data: marker, marker: true }\n\t\t},\n\t\tonDrop: options.onDrop,\n\t\t...(options.onDepth ? { onDepth: options.onDepth } : {})\n\t})\n\tlet closed = false\n\tlet failure: unknown\n\tlet wake: (() => void) | null = null\n\tconst notify = () => {\n\t\twake?.()\n\t\twake = null\n\t}\n\n\tasync function* events(): AsyncGenerator<T, void, unknown> {\n\t\twhile (!closed) {\n\t\t\tconst item = queue.dequeue()\n\t\t\tif (!item) {\n\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\twake = resolve\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (!item.marker && options.accept) {\n\t\t\t\ttry {\n\t\t\t\t\tif (!(await options.accept(item.data))) continue\n\t\t\t\t} catch (error) {\n\t\t\t\t\tsafely(() => options.onFilterError(error))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (closed) break\n\t\t\t}\n\t\t\tyield item.data\n\t\t}\n\t\tif (failure !== undefined) throw failure\n\t}\n\n\treturn {\n\t\tpush(data: T, marker = false) {\n\t\t\tif (closed) return\n\t\t\tqueue.enqueue({ data, marker })\n\t\t\tnotify()\n\t\t},\n\t\tevents: events(),\n\t\t/** Stop delivering; a parked read ends at once. */\n\t\tclose(error?: unknown) {\n\t\t\tif (closed) return\n\t\t\tfailure = error\n\t\t\tclosed = true\n\t\t\tsafely(() => options.onDepth?.(0))\n\t\t\tnotify()\n\t\t}\n\t}\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Runtime (internal: the typed surface is what `createFn` returns)\n// ═══════════════════════════════════════════════════════════════════════════\n\nconst DEFAULT_MAX_QUEUE_SIZE = 1000\n\n// Exponential resubscribe backoff with jitter so reconnecting subscribers don't stampede the broker.\nconst RESUBSCRIBE_BASE_DELAY_MS = 1000\nconst RESUBSCRIBE_MAX_DELAY_MS = 30_000\nconst RESUBSCRIBE_MAX_JITTER_MS = 250\n\nfunction getResubscribeDelayMs(attempt: number): number {\n\tconst base = Math.min(\n\t\tRESUBSCRIBE_BASE_DELAY_MS * 2 ** attempt,\n\t\tRESUBSCRIBE_MAX_DELAY_MS\n\t)\n\treturn base + Math.floor(Math.random() * RESUBSCRIBE_MAX_JITTER_MS)\n}\n\ntype Input = Record<string, unknown>\n\ntype LocalSubscriber = {\n\tisActive: () => boolean\n\tpush: (data: unknown, id?: string) => void\n\tgap: () => void\n\tfail: (error: unknown) => void\n}\n\ntype Hub = {\n\tsubscribers: Set<LocalSubscriber>\n\t/** Resolves after a successful broker subscription (or closure). */\n\tready: Promise<void>\n\tclose: () => void\n}\n\n/** An open subscription: registered, authorized and subscribed. */\nexport type LiveSubscription = {\n\t/** Live events, after the backlog replay. Ends when closed or aborted. */\n\tevents: AsyncGenerator<unknown, void, unknown>\n\t/** Release everything; safe to call more than once, and before `events` runs. */\n\tclose: () => void\n\tisClosed: () => boolean\n}\n\n/** @internal Untyped options; `PubSubOptions` is the typed surface. */\nexport type ChannelOptions = PublisherConfig &\n\tChannelQueueOptions & {\n\t\tchannel: ChannelDefinition<Input, unknown>\n\t\teventSchema: ZodType\n\t\tfilterFn?: FilterFn<Input, unknown>\n\t\tauthFn?: AuthFn<Input, unknown>\n\t\toverflowMarker?: (input: Input) => unknown\n\t}\n\n/** @internal */\nexport type Channel = {\n\t/** Authorize and subscribe; resolves once events can be delivered. */\n\topen: (options: {\n\t\tinput: Input\n\t\tcontext: unknown\n\t\tsignal: AbortSignal | undefined\n\t\trecoverGaps?: boolean\n\t}) => Promise<LiveSubscription>\n\tpublish: (data: unknown) => Promise<void>\n\tpublishMany: (items: readonly unknown[]) => Promise<void>\n\tgetChannelName: (params: Input, context?: unknown) => string\n\tgetSubscriptionChannelName: (params: {\n\t\tinput: Input\n\t\tcontext: unknown\n\t}) => string\n\tgetPublishChannelName: (event: Input) => string\n}\n\nconst resolveChannel = (\n\tchannel: ChannelDefinition<Input, unknown>,\n\tparams: Input,\n\tcontext?: unknown,\n\tpublishing = false\n) => {\n\tif (typeof channel === 'string') return channel\n\tif (typeof channel === 'function') return channel(params, context)\n\treturn publishing\n\t\t? channel.publish(params)\n\t\t: channel.subscribe({ input: params, context })\n}\n\n/** @internal */\nexport function createLiveRuntime(options: LiveRuntimeOptions) {\n\tconst { tracing, createLogger } = options\n\tconst logger = createLogger('pubsub', undefined)\n\tlet terminated = false\n\tlet shutdownPromise: Promise<void> | undefined\n\tconst releases = new Set<Promise<void>>()\n\tconst pendingInitialization = new Set<() => void>()\n\tconst pendingOpens = new Set<Promise<LiveSubscription>>()\n\tconst defaultMaxQueue = positiveInteger(\n\t\toptions.pubsub?.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE,\n\t\t'maxQueueSize'\n\t)\n\tconst defaultMaxIngress = positiveInteger(\n\t\toptions.pubsub?.maxIngressSize ?? defaultMaxQueue,\n\t\t'maxIngressSize'\n\t)\n\tconst defaultMaxReplay = positiveInteger(\n\t\toptions.pubsub?.maxReplaySize ?? defaultMaxQueue,\n\t\t'maxReplaySize'\n\t)\n\tconst initializationTimeout = positiveInteger(\n\t\toptions.pubsub?.initializationTimeoutMs ?? 10000,\n\t\t'initializationTimeoutMs'\n\t)\n\tconst metric = (event: PubSubMetric) =>\n\t\tsafely(() => options.pubsub?.onMetric?.(event))\n\tconst namespace = options.pubsub?.namespace\n\tconst qualify = (name: string) => (namespace ? `${namespace}:${name}` : name)\n\tconst assertOpen = () => {\n\t\tif (terminated)\n\t\t\tthrow new ORPCError('SERVICE_UNAVAILABLE', {\n\t\t\t\tmessage: 'Live runtime has shut down'\n\t\t\t})\n\t}\n\tconst releaseTransport = (release: (() => Promise<void>) | null) => {\n\t\tif (!release) return\n\t\tconst task = Promise.resolve(release()).catch((error) => {\n\t\t\tlogger.warn('Failed to release subscription', {\n\t\t\t\terror: errorMessageOf(error)\n\t\t\t})\n\t\t})\n\t\treleases.add(task)\n\t\tvoid task.finally(() => releases.delete(task))\n\t}\n\n\t// Deploy drain: every open subscription registers its close here. On\n\t// SIGTERM the app ends them deliberately instead of letting the socket die\n\t// with the process: the generator returns, oRPC closes the SSE response and\n\t// the client's backoff reconnects to the new deployment.\n\tconst activeSubscriberCleanups = new Set<() => void>()\n\n\tlet transport: PubSubTransport | undefined\n\tconst requireTransport = () => {\n\t\tif (!options.pubsub) {\n\t\t\tthrow new Error(\n\t\t\t\t'orpc-fn: live routes need a transport, pass createFn({ pubsub: { transport } })'\n\t\t\t)\n\t\t}\n\t\tif (transport) return transport\n\t\t// A lazy transport is never created during or after shutdown.\n\t\tassertOpen()\n\t\tconst configured = options.pubsub.transport\n\t\ttransport = typeof configured === 'function' ? configured() : configured\n\t\treturn transport\n\t}\n\n\t/**\n\t * Shared publish pipeline: validate the raw event, resolve the channel from\n\t * the parsed event, then publish the raw event (atomically maintaining the\n\t * backlog when enabled) inside a producer span.\n\t */\n\tfunction createChannelPublisher(\n\t\tconfig: PublisherConfig & {\n\t\t\teventSchema: ZodType\n\t\t\tgetChannelName: (data: Input) => string\n\t\t}\n\t) {\n\t\tconst { name, eventSchema, getChannelName } = config\n\t\tconst mirrorChannel = config.mirrorChannel\n\t\t\t? qualify(config.mirrorChannel)\n\t\t\t: undefined\n\t\tif (config.backlogSize !== undefined)\n\t\t\tpositiveInteger(config.backlogSize, 'backlogSize')\n\t\tif (config.backlogTtl !== undefined)\n\t\t\tpositiveInteger(config.backlogTtl, 'backlogTtl')\n\t\tconst backlog: BacklogOptions | undefined = config.useBacklog\n\t\t\t? { size: config.backlogSize ?? 50, ttlSeconds: config.backlogTtl ?? 30 }\n\t\t\t: undefined\n\n\t\tconst toMessages = async (items: readonly unknown[]) => {\n\t\t\tconst messages: PubSubMessage[] = []\n\t\t\tfor (const item of items) {\n\t\t\t\tconst data = (await eventSchema.parseAsync(item)) as Input\n\t\t\t\tconst channel = getChannelName(data)\n\t\t\t\tconst payload = encodePayload(item)\n\t\t\t\tmessages.push({ channel, payload })\n\t\t\t\tif (mirrorChannel && mirrorChannel !== channel) {\n\t\t\t\t\tmessages.push({ channel: mirrorChannel, payload })\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn messages\n\t\t}\n\n\t\tconst send = (\n\t\t\toperation: 'publish' | 'publishMany',\n\t\t\titems: readonly unknown[]\n\t\t) =>\n\t\t\ttracing.inSpan(`${name}:${operation}`, 'PRODUCER', async (span) => {\n\t\t\t\tassertOpen()\n\t\t\t\tconst startTime = performance.now()\n\t\t\t\ttry {\n\t\t\t\t\tspan?.setAttribute('pubsub.operation', operation)\n\t\t\t\t\tspan?.setAttribute('pubsub.name', name)\n\t\t\t\t\tspan?.setAttribute('pubsub.batch_size', items.length)\n\t\t\t\t\tconst messages = await toMessages(items)\n\t\t\t\t\tconst first = messages[0]\n\t\t\t\t\tif (first) {\n\t\t\t\t\t\tspan?.setAttribute('pubsub.channel', first.channel)\n\t\t\t\t\t\tspan?.setAttribute('pubsub.payload_size', first.payload.length)\n\t\t\t\t\t}\n\t\t\t\t\tawait requireTransport().publish(messages, backlog)\n\t\t\t\t} finally {\n\t\t\t\t\tspan?.setAttribute(\n\t\t\t\t\t\t'pubsub.duration_ms',\n\t\t\t\t\t\tperformance.now() - startTime\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t})\n\n\t\treturn {\n\t\t\tpublish: (data: unknown) => send('publish', [data]),\n\t\t\tpublishMany: async (items: readonly unknown[]) => {\n\t\t\t\tif (items.length > 0) await send('publishMany', items)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Hubs for one pub/sub definition, keyed by channel. Many subscribers can\n\t * share a channel (an org with many open tabs); one hub decodes and parses\n\t * each payload once and fans the event out to every local subscriber,\n\t * applying each subscriber's own filter. The hub also owns the broker\n\t * subscription and its resubscribe backoff.\n\t */\n\tfunction createChannelHubs(config: {\n\t\teventSchema: ZodType\n\t\tname: string\n\t\tmaxIngress: number\n\t}) {\n\t\tconst { eventSchema } = config\n\t\tconst hubs = new Map<string, Hub>()\n\n\t\tconst createHub = (channel: string): Hub => {\n\t\t\tconst subscribers = new Set<LocalSubscriber>()\n\t\t\tlet closed = false\n\t\t\tlet unsubscribe: (() => Promise<void>) | null = null\n\t\t\tlet attempt = 0\n\t\t\tlet timer: ReturnType<typeof setTimeout> | null = null\n\t\t\tlet markReady = () => {}\n\t\t\tlet connectedOnce = false\n\t\t\tlet connected = false\n\t\t\tlet ready: Promise<void>\n\t\t\tconst markPending = () => {\n\t\t\t\tready = new Promise<void>((resolve) => {\n\t\t\t\t\tmarkReady = resolve\n\t\t\t\t})\n\t\t\t}\n\t\t\tmarkPending()\n\n\t\t\tlet parsing = false\n\t\t\tconst ingress = createBoundedEventQueue<string>({\n\t\t\t\tmaxSize: config.maxIngress,\n\t\t\t\tonDepth: (depth) =>\n\t\t\t\t\tmetric({\n\t\t\t\t\t\ttype: 'queue',\n\t\t\t\t\t\tstage: 'ingress',\n\t\t\t\t\t\tdepth,\n\t\t\t\t\t\tlimit: config.maxIngress,\n\t\t\t\t\t\tname: config.name,\n\t\t\t\t\t\tchannel\n\t\t\t\t\t}),\n\t\t\t\tonDrop: () => {\n\t\t\t\t\tmetric({\n\t\t\t\t\t\ttype: 'drop',\n\t\t\t\t\t\tstage: 'ingress',\n\t\t\t\t\t\tcount: 1,\n\t\t\t\t\t\tname: config.name,\n\t\t\t\t\t\tchannel\n\t\t\t\t\t})\n\t\t\t\t\tsafely(() =>\n\t\t\t\t\t\toptions.pubsub?.onDrop?.(1, { name: config.name, channel })\n\t\t\t\t\t)\n\t\t\t\t\tfor (const sub of [...subscribers]) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tsub.gap()\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tsafely(() => sub.fail(error))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t\tconst parsePending = async () => {\n\t\t\t\tif (parsing) return\n\t\t\t\tparsing = true\n\t\t\t\ttry {\n\t\t\t\t\twhile (!closed) {\n\t\t\t\t\t\tconst raw = ingress.dequeue()\n\t\t\t\t\t\tif (raw === undefined) break\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst message = decodeMessage(raw)\n\t\t\t\t\t\t\tconst parsed = await eventSchema.parseAsync(message.value)\n\t\t\t\t\t\t\tif (closed) break\n\t\t\t\t\t\t\tfor (const sub of [...subscribers])\n\t\t\t\t\t\t\t\tif (sub.isActive()) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tsub.push(parsed, message.id)\n\t\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\t\tsafely(() => sub.fail(error))\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tmetric({\n\t\t\t\t\t\t\t\ttype: 'parseError',\n\t\t\t\t\t\t\t\tstage: 'ingress',\n\t\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\t\tname: config.name,\n\t\t\t\t\t\t\t\tchannel\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tlogger.warn('pubsub.message_dropped', {\n\t\t\t\t\t\t\t\tchannel,\n\t\t\t\t\t\t\t\t...errorAttributes(error)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} finally {\n\t\t\t\t\tparsing = false\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst release = releaseTransport\n\n\t\t\tconst scheduleResubscribe = (reason: string) => {\n\t\t\t\tif (closed || timer) return\n\t\t\t\tconst delayMs = getResubscribeDelayMs(attempt)\n\t\t\t\tattempt++\n\t\t\t\tlogger.warn('pubsub.resubscribe_scheduled', {\n\t\t\t\t\tchannel,\n\t\t\t\t\treason,\n\t\t\t\t\tattempt,\n\t\t\t\t\tdelayMs\n\t\t\t\t})\n\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\ttimer = null\n\t\t\t\t\tif (closed) return\n\t\t\t\t\trelease(unsubscribe)\n\t\t\t\t\tunsubscribe = null\n\t\t\t\t\tvoid connect()\n\t\t\t\t}, delayMs)\n\t\t\t}\n\n\t\t\tconst connect = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst next = await requireTransport().subscribe(\n\t\t\t\t\t\tchannel,\n\t\t\t\t\t\t(raw) => {\n\t\t\t\t\t\t\tif (closed) return\n\t\t\t\t\t\t\tingress.enqueue(raw)\n\t\t\t\t\t\t\tvoid parsePending()\n\t\t\t\t\t\t},\n\t\t\t\t\t\t(error) => {\n\t\t\t\t\t\t\tif (connected) {\n\t\t\t\t\t\t\t\tconnected = false\n\t\t\t\t\t\t\t\tmarkPending()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlogger.error('pubsub.subscription_lost', {\n\t\t\t\t\t\t\t\tchannel,\n\t\t\t\t\t\t\t\t...errorAttributes(error)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tscheduleResubscribe('lost')\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tonReconnect: () => {\n\t\t\t\t\t\t\t\tif (closed) return\n\t\t\t\t\t\t\t\tmetric({ type: 'reconnect', name: config.name, channel })\n\t\t\t\t\t\t\t\tfor (const sub of [...subscribers]) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tsub.gap()\n\t\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\t\tsafely(() => sub.fail(error))\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\tif (closed) return release(next)\n\t\t\t\t\tunsubscribe = next\n\t\t\t\t\tconnected = true\n\t\t\t\t\tif (connectedOnce) {\n\t\t\t\t\t\tmetric({ type: 'reconnect', name: config.name, channel })\n\t\t\t\t\t\tfor (const sub of [...subscribers]) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tsub.gap()\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tsafely(() => sub.fail(error))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconnectedOnce = true\n\t\t\t\t\tmarkReady()\n\t\t\t\t\tattempt = 0\n\t\t\t\t\tlogger.debug('pubsub.subscribed', { channel })\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger.error('pubsub.subscribe_failed', {\n\t\t\t\t\t\tchannel,\n\t\t\t\t\t\t...errorAttributes(error)\n\t\t\t\t\t})\n\t\t\t\t\tscheduleResubscribe('subscribe-failed')\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid connect()\n\n\t\t\treturn {\n\t\t\t\tsubscribers,\n\t\t\t\tget ready() {\n\t\t\t\t\treturn ready\n\t\t\t\t},\n\t\t\t\tclose: () => {\n\t\t\t\t\tclosed = true\n\t\t\t\t\tmetric({\n\t\t\t\t\t\ttype: 'queue',\n\t\t\t\t\t\tstage: 'ingress',\n\t\t\t\t\t\tdepth: 0,\n\t\t\t\t\t\tlimit: config.maxIngress,\n\t\t\t\t\t\tname: config.name,\n\t\t\t\t\t\tchannel\n\t\t\t\t\t})\n\t\t\t\t\tif (timer) clearTimeout(timer)\n\t\t\t\t\ttimer = null\n\t\t\t\t\tmarkReady()\n\t\t\t\t\trelease(unsubscribe)\n\t\t\t\t\tunsubscribe = null\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn function addLocalSubscriber(\n\t\t\tchannel: string,\n\t\t\tsubscriber: LocalSubscriber\n\t\t) {\n\t\t\tlet hub = hubs.get(channel)\n\t\t\tif (!hub) {\n\t\t\t\thub = createHub(channel)\n\t\t\t\thubs.set(channel, hub)\n\t\t\t}\n\t\t\thub.subscribers.add(subscriber)\n\t\t\tconst current = hub\n\t\t\treturn {\n\t\t\t\tready: current.ready,\n\t\t\t\tremove: () => {\n\t\t\t\t\tcurrent.subscribers.delete(subscriber)\n\t\t\t\t\tif (current.subscribers.size === 0 && hubs.get(channel) === current) {\n\t\t\t\t\t\tcurrent.close()\n\t\t\t\t\t\thubs.delete(channel)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Publish and open subscriptions on one channel definition. */\n\tfunction createChannel(channelOptions: ChannelOptions): Channel {\n\t\tconst {\n\t\t\tname,\n\t\t\tchannel,\n\t\t\teventSchema,\n\t\t\tfilterFn,\n\t\t\tauthFn,\n\t\t\toverflowMarker,\n\t\t\tuseBacklog = false\n\t\t} = channelOptions\n\n\t\tconst getChannelName = (params: Input, context?: unknown) =>\n\t\t\tqualify(resolveChannel(channel, params, context))\n\t\tconst getPublishChannel = (params: Input) =>\n\t\t\tqualify(resolveChannel(channel, params, undefined, true))\n\t\tconst maxQueue = positiveInteger(\n\t\t\tchannelOptions.maxQueueSize ?? defaultMaxQueue,\n\t\t\t'maxQueueSize'\n\t\t)\n\t\tconst maxIngress = positiveInteger(\n\t\t\tchannelOptions.maxIngressSize ?? defaultMaxIngress,\n\t\t\t'maxIngressSize'\n\t\t)\n\t\tconst maxReplay = positiveInteger(\n\t\t\tchannelOptions.maxReplaySize ?? defaultMaxReplay,\n\t\t\t'maxReplaySize'\n\t\t)\n\t\tconst addLocalSubscriber = createChannelHubs({\n\t\t\teventSchema,\n\t\t\tname,\n\t\t\tmaxIngress\n\t\t})\n\n\t\tconst openInternal: Channel['open'] = async ({\n\t\t\tinput,\n\t\t\tcontext,\n\t\t\tsignal,\n\t\t\trecoverGaps = false\n\t\t}) => {\n\t\t\tassertOpen()\n\t\t\tsignal?.throwIfAborted()\n\t\t\tconst initializing = new AbortController()\n\t\t\tconst transport = requireTransport()\n\t\t\tconst channelName = getChannelName(input, context)\n\t\t\tconst startTime = performance.now()\n\t\t\tconst span = tracing.startSpan(`${name}:subscribe`, 'SERVER', {\n\t\t\t\t'pubsub.channel': channelName,\n\t\t\t\t'pubsub.operation': 'subscribe',\n\t\t\t\t'pubsub.name': name\n\t\t\t})\n\t\t\tconst subscriberLogger = createLogger('pubsub', span)\n\t\t\tconst cancelInitialization = () =>\n\t\t\t\tinitializing.abort(\n\t\t\t\t\tsignal?.reason ?? new Error('Subscription initialization stopped')\n\t\t\t\t)\n\t\t\tpendingInitialization.add(cancelInitialization)\n\t\t\tsignal?.addEventListener('abort', cancelInitialization, { once: true })\n\t\t\tconst finishInitialization = () => {\n\t\t\t\tpendingInitialization.delete(cancelInitialization)\n\t\t\t\tsignal?.removeEventListener('abort', cancelInitialization)\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tif (\n\t\t\t\t\tauthFn !== undefined &&\n\t\t\t\t\tauthFn !== true &&\n\t\t\t\t\t!(await waitFor(\n\t\t\t\t\t\tPromise.resolve(authFn({ input, ctx: context })),\n\t\t\t\t\t\tinitializationTimeout,\n\t\t\t\t\t\tinitializing.signal\n\t\t\t\t\t))\n\t\t\t\t) {\n\t\t\t\t\tthrow new ORPCError('FORBIDDEN', {\n\t\t\t\t\t\tmessage: 'You do not have access to this subscription'\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tfinishInitialization()\n\t\t\t\ttracing.end(span, error)\n\t\t\t\tthrow error\n\t\t\t}\n\n\t\t\tsubscriberLogger.debug('pubsub.subscribing', { channel: channelName })\n\n\t\t\tlet messageCount = 0\n\t\t\tlet droppedCount = 0\n\t\t\tconst delivery = createSubscriberDelivery<unknown>({\n\t\t\t\tmaxSize: maxQueue,\n\t\t\t\tonDepth: (depth) =>\n\t\t\t\t\tmetric({\n\t\t\t\t\t\ttype: 'queue',\n\t\t\t\t\t\tstage: 'delivery',\n\t\t\t\t\t\tdepth,\n\t\t\t\t\t\tlimit: maxQueue,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tchannel: channelName\n\t\t\t\t\t}),\n\t\t\t\taccept:\n\t\t\t\t\tfilterFn &&\n\t\t\t\t\t((data) => (data === LIVE_GAP ? true : filterFn({ input, data }))),\n\t\t\t\toverflowMarker: recoverGaps\n\t\t\t\t\t? () => LIVE_GAP\n\t\t\t\t\t: overflowMarker && (() => overflowMarker(input)),\n\t\t\t\tonFilterError: (error) =>\n\t\t\t\t\tsubscriberLogger.error('Error processing message', {\n\t\t\t\t\t\terror: errorMessageOf(error)\n\t\t\t\t\t}),\n\t\t\t\tonDrop: () => {\n\t\t\t\t\tdroppedCount++\n\t\t\t\t\tmetric({\n\t\t\t\t\t\ttype: 'drop',\n\t\t\t\t\t\tstage: 'delivery',\n\t\t\t\t\t\tcount: 1,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tchannel: channelName\n\t\t\t\t\t})\n\t\t\t\t\tsafely(() =>\n\t\t\t\t\t\toptions.pubsub?.onDrop?.(1, { name, channel: channelName })\n\t\t\t\t\t)\n\t\t\t\t\tif (!recoverGaps && !overflowMarker)\n\t\t\t\t\t\tqueueMicrotask(() =>\n\t\t\t\t\t\t\tclose(\n\t\t\t\t\t\t\t\tnew ORPCError('SERVICE_UNAVAILABLE', {\n\t\t\t\t\t\t\t\t\tmessage: 'Subscription queue overflow; reconnect and resync'\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tlet replaying: Array<{ data: unknown; id: string | undefined }> | null =\n\t\t\t\tuseBacklog ? [] : null\n\t\t\tlet replayGap = false\n\t\t\tconst seen = new Set<string>()\n\t\t\tconst dedupe = (id: string | undefined) => {\n\t\t\t\tif (!id) return false\n\t\t\t\tif (seen.has(id)) return true\n\t\t\t\tseen.add(id)\n\t\t\t\tif (\n\t\t\t\t\tseen.size >\n\t\t\t\t\tMath.max(maxReplay, maxQueue, channelOptions.backlogSize ?? 50) * 2\n\t\t\t\t)\n\t\t\t\t\tseen.delete(seen.values().next().value as string)\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst push = (data: unknown, id?: string) => {\n\t\t\t\tmessageCount++\n\t\t\t\tif (replaying) {\n\t\t\t\t\tif (replaying.length >= maxReplay) {\n\t\t\t\t\t\treplaying.shift()\n\t\t\t\t\t\treplayGap = true\n\t\t\t\t\t\tmetric({\n\t\t\t\t\t\t\ttype: 'drop',\n\t\t\t\t\t\t\tstage: 'replay',\n\t\t\t\t\t\t\tcount: 1,\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\tchannel: channelName\n\t\t\t\t\t\t})\n\t\t\t\t\t\tsafely(() =>\n\t\t\t\t\t\t\toptions.pubsub?.onDrop?.(1, { name, channel: channelName })\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\treplaying.push({ data, id })\n\t\t\t\t\tmetric({\n\t\t\t\t\t\ttype: 'queue',\n\t\t\t\t\t\tstage: 'replay',\n\t\t\t\t\t\tdepth: replaying.length,\n\t\t\t\t\t\tlimit: maxReplay,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tchannel: channelName\n\t\t\t\t\t})\n\t\t\t\t} else if (!dedupe(id)) delivery.push(data)\n\t\t\t}\n\t\t\tconst gap = () => {\n\t\t\t\tif (replaying) {\n\t\t\t\t\treplayGap = true\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (recoverGaps) delivery.push(LIVE_GAP)\n\t\t\t\telse if (overflowMarker) {\n\t\t\t\t\tconst marker = overflowMarker(input)\n\t\t\t\t\tif (marker !== null) delivery.push(marker, true)\n\t\t\t\t} else\n\t\t\t\t\tclose(\n\t\t\t\t\t\tnew ORPCError('SERVICE_UNAVAILABLE', {\n\t\t\t\t\t\t\tmessage: 'Subscription lost events; reconnect and resync'\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t}\n\n\t\t\t// The one way a subscription ends, whatever ends it: abort, drain, the\n\t\t\t// stream finishing, or `close()`. Releases everything at once, even\n\t\t\t// while the stream is parked or not yet read.\n\t\t\tlet closed = false\n\t\t\tconst close = (...error: [] | [unknown]) => {\n\t\t\t\tif (closed) return\n\t\t\t\tclosed = true\n\t\t\t\tinitializing.abort(error[0] ?? new Error('Subscription closed'))\n\t\t\t\tdelivery.close(error[0])\n\t\t\t\tactiveSubscriberCleanups.delete(stop)\n\t\t\t\tsignal?.removeEventListener('abort', stop)\n\t\t\t\tlocal.remove()\n\t\t\t\tconst durationMs = performance.now() - startTime\n\t\t\t\tspan?.setAttribute('pubsub.duration_ms', durationMs)\n\t\t\t\tspan?.setAttribute('pubsub.message_count', messageCount)\n\t\t\t\tspan?.setAttribute('pubsub.dropped_count', droppedCount)\n\t\t\t\ttracing.end(span, ...error)\n\t\t\t\tsubscriberLogger.debug('pubsub.unsubscribed', {\n\t\t\t\t\tchannel: channelName,\n\t\t\t\t\tmessageCount,\n\t\t\t\t\tdroppedCount,\n\t\t\t\t\tdurationMs: Math.round(durationMs)\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst stop = () => close()\n\t\t\tconst local = addLocalSubscriber(channelName, {\n\t\t\t\tisActive: () => !closed,\n\t\t\t\tpush,\n\t\t\t\tgap,\n\t\t\t\tfail: (error) => close(error)\n\t\t\t})\n\t\t\tactiveSubscriberCleanups.add(stop)\n\t\t\tsignal?.addEventListener('abort', stop)\n\t\t\tif (signal?.aborted) close()\n\n\t\t\ttry {\n\t\t\t\tawait waitFor(local.ready, initializationTimeout, initializing.signal)\n\t\t\t\tif (replaying && !closed) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst items = await waitFor(\n\t\t\t\t\t\t\ttransport.readBacklog(channelName),\n\t\t\t\t\t\t\tinitializationTimeout,\n\t\t\t\t\t\t\tinitializing.signal\n\t\t\t\t\t\t)\n\t\t\t\t\t\tspan?.setAttribute('pubsub.backlog_count', items.length)\n\t\t\t\t\t\tfor (const raw of items.slice(-maxReplay)) {\n\t\t\t\t\t\t\tif (closed) break\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst message = decodeMessage(raw)\n\t\t\t\t\t\t\t\tif (!dedupe(message.id)) {\n\t\t\t\t\t\t\t\t\tmessageCount++\n\t\t\t\t\t\t\t\t\tdelivery.push(\n\t\t\t\t\t\t\t\t\t\tawait waitFor(\n\t\t\t\t\t\t\t\t\t\t\teventSchema.parseAsync(message.value),\n\t\t\t\t\t\t\t\t\t\t\tinitializationTimeout,\n\t\t\t\t\t\t\t\t\t\t\tinitializing.signal\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tmetric({\n\t\t\t\t\t\t\t\t\ttype: 'parseError',\n\t\t\t\t\t\t\t\t\tstage: 'replay',\n\t\t\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\t\tchannel: channelName\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t/* Malformed backlog entries are skipped. */\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (items.length > maxReplay) replayGap = true\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treplayGap = true\n\t\t\t\t\t\tsubscriberLogger.warn('pubsub.replay_failed', {\n\t\t\t\t\t\t\tchannel: channelName,\n\t\t\t\t\t\t\t...errorAttributes(error)\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (const { data, id } of replaying ?? [])\n\t\t\t\t\tif (!dedupe(id)) delivery.push(data)\n\t\t\t\treplaying = null\n\t\t\t\tmetric({\n\t\t\t\t\ttype: 'queue',\n\t\t\t\t\tstage: 'replay',\n\t\t\t\t\tdepth: 0,\n\t\t\t\t\tlimit: maxReplay,\n\t\t\t\t\tname,\n\t\t\t\t\tchannel: channelName\n\t\t\t\t})\n\t\t\t\tif (replayGap && !closed) gap()\n\t\t\t} catch (error) {\n\t\t\t\tif (!closed) {\n\t\t\t\t\tclose(error)\n\t\t\t\t\tthrow new ORPCError('SERVICE_UNAVAILABLE', {\n\t\t\t\t\t\tmessage: 'Unable to establish subscription',\n\t\t\t\t\t\tcause: error\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tfinishInitialization()\n\t\t\t}\n\n\t\t\tasync function* events() {\n\t\t\t\ttry {\n\t\t\t\t\tyield* delivery.events\n\t\t\t\t} finally {\n\t\t\t\t\tclose()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { events: events(), close: () => close(), isClosed: () => closed }\n\t\t}\n\n\t\tconst { publish, publishMany } = createChannelPublisher({\n\t\t\t...channelOptions,\n\t\t\tgetChannelName: getPublishChannel\n\t\t})\n\n\t\tconst open: Channel['open'] = (params) => {\n\t\t\tconst task = openInternal(params)\n\t\t\tpendingOpens.add(task)\n\t\t\tvoid task.then(\n\t\t\t\t() => pendingOpens.delete(task),\n\t\t\t\t() => pendingOpens.delete(task)\n\t\t\t)\n\t\t\treturn task\n\t\t}\n\t\treturn {\n\t\t\topen,\n\t\t\tpublish,\n\t\t\tpublishMany,\n\t\t\tgetChannelName,\n\t\t\tgetSubscriptionChannelName: ({ input, context }) =>\n\t\t\t\tgetChannelName(input, context),\n\t\t\tgetPublishChannelName: getPublishChannel\n\t\t}\n\t}\n\n\tfunction createPubSub(\n\t\tpubsubOptions: ChannelOptions & {\n\t\t\tinputSchema: ZodType\n\t\t\tprocedure?: string\n\t\t\ttags?: string[]\n\t\t\tsummary?: string\n\t\t\tdescription?: string\n\t\t}\n\t) {\n\t\tconst { name } = pubsubOptions\n\t\tconst channel = createChannel(pubsubOptions)\n\n\t\tconst {\n\t\t\tchannel: _channel,\n\t\t\teventSchema: _eventSchema,\n\t\t\tinputSchema,\n\t\t\tfilterFn: _filterFn,\n\t\t\tauthFn: _authFn,\n\t\t\toverflowMarker: _overflowMarker,\n\t\t\tuseBacklog: _useBacklog,\n\t\t\tbacklogSize: _backlogSize,\n\t\t\tbacklogTtl: _backlogTtl,\n\t\t\tmirrorChannel: _mirrorChannel,\n\t\t\tmaxQueueSize: _maxQueueSize,\n\t\t\tmaxIngressSize: _maxIngressSize,\n\t\t\tmaxReplaySize: _maxReplaySize,\n\t\t\t...routeOptions\n\t\t} = pubsubOptions\n\t\tconst subscribe = options.fn({\n\t\t\t...routeOptions,\n\t\t\tname,\n\t\t\tstream: true,\n\t\t\tmethod: 'GET',\n\t\t\tinput: inputSchema,\n\t\t\tsummary: pubsubOptions.summary ?? `Subscribe to ${name}`,\n\t\t\thandler: async function* ({\n\t\t\t\tinput,\n\t\t\t\tcontext,\n\t\t\t\tsignal\n\t\t\t}: {\n\t\t\t\tinput: Input\n\t\t\t\tcontext: unknown\n\t\t\t\tsignal: AbortSignal | undefined\n\t\t\t}) {\n\t\t\t\tyield* (await channel.open({ input, context, signal })).events\n\t\t\t}\n\t\t})\n\n\t\tconst { publish, publishMany, getChannelName } = channel\n\t\treturn {\n\t\t\tsubscribe,\n\t\t\tpublish,\n\t\t\tpublishMany,\n\t\t\tgetChannelName,\n\t\t\tgetSubscriptionChannelName: channel.getSubscriptionChannelName,\n\t\t\tgetPublishChannelName: channel.getPublishChannelName\n\t\t}\n\t}\n\n\tfunction createPublisher(publisherOptions: PublisherOptions<ZodType>) {\n\t\tconst getChannelName = (params: Input) =>\n\t\t\tqualify(resolveChannel(publisherOptions.channel, params, undefined, true))\n\t\tconst { publish, publishMany } = createChannelPublisher({\n\t\t\t...publisherOptions,\n\t\t\tgetChannelName\n\t\t})\n\t\treturn { publish, publishMany, getChannelName }\n\t}\n\n\treturn {\n\t\tcreateChannel,\n\t\tshutdown: () => {\n\t\t\tif (shutdownPromise) return shutdownPromise\n\t\t\tterminated = true\n\t\t\tfor (const cancel of [...pendingInitialization]) safely(cancel)\n\t\t\tfor (const cleanup of [...activeSubscriberCleanups]) safely(cleanup)\n\t\t\tshutdownPromise = (async () => {\n\t\t\t\tawait Promise.allSettled([...pendingOpens])\n\t\t\t\tawait Promise.all([...releases])\n\t\t\t\tif (options.pubsub?.ownsTransport) await transport?.close?.()\n\t\t\t})()\n\t\t\treturn shutdownPromise\n\t\t},\n\t\tcreatePubSub,\n\t\tcreatePublisher,\n\t\t/** Open subscriptions of this instance (drain progress, gauges). */\n\t\tactivePubSubSubscriberCount: () => activeSubscriberCleanups.size,\n\t\t/** End every open subscription; returns how many were closed. */\n\t\tdrainPubSubSubscribers: () => {\n\t\t\tconst cleanups = [...activeSubscriberCleanups]\n\t\t\tactiveSubscriberCleanups.clear()\n\t\t\tfor (const cleanup of cleanups) {\n\t\t\t\ttry {\n\t\t\t\t\tcleanup()\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// A failed cleanup must not stop the drain.\n\t\t\t\t\tlogger.warn('Subscriber cleanup failed during drain', {\n\t\t\t\t\t\terror: errorMessageOf(error)\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn cleanups.length\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"pub-sub.js","sourceRoot":"","sources":["../../src/live/pub-sub.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAGxC,OAAO,EACN,eAAe,EACf,cAAc,EAGd,MAAM,YAAY,CAAA;AAWnB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAmO3E,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,uBAAuB,CAAI,IAM1C;IACA,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IACxC,MAAM,KAAK,GAAQ,EAAE,CAAA;IACrB,wEAAwE;IACxE,wEAAwE;IACxE,IAAI,qBAAqB,GAAa,IAAI,CAAA;IAE1C,OAAO;QACN,IAAI,MAAM;YACT,OAAO,KAAK,CAAC,MAAM,CAAA;QACpB,CAAC;QACD,OAAO,CAAC,IAAO;YACd,IAAI,CAAC;gBACJ,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBAClC,IAAI,qBAAqB,KAAK,IAAI,EAAE,CAAC;wBACpC,gEAAgE;wBAChE,uCAAuC;wBACvC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;wBAC5D,IAAI,SAAS,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;4BAC/B,+DAA+D;4BAC/D,6DAA6D;4BAC7D,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;4BACnB,OAAM;wBACP,CAAC;wBACD,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;wBAC1B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;wBACnB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;wBAChB,OAAM;oBACP,CAAC;oBACD,KAAK,CAAC,KAAK,EAAE,CAAA;oBACb,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;oBACnB,MAAM,MAAM,GAAG,IAAI,CAAC,oBAAoB,EAAE,EAAE,IAAI,IAAI,CAAA;oBACpD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;wBACrB,qBAAqB,GAAG,MAAM,CAAA;wBAC9B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;wBAClB,OAAM;oBACP,CAAC;gBACF,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACjB,CAAC;oBAAS,CAAC;gBACV,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;YAC3C,CAAC;QACF,CAAC;QACD,OAAO;YACN,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAE,CAAA;YAC1B,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;YAC1C,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,qBAAqB,EAAE,CAAC;gBAC1D,qBAAqB,GAAG,IAAI,CAAA;YAC7B,CAAC;YACD,OAAO,IAAI,CAAA;QACZ,CAAC;KACD,CAAA;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CAAI,OAO3C;IAEA,MAAM,KAAK,GAAG,uBAAuB,CAAO;QAC3C,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,oBAAoB,EAAE,GAAG,EAAE;YAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,EAAE,IAAI,IAAI,CAAA;YACjD,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;QAC/D,CAAC;QACD,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxD,CAAC,CAAA;IACF,IAAI,MAAM,GAAG,KAAK,CAAA;IAClB,IAAI,OAAgB,CAAA;IACpB,IAAI,IAAI,GAAwB,IAAI,CAAA;IACpC,MAAM,MAAM,GAAG,GAAG,EAAE;QACnB,IAAI,EAAE,EAAE,CAAA;QACR,IAAI,GAAG,IAAI,CAAA;IACZ,CAAC,CAAA;IAED,KAAK,SAAS,CAAC,CAAC,MAAM;QACrB,OAAO,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,EAAE,CAAA;YAC5B,IAAI,CAAC,IAAI,EAAE,CAAC;gBACX,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;oBACnC,IAAI,GAAG,OAAO,CAAA;gBACf,CAAC,CAAC,CAAA;gBACF,SAAQ;YACT,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACpC,IAAI,CAAC;oBACJ,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBAAE,SAAQ;gBACjD,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAA;oBAC1C,SAAQ;gBACT,CAAC;gBACD,IAAI,MAAM;oBAAE,MAAK;YAClB,CAAC;YACD,MAAM,IAAI,CAAC,IAAI,CAAA;QAChB,CAAC;QACD,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,OAAO,CAAA;IACzC,CAAC;IAED,OAAO;QACN,IAAI,CAAC,IAAO,EAAE,MAAM,GAAG,KAAK;YAC3B,IAAI,MAAM;gBAAE,OAAM;YAClB,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;YAC/B,MAAM,EAAE,CAAA;QACT,CAAC;QACD,MAAM,EAAE,MAAM,EAAE;QAChB,mDAAmD;QACnD,KAAK,CAAC,KAAe;YACpB,IAAI,MAAM;gBAAE,OAAM;YAClB,OAAO,GAAG,KAAK,CAAA;YACf,MAAM,GAAG,IAAI,CAAA;YACb,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;YAClC,MAAM,EAAE,CAAA;QACT,CAAC;KACD,CAAA;AACF,CAAC;AAED,8EAA8E;AAC9E,mEAAmE;AACnE,8EAA8E;AAE9E,MAAM,sBAAsB,GAAG,IAAI,CAAA;AAEnC,qGAAqG;AACrG,MAAM,yBAAyB,GAAG,IAAI,CAAA;AACtC,MAAM,wBAAwB,GAAG,MAAM,CAAA;AACvC,MAAM,yBAAyB,GAAG,GAAG,CAAA;AAErC,SAAS,qBAAqB,CAAC,OAAe;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CACpB,yBAAyB,GAAG,CAAC,IAAI,OAAO,EACxC,wBAAwB,CACxB,CAAA;IACD,OAAO,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,yBAAyB,CAAC,CAAA;AACpE,CAAC;AAwDD,MAAM,cAAc,GAAG,CACtB,OAA0C,EAC1C,MAAa,EACb,OAAiB,EACjB,UAAU,GAAG,KAAK,EACjB,EAAE;IACH,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAA;IAC/C,IAAI,OAAO,OAAO,KAAK,UAAU;QAAE,OAAO,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClE,OAAO,UAAU;QAChB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;QACzB,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;AACjD,CAAC,CAAA;AAED,gBAAgB;AAChB,MAAM,UAAU,iBAAiB,CAAC,OAA2B;IAC5D,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAA;IACzC,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;IAChD,IAAI,UAAU,GAAG,KAAK,CAAA;IACtB,IAAI,eAA0C,CAAA;IAC9C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAiB,CAAA;IACzC,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAc,CAAA;IACnD,MAAM,YAAY,GAAG,IAAI,GAAG,EAA6B,CAAA;IACzD,MAAM,eAAe,GAAG,eAAe,CACtC,OAAO,CAAC,MAAM,EAAE,YAAY,IAAI,sBAAsB,EACtD,cAAc,CACd,CAAA;IACD,MAAM,iBAAiB,GAAG,eAAe,CACxC,OAAO,CAAC,MAAM,EAAE,cAAc,IAAI,eAAe,EACjD,gBAAgB,CAChB,CAAA;IACD,MAAM,gBAAgB,GAAG,eAAe,CACvC,OAAO,CAAC,MAAM,EAAE,aAAa,IAAI,eAAe,EAChD,eAAe,CACf,CAAA;IACD,MAAM,qBAAqB,GAAG,eAAe,CAC5C,OAAO,CAAC,MAAM,EAAE,uBAAuB,IAAI,KAAK,EAChD,yBAAyB,CACzB,CAAA;IACD,MAAM,MAAM,GAAG,CAAC,KAAmB,EAAE,EAAE,CACtC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAChD,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,SAAS,CAAA;IAC3C,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IAC7E,MAAM,UAAU,GAAG,GAAG,EAAE;QACvB,IAAI,UAAU;YACb,MAAM,IAAI,SAAS,CAAC,qBAAqB,EAAE;gBAC1C,OAAO,EAAE,4BAA4B;aACrC,CAAC,CAAA;IACJ,CAAC,CAAA;IACD,MAAM,gBAAgB,GAAG,CAAC,OAAqC,EAAE,EAAE;QAClE,IAAI,CAAC,OAAO;YAAE,OAAM;QACpB,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACvD,MAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE;gBAC7C,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC;aAC5B,CAAC,CAAA;QACH,CAAC,CAAC,CAAA;QACF,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAClB,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;IAC/C,CAAC,CAAA;IAED,qEAAqE;IACrE,2EAA2E;IAC3E,4EAA4E;IAC5E,yDAAyD;IACzD,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAc,CAAA;IAEtD,IAAI,SAAsC,CAAA;IAC1C,MAAM,gBAAgB,GAAG,GAAG,EAAE;QAC7B,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACd,iFAAiF,CACjF,CAAA;QACF,CAAC;QACD,IAAI,SAAS;YAAE,OAAO,SAAS,CAAA;QAC/B,8DAA8D;QAC9D,UAAU,EAAE,CAAA;QACZ,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAA;QAC3C,SAAS,GAAG,OAAO,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,CAAA;QACxE,OAAO,SAAS,CAAA;IACjB,CAAC,CAAA;IAED;;;;OAIG;IACH,SAAS,sBAAsB,CAC9B,MAGC;QAED,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,MAAM,CAAA;QACpD,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa;YACzC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC;YAC/B,CAAC,CAAC,SAAS,CAAA;QACZ,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS;YACnC,eAAe,CAAC,MAAM,CAAC,WAAW,EAAE,aAAa,CAAC,CAAA;QACnD,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS;YAClC,eAAe,CAAC,MAAM,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;QACjD,MAAM,OAAO,GAA+B,MAAM,CAAC,UAAU;YAC5D,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,EAAE,EAAE;YACzE,CAAC,CAAC,SAAS,CAAA;QAEZ,MAAM,UAAU,GAAG,KAAK,EAAE,KAAyB,EAAE,EAAE;YACtD,MAAM,QAAQ,GAAoB,EAAE,CAAA;YACpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBAC1B,MAAM,IAAI,GAAG,CAAC,MAAM,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAU,CAAA;gBAC1D,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAA;gBACpC,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;gBACnC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;gBACnC,IAAI,aAAa,IAAI,aAAa,KAAK,OAAO,EAAE,CAAC;oBAChD,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,CAAA;gBACnD,CAAC;YACF,CAAC;YACD,OAAO,QAAQ,CAAA;QAChB,CAAC,CAAA;QAED,MAAM,IAAI,GAAG,CACZ,SAAoC,EACpC,KAAyB,EACxB,EAAE,CACH,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,IAAI,SAAS,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACjE,UAAU,EAAE,CAAA;YACZ,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;YACnC,IAAI,CAAC;gBACJ,IAAI,EAAE,YAAY,CAAC,kBAAkB,EAAE,SAAS,CAAC,CAAA;gBACjD,IAAI,EAAE,YAAY,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;gBACvC,IAAI,EAAE,YAAY,CAAC,mBAAmB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;gBACrD,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,CAAA;gBACxC,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;gBACzB,IAAI,KAAK,EAAE,CAAC;oBACX,IAAI,EAAE,YAAY,CAAC,gBAAgB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;oBACnD,IAAI,EAAE,YAAY,CAAC,qBAAqB,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;gBAChE,CAAC;gBACD,MAAM,gBAAgB,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YACpD,CAAC;oBAAS,CAAC;gBACV,IAAI,EAAE,YAAY,CACjB,oBAAoB,EACpB,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAC7B,CAAA;YACF,CAAC;QACF,CAAC,CAAC,CAAA;QAEH,MAAM,OAAO,GAAG,KAAK,EACpB,SAAoC,EACpC,KAAyB,EACxB,EAAE;YACH,IAAI,CAAC,MAAM,CAAC,WAAW;gBAAE,OAAO,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;YACtD,IAAI,CAAC;gBACJ,MAAM,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;YAC7B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE;oBACrC,IAAI;oBACJ,GAAG,eAAe,CAAC,KAAK,CAAC;iBACzB,CAAC,CAAA;YACH,CAAC;QACF,CAAC,CAAA;QAED,OAAO;YACN,OAAO,EAAE,CAAC,IAAa,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC;YACtD,WAAW,EAAE,KAAK,EAAE,KAAyB,EAAE,EAAE;gBAChD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;oBAAE,MAAM,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;YAC1D,CAAC;SACD,CAAA;IACF,CAAC;IAED;;;;;;OAMG;IACH,SAAS,iBAAiB,CAAC,MAI1B;QACA,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAA;QAC9B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAe,CAAA;QAEnC,MAAM,SAAS,GAAG,CAAC,OAAe,EAAO,EAAE;YAC1C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAmB,CAAA;YAC9C,IAAI,MAAM,GAAG,KAAK,CAAA;YAClB,IAAI,WAAW,GAAiC,IAAI,CAAA;YACpD,IAAI,OAAO,GAAG,CAAC,CAAA;YACf,IAAI,KAAK,GAAyC,IAAI,CAAA;YACtD,IAAI,SAAS,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;YACxB,IAAI,aAAa,GAAG,KAAK,CAAA;YACzB,IAAI,SAAS,GAAG,KAAK,CAAA;YACrB,IAAI,KAAoB,CAAA;YACxB,MAAM,WAAW,GAAG,GAAG,EAAE;gBACxB,KAAK,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;oBACrC,SAAS,GAAG,OAAO,CAAA;gBACpB,CAAC,CAAC,CAAA;YACH,CAAC,CAAA;YACD,WAAW,EAAE,CAAA;YAEb,IAAI,OAAO,GAAG,KAAK,CAAA;YACnB,MAAM,OAAO,GAAG,uBAAuB,CAAS;gBAC/C,OAAO,EAAE,MAAM,CAAC,UAAU;gBAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAClB,MAAM,CAAC;oBACN,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,SAAS;oBAChB,KAAK;oBACL,KAAK,EAAE,MAAM,CAAC,UAAU;oBACxB,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,OAAO;iBACP,CAAC;gBACH,MAAM,EAAE,GAAG,EAAE;oBACZ,MAAM,CAAC;wBACN,IAAI,EAAE,MAAM;wBACZ,KAAK,EAAE,SAAS;wBAChB,KAAK,EAAE,CAAC;wBACR,IAAI,EAAE,MAAM,CAAC,IAAI;wBACjB,OAAO;qBACP,CAAC,CAAA;oBACF,MAAM,CAAC,GAAG,EAAE,CACX,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAC3D,CAAA;oBACD,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC,EAAE,CAAC;wBACpC,IAAI,CAAC;4BACJ,GAAG,CAAC,GAAG,EAAE,CAAA;wBACV,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BAChB,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;wBAC9B,CAAC;oBACF,CAAC;gBACF,CAAC;aACD,CAAC,CAAA;YACF,MAAM,YAAY,GAAG,KAAK,IAAI,EAAE;gBAC/B,IAAI,OAAO;oBAAE,OAAM;gBACnB,OAAO,GAAG,IAAI,CAAA;gBACd,IAAI,CAAC;oBACJ,OAAO,CAAC,MAAM,EAAE,CAAC;wBAChB,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,CAAA;wBAC7B,IAAI,GAAG,KAAK,SAAS;4BAAE,MAAK;wBAC5B,IAAI,CAAC;4BACJ,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;4BAClC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;4BAC1D,IAAI,MAAM;gCAAE,MAAK;4BACjB,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC;gCACjC,IAAI,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC;oCACpB,IAAI,CAAC;wCACJ,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;oCAC7B,CAAC;oCAAC,OAAO,KAAK,EAAE,CAAC;wCAChB,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;oCAC9B,CAAC;gCACF,CAAC;wBACH,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BAChB,MAAM,CAAC;gCACN,IAAI,EAAE,YAAY;gCAClB,KAAK,EAAE,SAAS;gCAChB,KAAK;gCACL,IAAI,EAAE,MAAM,CAAC,IAAI;gCACjB,OAAO;6BACP,CAAC,CAAA;4BACF,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE;gCACrC,OAAO;gCACP,GAAG,eAAe,CAAC,KAAK,CAAC;6BACzB,CAAC,CAAA;wBACH,CAAC;oBACF,CAAC;gBACF,CAAC;wBAAS,CAAC;oBACV,OAAO,GAAG,KAAK,CAAA;gBAChB,CAAC;YACF,CAAC,CAAA;YACD,MAAM,OAAO,GAAG,gBAAgB,CAAA;YAEhC,MAAM,mBAAmB,GAAG,CAAC,MAAc,EAAE,EAAE;gBAC9C,IAAI,MAAM,IAAI,KAAK;oBAAE,OAAM;gBAC3B,MAAM,OAAO,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAA;gBAC9C,OAAO,EAAE,CAAA;gBACT,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE;oBAC3C,OAAO;oBACP,MAAM;oBACN,OAAO;oBACP,OAAO;iBACP,CAAC,CAAA;gBACF,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBACvB,KAAK,GAAG,IAAI,CAAA;oBACZ,IAAI,MAAM;wBAAE,OAAM;oBAClB,OAAO,CAAC,WAAW,CAAC,CAAA;oBACpB,WAAW,GAAG,IAAI,CAAA;oBAClB,KAAK,OAAO,EAAE,CAAA;gBACf,CAAC,EAAE,OAAO,CAAC,CAAA;YACZ,CAAC,CAAA;YAED,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;gBAC1B,IAAI,CAAC;oBACJ,MAAM,IAAI,GAAG,MAAM,gBAAgB,EAAE,CAAC,SAAS,CAC9C,OAAO,EACP,CAAC,GAAG,EAAE,EAAE;wBACP,IAAI,MAAM;4BAAE,OAAM;wBAClB,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;wBACpB,KAAK,YAAY,EAAE,CAAA;oBACpB,CAAC,EACD,CAAC,KAAK,EAAE,EAAE;wBACT,IAAI,SAAS,EAAE,CAAC;4BACf,SAAS,GAAG,KAAK,CAAA;4BACjB,WAAW,EAAE,CAAA;wBACd,CAAC;wBACD,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE;4BACxC,OAAO;4BACP,GAAG,eAAe,CAAC,KAAK,CAAC;yBACzB,CAAC,CAAA;wBACF,mBAAmB,CAAC,MAAM,CAAC,CAAA;oBAC5B,CAAC,EACD;wBACC,WAAW,EAAE,GAAG,EAAE;4BACjB,IAAI,MAAM;gCAAE,OAAM;4BAClB,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;4BACzD,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC,EAAE,CAAC;gCACpC,IAAI,CAAC;oCACJ,GAAG,CAAC,GAAG,EAAE,CAAA;gCACV,CAAC;gCAAC,OAAO,KAAK,EAAE,CAAC;oCAChB,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;gCAC9B,CAAC;4BACF,CAAC;wBACF,CAAC;qBACD,CACD,CAAA;oBACD,IAAI,MAAM;wBAAE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAA;oBAChC,WAAW,GAAG,IAAI,CAAA;oBAClB,SAAS,GAAG,IAAI,CAAA;oBAChB,IAAI,aAAa,EAAE,CAAC;wBACnB,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;wBACzD,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC,EAAE,CAAC;4BACpC,IAAI,CAAC;gCACJ,GAAG,CAAC,GAAG,EAAE,CAAA;4BACV,CAAC;4BAAC,OAAO,KAAK,EAAE,CAAC;gCAChB,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;4BAC9B,CAAC;wBACF,CAAC;oBACF,CAAC;oBACD,aAAa,GAAG,IAAI,CAAA;oBACpB,SAAS,EAAE,CAAA;oBACX,OAAO,GAAG,CAAC,CAAA;oBACX,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;gBAC/C,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE;wBACvC,OAAO;wBACP,GAAG,eAAe,CAAC,KAAK,CAAC;qBACzB,CAAC,CAAA;oBACF,mBAAmB,CAAC,kBAAkB,CAAC,CAAA;gBACxC,CAAC;YACF,CAAC,CAAA;YAED,KAAK,OAAO,EAAE,CAAA;YAEd,OAAO;gBACN,WAAW;gBACX,IAAI,KAAK;oBACR,OAAO,KAAK,CAAA;gBACb,CAAC;gBACD,KAAK,EAAE,GAAG,EAAE;oBACX,MAAM,GAAG,IAAI,CAAA;oBACb,MAAM,CAAC;wBACN,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,SAAS;wBAChB,KAAK,EAAE,CAAC;wBACR,KAAK,EAAE,MAAM,CAAC,UAAU;wBACxB,IAAI,EAAE,MAAM,CAAC,IAAI;wBACjB,OAAO;qBACP,CAAC,CAAA;oBACF,IAAI,KAAK;wBAAE,YAAY,CAAC,KAAK,CAAC,CAAA;oBAC9B,KAAK,GAAG,IAAI,CAAA;oBACZ,SAAS,EAAE,CAAA;oBACX,OAAO,CAAC,WAAW,CAAC,CAAA;oBACpB,WAAW,GAAG,IAAI,CAAA;gBACnB,CAAC;aACD,CAAA;QACF,CAAC,CAAA;QAED,OAAO,SAAS,kBAAkB,CACjC,OAAe,EACf,UAA2B;YAE3B,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAC3B,IAAI,CAAC,GAAG,EAAE,CAAC;gBACV,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;gBACxB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;YACvB,CAAC;YACD,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;YAC/B,MAAM,OAAO,GAAG,GAAG,CAAA;YACnB,OAAO;gBACN,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,MAAM,EAAE,GAAG,EAAE;oBACZ,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;oBACtC,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,OAAO,EAAE,CAAC;wBACrE,OAAO,CAAC,KAAK,EAAE,CAAA;wBACf,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;oBACrB,CAAC;gBACF,CAAC;aACD,CAAA;QACF,CAAC,CAAA;IACF,CAAC;IAED,gEAAgE;IAChE,SAAS,aAAa,CAAC,cAA8B;QACpD,MAAM,EACL,IAAI,EACJ,OAAO,EACP,WAAW,EACX,QAAQ,EACR,MAAM,EACN,cAAc,EACd,UAAU,GAAG,KAAK,EAClB,GAAG,cAAc,CAAA;QAElB,MAAM,cAAc,GAAG,CAAC,MAAa,EAAE,OAAiB,EAAE,EAAE,CAC3D,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;QAClD,MAAM,iBAAiB,GAAG,CAAC,MAAa,EAAE,EAAE,CAC3C,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAA;QAC1D,MAAM,QAAQ,GAAG,eAAe,CAC/B,cAAc,CAAC,YAAY,IAAI,eAAe,EAC9C,cAAc,CACd,CAAA;QACD,MAAM,UAAU,GAAG,eAAe,CACjC,cAAc,CAAC,cAAc,IAAI,iBAAiB,EAClD,gBAAgB,CAChB,CAAA;QACD,MAAM,SAAS,GAAG,eAAe,CAChC,cAAc,CAAC,aAAa,IAAI,gBAAgB,EAChD,eAAe,CACf,CAAA;QACD,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;YAC5C,WAAW;YACX,IAAI;YACJ,UAAU;SACV,CAAC,CAAA;QAEF,MAAM,YAAY,GAAoB,KAAK,EAAE,EAC5C,KAAK,EACL,OAAO,EACP,MAAM,EACN,WAAW,GAAG,KAAK,EACnB,EAAE,EAAE;YACJ,UAAU,EAAE,CAAA;YACZ,MAAM,EAAE,cAAc,EAAE,CAAA;YACxB,MAAM,YAAY,GAAG,IAAI,eAAe,EAAE,CAAA;YAC1C,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAA;YACpC,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;YAClD,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;YACnC,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,YAAY,EAAE,QAAQ,EAAE;gBAC7D,gBAAgB,EAAE,WAAW;gBAC7B,kBAAkB,EAAE,WAAW;gBAC/B,aAAa,EAAE,IAAI;aACnB,CAAC,CAAA;YACF,MAAM,gBAAgB,GAAG,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;YACrD,MAAM,oBAAoB,GAAG,GAAG,EAAE,CACjC,YAAY,CAAC,KAAK,CACjB,MAAM,EAAE,MAAM,IAAI,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAClE,CAAA;YACF,qBAAqB,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;YAC/C,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;YACvE,MAAM,oBAAoB,GAAG,GAAG,EAAE;gBACjC,qBAAqB,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAA;gBAClD,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAA;YAC3D,CAAC,CAAA;YAED,IAAI,CAAC;gBACJ,IACC,MAAM,KAAK,SAAS;oBACpB,MAAM,KAAK,IAAI;oBACf,CAAC,CAAC,MAAM,OAAO,CACd,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,EAChD,qBAAqB,EACrB,YAAY,CAAC,MAAM,CACnB,CAAC,EACD,CAAC;oBACF,MAAM,IAAI,SAAS,CAAC,WAAW,EAAE;wBAChC,OAAO,EAAE,6CAA6C;qBACtD,CAAC,CAAA;gBACH,CAAC;YACF,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,oBAAoB,EAAE,CAAA;gBACtB,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;gBACxB,MAAM,KAAK,CAAA;YACZ,CAAC;YAED,gBAAgB,CAAC,KAAK,CAAC,oBAAoB,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAA;YAEtE,IAAI,YAAY,GAAG,CAAC,CAAA;YACpB,IAAI,YAAY,GAAG,CAAC,CAAA;YACpB,MAAM,QAAQ,GAAG,wBAAwB,CAAU;gBAClD,OAAO,EAAE,QAAQ;gBACjB,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAClB,MAAM,CAAC;oBACN,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,UAAU;oBACjB,KAAK;oBACL,KAAK,EAAE,QAAQ;oBACf,IAAI;oBACJ,OAAO,EAAE,WAAW;iBACpB,CAAC;gBACH,MAAM,EACL,QAAQ;oBACR,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBACnE,cAAc,EAAE,WAAW;oBAC1B,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ;oBAChB,CAAC,CAAC,cAAc,IAAI,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;gBAClD,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE,CACxB,gBAAgB,CAAC,KAAK,CAAC,0BAA0B,EAAE;oBAClD,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC;iBAC5B,CAAC;gBACH,MAAM,EAAE,GAAG,EAAE;oBACZ,YAAY,EAAE,CAAA;oBACd,MAAM,CAAC;wBACN,IAAI,EAAE,MAAM;wBACZ,KAAK,EAAE,UAAU;wBACjB,KAAK,EAAE,CAAC;wBACR,IAAI;wBACJ,OAAO,EAAE,WAAW;qBACpB,CAAC,CAAA;oBACF,MAAM,CAAC,GAAG,EAAE,CACX,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAC3D,CAAA;oBACD,IAAI,CAAC,WAAW,IAAI,CAAC,cAAc;wBAClC,cAAc,CAAC,GAAG,EAAE,CACnB,KAAK,CACJ,IAAI,SAAS,CAAC,qBAAqB,EAAE;4BACpC,OAAO,EAAE,mDAAmD;yBAC5D,CAAC,CACF,CACD,CAAA;gBACH,CAAC;aACD,CAAC,CAAA;YAEF,IAAI,SAAS,GACZ,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;YACvB,IAAI,SAAS,GAAG,KAAK,CAAA;YACrB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;YAC9B,MAAM,MAAM,GAAG,CAAC,EAAsB,EAAE,EAAE;gBACzC,IAAI,CAAC,EAAE;oBAAE,OAAO,KAAK,CAAA;gBACrB,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;oBAAE,OAAO,IAAI,CAAA;gBAC7B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;gBACZ,IACC,IAAI,CAAC,IAAI;oBACT,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,cAAc,CAAC,WAAW,IAAI,EAAE,CAAC,GAAG,CAAC;oBAEnE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAe,CAAC,CAAA;gBAClD,OAAO,KAAK,CAAA;YACb,CAAC,CAAA;YACD,MAAM,IAAI,GAAG,CAAC,IAAa,EAAE,EAAW,EAAE,EAAE;gBAC3C,YAAY,EAAE,CAAA;gBACd,IAAI,SAAS,EAAE,CAAC;oBACf,IAAI,SAAS,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;wBACnC,SAAS,CAAC,KAAK,EAAE,CAAA;wBACjB,SAAS,GAAG,IAAI,CAAA;wBAChB,MAAM,CAAC;4BACN,IAAI,EAAE,MAAM;4BACZ,KAAK,EAAE,QAAQ;4BACf,KAAK,EAAE,CAAC;4BACR,IAAI;4BACJ,OAAO,EAAE,WAAW;yBACpB,CAAC,CAAA;wBACF,MAAM,CAAC,GAAG,EAAE,CACX,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAC3D,CAAA;oBACF,CAAC;oBACD,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;oBAC5B,MAAM,CAAC;wBACN,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,QAAQ;wBACf,KAAK,EAAE,SAAS,CAAC,MAAM;wBACvB,KAAK,EAAE,SAAS;wBAChB,IAAI;wBACJ,OAAO,EAAE,WAAW;qBACpB,CAAC,CAAA;gBACH,CAAC;qBAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;oBAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAC5C,CAAC,CAAA;YACD,MAAM,GAAG,GAAG,GAAG,EAAE;gBAChB,IAAI,SAAS,EAAE,CAAC;oBACf,SAAS,GAAG,IAAI,CAAA;oBAChB,OAAM;gBACP,CAAC;gBACD,IAAI,WAAW;oBAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;qBACnC,IAAI,cAAc,EAAE,CAAC;oBACzB,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;oBACpC,IAAI,MAAM,KAAK,IAAI;wBAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;gBACjD,CAAC;;oBACA,KAAK,CACJ,IAAI,SAAS,CAAC,qBAAqB,EAAE;wBACpC,OAAO,EAAE,gDAAgD;qBACzD,CAAC,CACF,CAAA;YACH,CAAC,CAAA;YAED,uEAAuE;YACvE,oEAAoE;YACpE,8CAA8C;YAC9C,IAAI,MAAM,GAAG,KAAK,CAAA;YAClB,MAAM,KAAK,GAAG,CAAC,GAAG,KAAqB,EAAE,EAAE;gBAC1C,IAAI,MAAM;oBAAE,OAAM;gBAClB,MAAM,GAAG,IAAI,CAAA;gBACb,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAA;gBAChE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;gBACxB,wBAAwB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;gBACrC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;gBAC1C,KAAK,CAAC,MAAM,EAAE,CAAA;gBACd,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;gBAChD,IAAI,EAAE,YAAY,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAA;gBACpD,IAAI,EAAE,YAAY,CAAC,sBAAsB,EAAE,YAAY,CAAC,CAAA;gBACxD,IAAI,EAAE,YAAY,CAAC,sBAAsB,EAAE,YAAY,CAAC,CAAA;gBACxD,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAA;gBAC3B,gBAAgB,CAAC,KAAK,CAAC,qBAAqB,EAAE;oBAC7C,OAAO,EAAE,WAAW;oBACpB,YAAY;oBACZ,YAAY;oBACZ,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;iBAClC,CAAC,CAAA;YACH,CAAC,CAAA;YACD,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,KAAK,EAAE,CAAA;YAC1B,MAAM,KAAK,GAAG,kBAAkB,CAAC,WAAW,EAAE;gBAC7C,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM;gBACvB,IAAI;gBACJ,GAAG;gBACH,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;aAC7B,CAAC,CAAA;YACF,wBAAwB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YAClC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;YACvC,IAAI,MAAM,EAAE,OAAO;gBAAE,KAAK,EAAE,CAAA;YAE5B,IAAI,CAAC;gBACJ,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,qBAAqB,EAAE,YAAY,CAAC,MAAM,CAAC,CAAA;gBACtE,IAAI,SAAS,IAAI,CAAC,MAAM,EAAE,CAAC;oBAC1B,IAAI,CAAC;wBACJ,MAAM,KAAK,GAAG,MAAM,OAAO,CAC1B,SAAS,CAAC,WAAW,CAAC,WAAW,CAAC,EAClC,qBAAqB,EACrB,YAAY,CAAC,MAAM,CACnB,CAAA;wBACD,IAAI,EAAE,YAAY,CAAC,sBAAsB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;wBACxD,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;4BAC3C,IAAI,MAAM;gCAAE,MAAK;4BACjB,IAAI,CAAC;gCACJ,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;gCAClC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;oCACzB,YAAY,EAAE,CAAA;oCACd,QAAQ,CAAC,IAAI,CACZ,MAAM,OAAO,CACZ,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,EACrC,qBAAqB,EACrB,YAAY,CAAC,MAAM,CACnB,CACD,CAAA;gCACF,CAAC;4BACF,CAAC;4BAAC,OAAO,KAAK,EAAE,CAAC;gCAChB,MAAM,CAAC;oCACN,IAAI,EAAE,YAAY;oCAClB,KAAK,EAAE,QAAQ;oCACf,KAAK;oCACL,IAAI;oCACJ,OAAO,EAAE,WAAW;iCACpB,CAAC,CAAA;gCACF,4CAA4C;4BAC7C,CAAC;wBACF,CAAC;wBACD,IAAI,KAAK,CAAC,MAAM,GAAG,SAAS;4BAAE,SAAS,GAAG,IAAI,CAAA;oBAC/C,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBAChB,SAAS,GAAG,IAAI,CAAA;wBAChB,gBAAgB,CAAC,IAAI,CAAC,sBAAsB,EAAE;4BAC7C,OAAO,EAAE,WAAW;4BACpB,GAAG,eAAe,CAAC,KAAK,CAAC;yBACzB,CAAC,CAAA;oBACH,CAAC;gBACF,CAAC;gBACD,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,SAAS,IAAI,EAAE;oBACzC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;wBAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACrC,SAAS,GAAG,IAAI,CAAA;gBAChB,MAAM,CAAC;oBACN,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,QAAQ;oBACf,KAAK,EAAE,CAAC;oBACR,KAAK,EAAE,SAAS;oBAChB,IAAI;oBACJ,OAAO,EAAE,WAAW;iBACpB,CAAC,CAAA;gBACF,IAAI,SAAS,IAAI,CAAC,MAAM;oBAAE,GAAG,EAAE,CAAA;YAChC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,IAAI,CAAC,MAAM,EAAE,CAAC;oBACb,KAAK,CAAC,KAAK,CAAC,CAAA;oBACZ,MAAM,IAAI,SAAS,CAAC,qBAAqB,EAAE;wBAC1C,OAAO,EAAE,kCAAkC;wBAC3C,KAAK,EAAE,KAAK;qBACZ,CAAC,CAAA;gBACH,CAAC;YACF,CAAC;oBAAS,CAAC;gBACV,oBAAoB,EAAE,CAAA;YACvB,CAAC;YAED,KAAK,SAAS,CAAC,CAAC,MAAM;gBACrB,IAAI,CAAC;oBACJ,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAA;gBACvB,CAAC;wBAAS,CAAC;oBACV,KAAK,EAAE,CAAA;gBACR,CAAC;YACF,CAAC;YAED,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAA;QAC1E,CAAC,CAAA;QAED,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,sBAAsB,CAAC;YACvD,GAAG,cAAc;YACjB,cAAc,EAAE,iBAAiB;SACjC,CAAC,CAAA;QAEF,MAAM,IAAI,GAAoB,CAAC,MAAM,EAAE,EAAE;YACxC,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;YACjC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YACtB,KAAK,IAAI,CAAC,IAAI,CACb,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAC/B,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAC/B,CAAA;YACD,OAAO,IAAI,CAAA;QACZ,CAAC,CAAA;QACD,OAAO;YACN,IAAI;YACJ,OAAO;YACP,WAAW;YACX,cAAc;YACd,0BAA0B,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAClD,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC;YAC/B,qBAAqB,EAAE,iBAAiB;SACxC,CAAA;IACF,CAAC;IAED,SAAS,YAAY,CACpB,aAMC;QAED,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,CAAA;QAC9B,MAAM,OAAO,GAAG,aAAa,CAAC,aAAa,CAAC,CAAA;QAE5C,MAAM,EACL,OAAO,EAAE,QAAQ,EACjB,WAAW,EAAE,YAAY,EACzB,WAAW,EACX,QAAQ,EAAE,SAAS,EACnB,MAAM,EAAE,OAAO,EACf,cAAc,EAAE,eAAe,EAC/B,UAAU,EAAE,WAAW,EACvB,WAAW,EAAE,YAAY,EACzB,UAAU,EAAE,WAAW,EACvB,aAAa,EAAE,cAAc,EAC7B,WAAW,EAAE,YAAY,EACzB,YAAY,EAAE,aAAa,EAC3B,cAAc,EAAE,eAAe,EAC/B,aAAa,EAAE,cAAc,EAC7B,GAAG,YAAY,EACf,GAAG,aAAa,CAAA;QACjB,MAAM,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC;YAC5B,GAAG,YAAY;YACf,IAAI;YACJ,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,KAAK;YACb,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,aAAa,CAAC,OAAO,IAAI,gBAAgB,IAAI,EAAE;YACxD,OAAO,EAAE,KAAK,SAAS,CAAC,EAAE,EACzB,KAAK,EACL,OAAO,EACP,MAAM,EAKN;gBACA,KAAK,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAA;YAC/D,CAAC;SACD,CAAC,CAAA;QAEF,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,OAAO,CAAA;QACxD,OAAO;YACN,SAAS;YACT,OAAO;YACP,WAAW;YACX,cAAc;YACd,0BAA0B,EAAE,OAAO,CAAC,0BAA0B;YAC9D,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;SACpD,CAAA;IACF,CAAC;IAED,SAAS,eAAe,CAAC,gBAA2C;QACnE,MAAM,cAAc,GAAG,CAAC,MAAa,EAAE,EAAE,CACxC,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAA;QAC3E,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,sBAAsB,CAAC;YACvD,GAAG,gBAAgB;YACnB,cAAc;SACd,CAAC,CAAA;QACF,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,CAAA;IAChD,CAAC;IAED,OAAO;QACN,aAAa;QACb,QAAQ,EAAE,GAAG,EAAE;YACd,IAAI,eAAe;gBAAE,OAAO,eAAe,CAAA;YAC3C,UAAU,GAAG,IAAI,CAAA;YACjB,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,qBAAqB,CAAC;gBAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YAC/D,KAAK,MAAM,OAAO,IAAI,CAAC,GAAG,wBAAwB,CAAC;gBAAE,MAAM,CAAC,OAAO,CAAC,CAAA;YACpE,eAAe,GAAG,CAAC,KAAK,IAAI,EAAE;gBAC7B,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAA;gBAC3C,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAA;gBAChC,IAAI,OAAO,CAAC,MAAM,EAAE,aAAa;oBAAE,MAAM,SAAS,EAAE,KAAK,EAAE,EAAE,CAAA;YAC9D,CAAC,CAAC,EAAE,CAAA;YACJ,OAAO,eAAe,CAAA;QACvB,CAAC;QACD,YAAY;QACZ,eAAe;QACf,oEAAoE;QACpE,2BAA2B,EAAE,GAAG,EAAE,CAAC,wBAAwB,CAAC,IAAI;QAChE,iEAAiE;QACjE,sBAAsB,EAAE,GAAG,EAAE;YAC5B,MAAM,QAAQ,GAAG,CAAC,GAAG,wBAAwB,CAAC,CAAA;YAC9C,wBAAwB,CAAC,KAAK,EAAE,CAAA;YAChC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAChC,IAAI,CAAC;oBACJ,OAAO,EAAE,CAAA;gBACV,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,4CAA4C;oBAC5C,MAAM,CAAC,IAAI,CAAC,wCAAwC,EAAE;wBACrD,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC;qBAC5B,CAAC,CAAA;gBACH,CAAC;YACF,CAAC;YACD,OAAO,QAAQ,CAAC,MAAM,CAAA;QACvB,CAAC;KACD,CAAA;AACF,CAAC","sourcesContent":["import type { Schema } from '@orpc/contract'\nimport { ORPCError } from '@orpc/server'\nimport type { ZodObject, ZodRawShape, ZodType, z } from 'zod'\nimport type { FnLogger } from '../logger.js'\nimport {\n\terrorAttributes,\n\terrorMessageOf,\n\ttype SpanLike,\n\ttype Tracing\n} from '../otel.js'\nimport type {\n\tGuardOptions,\n\tFnContext,\n\tFnDefinition,\n\tFnProcedure,\n\tFnRouteOptions,\n\tMaybePromise,\n\tProcedureKey,\n\tProcedureOption\n} from '../types.js'\nimport { decodeMessage, encodePayload } from './codec.js'\nimport { LIVE_GAP, positiveInteger, safely, waitFor } from './lifecycle.js'\nimport type {\n\tBacklogOptions,\n\tPubSubMessage,\n\tPubSubTransport\n} from './transport.js'\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Types\n//\n// Publishers pass an event schema's INPUT (`z.input`); subscribers, filters\n// and channel resolvers see its OUTPUT (`z.output`). The raw input travels on\n// the wire and every receiver parses it once.\n// ═══════════════════════════════════════════════════════════════════════════\n\n/** Any Zod object schema, including `.strict()`, `.passthrough()` and `.catchall()`. */\nexport type ObjectSchema = ZodObject<ZodRawShape, z.core.$ZodObjectConfig>\n\n/**\n * A static channel name, or one derived from (partial) subscriber input or\n * event data.\n */\nexport type ChannelDefinition<TInput, TEventData, TContext = unknown> =\n\t| string\n\t| {\n\t\t\tsubscribe: (params: { input: TInput; context: TContext }) => string\n\t\t\tpublish: (event: TEventData) => string\n\t }\n\t| ((\n\t\t\tparams: Partial<TInput> | Partial<TEventData>,\n\t\t\tcontext?: TContext\n\t ) => string)\n\n/** Decides whether one event reaches one subscriber. */\nexport type FilterFn<TInput, TEventData> = (params: {\n\tinput: TInput\n\tdata: TEventData\n}) => MaybePromise<boolean>\n\n/**\n * Checked when a subscription opens, before anything is sent. `true` allows\n * everyone; a function returns false (or throws) to refuse with FORBIDDEN.\n */\nexport type AuthFn<TInput, TContext> =\n\t| ((params: { input: TInput; ctx: TContext }) => MaybePromise<boolean>)\n\t| true\n\nexport type PublisherConfig = {\n\t/** Required name for tracing (e.g. 'chat.messages'). */\n\tname: string\n\t/**\n\t * Store recent events in a backlog list; new subscribers receive it before\n\t * live events. Default: false\n\t */\n\tuseBacklog?: boolean\n\t/** Maximum backlog items to keep (default: 50). */\n\tbacklogSize?: number\n\t/** Backlog TTL in seconds (default: 30). */\n\tbacklogTtl?: number\n\t/**\n\t * Also publish every payload to this channel (with its own backlog when\n\t * `useBacklog`). Subscribers still use `channel`. Equal to the primary\n\t * channel means no duplicate work.\n\t */\n\tmirrorChannel?: string\n\t/**\n\t * Log publish failures (validation or broker) instead of throwing them, so\n\t * a publish after a committed write cannot fail the request. No retry.\n\t */\n\tsafePublish?: boolean\n}\n\n/** Per-definition overrides of the factory queue bounds. */\nexport type ChannelQueueOptions = {\n\tmaxQueueSize?: number\n\tmaxIngressSize?: number\n\tmaxReplaySize?: number\n}\n\n/** Synchronous observational events; failures cannot interrupt delivery. */\nexport type PubSubMetric = { name: string; channel: string } & (\n\t| {\n\t\t\ttype: 'queue'\n\t\t\tstage: 'ingress' | 'replay' | 'delivery'\n\t\t\tdepth: number\n\t\t\tlimit: number\n\t }\n\t| { type: 'drop'; stage: 'ingress' | 'replay' | 'delivery'; count: number }\n\t| { type: 'reconnect' }\n\t| { type: 'parseError'; stage: 'ingress' | 'replay'; error: unknown }\n)\n\nexport type PubSubOptions<\n\tTDef extends FnDefinition,\n\tTInputSchema extends ObjectSchema,\n\tTEventSchema extends ZodType,\n\tTKey extends ProcedureKey<TDef>\n> = PublisherConfig &\n\tChannelQueueOptions & {\n\t\tchannel: ChannelDefinition<\n\t\t\tz.output<TInputSchema>,\n\t\t\tz.output<TEventSchema>,\n\t\t\tFnContext<TDef, TKey>\n\t\t>\n\t\t/** What the subscriber provides. */\n\t\tinputSchema: TInputSchema\n\t\t/** What gets published. */\n\t\teventSchema: TEventSchema\n\t\tfilterFn?: FilterFn<z.output<TInputSchema>, z.output<TEventSchema>>\n\t\tauthFn?: AuthFn<z.output<TInputSchema>, FnContext<TDef, TKey>>\n\t\t/**\n\t\t * When a slow subscriber's queue overflows (drop-oldest), enqueue this\n\t\t * marker INSTEAD of the new event so the subscriber resyncs from its\n\t\t * cursor. A wholly dropped item leaves no per-item gap a consumer could\n\t\t * detect, so the marker is the only reliable live signal of loss. Return\n\t\t * null to skip.\n\t\t */\n\t\toverflowMarker?: (\n\t\t\tinput: z.output<TInputSchema>\n\t\t) => z.output<TEventSchema> | null\n\t\ttags?: TDef['tag'][]\n\t\tsummary?: string\n\t\tdescription?: string\n\t}\n\nexport type PubSub<\n\tTDef extends FnDefinition,\n\tTInputSchema extends ObjectSchema,\n\tTEventSchema extends ZodType,\n\tTKey extends ProcedureKey<TDef>\n> = {\n\tsubscribe: FnProcedure<\n\t\tTDef,\n\t\tTKey,\n\t\tTInputSchema,\n\t\tSchema<\n\t\t\tAsyncGenerator<z.output<TEventSchema>, void, unknown>,\n\t\t\tAsyncGenerator<z.output<TEventSchema>, void, unknown>\n\t\t>\n\t>\n\tpublish: (data: z.input<TEventSchema>) => Promise<void>\n\t/** Publish a batch in one atomic round-trip; items may target different channels. */\n\tpublishMany: (items: readonly z.input<TEventSchema>[]) => Promise<void>\n\tgetSubscriptionChannelName: (params: {\n\t\tinput: z.output<TInputSchema>\n\t\tcontext: FnContext<TDef, TKey>\n\t}) => string\n\tgetPublishChannelName: (event: z.output<TEventSchema>) => string\n\t/** @deprecated Prefer the separate required-input resolver methods. */\n\tgetChannelName: (\n\t\tparams: Partial<z.output<TInputSchema>> | Partial<z.output<TEventSchema>>,\n\t\tcontext?: FnContext<TDef, TKey>\n\t) => string\n}\n\nexport type CreatePubSub<TDef extends FnDefinition> = <\n\tTInputSchema extends ObjectSchema,\n\tTEventSchema extends ZodType,\n\tTKey extends ProcedureKey<TDef> = TDef['default']\n>(\n\toptions: PubSubOptions<TDef, TInputSchema, TEventSchema, NoInfer<TKey>> &\n\t\tGuardOptions<TDef['guards']> &\n\t\tPick<\n\t\t\tFnRouteOptions<TDef, TKey, z.output<TInputSchema>>,\n\t\t\t'meta' | 'guardResolvers'\n\t\t> &\n\t\t/** Which `procedures` builder the subscribe route uses. */ ProcedureOption<\n\t\t\tTDef,\n\t\t\tTKey\n\t\t>\n) => PubSub<TDef, TInputSchema, TEventSchema, TKey>\n\nexport type PublisherOptions<TEventSchema extends ZodType> = PublisherConfig & {\n\t/** Static channel name, or a resolver over (partial) parsed event data. */\n\tchannel: string | ((params: Partial<z.output<TEventSchema>>) => string)\n\teventSchema: TEventSchema\n}\n\nexport type Publisher<TEventSchema extends ZodType> = {\n\tpublish: (data: z.input<TEventSchema>) => Promise<void>\n\tpublishMany: (items: readonly z.input<TEventSchema>[]) => Promise<void>\n\tgetChannelName: (params: Partial<z.output<TEventSchema>>) => string\n}\n\n/**\n * Publish-only counterpart to `createPubSub`, for buses whose subscribe side\n * lives elsewhere (e.g. an `fnLive` route sharing the channel and schema).\n */\nexport type CreatePublisher = <TEventSchema extends ZodType>(\n\toptions: PublisherOptions<TEventSchema>\n) => Publisher<TEventSchema>\n\nexport type PubSubRuntimeOptions = {\n\t/** Queue depths, drops, successful reconnects and parse failures. */\n\tonMetric?: (event: PubSubMetric) => void\n\t/**\n\t * The broker, or a function creating it on first use so importing routes\n\t * opens no connection: `transport: () => bunRedisTransport(getRedis())`.\n\t */\n\ttransport: PubSubTransport | (() => PubSubTransport)\n\t/**\n\t * Called per event dropped from ingress, replay or delivery queues.\n\t * Delivery drops count events before subscriber filtering.\n\t */\n\tonDrop?: (count: number, info: { name: string; channel: string }) => void\n\t/** Per-subscriber queue bound before drop-oldest (default: 1000). */\n\tmaxQueueSize?: number\n\t/** Pending raw messages per channel, before asynchronous parsing. */\n\tmaxIngressSize?: number\n\t/** Buffered live messages during replay. */\n\tmaxReplaySize?: number\n\t/** Broker subscription and backlog wait bound (default 10000ms). */\n\tinitializationTimeoutMs?: number\n\t/** Applied to channels, mirrors and therefore backlog keys. */\n\tnamespace?: string\n\t/** Close this transport only when its ownership is explicitly transferred. */\n\townsTransport?: boolean\n}\n\n/** @internal */\nexport type LiveRuntimeOptions = {\n\tfn: (options: Record<string, unknown>) => import('@orpc/server').AnyProcedure\n\ttracing: Tracing\n\tcreateLogger: (scope: string, span: SpanLike | undefined) => FnLogger\n\tpubsub?: PubSubRuntimeOptions | undefined\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Bounded queue\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Bounded drop-oldest FIFO with \"one overflow marker per overflow episode\"\n * semantics.\n *\n * On the FIRST overflow of an episode the oldest message is dropped and the\n * marker from `createOverflowMarker` is enqueued INSTEAD of the new event - the\n * subscriber's resync-from-cursor recovers the loss. While that marker is still\n * queued, further overflows drop the oldest NON-marker message (the marker\n * itself is never displaced) and enqueue the new event WITHOUT a second marker:\n * the pending marker's resync already covers every drop that happens before it\n * is delivered. Without this dedupe a sustained overflow converges the whole\n * queue to markers - one full snapshot re-run per queued slot. Dequeuing the\n * marker ends the episode; the next overflow starts a fresh one.\n *\n * `createOverflowMarker` absent (or returning null) falls back to plain\n * drop-oldest with the new event enqueued.\n */\nexport function createBoundedEventQueue<T>(opts: {\n\tmaxSize: number\n\tcreateOverflowMarker?: () => T | null\n\t/** Called once per dropped message (metrics/counters). */\n\tonDrop?: () => void\n\tonDepth?: (depth: number) => void\n}) {\n\tpositiveInteger(opts.maxSize, 'maxSize')\n\tconst items: T[] = []\n\t// The queued marker while an overflow episode is open. Created once per\n\t// episode, so identity is the exact \"is this the pending marker?\" test.\n\tlet pendingOverflowMarker: T | null = null\n\n\treturn {\n\t\tget length() {\n\t\t\treturn items.length\n\t\t},\n\t\tenqueue(data: T): void {\n\t\t\ttry {\n\t\t\t\tif (items.length >= opts.maxSize) {\n\t\t\t\t\tif (pendingOverflowMarker !== null) {\n\t\t\t\t\t\t// Episode already signalled: drop the oldest non-marker message\n\t\t\t\t\t\t// and enqueue WITHOUT a second marker.\n\t\t\t\t\t\tconst dropIndex = items[0] === pendingOverflowMarker ? 1 : 0\n\t\t\t\t\t\tif (dropIndex >= items.length) {\n\t\t\t\t\t\t\t// Degenerate maxSize: the queue is just the pending marker, so\n\t\t\t\t\t\t\t// the new event is the drop - the marker's resync covers it.\n\t\t\t\t\t\t\tsafely(opts.onDrop)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\titems.splice(dropIndex, 1)\n\t\t\t\t\t\tsafely(opts.onDrop)\n\t\t\t\t\t\titems.push(data)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\titems.shift()\n\t\t\t\t\tsafely(opts.onDrop)\n\t\t\t\t\tconst marker = opts.createOverflowMarker?.() ?? null\n\t\t\t\t\tif (marker !== null) {\n\t\t\t\t\t\tpendingOverflowMarker = marker\n\t\t\t\t\t\titems.push(marker)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\titems.push(data)\n\t\t\t} finally {\n\t\t\t\tsafely(() => opts.onDepth?.(items.length))\n\t\t\t}\n\t\t},\n\t\tdequeue(): T | undefined {\n\t\t\tconst next = items.shift()\n\t\t\tsafely(() => opts.onDepth?.(items.length))\n\t\t\tif (next !== undefined && next === pendingOverflowMarker) {\n\t\t\t\tpendingOverflowMarker = null\n\t\t\t}\n\t\t\treturn next\n\t\t}\n\t}\n}\n\n/**\n * One subscriber's ordered, bounded delivery. Events wait in a bounded\n * drop-oldest queue (see {@link createBoundedEventQueue}) BEFORE the\n * subscriber's filter runs; the filter runs in order as the consumer reads,\n * so a slow async filter neither reorders events nor lets pending work grow\n * past `maxSize`. Overflow markers skip the filter.\n */\nexport function createSubscriberDelivery<T>(options: {\n\tmaxSize: number\n\taccept?: ((data: T) => MaybePromise<boolean>) | undefined\n\toverflowMarker?: (() => T | null) | undefined\n\tonFilterError: (error: unknown) => void\n\tonDrop: () => void\n\tonDepth?: (depth: number) => void\n}) {\n\ttype Item = { data: T; marker: boolean }\n\tconst queue = createBoundedEventQueue<Item>({\n\t\tmaxSize: options.maxSize,\n\t\tcreateOverflowMarker: () => {\n\t\t\tconst marker = options.overflowMarker?.() ?? null\n\t\t\treturn marker === null ? null : { data: marker, marker: true }\n\t\t},\n\t\tonDrop: options.onDrop,\n\t\t...(options.onDepth ? { onDepth: options.onDepth } : {})\n\t})\n\tlet closed = false\n\tlet failure: unknown\n\tlet wake: (() => void) | null = null\n\tconst notify = () => {\n\t\twake?.()\n\t\twake = null\n\t}\n\n\tasync function* events(): AsyncGenerator<T, void, unknown> {\n\t\twhile (!closed) {\n\t\t\tconst item = queue.dequeue()\n\t\t\tif (!item) {\n\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\twake = resolve\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (!item.marker && options.accept) {\n\t\t\t\ttry {\n\t\t\t\t\tif (!(await options.accept(item.data))) continue\n\t\t\t\t} catch (error) {\n\t\t\t\t\tsafely(() => options.onFilterError(error))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (closed) break\n\t\t\t}\n\t\t\tyield item.data\n\t\t}\n\t\tif (failure !== undefined) throw failure\n\t}\n\n\treturn {\n\t\tpush(data: T, marker = false) {\n\t\t\tif (closed) return\n\t\t\tqueue.enqueue({ data, marker })\n\t\t\tnotify()\n\t\t},\n\t\tevents: events(),\n\t\t/** Stop delivering; a parked read ends at once. */\n\t\tclose(error?: unknown) {\n\t\t\tif (closed) return\n\t\t\tfailure = error\n\t\t\tclosed = true\n\t\t\tsafely(() => options.onDepth?.(0))\n\t\t\tnotify()\n\t\t}\n\t}\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Runtime (internal: the typed surface is what `createFn` returns)\n// ═══════════════════════════════════════════════════════════════════════════\n\nconst DEFAULT_MAX_QUEUE_SIZE = 1000\n\n// Exponential resubscribe backoff with jitter so reconnecting subscribers don't stampede the broker.\nconst RESUBSCRIBE_BASE_DELAY_MS = 1000\nconst RESUBSCRIBE_MAX_DELAY_MS = 30_000\nconst RESUBSCRIBE_MAX_JITTER_MS = 250\n\nfunction getResubscribeDelayMs(attempt: number): number {\n\tconst base = Math.min(\n\t\tRESUBSCRIBE_BASE_DELAY_MS * 2 ** attempt,\n\t\tRESUBSCRIBE_MAX_DELAY_MS\n\t)\n\treturn base + Math.floor(Math.random() * RESUBSCRIBE_MAX_JITTER_MS)\n}\n\ntype Input = Record<string, unknown>\n\ntype LocalSubscriber = {\n\tisActive: () => boolean\n\tpush: (data: unknown, id?: string) => void\n\tgap: () => void\n\tfail: (error: unknown) => void\n}\n\ntype Hub = {\n\tsubscribers: Set<LocalSubscriber>\n\t/** Resolves after a successful broker subscription (or closure). */\n\tready: Promise<void>\n\tclose: () => void\n}\n\n/** An open subscription: registered, authorized and subscribed. */\nexport type LiveSubscription = {\n\t/** Live events, after the backlog replay. Ends when closed or aborted. */\n\tevents: AsyncGenerator<unknown, void, unknown>\n\t/** Release everything; safe to call more than once, and before `events` runs. */\n\tclose: () => void\n\tisClosed: () => boolean\n}\n\n/** @internal Untyped options; `PubSubOptions` is the typed surface. */\nexport type ChannelOptions = PublisherConfig &\n\tChannelQueueOptions & {\n\t\tchannel: ChannelDefinition<Input, unknown>\n\t\teventSchema: ZodType\n\t\tfilterFn?: FilterFn<Input, unknown>\n\t\tauthFn?: AuthFn<Input, unknown>\n\t\toverflowMarker?: (input: Input) => unknown\n\t}\n\n/** @internal */\nexport type Channel = {\n\t/** Authorize and subscribe; resolves once events can be delivered. */\n\topen: (options: {\n\t\tinput: Input\n\t\tcontext: unknown\n\t\tsignal: AbortSignal | undefined\n\t\trecoverGaps?: boolean\n\t}) => Promise<LiveSubscription>\n\tpublish: (data: unknown) => Promise<void>\n\tpublishMany: (items: readonly unknown[]) => Promise<void>\n\tgetChannelName: (params: Input, context?: unknown) => string\n\tgetSubscriptionChannelName: (params: {\n\t\tinput: Input\n\t\tcontext: unknown\n\t}) => string\n\tgetPublishChannelName: (event: Input) => string\n}\n\nconst resolveChannel = (\n\tchannel: ChannelDefinition<Input, unknown>,\n\tparams: Input,\n\tcontext?: unknown,\n\tpublishing = false\n) => {\n\tif (typeof channel === 'string') return channel\n\tif (typeof channel === 'function') return channel(params, context)\n\treturn publishing\n\t\t? channel.publish(params)\n\t\t: channel.subscribe({ input: params, context })\n}\n\n/** @internal */\nexport function createLiveRuntime(options: LiveRuntimeOptions) {\n\tconst { tracing, createLogger } = options\n\tconst logger = createLogger('pubsub', undefined)\n\tlet terminated = false\n\tlet shutdownPromise: Promise<void> | undefined\n\tconst releases = new Set<Promise<void>>()\n\tconst pendingInitialization = new Set<() => void>()\n\tconst pendingOpens = new Set<Promise<LiveSubscription>>()\n\tconst defaultMaxQueue = positiveInteger(\n\t\toptions.pubsub?.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE,\n\t\t'maxQueueSize'\n\t)\n\tconst defaultMaxIngress = positiveInteger(\n\t\toptions.pubsub?.maxIngressSize ?? defaultMaxQueue,\n\t\t'maxIngressSize'\n\t)\n\tconst defaultMaxReplay = positiveInteger(\n\t\toptions.pubsub?.maxReplaySize ?? defaultMaxQueue,\n\t\t'maxReplaySize'\n\t)\n\tconst initializationTimeout = positiveInteger(\n\t\toptions.pubsub?.initializationTimeoutMs ?? 10000,\n\t\t'initializationTimeoutMs'\n\t)\n\tconst metric = (event: PubSubMetric) =>\n\t\tsafely(() => options.pubsub?.onMetric?.(event))\n\tconst namespace = options.pubsub?.namespace\n\tconst qualify = (name: string) => (namespace ? `${namespace}:${name}` : name)\n\tconst assertOpen = () => {\n\t\tif (terminated)\n\t\t\tthrow new ORPCError('SERVICE_UNAVAILABLE', {\n\t\t\t\tmessage: 'Live runtime has shut down'\n\t\t\t})\n\t}\n\tconst releaseTransport = (release: (() => Promise<void>) | null) => {\n\t\tif (!release) return\n\t\tconst task = Promise.resolve(release()).catch((error) => {\n\t\t\tlogger.warn('Failed to release subscription', {\n\t\t\t\terror: errorMessageOf(error)\n\t\t\t})\n\t\t})\n\t\treleases.add(task)\n\t\tvoid task.finally(() => releases.delete(task))\n\t}\n\n\t// Deploy drain: every open subscription registers its close here. On\n\t// SIGTERM the app ends them deliberately instead of letting the socket die\n\t// with the process: the generator returns, oRPC closes the SSE response and\n\t// the client's backoff reconnects to the new deployment.\n\tconst activeSubscriberCleanups = new Set<() => void>()\n\n\tlet transport: PubSubTransport | undefined\n\tconst requireTransport = () => {\n\t\tif (!options.pubsub) {\n\t\t\tthrow new Error(\n\t\t\t\t'orpc-fn: live routes need a transport, pass createFn({ pubsub: { transport } })'\n\t\t\t)\n\t\t}\n\t\tif (transport) return transport\n\t\t// A lazy transport is never created during or after shutdown.\n\t\tassertOpen()\n\t\tconst configured = options.pubsub.transport\n\t\ttransport = typeof configured === 'function' ? configured() : configured\n\t\treturn transport\n\t}\n\n\t/**\n\t * Shared publish pipeline: validate the raw event, resolve the channel from\n\t * the parsed event, then publish the raw event (atomically maintaining the\n\t * backlog when enabled) inside a producer span.\n\t */\n\tfunction createChannelPublisher(\n\t\tconfig: PublisherConfig & {\n\t\t\teventSchema: ZodType\n\t\t\tgetChannelName: (data: Input) => string\n\t\t}\n\t) {\n\t\tconst { name, eventSchema, getChannelName } = config\n\t\tconst mirrorChannel = config.mirrorChannel\n\t\t\t? qualify(config.mirrorChannel)\n\t\t\t: undefined\n\t\tif (config.backlogSize !== undefined)\n\t\t\tpositiveInteger(config.backlogSize, 'backlogSize')\n\t\tif (config.backlogTtl !== undefined)\n\t\t\tpositiveInteger(config.backlogTtl, 'backlogTtl')\n\t\tconst backlog: BacklogOptions | undefined = config.useBacklog\n\t\t\t? { size: config.backlogSize ?? 50, ttlSeconds: config.backlogTtl ?? 30 }\n\t\t\t: undefined\n\n\t\tconst toMessages = async (items: readonly unknown[]) => {\n\t\t\tconst messages: PubSubMessage[] = []\n\t\t\tfor (const item of items) {\n\t\t\t\tconst data = (await eventSchema.parseAsync(item)) as Input\n\t\t\t\tconst channel = getChannelName(data)\n\t\t\t\tconst payload = encodePayload(item)\n\t\t\t\tmessages.push({ channel, payload })\n\t\t\t\tif (mirrorChannel && mirrorChannel !== channel) {\n\t\t\t\t\tmessages.push({ channel: mirrorChannel, payload })\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn messages\n\t\t}\n\n\t\tconst send = (\n\t\t\toperation: 'publish' | 'publishMany',\n\t\t\titems: readonly unknown[]\n\t\t) =>\n\t\t\ttracing.inSpan(`${name}:${operation}`, 'PRODUCER', async (span) => {\n\t\t\t\tassertOpen()\n\t\t\t\tconst startTime = performance.now()\n\t\t\t\ttry {\n\t\t\t\t\tspan?.setAttribute('pubsub.operation', operation)\n\t\t\t\t\tspan?.setAttribute('pubsub.name', name)\n\t\t\t\t\tspan?.setAttribute('pubsub.batch_size', items.length)\n\t\t\t\t\tconst messages = await toMessages(items)\n\t\t\t\t\tconst first = messages[0]\n\t\t\t\t\tif (first) {\n\t\t\t\t\t\tspan?.setAttribute('pubsub.channel', first.channel)\n\t\t\t\t\t\tspan?.setAttribute('pubsub.payload_size', first.payload.length)\n\t\t\t\t\t}\n\t\t\t\t\tawait requireTransport().publish(messages, backlog)\n\t\t\t\t} finally {\n\t\t\t\t\tspan?.setAttribute(\n\t\t\t\t\t\t'pubsub.duration_ms',\n\t\t\t\t\t\tperformance.now() - startTime\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t})\n\n\t\tconst guarded = async (\n\t\t\toperation: 'publish' | 'publishMany',\n\t\t\titems: readonly unknown[]\n\t\t) => {\n\t\t\tif (!config.safePublish) return send(operation, items)\n\t\t\ttry {\n\t\t\t\tawait send(operation, items)\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error('pubsub.publish_failed', {\n\t\t\t\t\tname,\n\t\t\t\t\t...errorAttributes(error)\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tpublish: (data: unknown) => guarded('publish', [data]),\n\t\t\tpublishMany: async (items: readonly unknown[]) => {\n\t\t\t\tif (items.length > 0) await guarded('publishMany', items)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Hubs for one pub/sub definition, keyed by channel. Many subscribers can\n\t * share a channel (an org with many open tabs); one hub decodes and parses\n\t * each payload once and fans the event out to every local subscriber,\n\t * applying each subscriber's own filter. The hub also owns the broker\n\t * subscription and its resubscribe backoff.\n\t */\n\tfunction createChannelHubs(config: {\n\t\teventSchema: ZodType\n\t\tname: string\n\t\tmaxIngress: number\n\t}) {\n\t\tconst { eventSchema } = config\n\t\tconst hubs = new Map<string, Hub>()\n\n\t\tconst createHub = (channel: string): Hub => {\n\t\t\tconst subscribers = new Set<LocalSubscriber>()\n\t\t\tlet closed = false\n\t\t\tlet unsubscribe: (() => Promise<void>) | null = null\n\t\t\tlet attempt = 0\n\t\t\tlet timer: ReturnType<typeof setTimeout> | null = null\n\t\t\tlet markReady = () => {}\n\t\t\tlet connectedOnce = false\n\t\t\tlet connected = false\n\t\t\tlet ready: Promise<void>\n\t\t\tconst markPending = () => {\n\t\t\t\tready = new Promise<void>((resolve) => {\n\t\t\t\t\tmarkReady = resolve\n\t\t\t\t})\n\t\t\t}\n\t\t\tmarkPending()\n\n\t\t\tlet parsing = false\n\t\t\tconst ingress = createBoundedEventQueue<string>({\n\t\t\t\tmaxSize: config.maxIngress,\n\t\t\t\tonDepth: (depth) =>\n\t\t\t\t\tmetric({\n\t\t\t\t\t\ttype: 'queue',\n\t\t\t\t\t\tstage: 'ingress',\n\t\t\t\t\t\tdepth,\n\t\t\t\t\t\tlimit: config.maxIngress,\n\t\t\t\t\t\tname: config.name,\n\t\t\t\t\t\tchannel\n\t\t\t\t\t}),\n\t\t\t\tonDrop: () => {\n\t\t\t\t\tmetric({\n\t\t\t\t\t\ttype: 'drop',\n\t\t\t\t\t\tstage: 'ingress',\n\t\t\t\t\t\tcount: 1,\n\t\t\t\t\t\tname: config.name,\n\t\t\t\t\t\tchannel\n\t\t\t\t\t})\n\t\t\t\t\tsafely(() =>\n\t\t\t\t\t\toptions.pubsub?.onDrop?.(1, { name: config.name, channel })\n\t\t\t\t\t)\n\t\t\t\t\tfor (const sub of [...subscribers]) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tsub.gap()\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tsafely(() => sub.fail(error))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t\tconst parsePending = async () => {\n\t\t\t\tif (parsing) return\n\t\t\t\tparsing = true\n\t\t\t\ttry {\n\t\t\t\t\twhile (!closed) {\n\t\t\t\t\t\tconst raw = ingress.dequeue()\n\t\t\t\t\t\tif (raw === undefined) break\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst message = decodeMessage(raw)\n\t\t\t\t\t\t\tconst parsed = await eventSchema.parseAsync(message.value)\n\t\t\t\t\t\t\tif (closed) break\n\t\t\t\t\t\t\tfor (const sub of [...subscribers])\n\t\t\t\t\t\t\t\tif (sub.isActive()) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tsub.push(parsed, message.id)\n\t\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\t\tsafely(() => sub.fail(error))\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tmetric({\n\t\t\t\t\t\t\t\ttype: 'parseError',\n\t\t\t\t\t\t\t\tstage: 'ingress',\n\t\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\t\tname: config.name,\n\t\t\t\t\t\t\t\tchannel\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tlogger.warn('pubsub.message_dropped', {\n\t\t\t\t\t\t\t\tchannel,\n\t\t\t\t\t\t\t\t...errorAttributes(error)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} finally {\n\t\t\t\t\tparsing = false\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst release = releaseTransport\n\n\t\t\tconst scheduleResubscribe = (reason: string) => {\n\t\t\t\tif (closed || timer) return\n\t\t\t\tconst delayMs = getResubscribeDelayMs(attempt)\n\t\t\t\tattempt++\n\t\t\t\tlogger.warn('pubsub.resubscribe_scheduled', {\n\t\t\t\t\tchannel,\n\t\t\t\t\treason,\n\t\t\t\t\tattempt,\n\t\t\t\t\tdelayMs\n\t\t\t\t})\n\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\ttimer = null\n\t\t\t\t\tif (closed) return\n\t\t\t\t\trelease(unsubscribe)\n\t\t\t\t\tunsubscribe = null\n\t\t\t\t\tvoid connect()\n\t\t\t\t}, delayMs)\n\t\t\t}\n\n\t\t\tconst connect = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst next = await requireTransport().subscribe(\n\t\t\t\t\t\tchannel,\n\t\t\t\t\t\t(raw) => {\n\t\t\t\t\t\t\tif (closed) return\n\t\t\t\t\t\t\tingress.enqueue(raw)\n\t\t\t\t\t\t\tvoid parsePending()\n\t\t\t\t\t\t},\n\t\t\t\t\t\t(error) => {\n\t\t\t\t\t\t\tif (connected) {\n\t\t\t\t\t\t\t\tconnected = false\n\t\t\t\t\t\t\t\tmarkPending()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlogger.error('pubsub.subscription_lost', {\n\t\t\t\t\t\t\t\tchannel,\n\t\t\t\t\t\t\t\t...errorAttributes(error)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tscheduleResubscribe('lost')\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tonReconnect: () => {\n\t\t\t\t\t\t\t\tif (closed) return\n\t\t\t\t\t\t\t\tmetric({ type: 'reconnect', name: config.name, channel })\n\t\t\t\t\t\t\t\tfor (const sub of [...subscribers]) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tsub.gap()\n\t\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\t\tsafely(() => sub.fail(error))\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\tif (closed) return release(next)\n\t\t\t\t\tunsubscribe = next\n\t\t\t\t\tconnected = true\n\t\t\t\t\tif (connectedOnce) {\n\t\t\t\t\t\tmetric({ type: 'reconnect', name: config.name, channel })\n\t\t\t\t\t\tfor (const sub of [...subscribers]) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tsub.gap()\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tsafely(() => sub.fail(error))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconnectedOnce = true\n\t\t\t\t\tmarkReady()\n\t\t\t\t\tattempt = 0\n\t\t\t\t\tlogger.debug('pubsub.subscribed', { channel })\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger.error('pubsub.subscribe_failed', {\n\t\t\t\t\t\tchannel,\n\t\t\t\t\t\t...errorAttributes(error)\n\t\t\t\t\t})\n\t\t\t\t\tscheduleResubscribe('subscribe-failed')\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid connect()\n\n\t\t\treturn {\n\t\t\t\tsubscribers,\n\t\t\t\tget ready() {\n\t\t\t\t\treturn ready\n\t\t\t\t},\n\t\t\t\tclose: () => {\n\t\t\t\t\tclosed = true\n\t\t\t\t\tmetric({\n\t\t\t\t\t\ttype: 'queue',\n\t\t\t\t\t\tstage: 'ingress',\n\t\t\t\t\t\tdepth: 0,\n\t\t\t\t\t\tlimit: config.maxIngress,\n\t\t\t\t\t\tname: config.name,\n\t\t\t\t\t\tchannel\n\t\t\t\t\t})\n\t\t\t\t\tif (timer) clearTimeout(timer)\n\t\t\t\t\ttimer = null\n\t\t\t\t\tmarkReady()\n\t\t\t\t\trelease(unsubscribe)\n\t\t\t\t\tunsubscribe = null\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn function addLocalSubscriber(\n\t\t\tchannel: string,\n\t\t\tsubscriber: LocalSubscriber\n\t\t) {\n\t\t\tlet hub = hubs.get(channel)\n\t\t\tif (!hub) {\n\t\t\t\thub = createHub(channel)\n\t\t\t\thubs.set(channel, hub)\n\t\t\t}\n\t\t\thub.subscribers.add(subscriber)\n\t\t\tconst current = hub\n\t\t\treturn {\n\t\t\t\tready: current.ready,\n\t\t\t\tremove: () => {\n\t\t\t\t\tcurrent.subscribers.delete(subscriber)\n\t\t\t\t\tif (current.subscribers.size === 0 && hubs.get(channel) === current) {\n\t\t\t\t\t\tcurrent.close()\n\t\t\t\t\t\thubs.delete(channel)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Publish and open subscriptions on one channel definition. */\n\tfunction createChannel(channelOptions: ChannelOptions): Channel {\n\t\tconst {\n\t\t\tname,\n\t\t\tchannel,\n\t\t\teventSchema,\n\t\t\tfilterFn,\n\t\t\tauthFn,\n\t\t\toverflowMarker,\n\t\t\tuseBacklog = false\n\t\t} = channelOptions\n\n\t\tconst getChannelName = (params: Input, context?: unknown) =>\n\t\t\tqualify(resolveChannel(channel, params, context))\n\t\tconst getPublishChannel = (params: Input) =>\n\t\t\tqualify(resolveChannel(channel, params, undefined, true))\n\t\tconst maxQueue = positiveInteger(\n\t\t\tchannelOptions.maxQueueSize ?? defaultMaxQueue,\n\t\t\t'maxQueueSize'\n\t\t)\n\t\tconst maxIngress = positiveInteger(\n\t\t\tchannelOptions.maxIngressSize ?? defaultMaxIngress,\n\t\t\t'maxIngressSize'\n\t\t)\n\t\tconst maxReplay = positiveInteger(\n\t\t\tchannelOptions.maxReplaySize ?? defaultMaxReplay,\n\t\t\t'maxReplaySize'\n\t\t)\n\t\tconst addLocalSubscriber = createChannelHubs({\n\t\t\teventSchema,\n\t\t\tname,\n\t\t\tmaxIngress\n\t\t})\n\n\t\tconst openInternal: Channel['open'] = async ({\n\t\t\tinput,\n\t\t\tcontext,\n\t\t\tsignal,\n\t\t\trecoverGaps = false\n\t\t}) => {\n\t\t\tassertOpen()\n\t\t\tsignal?.throwIfAborted()\n\t\t\tconst initializing = new AbortController()\n\t\t\tconst transport = requireTransport()\n\t\t\tconst channelName = getChannelName(input, context)\n\t\t\tconst startTime = performance.now()\n\t\t\tconst span = tracing.startSpan(`${name}:subscribe`, 'SERVER', {\n\t\t\t\t'pubsub.channel': channelName,\n\t\t\t\t'pubsub.operation': 'subscribe',\n\t\t\t\t'pubsub.name': name\n\t\t\t})\n\t\t\tconst subscriberLogger = createLogger('pubsub', span)\n\t\t\tconst cancelInitialization = () =>\n\t\t\t\tinitializing.abort(\n\t\t\t\t\tsignal?.reason ?? new Error('Subscription initialization stopped')\n\t\t\t\t)\n\t\t\tpendingInitialization.add(cancelInitialization)\n\t\t\tsignal?.addEventListener('abort', cancelInitialization, { once: true })\n\t\t\tconst finishInitialization = () => {\n\t\t\t\tpendingInitialization.delete(cancelInitialization)\n\t\t\t\tsignal?.removeEventListener('abort', cancelInitialization)\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tif (\n\t\t\t\t\tauthFn !== undefined &&\n\t\t\t\t\tauthFn !== true &&\n\t\t\t\t\t!(await waitFor(\n\t\t\t\t\t\tPromise.resolve(authFn({ input, ctx: context })),\n\t\t\t\t\t\tinitializationTimeout,\n\t\t\t\t\t\tinitializing.signal\n\t\t\t\t\t))\n\t\t\t\t) {\n\t\t\t\t\tthrow new ORPCError('FORBIDDEN', {\n\t\t\t\t\t\tmessage: 'You do not have access to this subscription'\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tfinishInitialization()\n\t\t\t\ttracing.end(span, error)\n\t\t\t\tthrow error\n\t\t\t}\n\n\t\t\tsubscriberLogger.debug('pubsub.subscribing', { channel: channelName })\n\n\t\t\tlet messageCount = 0\n\t\t\tlet droppedCount = 0\n\t\t\tconst delivery = createSubscriberDelivery<unknown>({\n\t\t\t\tmaxSize: maxQueue,\n\t\t\t\tonDepth: (depth) =>\n\t\t\t\t\tmetric({\n\t\t\t\t\t\ttype: 'queue',\n\t\t\t\t\t\tstage: 'delivery',\n\t\t\t\t\t\tdepth,\n\t\t\t\t\t\tlimit: maxQueue,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tchannel: channelName\n\t\t\t\t\t}),\n\t\t\t\taccept:\n\t\t\t\t\tfilterFn &&\n\t\t\t\t\t((data) => (data === LIVE_GAP ? true : filterFn({ input, data }))),\n\t\t\t\toverflowMarker: recoverGaps\n\t\t\t\t\t? () => LIVE_GAP\n\t\t\t\t\t: overflowMarker && (() => overflowMarker(input)),\n\t\t\t\tonFilterError: (error) =>\n\t\t\t\t\tsubscriberLogger.error('Error processing message', {\n\t\t\t\t\t\terror: errorMessageOf(error)\n\t\t\t\t\t}),\n\t\t\t\tonDrop: () => {\n\t\t\t\t\tdroppedCount++\n\t\t\t\t\tmetric({\n\t\t\t\t\t\ttype: 'drop',\n\t\t\t\t\t\tstage: 'delivery',\n\t\t\t\t\t\tcount: 1,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tchannel: channelName\n\t\t\t\t\t})\n\t\t\t\t\tsafely(() =>\n\t\t\t\t\t\toptions.pubsub?.onDrop?.(1, { name, channel: channelName })\n\t\t\t\t\t)\n\t\t\t\t\tif (!recoverGaps && !overflowMarker)\n\t\t\t\t\t\tqueueMicrotask(() =>\n\t\t\t\t\t\t\tclose(\n\t\t\t\t\t\t\t\tnew ORPCError('SERVICE_UNAVAILABLE', {\n\t\t\t\t\t\t\t\t\tmessage: 'Subscription queue overflow; reconnect and resync'\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tlet replaying: Array<{ data: unknown; id: string | undefined }> | null =\n\t\t\t\tuseBacklog ? [] : null\n\t\t\tlet replayGap = false\n\t\t\tconst seen = new Set<string>()\n\t\t\tconst dedupe = (id: string | undefined) => {\n\t\t\t\tif (!id) return false\n\t\t\t\tif (seen.has(id)) return true\n\t\t\t\tseen.add(id)\n\t\t\t\tif (\n\t\t\t\t\tseen.size >\n\t\t\t\t\tMath.max(maxReplay, maxQueue, channelOptions.backlogSize ?? 50) * 2\n\t\t\t\t)\n\t\t\t\t\tseen.delete(seen.values().next().value as string)\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst push = (data: unknown, id?: string) => {\n\t\t\t\tmessageCount++\n\t\t\t\tif (replaying) {\n\t\t\t\t\tif (replaying.length >= maxReplay) {\n\t\t\t\t\t\treplaying.shift()\n\t\t\t\t\t\treplayGap = true\n\t\t\t\t\t\tmetric({\n\t\t\t\t\t\t\ttype: 'drop',\n\t\t\t\t\t\t\tstage: 'replay',\n\t\t\t\t\t\t\tcount: 1,\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\tchannel: channelName\n\t\t\t\t\t\t})\n\t\t\t\t\t\tsafely(() =>\n\t\t\t\t\t\t\toptions.pubsub?.onDrop?.(1, { name, channel: channelName })\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\treplaying.push({ data, id })\n\t\t\t\t\tmetric({\n\t\t\t\t\t\ttype: 'queue',\n\t\t\t\t\t\tstage: 'replay',\n\t\t\t\t\t\tdepth: replaying.length,\n\t\t\t\t\t\tlimit: maxReplay,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tchannel: channelName\n\t\t\t\t\t})\n\t\t\t\t} else if (!dedupe(id)) delivery.push(data)\n\t\t\t}\n\t\t\tconst gap = () => {\n\t\t\t\tif (replaying) {\n\t\t\t\t\treplayGap = true\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (recoverGaps) delivery.push(LIVE_GAP)\n\t\t\t\telse if (overflowMarker) {\n\t\t\t\t\tconst marker = overflowMarker(input)\n\t\t\t\t\tif (marker !== null) delivery.push(marker, true)\n\t\t\t\t} else\n\t\t\t\t\tclose(\n\t\t\t\t\t\tnew ORPCError('SERVICE_UNAVAILABLE', {\n\t\t\t\t\t\t\tmessage: 'Subscription lost events; reconnect and resync'\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t}\n\n\t\t\t// The one way a subscription ends, whatever ends it: abort, drain, the\n\t\t\t// stream finishing, or `close()`. Releases everything at once, even\n\t\t\t// while the stream is parked or not yet read.\n\t\t\tlet closed = false\n\t\t\tconst close = (...error: [] | [unknown]) => {\n\t\t\t\tif (closed) return\n\t\t\t\tclosed = true\n\t\t\t\tinitializing.abort(error[0] ?? new Error('Subscription closed'))\n\t\t\t\tdelivery.close(error[0])\n\t\t\t\tactiveSubscriberCleanups.delete(stop)\n\t\t\t\tsignal?.removeEventListener('abort', stop)\n\t\t\t\tlocal.remove()\n\t\t\t\tconst durationMs = performance.now() - startTime\n\t\t\t\tspan?.setAttribute('pubsub.duration_ms', durationMs)\n\t\t\t\tspan?.setAttribute('pubsub.message_count', messageCount)\n\t\t\t\tspan?.setAttribute('pubsub.dropped_count', droppedCount)\n\t\t\t\ttracing.end(span, ...error)\n\t\t\t\tsubscriberLogger.debug('pubsub.unsubscribed', {\n\t\t\t\t\tchannel: channelName,\n\t\t\t\t\tmessageCount,\n\t\t\t\t\tdroppedCount,\n\t\t\t\t\tdurationMs: Math.round(durationMs)\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst stop = () => close()\n\t\t\tconst local = addLocalSubscriber(channelName, {\n\t\t\t\tisActive: () => !closed,\n\t\t\t\tpush,\n\t\t\t\tgap,\n\t\t\t\tfail: (error) => close(error)\n\t\t\t})\n\t\t\tactiveSubscriberCleanups.add(stop)\n\t\t\tsignal?.addEventListener('abort', stop)\n\t\t\tif (signal?.aborted) close()\n\n\t\t\ttry {\n\t\t\t\tawait waitFor(local.ready, initializationTimeout, initializing.signal)\n\t\t\t\tif (replaying && !closed) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst items = await waitFor(\n\t\t\t\t\t\t\ttransport.readBacklog(channelName),\n\t\t\t\t\t\t\tinitializationTimeout,\n\t\t\t\t\t\t\tinitializing.signal\n\t\t\t\t\t\t)\n\t\t\t\t\t\tspan?.setAttribute('pubsub.backlog_count', items.length)\n\t\t\t\t\t\tfor (const raw of items.slice(-maxReplay)) {\n\t\t\t\t\t\t\tif (closed) break\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst message = decodeMessage(raw)\n\t\t\t\t\t\t\t\tif (!dedupe(message.id)) {\n\t\t\t\t\t\t\t\t\tmessageCount++\n\t\t\t\t\t\t\t\t\tdelivery.push(\n\t\t\t\t\t\t\t\t\t\tawait waitFor(\n\t\t\t\t\t\t\t\t\t\t\teventSchema.parseAsync(message.value),\n\t\t\t\t\t\t\t\t\t\t\tinitializationTimeout,\n\t\t\t\t\t\t\t\t\t\t\tinitializing.signal\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tmetric({\n\t\t\t\t\t\t\t\t\ttype: 'parseError',\n\t\t\t\t\t\t\t\t\tstage: 'replay',\n\t\t\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\t\tchannel: channelName\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t/* Malformed backlog entries are skipped. */\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (items.length > maxReplay) replayGap = true\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treplayGap = true\n\t\t\t\t\t\tsubscriberLogger.warn('pubsub.replay_failed', {\n\t\t\t\t\t\t\tchannel: channelName,\n\t\t\t\t\t\t\t...errorAttributes(error)\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (const { data, id } of replaying ?? [])\n\t\t\t\t\tif (!dedupe(id)) delivery.push(data)\n\t\t\t\treplaying = null\n\t\t\t\tmetric({\n\t\t\t\t\ttype: 'queue',\n\t\t\t\t\tstage: 'replay',\n\t\t\t\t\tdepth: 0,\n\t\t\t\t\tlimit: maxReplay,\n\t\t\t\t\tname,\n\t\t\t\t\tchannel: channelName\n\t\t\t\t})\n\t\t\t\tif (replayGap && !closed) gap()\n\t\t\t} catch (error) {\n\t\t\t\tif (!closed) {\n\t\t\t\t\tclose(error)\n\t\t\t\t\tthrow new ORPCError('SERVICE_UNAVAILABLE', {\n\t\t\t\t\t\tmessage: 'Unable to establish subscription',\n\t\t\t\t\t\tcause: error\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tfinishInitialization()\n\t\t\t}\n\n\t\t\tasync function* events() {\n\t\t\t\ttry {\n\t\t\t\t\tyield* delivery.events\n\t\t\t\t} finally {\n\t\t\t\t\tclose()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { events: events(), close: () => close(), isClosed: () => closed }\n\t\t}\n\n\t\tconst { publish, publishMany } = createChannelPublisher({\n\t\t\t...channelOptions,\n\t\t\tgetChannelName: getPublishChannel\n\t\t})\n\n\t\tconst open: Channel['open'] = (params) => {\n\t\t\tconst task = openInternal(params)\n\t\t\tpendingOpens.add(task)\n\t\t\tvoid task.then(\n\t\t\t\t() => pendingOpens.delete(task),\n\t\t\t\t() => pendingOpens.delete(task)\n\t\t\t)\n\t\t\treturn task\n\t\t}\n\t\treturn {\n\t\t\topen,\n\t\t\tpublish,\n\t\t\tpublishMany,\n\t\t\tgetChannelName,\n\t\t\tgetSubscriptionChannelName: ({ input, context }) =>\n\t\t\t\tgetChannelName(input, context),\n\t\t\tgetPublishChannelName: getPublishChannel\n\t\t}\n\t}\n\n\tfunction createPubSub(\n\t\tpubsubOptions: ChannelOptions & {\n\t\t\tinputSchema: ZodType\n\t\t\tprocedure?: string\n\t\t\ttags?: string[]\n\t\t\tsummary?: string\n\t\t\tdescription?: string\n\t\t}\n\t) {\n\t\tconst { name } = pubsubOptions\n\t\tconst channel = createChannel(pubsubOptions)\n\n\t\tconst {\n\t\t\tchannel: _channel,\n\t\t\teventSchema: _eventSchema,\n\t\t\tinputSchema,\n\t\t\tfilterFn: _filterFn,\n\t\t\tauthFn: _authFn,\n\t\t\toverflowMarker: _overflowMarker,\n\t\t\tuseBacklog: _useBacklog,\n\t\t\tbacklogSize: _backlogSize,\n\t\t\tbacklogTtl: _backlogTtl,\n\t\t\tmirrorChannel: _mirrorChannel,\n\t\t\tsafePublish: _safePublish,\n\t\t\tmaxQueueSize: _maxQueueSize,\n\t\t\tmaxIngressSize: _maxIngressSize,\n\t\t\tmaxReplaySize: _maxReplaySize,\n\t\t\t...routeOptions\n\t\t} = pubsubOptions\n\t\tconst subscribe = options.fn({\n\t\t\t...routeOptions,\n\t\t\tname,\n\t\t\tstream: true,\n\t\t\tmethod: 'GET',\n\t\t\tinput: inputSchema,\n\t\t\tsummary: pubsubOptions.summary ?? `Subscribe to ${name}`,\n\t\t\thandler: async function* ({\n\t\t\t\tinput,\n\t\t\t\tcontext,\n\t\t\t\tsignal\n\t\t\t}: {\n\t\t\t\tinput: Input\n\t\t\t\tcontext: unknown\n\t\t\t\tsignal: AbortSignal | undefined\n\t\t\t}) {\n\t\t\t\tyield* (await channel.open({ input, context, signal })).events\n\t\t\t}\n\t\t})\n\n\t\tconst { publish, publishMany, getChannelName } = channel\n\t\treturn {\n\t\t\tsubscribe,\n\t\t\tpublish,\n\t\t\tpublishMany,\n\t\t\tgetChannelName,\n\t\t\tgetSubscriptionChannelName: channel.getSubscriptionChannelName,\n\t\t\tgetPublishChannelName: channel.getPublishChannelName\n\t\t}\n\t}\n\n\tfunction createPublisher(publisherOptions: PublisherOptions<ZodType>) {\n\t\tconst getChannelName = (params: Input) =>\n\t\t\tqualify(resolveChannel(publisherOptions.channel, params, undefined, true))\n\t\tconst { publish, publishMany } = createChannelPublisher({\n\t\t\t...publisherOptions,\n\t\t\tgetChannelName\n\t\t})\n\t\treturn { publish, publishMany, getChannelName }\n\t}\n\n\treturn {\n\t\tcreateChannel,\n\t\tshutdown: () => {\n\t\t\tif (shutdownPromise) return shutdownPromise\n\t\t\tterminated = true\n\t\t\tfor (const cancel of [...pendingInitialization]) safely(cancel)\n\t\t\tfor (const cleanup of [...activeSubscriberCleanups]) safely(cleanup)\n\t\t\tshutdownPromise = (async () => {\n\t\t\t\tawait Promise.allSettled([...pendingOpens])\n\t\t\t\tawait Promise.all([...releases])\n\t\t\t\tif (options.pubsub?.ownsTransport) await transport?.close?.()\n\t\t\t})()\n\t\t\treturn shutdownPromise\n\t\t},\n\t\tcreatePubSub,\n\t\tcreatePublisher,\n\t\t/** Open subscriptions of this instance (drain progress, gauges). */\n\t\tactivePubSubSubscriberCount: () => activeSubscriberCleanups.size,\n\t\t/** End every open subscription; returns how many were closed. */\n\t\tdrainPubSubSubscribers: () => {\n\t\t\tconst cleanups = [...activeSubscriberCleanups]\n\t\t\tactiveSubscriberCleanups.clear()\n\t\t\tfor (const cleanup of cleanups) {\n\t\t\t\ttry {\n\t\t\t\t\tcleanup()\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// A failed cleanup must not stop the drain.\n\t\t\t\t\tlogger.warn('Subscriber cleanup failed during drain', {\n\t\t\t\t\t\terror: errorMessageOf(error)\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn cleanups.length\n\t\t}\n\t}\n}\n"]}
|
package/dist/live/redis-bun.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export interface BunRedisClientLike {
|
|
|
6
6
|
unsubscribe(channel: string, listener?: Listener): Promise<unknown>;
|
|
7
7
|
duplicate(): Promise<BunRedisClientLike>;
|
|
8
8
|
close(): void;
|
|
9
|
+
/** Bun's `RedisClient.connected`; read by `stats()` when present. */
|
|
10
|
+
readonly connected?: boolean;
|
|
9
11
|
onconnect: ((this: never) => void) | null;
|
|
10
12
|
onclose: ((this: never, error: Error) => void) | null;
|
|
11
13
|
}
|
|
@@ -21,6 +23,7 @@ export declare function bunRedisTransport(client: BunRedisClientLike, options?:
|
|
|
21
23
|
subscriber?: BunRedisClientLike;
|
|
22
24
|
}): import("./transport.js").PubSubTransport & {
|
|
23
25
|
close(): Promise<void>;
|
|
26
|
+
stats(): import("./transport.js").PubSubTransportStats;
|
|
24
27
|
};
|
|
25
28
|
export {};
|
|
26
29
|
//# sourceMappingURL=redis-bun.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-bun.d.ts","sourceRoot":"","sources":["../../src/live/redis-bun.ts"],"names":[],"mappings":"AAEA,KAAK,QAAQ,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;AAE1D,2DAA2D;AAC3D,MAAM,WAAW,kBAAkB;IAClC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACvD,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAChE,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACnE,SAAS,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACxC,KAAK,IAAI,IAAI,CAAA;IACb,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAA;IACzC,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAA;CACrD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,kBAAkB,CAAA;CAAO
|
|
1
|
+
{"version":3,"file":"redis-bun.d.ts","sourceRoot":"","sources":["../../src/live/redis-bun.ts"],"names":[],"mappings":"AAEA,KAAK,QAAQ,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;AAE1D,2DAA2D;AAC3D,MAAM,WAAW,kBAAkB;IAClC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACvD,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAChE,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACnE,SAAS,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACxC,KAAK,IAAI,IAAI,CAAA;IACb,qEAAqE;IACrE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAA;IACzC,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAA;CACrD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,kBAAkB,CAAA;CAAO;;;EAqDjD"}
|
package/dist/live/redis-bun.js
CHANGED
|
@@ -39,6 +39,7 @@ export function bunRedisTransport(client, options = {}) {
|
|
|
39
39
|
ours.delete(channel);
|
|
40
40
|
return subscriber.unsubscribe(channel, dispatch);
|
|
41
41
|
},
|
|
42
|
+
connected: () => subscriber.connected !== false,
|
|
42
43
|
close() {
|
|
43
44
|
// No-ops, not null: Bun calls `onclose` without checking it.
|
|
44
45
|
subscriber.onconnect = () => { };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-bun.js","sourceRoot":"","sources":["../../src/live/redis-bun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"redis-bun.js","sourceRoot":"","sources":["../../src/live/redis-bun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAiBjD;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAChC,MAA0B,EAC1B,OAAO,GAAwC,EAAE;IAEjD,OAAO,oBAAoB,CAAC;QAC3B,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC;QACnD,KAAK,CAAC,iBAAiB,CAAC,QAAQ;YAC/B,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,UAAU,CAAA;YACjC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;YACnE,MAAM,QAAQ,GAAa,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAC/C,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YACrC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;YAC9B,wEAAwE;YACxE,2DAA2D;YAC3D,UAAU,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAA;YACnD,mEAAmE;YACnE,sBAAsB;YACtB,UAAU,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE,CAC9B,QAAQ,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAA;YAC/D,OAAO;gBACN,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;oBACtB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;oBACjB,OAAO,UAAU,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;gBAC/C,CAAC;gBACD,sEAAsE;gBACtE,kEAAkE;gBAClE,gDAAgD;gBAChD,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;oBAC9B,MAAM,OAAO,CAAC,OAAO,EAAE;yBACrB,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;yBAC3C,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;oBACjB,OAAO,UAAU,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;gBAC/C,CAAC;gBACD,WAAW,EAAE,CAAC,OAAO,EAAE,EAAE;oBACxB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;oBACpB,OAAO,UAAU,CAAC,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;gBACjD,CAAC;gBACD,SAAS,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,KAAK,KAAK;gBAC/C,KAAK;oBACJ,6DAA6D;oBAC7D,UAAU,CAAC,SAAS,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;oBAC/B,UAAU,CAAC,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;oBAC7B,IAAI,KAAK;wBAAE,OAAO,UAAU,CAAC,KAAK,EAAE,CAAA;oBACpC,yEAAyE;oBACzE,OAAO,OAAO,CAAC,GAAG,CACjB,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACzB,OAAO,CAAC,OAAO,EAAE;yBACf,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;yBACrD,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CACjB,CACD,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;gBACjB,CAAC;aACD,CAAA;QACF,CAAC;KACD,CAAC,CAAA;AACH,CAAC","sourcesContent":["import { createRedisTransport } from './redis.js'\n\ntype Listener = (message: string, channel: string) => void\n\n/** The part of Bun's `RedisClient` this transport uses. */\nexport interface BunRedisClientLike {\n\tsend(command: string, args: string[]): Promise<unknown>\n\tsubscribe(channel: string, listener: Listener): Promise<unknown>\n\tunsubscribe(channel: string, listener?: Listener): Promise<unknown>\n\tduplicate(): Promise<BunRedisClientLike>\n\tclose(): void\n\t/** Bun's `RedisClient.connected`; read by `stats()` when present. */\n\treadonly connected?: boolean\n\tonconnect: ((this: never) => void) | null\n\tonclose: ((this: never, error: Error) => void) | null\n}\n\n/**\n * `PubSubTransport` for Bun's built-in `RedisClient`. Subscriptions use a\n * dedicated connection (`client.duplicate()` unless `subscriber` is given)\n * that re-subscribes its channels after every reconnect; configure retries on\n * the client (`maxRetries`) since the duplicate copies its options.\n *\n * Call `close()` on shutdown to close the subscriber connection it created.\n */\nexport function bunRedisTransport(\n\tclient: BunRedisClientLike,\n\toptions: { subscriber?: BunRedisClientLike } = {}\n) {\n\treturn createRedisTransport({\n\t\tsend: (command, args) => client.send(command, args),\n\t\tasync connectSubscriber(handlers) {\n\t\t\tconst owned = !options.subscriber\n\t\t\tconst subscriber = options.subscriber ?? (await client.duplicate())\n\t\t\tconst dispatch: Listener = (message, channel) =>\n\t\t\t\thandlers.onMessage(channel, message)\n\t\t\tconst ours = new Set<string>()\n\t\t\t// Bun reconnects on its own but drops every subscription. Also fires on\n\t\t\t// the first connect, when there is nothing to restore yet.\n\t\t\tsubscriber.onconnect = () => handlers.onReconnect()\n\t\t\t// Fires only when Bun gives up reconnecting (and on close(), which\n\t\t\t// detaches it first).\n\t\t\tsubscriber.onclose = (error) =>\n\t\t\t\thandlers.onLost(error ?? new Error('Redis subscriber closed'))\n\t\t\treturn {\n\t\t\t\tsubscribe: (channel) => {\n\t\t\t\t\tours.add(channel)\n\t\t\t\t\treturn subscriber.subscribe(channel, dispatch)\n\t\t\t\t},\n\t\t\t\t// Bun keeps listeners across a reconnect and does not dedupe them, so\n\t\t\t\t// clear the channel before adding its listener again. unsubscribe\n\t\t\t\t// throws synchronously outside subscriber mode.\n\t\t\t\tresubscribe: async (channel) => {\n\t\t\t\t\tawait Promise.resolve()\n\t\t\t\t\t\t.then(() => subscriber.unsubscribe(channel))\n\t\t\t\t\t\t.catch(() => {})\n\t\t\t\t\treturn subscriber.subscribe(channel, dispatch)\n\t\t\t\t},\n\t\t\t\tunsubscribe: (channel) => {\n\t\t\t\t\tours.delete(channel)\n\t\t\t\t\treturn subscriber.unsubscribe(channel, dispatch)\n\t\t\t\t},\n\t\t\t\tconnected: () => subscriber.connected !== false,\n\t\t\t\tclose() {\n\t\t\t\t\t// No-ops, not null: Bun calls `onclose` without checking it.\n\t\t\t\t\tsubscriber.onconnect = () => {}\n\t\t\t\t\tsubscriber.onclose = () => {}\n\t\t\t\t\tif (owned) return subscriber.close()\n\t\t\t\t\t// A given subscriber stays open: remove only this transport's listeners.\n\t\t\t\t\treturn Promise.all(\n\t\t\t\t\t\t[...ours].map((channel) =>\n\t\t\t\t\t\t\tPromise.resolve()\n\t\t\t\t\t\t\t\t.then(() => subscriber.unsubscribe(channel, dispatch))\n\t\t\t\t\t\t\t\t.catch(() => {})\n\t\t\t\t\t\t)\n\t\t\t\t\t).then(() => {})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})\n}\n"]}
|
package/dist/live/redis.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type PubSubTransport } from './transport.js';
|
|
1
|
+
import { type PubSubTransport, type PubSubTransportStats } from './transport.js';
|
|
2
2
|
export type RedisSend = (command: string, args: string[]) => Promise<unknown>;
|
|
3
3
|
/**
|
|
4
4
|
* Ship a Lua script by SHA instead of resending its source on every call.
|
|
@@ -17,6 +17,8 @@ export type SubscriberConnection = {
|
|
|
17
17
|
resubscribe?(channel: string): Promise<unknown>;
|
|
18
18
|
/** Stop delivering and release the connection (if the driver created it). */
|
|
19
19
|
close(): void | Promise<void>;
|
|
20
|
+
/** The driver reports the connection open; omitted means open until lost. */
|
|
21
|
+
connected?(): boolean;
|
|
20
22
|
};
|
|
21
23
|
/** Callbacks for one connection; they do nothing once it is replaced. */
|
|
22
24
|
export type SubscriberHandlers = {
|
|
@@ -41,5 +43,6 @@ export declare function createRedisTransport(driver: {
|
|
|
41
43
|
connectSubscriber: (handlers: SubscriberHandlers) => Promise<SubscriberConnection>;
|
|
42
44
|
}): PubSubTransport & {
|
|
43
45
|
close(): Promise<void>;
|
|
46
|
+
stats(): PubSubTransportStats;
|
|
44
47
|
};
|
|
45
48
|
//# sourceMappingURL=redis.d.ts.map
|
package/dist/live/redis.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/live/redis.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/live/redis.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,MAAM,gBAAgB,CAAA;AAEvB,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAM7E;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,UAavB,MAAM,EAAE,QAAQ,MAAM,EAAE,sBAW/D;AA8BD,MAAM,MAAM,oBAAoB,GAAG;IAClC,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC9C;;;OAGG;IACH,WAAW,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/C,6EAA6E;IAC7E,KAAK,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7B,6EAA6E;IAC7E,SAAS,CAAC,IAAI,OAAO,CAAA;CACrB,CAAA;AAED,yEAAyE;AACzE,MAAM,MAAM,kBAAkB,GAAG;IAChC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACjD,kEAAkE;IAClE,WAAW,IAAI,IAAI,CAAA;IACnB,gEAAgE;IAChE,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CAC1B,CAAA;AAcD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC5C,IAAI,EAAE,SAAS,CAAA;IACf,iBAAiB,EAAE,CAClB,QAAQ,EAAE,kBAAkB,KACxB,OAAO,CAAC,oBAAoB,CAAC,CAAA;CAClC,GAAG,eAAe,GAAG;IACrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,KAAK,IAAI,oBAAoB,CAAA;CAC7B,CAkLA"}
|
package/dist/live/redis.js
CHANGED
|
@@ -77,6 +77,8 @@ export function createRedisTransport(driver) {
|
|
|
77
77
|
// An UNSUBSCRIBE still in flight would cancel a SUBSCRIBE sent after it.
|
|
78
78
|
const unsubscribing = new Map();
|
|
79
79
|
let current = null;
|
|
80
|
+
// The open connection of the current generation, once it resolves.
|
|
81
|
+
let open = null;
|
|
80
82
|
const connect = () => {
|
|
81
83
|
let retired = false;
|
|
82
84
|
let closing;
|
|
@@ -84,8 +86,10 @@ export function createRedisTransport(driver) {
|
|
|
84
86
|
if (retired)
|
|
85
87
|
return closing ?? Promise.resolve();
|
|
86
88
|
retired = true;
|
|
87
|
-
if (current?.connection === connection)
|
|
89
|
+
if (current?.connection === connection) {
|
|
88
90
|
current = null;
|
|
91
|
+
open = null;
|
|
92
|
+
}
|
|
89
93
|
closing = connection.then((open) => open.close()).catch(() => { });
|
|
90
94
|
if (!error)
|
|
91
95
|
return closing;
|
|
@@ -141,7 +145,10 @@ export function createRedisTransport(driver) {
|
|
|
141
145
|
onLost: (error) => retire(error)
|
|
142
146
|
};
|
|
143
147
|
const connection = driver.connectSubscriber(handlers);
|
|
144
|
-
connection.
|
|
148
|
+
connection.then((resolved) => {
|
|
149
|
+
if (!retired)
|
|
150
|
+
open = resolved;
|
|
151
|
+
}, () => {
|
|
145
152
|
if (current?.connection === connection)
|
|
146
153
|
current = null;
|
|
147
154
|
});
|
|
@@ -229,6 +236,11 @@ export function createRedisTransport(driver) {
|
|
|
229
236
|
await done;
|
|
230
237
|
};
|
|
231
238
|
},
|
|
239
|
+
stats: () => ({
|
|
240
|
+
channels: channels.size,
|
|
241
|
+
listeners: [...channels.values()].reduce((sum, state) => sum + state.entries.size, 0),
|
|
242
|
+
subscriberConnected: open ? (open.connected?.() ?? true) : false
|
|
243
|
+
}),
|
|
232
244
|
async close() {
|
|
233
245
|
const closing = current?.retire();
|
|
234
246
|
channels.clear();
|
package/dist/live/redis.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/live/redis.ts"],"names":[],"mappings":"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","sourcesContent":["import { errorMessageOf } from '../otel.js'\nimport { backlogKey, type PubSubTransport } from './transport.js'\n\nexport type RedisSend = (command: string, args: string[]) => Promise<unknown>\n\nfunction isNoScriptError(error: unknown) {\n\treturn errorMessageOf(error).includes('NOSCRIPT')\n}\n\n/**\n * Ship a Lua script by SHA instead of resending its source on every call.\n * Redis forgets its script cache on restart and on `SCRIPT FLUSH`, so a\n * `NOSCRIPT` reply falls back to an inline `EVAL` (which repopulates the\n * cache) and drops the stale digest.\n */\nexport function createLuaScript(send: RedisSend, source: string) {\n\tlet sha: string | null = null\n\tlet loading: Promise<string> | null = null\n\n\tfunction load() {\n\t\tloading ??= send('SCRIPT', ['LOAD', source])\n\t\t\t.then(String)\n\t\t\t.finally(() => {\n\t\t\t\tloading = null\n\t\t\t})\n\t\treturn loading\n\t}\n\n\treturn async function evalScript(keys: string[], args: string[]) {\n\t\tconst tail = [String(keys.length), ...keys, ...args]\n\t\tsha ??= await load()\n\t\ttry {\n\t\t\treturn await send('EVALSHA', [sha, ...tail])\n\t\t} catch (error) {\n\t\t\tif (!isNoScriptError(error)) throw error\n\t\t\tsha = null\n\t\t\treturn await send('EVAL', [source, ...tail])\n\t\t}\n\t}\n}\n\n/**\n * Publish payloads and maintain each channel's capped, TTL'd backlog in one\n * atomic round-trip. Separate PUBLISH/RPUSH/LTRIM/EXPIRE calls can tear (a\n * message published but missing from the backlog, or a backlog without TTL).\n *\n * KEYS = channel1, backlog1, channel2, backlog2, ...\n * ARGV[1] = max backlog size (0 = no backlog), ARGV[2] = TTL seconds,\n * ARGV[3..] = pairs of (channel slot, payload)\n */\nconst PUBLISH_LUA = `\nlocal maxSize = tonumber(ARGV[1])\nlocal ttl = tonumber(ARGV[2])\nfor i = 3, #ARGV, 2 do\n local slot = tonumber(ARGV[i]) * 2\n redis.call('PUBLISH', KEYS[slot - 1], ARGV[i + 1])\n if maxSize > 0 then\n redis.call('RPUSH', KEYS[slot], ARGV[i + 1])\n end\nend\nif maxSize > 0 then\n for slot = 2, #KEYS, 2 do\n redis.call('LTRIM', KEYS[slot], -maxSize, -1)\n redis.call('EXPIRE', KEYS[slot], ttl)\n end\nend\nreturn (#ARGV - 2) / 2\n`\n\nexport type SubscriberConnection = {\n\tsubscribe(channel: string): Promise<unknown>\n\tunsubscribe(channel: string): Promise<unknown>\n\t/**\n\t * Restore one channel after the driver reconnected on its own and lost its\n\t * subscriptions. Omit when the client re-subscribes itself (ioredis).\n\t */\n\tresubscribe?(channel: string): Promise<unknown>\n\t/** Stop delivering and release the connection (if the driver created it). */\n\tclose(): void | Promise<void>\n}\n\n/** Callbacks for one connection; they do nothing once it is replaced. */\nexport type SubscriberHandlers = {\n\tonMessage(channel: string, message: string): void\n\t/** The driver reconnected; its subscriptions must be restored. */\n\tonReconnect(): void\n\t/** The connection is gone for good; a fresh one replaces it. */\n\tonLost(error: Error): void\n}\n\ntype Entry = {\n\tlistener: (payload: string) => void\n\tonLost: ((error: Error) => void) | undefined\n\tonReconnect: (() => void) | undefined\n}\n\ntype ChannelState = {\n\tentries: Set<Entry>\n\tready: Promise<unknown>\n\tsettled: boolean\n}\n\n/**\n * Shared core of the Redis transports: one SUBSCRIBE per channel no matter\n * how many listeners, and one dedicated subscriber connection at a time.\n *\n * Each connection is a generation. Losing it (or failing to restore its\n * channels after a reconnect) retires it: the core closes it, ignores\n * anything it still emits, and tells every listener, whose resubscribe then\n * opens the next generation. Nothing from an old connection can reach the\n * channels of a new one.\n */\nexport function createRedisTransport(driver: {\n\tsend: RedisSend\n\tconnectSubscriber: (\n\t\thandlers: SubscriberHandlers\n\t) => Promise<SubscriberConnection>\n}): PubSubTransport & { close(): Promise<void> } {\n\tconst publishScript = createLuaScript(driver.send, PUBLISH_LUA)\n\tconst channels = new Map<string, ChannelState>()\n\t// An UNSUBSCRIBE still in flight would cancel a SUBSCRIBE sent after it.\n\tconst unsubscribing = new Map<string, Promise<unknown>>()\n\tlet current: {\n\t\tconnection: Promise<SubscriberConnection>\n\t\tretire: () => Promise<void>\n\t} | null = null\n\n\tconst connect = () => {\n\t\tlet retired = false\n\t\tlet closing: Promise<void> | undefined\n\t\tconst retire = (error?: Error) => {\n\t\t\tif (retired) return closing ?? Promise.resolve()\n\t\t\tretired = true\n\t\t\tif (current?.connection === connection) current = null\n\t\t\tclosing = connection.then((open) => open.close()).catch(() => {})\n\t\t\tif (!error) return closing\n\t\t\tconst lost = [...channels.values()].flatMap((state) => [...state.entries])\n\t\t\tchannels.clear()\n\t\t\tfor (const entry of lost) {\n\t\t\t\ttry {\n\t\t\t\t\tentry.onLost?.(error)\n\t\t\t\t} catch {\n\t\t\t\t\t/* One callback cannot interrupt retirement. */\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn closing\n\t\t}\n\t\tconst handlers: SubscriberHandlers = {\n\t\t\tonMessage(channel, message) {\n\t\t\t\tif (retired) return\n\t\t\t\tfor (const entry of [...(channels.get(channel)?.entries ?? [])]) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tentry.listener(message)\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// One listener must not starve the others.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tonReconnect() {\n\t\t\t\tif (retired) return\n\t\t\t\t// In-flight SUBSCRIBEs are excluded: they still land on their own.\n\t\t\t\tconst settled = [...channels]\n\t\t\t\t\t.filter(([, state]) => state.settled)\n\t\t\t\t\t.map(([channel]) => channel)\n\t\t\t\tvoid connection\n\t\t\t\t\t.then((open) =>\n\t\t\t\t\t\tPromise.all(settled.map((channel) => open.resubscribe?.(channel)))\n\t\t\t\t\t)\n\t\t\t\t\t.then(() => {\n\t\t\t\t\t\tif (retired) return\n\t\t\t\t\t\tfor (const channel of settled)\n\t\t\t\t\t\t\tfor (const entry of [...(channels.get(channel)?.entries ?? [])]) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tentry.onReconnect?.()\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t/* Isolate subscriber callbacks. */\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.catch((error) => retire(asError(error)))\n\t\t\t},\n\t\t\tonLost: (error) => retire(error)\n\t\t}\n\t\tconst connection = driver.connectSubscriber(handlers)\n\t\tconnection.catch(() => {\n\t\t\tif (current?.connection === connection) current = null\n\t\t})\n\t\tcurrent = { connection, retire: () => retire() }\n\t\treturn connection\n\t}\n\n\treturn {\n\t\tasync publish(messages, backlog) {\n\t\t\tconst [first] = messages\n\t\t\tif (!first) return\n\t\t\tif (!backlog && messages.length === 1) {\n\t\t\t\tawait driver.send('PUBLISH', [first.channel, first.payload])\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst keys: string[] = []\n\t\t\tconst slots = new Map<string, number>()\n\t\t\tconst args = [\n\t\t\t\tString(backlog?.size ?? 0),\n\t\t\t\tString(backlog?.ttlSeconds ?? 0)\n\t\t\t]\n\t\t\tfor (const { channel, payload } of messages) {\n\t\t\t\tlet slot = slots.get(channel)\n\t\t\t\tif (slot === undefined) {\n\t\t\t\t\tkeys.push(channel, backlogKey(channel))\n\t\t\t\t\tslot = keys.length / 2\n\t\t\t\t\tslots.set(channel, slot)\n\t\t\t\t}\n\t\t\t\targs.push(String(slot), payload)\n\t\t\t}\n\t\t\tawait publishScript(keys, args)\n\t\t},\n\t\tasync readBacklog(channel) {\n\t\t\tconst items = await driver.send('LRANGE', [\n\t\t\t\tbacklogKey(channel),\n\t\t\t\t'0',\n\t\t\t\t'-1'\n\t\t\t])\n\t\t\treturn Array.isArray(items) ? items.map(String) : []\n\t\t},\n\t\tasync subscribe(channel, listener, onLost, options) {\n\t\t\tconst connection = await (current?.connection ?? connect())\n\t\t\tconst entry: Entry = {\n\t\t\t\tlistener,\n\t\t\t\tonLost,\n\t\t\t\tonReconnect: options?.onReconnect\n\t\t\t}\n\t\t\tawait unsubscribing.get(channel)\n\t\t\tlet state = channels.get(channel)\n\t\t\tif (!state) {\n\t\t\t\tconst created: ChannelState = {\n\t\t\t\t\tentries: new Set(),\n\t\t\t\t\tready: connection.subscribe(channel),\n\t\t\t\t\tsettled: false\n\t\t\t\t}\n\t\t\t\tcreated.ready.then(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tcreated.settled = true\n\t\t\t\t\t},\n\t\t\t\t\t() => {\n\t\t\t\t\t\tif (channels.get(channel) === created) channels.delete(channel)\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t\tchannels.set(channel, created)\n\t\t\t\tstate = created\n\t\t\t}\n\t\t\tstate.entries.add(entry)\n\t\t\ttry {\n\t\t\t\tawait state.ready\n\t\t\t} catch (error) {\n\t\t\t\tstate.entries.delete(entry)\n\t\t\t\tthrow error\n\t\t\t}\n\t\t\tconst subscribed = state\n\t\t\treturn async () => {\n\t\t\t\tif (!subscribed.entries.delete(entry)) return\n\t\t\t\tif (subscribed.entries.size > 0 || channels.get(channel) !== subscribed)\n\t\t\t\t\treturn\n\t\t\t\tchannels.delete(channel)\n\t\t\t\tconst done = connection.unsubscribe(channel).finally(() => {\n\t\t\t\t\tif (unsubscribing.get(channel) === done) unsubscribing.delete(channel)\n\t\t\t\t})\n\t\t\t\tunsubscribing.set(channel, done)\n\t\t\t\tawait done\n\t\t\t}\n\t\t},\n\t\tasync close() {\n\t\t\tconst closing = current?.retire()\n\t\t\tchannels.clear()\n\t\t\tawait closing\n\t\t\tawait Promise.allSettled([...unsubscribing.values()])\n\t\t}\n\t}\n}\n\nconst asError = (error: unknown) =>\n\terror instanceof Error ? error : new Error(errorMessageOf(error))\n"]}
|
|
1
|
+
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/live/redis.ts"],"names":[],"mappings":"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","sourcesContent":["import { errorMessageOf } from '../otel.js'\nimport {\n\tbacklogKey,\n\ttype PubSubTransport,\n\ttype PubSubTransportStats\n} from './transport.js'\n\nexport type RedisSend = (command: string, args: string[]) => Promise<unknown>\n\nfunction isNoScriptError(error: unknown) {\n\treturn errorMessageOf(error).includes('NOSCRIPT')\n}\n\n/**\n * Ship a Lua script by SHA instead of resending its source on every call.\n * Redis forgets its script cache on restart and on `SCRIPT FLUSH`, so a\n * `NOSCRIPT` reply falls back to an inline `EVAL` (which repopulates the\n * cache) and drops the stale digest.\n */\nexport function createLuaScript(send: RedisSend, source: string) {\n\tlet sha: string | null = null\n\tlet loading: Promise<string> | null = null\n\n\tfunction load() {\n\t\tloading ??= send('SCRIPT', ['LOAD', source])\n\t\t\t.then(String)\n\t\t\t.finally(() => {\n\t\t\t\tloading = null\n\t\t\t})\n\t\treturn loading\n\t}\n\n\treturn async function evalScript(keys: string[], args: string[]) {\n\t\tconst tail = [String(keys.length), ...keys, ...args]\n\t\tsha ??= await load()\n\t\ttry {\n\t\t\treturn await send('EVALSHA', [sha, ...tail])\n\t\t} catch (error) {\n\t\t\tif (!isNoScriptError(error)) throw error\n\t\t\tsha = null\n\t\t\treturn await send('EVAL', [source, ...tail])\n\t\t}\n\t}\n}\n\n/**\n * Publish payloads and maintain each channel's capped, TTL'd backlog in one\n * atomic round-trip. Separate PUBLISH/RPUSH/LTRIM/EXPIRE calls can tear (a\n * message published but missing from the backlog, or a backlog without TTL).\n *\n * KEYS = channel1, backlog1, channel2, backlog2, ...\n * ARGV[1] = max backlog size (0 = no backlog), ARGV[2] = TTL seconds,\n * ARGV[3..] = pairs of (channel slot, payload)\n */\nconst PUBLISH_LUA = `\nlocal maxSize = tonumber(ARGV[1])\nlocal ttl = tonumber(ARGV[2])\nfor i = 3, #ARGV, 2 do\n local slot = tonumber(ARGV[i]) * 2\n redis.call('PUBLISH', KEYS[slot - 1], ARGV[i + 1])\n if maxSize > 0 then\n redis.call('RPUSH', KEYS[slot], ARGV[i + 1])\n end\nend\nif maxSize > 0 then\n for slot = 2, #KEYS, 2 do\n redis.call('LTRIM', KEYS[slot], -maxSize, -1)\n redis.call('EXPIRE', KEYS[slot], ttl)\n end\nend\nreturn (#ARGV - 2) / 2\n`\n\nexport type SubscriberConnection = {\n\tsubscribe(channel: string): Promise<unknown>\n\tunsubscribe(channel: string): Promise<unknown>\n\t/**\n\t * Restore one channel after the driver reconnected on its own and lost its\n\t * subscriptions. Omit when the client re-subscribes itself (ioredis).\n\t */\n\tresubscribe?(channel: string): Promise<unknown>\n\t/** Stop delivering and release the connection (if the driver created it). */\n\tclose(): void | Promise<void>\n\t/** The driver reports the connection open; omitted means open until lost. */\n\tconnected?(): boolean\n}\n\n/** Callbacks for one connection; they do nothing once it is replaced. */\nexport type SubscriberHandlers = {\n\tonMessage(channel: string, message: string): void\n\t/** The driver reconnected; its subscriptions must be restored. */\n\tonReconnect(): void\n\t/** The connection is gone for good; a fresh one replaces it. */\n\tonLost(error: Error): void\n}\n\ntype Entry = {\n\tlistener: (payload: string) => void\n\tonLost: ((error: Error) => void) | undefined\n\tonReconnect: (() => void) | undefined\n}\n\ntype ChannelState = {\n\tentries: Set<Entry>\n\tready: Promise<unknown>\n\tsettled: boolean\n}\n\n/**\n * Shared core of the Redis transports: one SUBSCRIBE per channel no matter\n * how many listeners, and one dedicated subscriber connection at a time.\n *\n * Each connection is a generation. Losing it (or failing to restore its\n * channels after a reconnect) retires it: the core closes it, ignores\n * anything it still emits, and tells every listener, whose resubscribe then\n * opens the next generation. Nothing from an old connection can reach the\n * channels of a new one.\n */\nexport function createRedisTransport(driver: {\n\tsend: RedisSend\n\tconnectSubscriber: (\n\t\thandlers: SubscriberHandlers\n\t) => Promise<SubscriberConnection>\n}): PubSubTransport & {\n\tclose(): Promise<void>\n\tstats(): PubSubTransportStats\n} {\n\tconst publishScript = createLuaScript(driver.send, PUBLISH_LUA)\n\tconst channels = new Map<string, ChannelState>()\n\t// An UNSUBSCRIBE still in flight would cancel a SUBSCRIBE sent after it.\n\tconst unsubscribing = new Map<string, Promise<unknown>>()\n\tlet current: {\n\t\tconnection: Promise<SubscriberConnection>\n\t\tretire: () => Promise<void>\n\t} | null = null\n\t// The open connection of the current generation, once it resolves.\n\tlet open: SubscriberConnection | null = null\n\n\tconst connect = () => {\n\t\tlet retired = false\n\t\tlet closing: Promise<void> | undefined\n\t\tconst retire = (error?: Error) => {\n\t\t\tif (retired) return closing ?? Promise.resolve()\n\t\t\tretired = true\n\t\t\tif (current?.connection === connection) {\n\t\t\t\tcurrent = null\n\t\t\t\topen = null\n\t\t\t}\n\t\t\tclosing = connection.then((open) => open.close()).catch(() => {})\n\t\t\tif (!error) return closing\n\t\t\tconst lost = [...channels.values()].flatMap((state) => [...state.entries])\n\t\t\tchannels.clear()\n\t\t\tfor (const entry of lost) {\n\t\t\t\ttry {\n\t\t\t\t\tentry.onLost?.(error)\n\t\t\t\t} catch {\n\t\t\t\t\t/* One callback cannot interrupt retirement. */\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn closing\n\t\t}\n\t\tconst handlers: SubscriberHandlers = {\n\t\t\tonMessage(channel, message) {\n\t\t\t\tif (retired) return\n\t\t\t\tfor (const entry of [...(channels.get(channel)?.entries ?? [])]) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tentry.listener(message)\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// One listener must not starve the others.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tonReconnect() {\n\t\t\t\tif (retired) return\n\t\t\t\t// In-flight SUBSCRIBEs are excluded: they still land on their own.\n\t\t\t\tconst settled = [...channels]\n\t\t\t\t\t.filter(([, state]) => state.settled)\n\t\t\t\t\t.map(([channel]) => channel)\n\t\t\t\tvoid connection\n\t\t\t\t\t.then((open) =>\n\t\t\t\t\t\tPromise.all(settled.map((channel) => open.resubscribe?.(channel)))\n\t\t\t\t\t)\n\t\t\t\t\t.then(() => {\n\t\t\t\t\t\tif (retired) return\n\t\t\t\t\t\tfor (const channel of settled)\n\t\t\t\t\t\t\tfor (const entry of [...(channels.get(channel)?.entries ?? [])]) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tentry.onReconnect?.()\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t/* Isolate subscriber callbacks. */\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.catch((error) => retire(asError(error)))\n\t\t\t},\n\t\t\tonLost: (error) => retire(error)\n\t\t}\n\t\tconst connection = driver.connectSubscriber(handlers)\n\t\tconnection.then(\n\t\t\t(resolved) => {\n\t\t\t\tif (!retired) open = resolved\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tif (current?.connection === connection) current = null\n\t\t\t}\n\t\t)\n\t\tcurrent = { connection, retire: () => retire() }\n\t\treturn connection\n\t}\n\n\treturn {\n\t\tasync publish(messages, backlog) {\n\t\t\tconst [first] = messages\n\t\t\tif (!first) return\n\t\t\tif (!backlog && messages.length === 1) {\n\t\t\t\tawait driver.send('PUBLISH', [first.channel, first.payload])\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst keys: string[] = []\n\t\t\tconst slots = new Map<string, number>()\n\t\t\tconst args = [\n\t\t\t\tString(backlog?.size ?? 0),\n\t\t\t\tString(backlog?.ttlSeconds ?? 0)\n\t\t\t]\n\t\t\tfor (const { channel, payload } of messages) {\n\t\t\t\tlet slot = slots.get(channel)\n\t\t\t\tif (slot === undefined) {\n\t\t\t\t\tkeys.push(channel, backlogKey(channel))\n\t\t\t\t\tslot = keys.length / 2\n\t\t\t\t\tslots.set(channel, slot)\n\t\t\t\t}\n\t\t\t\targs.push(String(slot), payload)\n\t\t\t}\n\t\t\tawait publishScript(keys, args)\n\t\t},\n\t\tasync readBacklog(channel) {\n\t\t\tconst items = await driver.send('LRANGE', [\n\t\t\t\tbacklogKey(channel),\n\t\t\t\t'0',\n\t\t\t\t'-1'\n\t\t\t])\n\t\t\treturn Array.isArray(items) ? items.map(String) : []\n\t\t},\n\t\tasync subscribe(channel, listener, onLost, options) {\n\t\t\tconst connection = await (current?.connection ?? connect())\n\t\t\tconst entry: Entry = {\n\t\t\t\tlistener,\n\t\t\t\tonLost,\n\t\t\t\tonReconnect: options?.onReconnect\n\t\t\t}\n\t\t\tawait unsubscribing.get(channel)\n\t\t\tlet state = channels.get(channel)\n\t\t\tif (!state) {\n\t\t\t\tconst created: ChannelState = {\n\t\t\t\t\tentries: new Set(),\n\t\t\t\t\tready: connection.subscribe(channel),\n\t\t\t\t\tsettled: false\n\t\t\t\t}\n\t\t\t\tcreated.ready.then(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tcreated.settled = true\n\t\t\t\t\t},\n\t\t\t\t\t() => {\n\t\t\t\t\t\tif (channels.get(channel) === created) channels.delete(channel)\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t\tchannels.set(channel, created)\n\t\t\t\tstate = created\n\t\t\t}\n\t\t\tstate.entries.add(entry)\n\t\t\ttry {\n\t\t\t\tawait state.ready\n\t\t\t} catch (error) {\n\t\t\t\tstate.entries.delete(entry)\n\t\t\t\tthrow error\n\t\t\t}\n\t\t\tconst subscribed = state\n\t\t\treturn async () => {\n\t\t\t\tif (!subscribed.entries.delete(entry)) return\n\t\t\t\tif (subscribed.entries.size > 0 || channels.get(channel) !== subscribed)\n\t\t\t\t\treturn\n\t\t\t\tchannels.delete(channel)\n\t\t\t\tconst done = connection.unsubscribe(channel).finally(() => {\n\t\t\t\t\tif (unsubscribing.get(channel) === done) unsubscribing.delete(channel)\n\t\t\t\t})\n\t\t\t\tunsubscribing.set(channel, done)\n\t\t\t\tawait done\n\t\t\t}\n\t\t},\n\t\tstats: () => ({\n\t\t\tchannels: channels.size,\n\t\t\tlisteners: [...channels.values()].reduce(\n\t\t\t\t(sum, state) => sum + state.entries.size,\n\t\t\t\t0\n\t\t\t),\n\t\t\tsubscriberConnected: open ? (open.connected?.() ?? true) : false\n\t\t}),\n\t\tasync close() {\n\t\t\tconst closing = current?.retire()\n\t\t\tchannels.clear()\n\t\t\tawait closing\n\t\t\tawait Promise.allSettled([...unsubscribing.values()])\n\t\t}\n\t}\n}\n\nconst asError = (error: unknown) =>\n\terror instanceof Error ? error : new Error(errorMessageOf(error))\n"]}
|