{"version":3,"file":"index.mjs","names":["createBaseContext","createBaseContext"],"sources":["../../../../src/adapters/websocket/hono/shared.ts","../../../../src/adapters/websocket/hono/internal.ts","../../../../src/adapters/websocket/hono/global.ts","../../../../src/adapters/websocket/hono/peer.ts"],"sourcesContent":["import type { WSEvents } from 'hono/ws'\n\nimport type { EventContext } from '../../../context'\nimport type { InvocableEventContext } from '../../../invoke'\n\nimport { defineEventa } from '../../../eventa'\n\nexport const wsConnectedEvent = defineEventa('eventa:adapters:hono-ws:connected')\nexport const wsDisconnectedEvent = defineEventa('eventa:adapters:hono-ws:disconnected')\nexport const wsErrorEvent = defineEventa<{ error: unknown }>('eventa:adapters:hono-ws:error')\n\nexport type HonoWsOpenEvent = Parameters<NonNullable<WSEvents['onOpen']>>[0]\nexport type HonoWsMessageEvent = Parameters<NonNullable<WSEvents['onMessage']>>[0]\nexport type HonoWsCloseEvent = Parameters<NonNullable<WSEvents['onClose']>>[0]\nexport type HonoWsErrorEvent = Parameters<NonNullable<WSEvents['onError']>>[0]\n\nexport interface HonoWsRawEventOptions {\n  raw?: {\n    close?: HonoWsCloseEvent\n    error?: HonoWsErrorEvent\n    message?: HonoWsMessageEvent\n    open?: HonoWsOpenEvent\n  }\n}\n\nexport type HonoWsEventContext = EventContext<any, HonoWsRawEventOptions>\nexport type HonoWsInvocableEventContext = InvocableEventContext<any, HonoWsRawEventOptions>\n","import type { WSMessageReceive } from 'hono/ws'\n\nimport type { DirectionalEventa, Eventa } from '../../../eventa'\nimport type { HonoWsEventContext, HonoWsMessageEvent } from './shared'\n\nimport { and, defineInboundEventa, defineOutboundEventa, EventaFlowDirection, matchBy } from '../../../eventa'\nimport { generateWebsocketPayload, parseWebsocketPayload } from '../internal'\nimport { wsErrorEvent } from './shared'\n\nexport function forwardOutboundEvents(\n  context: HonoWsEventContext,\n  send: (data: string) => void,\n): () => void {\n  return context.on(and(\n    matchBy((event: DirectionalEventa<any>) => event._flowDirection === EventaFlowDirection.Outbound || !event._flowDirection),\n    matchBy('*'),\n  ), (event) => {\n    const data = JSON.stringify(generateWebsocketPayload(event.id, { ...defineOutboundEventa(event.type), ...event }))\n    send(data)\n  })\n}\n\nexport async function emitInboundMessage(\n  context: HonoWsEventContext,\n  event: HonoWsMessageEvent,\n): Promise<void> {\n  try {\n    const raw = await readMessageText(event.data)\n    const { type, payload } = parseWebsocketPayload<Eventa<any>>(raw)\n    context.emit(defineInboundEventa(type), payload.body, { raw: { message: event } })\n  }\n  catch (error) {\n    // Per-message parse failure is recoverable; keep the socket lifetime alive.\n    console.error('Failed to parse WebSocket message:', error)\n    context.emit(wsErrorEvent, { error }, { raw: { message: event } })\n  }\n}\n\nasync function readMessageText(data: WSMessageReceive): Promise<string> {\n  if (typeof data === 'string') {\n    return data\n  }\n\n  if (data instanceof Blob) {\n    return data.text()\n  }\n\n  if (data instanceof ArrayBuffer) {\n    return new TextDecoder().decode(data)\n  }\n\n  if (ArrayBuffer.isView(data)) {\n    return new TextDecoder().decode(data)\n  }\n\n  throw new TypeError('Unsupported Hono websocket message payload')\n}\n","import type { WSContext, WSEvents } from 'hono/ws'\n\nimport type { HonoWsEventContext, HonoWsRawEventOptions } from './shared'\n\nimport { createContext as createBaseContext } from '../../../context'\nimport { emitInboundMessage, forwardOutboundEvents } from './internal'\nimport { wsConnectedEvent, wsDisconnectedEvent, wsErrorEvent } from './shared'\n\nexport interface GlobalHooksResult {\n  context: HonoWsEventContext\n  hooks: WSEvents\n}\n\n/**\n * Creates Hono `WSEvents` hooks backed by one shared broadcasting context.\n *\n * Use when:\n * - A server needs one Eventa context that broadcasts outbound events to every\n *   connected Hono WebSocket peer.\n *\n * Expects:\n * - Connected peers accept the standard Eventa websocket JSON wire format.\n *\n * Returns:\n * - A shared context plus Hono websocket hooks.\n */\nexport function createGlobalHooks(): GlobalHooksResult {\n  const context = createBaseContext<any, HonoWsRawEventOptions>()\n  const peers = new Set<WSContext>()\n\n  forwardOutboundEvents(context, (data) => {\n    for (const peer of peers) {\n      peer.send(data)\n    }\n  })\n\n  const hooks: WSEvents = {\n    onOpen(event, ws) {\n      peers.add(ws)\n      context.emit(wsConnectedEvent, undefined, { raw: { open: event } })\n    },\n\n    onMessage(event) {\n      void emitInboundMessage(context, event)\n    },\n\n    onClose(event, ws) {\n      peers.delete(ws)\n      context.emit(wsDisconnectedEvent, undefined, { raw: { close: event } })\n    },\n\n    onError(event) {\n      context.emit(wsErrorEvent, { error: event }, { raw: { error: event } })\n    },\n  }\n\n  return { context, hooks }\n}\n","import type { WSEvents } from 'hono/ws'\n\nimport type { HonoWsInvocableEventContext, HonoWsRawEventOptions } from './shared'\n\nimport { createContext as createBaseContext } from '../../../context'\nimport { emitInboundMessage, forwardOutboundEvents } from './internal'\nimport { wsConnectedEvent, wsDisconnectedEvent, wsErrorEvent } from './shared'\n\nexport interface CreatePeerHooksOptions {\n  onContext?: (ctx: HonoWsInvocableEventContext) => void\n}\n\nexport interface PeerHooksResult {\n  hooks: WSEvents\n}\n\n/**\n * Creates Hono `WSEvents` hooks with one Eventa context per connected peer.\n *\n * Use when:\n * - A Hono route wants per-socket Eventa RPC handlers or per-peer fanout.\n *\n * Expects:\n * - The returned hooks are passed to Hono's `upgradeWebSocket(...)` helper.\n *\n * Returns:\n * - Hono websocket hooks. `options.onContext` receives the peer context after\n *   `onOpen`, when Hono exposes the `WSContext`.\n */\nexport function createPeerHooks(options: CreatePeerHooksOptions = {}): PeerHooksResult {\n  let context: HonoWsInvocableEventContext | undefined\n  let offOutbound: (() => void) | undefined\n\n  const hooks: WSEvents = {\n    onOpen(event, ws) {\n      const ctx = createBaseContext<any, HonoWsRawEventOptions>()\n      context = ctx\n\n      offOutbound = forwardOutboundEvents(ctx, data => ws.send(data))\n\n      ctx.emit(wsConnectedEvent, undefined, { raw: { open: event } })\n      options.onContext?.(ctx)\n    },\n\n    onMessage(event) {\n      if (!context) {\n        return\n      }\n\n      void emitInboundMessage(context, event)\n    },\n\n    onClose(event) {\n      if (!context) {\n        return\n      }\n\n      context.abort(new Error('eventa: invoke cancelled, hono websocket disconnected'))\n      context.emit(wsDisconnectedEvent, undefined, { raw: { close: event } })\n      offOutbound?.()\n      context = undefined\n      offOutbound = undefined\n    },\n\n    onError(event) {\n      if (!context) {\n        return\n      }\n\n      context.abort(new Error('eventa: invoke cancelled, hono websocket error'))\n      context.emit(wsErrorEvent, { error: event }, { raw: { error: event } })\n    },\n  }\n\n  return { hooks }\n}\n"],"mappings":"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"}