{"version":3,"file":"index.mjs","names":["createBaseContext"],"sources":["../../../src/adapters/window-message/internal.ts","../../../src/adapters/window-message/shared.ts","../../../src/adapters/window-message/index.ts"],"sourcesContent":["import type { EventTag } from '../..'\nimport type { Payload } from './shared'\n\nimport { nanoid } from '../..'\n\nexport function generatePayload<T>(type: EventTag<any, any>, payload: T): Payload<T> {\n  return {\n    id: nanoid(),\n    type,\n    payload,\n  }\n}\n\nexport function parsePayload<T>(data: unknown): Payload<T> {\n  return data as Payload<T>\n}\n","import type { EventTag } from '../../eventa'\nimport type { AdapterErrorPayload } from '../errors'\n\nimport { defineEventa } from '../../eventa'\n\nexport type { AdapterErrorKind, AdapterErrorPayload } from '../errors'\n\nexport interface Payload<T> {\n  id: string\n  type: EventTag<any, any>\n  payload: T\n}\n\nexport interface WindowMessageEnvelope<T> {\n  __eventa: true\n  channel: string\n  sourceId: string\n  payload: Payload<T>\n}\n\n/**\n * Emitted by the window-message adapter when an inbound message fails to parse\n * (`kind: 'parse'`) or the window dispatches a `messageerror`\n * (`kind: 'messageerror'`). Neither is fatal — the window itself stays alive,\n * so the context is not aborted. Has a stable id so it can be subscribed to\n * across module boundaries.\n */\nexport const errorEvent = defineEventa<AdapterErrorPayload>('eventa:window-message:error')\n","import type { EventContext } from '../../context'\nimport type { DirectionalEventa, Eventa } from '../../eventa'\nimport type { WindowMessageEnvelope } from './shared'\n\nimport { createContext as createBaseContext } from '../../context'\nimport { and, defineInboundEventa, defineOutboundEventa, EventaFlowDirection, matchBy } from '../../eventa'\nimport { toError } from '../errors'\nimport { generatePayload, parsePayload } from './internal'\nimport { errorEvent } from './shared'\n\nfunction withRemoval<K extends keyof WindowEventMap>(currentWindow: Window, type: K, listener: (event: WindowEventMap[K]) => void) {\n  currentWindow.addEventListener(type, listener)\n\n  return {\n    remove: () => {\n      currentWindow.removeEventListener(type, listener)\n    },\n  }\n}\n\nfunction isEnvelope(value: unknown, channel: string): value is WindowMessageEnvelope<Eventa<any>> {\n  return typeof value === 'object'\n    && value !== null\n    && '__eventa' in value\n    && value.__eventa === true\n    && 'channel' in value\n    && value.channel === channel\n    && 'sourceId' in value\n    && typeof value.sourceId === 'string'\n    && 'payload' in value\n    && typeof value.payload === 'object'\n    && value.payload !== null\n}\n\nfunction matchOrigin(expectedOrigin: string | ((origin: string) => boolean), origin: string) {\n  if (typeof expectedOrigin === 'function') {\n    return expectedOrigin(origin)\n  }\n\n  return expectedOrigin === origin\n}\n\nexport interface WindowMessageAdapterOptions {\n  channel: string\n  currentWindow: Window\n  targetWindow: () => Window | null | undefined\n  expectedSource?: () => MessageEventSource | null | undefined\n  targetOrigin?: string\n  expectedOrigin?: string | ((origin: string) => boolean)\n  acceptMessage?: (event: MessageEvent<unknown>) => boolean\n  messageEvents?: boolean\n  messageErrorEvents?: boolean\n}\n\nexport function createContext(options: WindowMessageAdapterOptions) {\n  const ctx = createBaseContext() as EventContext<any, { raw: { message?: MessageEvent, messageError?: MessageEvent, error?: unknown } }>\n  const sourceId = crypto.randomUUID()\n\n  const {\n    messageEvents: message = true,\n    messageErrorEvents: messageError = true,\n  } = options\n\n  const cleanupRemoval: Array<{ remove: () => void }> = []\n\n  ctx.on(and(\n    matchBy((e: DirectionalEventa<any>) => e._flowDirection === EventaFlowDirection.Outbound || !e._flowDirection),\n    matchBy('*'),\n  ), (event) => {\n    const targetWindow = options.targetWindow()\n    if (!targetWindow) {\n      return\n    }\n\n    const payload = generatePayload(event.id, { ...defineOutboundEventa(event.type), ...event })\n    targetWindow.postMessage({\n      __eventa: true,\n      channel: options.channel,\n      sourceId,\n      payload,\n    } satisfies WindowMessageEnvelope<Eventa<any>>, options.targetOrigin ?? '*')\n  })\n\n  if (message) {\n    cleanupRemoval.push(withRemoval(options.currentWindow, 'message', (event) => {\n      if (!isEnvelope(event.data, options.channel)) {\n        return\n      }\n\n      const expectedSource = options.expectedSource?.()\n      if (expectedSource && event.source !== expectedSource) {\n        return\n      }\n\n      if (options.expectedOrigin && !matchOrigin(options.expectedOrigin, event.origin)) {\n        return\n      }\n\n      if (event.data.sourceId === sourceId) {\n        return\n      }\n\n      if (options.acceptMessage && !options.acceptMessage(event)) {\n        return\n      }\n\n      try {\n        const { type, payload } = parsePayload<Eventa<any>>(event.data.payload)\n        ctx.emit(defineInboundEventa(type), payload.body, { raw: { message: event } })\n      }\n      catch (error) {\n        console.error('Failed to parse window message:', error)\n        ctx.emit(errorEvent, { kind: 'parse', error: toError(error, 'eventa: window message parse error') }, { raw: { error } })\n      }\n    }))\n  }\n\n  if (messageError) {\n    cleanupRemoval.push(withRemoval(options.currentWindow, 'messageerror', (event) => {\n      ctx.emit(errorEvent, { kind: 'messageerror', error: toError(event, 'eventa: window messageerror'), message: event }, { raw: { messageError: event } })\n    }))\n  }\n\n  return {\n    context: ctx,\n    dispose: (reason?: unknown) => {\n      ctx.abort(reason ?? new Error('eventa: invoke cancelled, window message adapter disposed'))\n      cleanupRemoval.forEach(removal => removal.remove())\n    },\n  }\n}\n\nexport { errorEvent } from './shared'\nexport type * from './shared'\n"],"mappings":";;;;AAKA,SAAgB,gBAAmB,MAA0B,SAAwB;CACnF,OAAO;EACL,IAAI,OAAO;EACX;EACA;CACF;AACF;AAEA,SAAgB,aAAgB,MAA2B;CACzD,OAAO;AACT;;;;;;;;;;ACYA,MAAa,aAAa,aAAkC,6BAA6B;;;ACjBzF,SAAS,YAA4C,eAAuB,MAAS,UAA8C;CACjI,cAAc,iBAAiB,MAAM,QAAQ;CAE7C,OAAO,EACL,cAAc;EACZ,cAAc,oBAAoB,MAAM,QAAQ;CAClD,EACF;AACF;AAEA,SAAS,WAAW,OAAgB,SAA8D;CAChG,OAAO,OAAO,UAAU,YACnB,UAAU,QACV,cAAc,SACd,MAAM,aAAa,QACnB,aAAa,SACb,MAAM,YAAY,WAClB,cAAc,SACd,OAAO,MAAM,aAAa,YAC1B,aAAa,SACb,OAAO,MAAM,YAAY,YACzB,MAAM,YAAY;AACzB;AAEA,SAAS,YAAY,gBAAwD,QAAgB;CAC3F,IAAI,OAAO,mBAAmB,YAC5B,OAAO,eAAe,MAAM;CAG9B,OAAO,mBAAmB;AAC5B;AAcA,SAAgB,cAAc,SAAsC;CAClE,MAAM,MAAMA,gBAAkB;CAC9B,MAAM,WAAW,OAAO,WAAW;CAEnC,MAAM,EACJ,eAAe,UAAU,MACzB,oBAAoB,eAAe,SACjC;CAEJ,MAAM,iBAAgD,CAAC;CAEvD,IAAI,GAAG,IACL,SAAS,MAA8B,EAAE,mBAAA,cAAmD,CAAC,EAAE,cAAc,GAC7G,QAAQ,GAAG,CACb,IAAI,UAAU;EACZ,MAAM,eAAe,QAAQ,aAAa;EAC1C,IAAI,CAAC,cACH;EAGF,MAAM,UAAU,gBAAgB,MAAM,IAAI;GAAE,GAAG,qBAAqB,MAAM,IAAI;GAAG,GAAG;EAAM,CAAC;EAC3F,aAAa,YAAY;GACvB,UAAU;GACV,SAAS,QAAQ;GACjB;GACA;EACF,GAAgD,QAAQ,gBAAgB,GAAG;CAC7E,CAAC;CAED,IAAI,SACF,eAAe,KAAK,YAAY,QAAQ,eAAe,YAAY,UAAU;EAC3E,IAAI,CAAC,WAAW,MAAM,MAAM,QAAQ,OAAO,GACzC;EAGF,MAAM,iBAAiB,QAAQ,iBAAiB;EAChD,IAAI,kBAAkB,MAAM,WAAW,gBACrC;EAGF,IAAI,QAAQ,kBAAkB,CAAC,YAAY,QAAQ,gBAAgB,MAAM,MAAM,GAC7E;EAGF,IAAI,MAAM,KAAK,aAAa,UAC1B;EAGF,IAAI,QAAQ,iBAAiB,CAAC,QAAQ,cAAc,KAAK,GACvD;EAGF,IAAI;GACF,MAAM,EAAE,MAAM,YAAY,aAA0B,MAAM,KAAK,OAAO;GACtE,IAAI,KAAK,oBAAoB,IAAI,GAAG,QAAQ,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;EAC/E,SACO,OAAO;GACZ,QAAQ,MAAM,mCAAmC,KAAK;GACtD,IAAI,KAAK,YAAY;IAAE,MAAM;IAAS,OAAO,QAAQ,OAAO,oCAAoC;GAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;EACzH;CACF,CAAC,CAAC;CAGJ,IAAI,cACF,eAAe,KAAK,YAAY,QAAQ,eAAe,iBAAiB,UAAU;EAChF,IAAI,KAAK,YAAY;GAAE,MAAM;GAAgB,OAAO,QAAQ,OAAO,6BAA6B;GAAG,SAAS;EAAM,GAAG,EAAE,KAAK,EAAE,cAAc,MAAM,EAAE,CAAC;CACvJ,CAAC,CAAC;CAGJ,OAAO;EACL,SAAS;EACT,UAAU,WAAqB;GAC7B,IAAI,MAAM,0BAAU,IAAI,MAAM,2DAA2D,CAAC;GAC1F,eAAe,SAAQ,YAAW,QAAQ,OAAO,CAAC;EACpD;CACF;AACF"}