{"version":3,"sources":["../../src/core/sse.ts"],"sourcesContent":["import { invariant } from 'outvariant'\nimport { Emitter } from 'strict-event-emitter'\nimport type { ResponseResolver } from './handlers/RequestHandler'\nimport {\n  HttpHandler,\n  type HttpRequestResolverExtras,\n  type HttpRequestParsedResult,\n} from './handlers/HttpHandler'\nimport type { ResponseResolutionContext } from '~/core/utils/executeHandlers'\nimport type { Path, PathParams } from './utils/matching/matchRequestUrl'\nimport { delay } from './delay'\nimport { getTimestamp } from './utils/logging/getTimestamp'\nimport { devUtils } from './utils/internal/devUtils'\nimport { colors } from './ws/utils/attachWebSocketLogger'\nimport { toPublicUrl } from './utils/request/toPublicUrl'\n\ntype EventMapConstraint = {\n  message?: unknown\n  [key: string]: unknown\n  [key: symbol | number]: never\n}\n\nexport type ServerSentEventResolverExtras<\n  EventMap extends EventMapConstraint,\n  Params extends PathParams,\n> = HttpRequestResolverExtras<Params> & {\n  client: ServerSentEventClient<EventMap>\n  server: ServerSentEventServer\n}\n\nexport type ServerSentEventResolver<\n  EventMap extends EventMapConstraint,\n  Params extends PathParams,\n> = ResponseResolver<ServerSentEventResolverExtras<EventMap, Params>, any, any>\n\nexport type ServerSentEventRequestHandler = <\n  EventMap extends EventMapConstraint = { message: unknown },\n  Params extends PathParams<keyof Params> = PathParams,\n  RequestPath extends Path = Path,\n>(\n  path: RequestPath,\n  resolver: ServerSentEventResolver<EventMap, Params>,\n) => HttpHandler\n\nexport type ServerSentEventMessage<\n  EventMap extends EventMapConstraint = { message: unknown },\n> =\n  | ToEventDiscriminatedUnion<EventMap & { message: unknown }>\n  | {\n      id?: never\n      event?: never\n      data?: never\n      retry: number\n    }\n\n/**\n * Intercept Server-Sent Events (SSE).\n *\n * @example\n * sse('http://localhost:4321', ({ client }) => {\n *   client.send({ data: 'hello world' })\n * })\n *\n * @see {@link https://mswjs.io/docs/sse/ Mocking Server-Sent Events}\n * @see {@link https://mswjs.io/docs/api/sse `sse()` API reference}\n */\nexport const sse: ServerSentEventRequestHandler = (path, resolver) => {\n  return new ServerSentEventHandler(path, resolver)\n}\n\nconst SSE_RESPONSE_INIT: ResponseInit = {\n  headers: {\n    'content-type': 'text/event-stream',\n    'cache-control': 'no-cache',\n    connection: 'keep-alive',\n  },\n}\n\nclass ServerSentEventHandler<\n  EventMap extends EventMapConstraint,\n> extends HttpHandler {\n  #emitter: Emitter<ServerSentEventClientEventMap>\n\n  constructor(path: Path, resolver: ServerSentEventResolver<EventMap, any>) {\n    invariant(\n      typeof EventSource !== 'undefined',\n      'Failed to construct a Server-Sent Event handler for path \"%s\": the EventSource API is not supported in this environment',\n      path,\n    )\n\n    super('GET', path, async (info) => {\n      const stream = new ReadableStream({\n        start: async (controller) => {\n          const client = new ServerSentEventClient<EventMap>({\n            controller,\n            emitter: this.#emitter,\n          })\n          const server = new ServerSentEventServer({\n            request: info.request,\n            client,\n          })\n\n          await resolver({\n            ...info,\n            client,\n            server,\n          })\n        },\n      })\n\n      return new Response(stream, SSE_RESPONSE_INIT)\n    })\n\n    this.#emitter = new Emitter<ServerSentEventClientEventMap>()\n  }\n\n  async predicate(args: {\n    request: Request\n    parsedResult: HttpRequestParsedResult\n    resolutionContext?: ResponseResolutionContext\n  }) {\n    if (args.request.headers.get('accept') !== 'text/event-stream') {\n      return false\n    }\n\n    const matches = await super.predicate(args)\n\n    if (matches && !args.resolutionContext?.quiet) {\n      /**\n       * @note Log the intercepted request early.\n       * Normally, the `this.log()` method is called when the handler returns a response.\n       * For SSE, call that method earlier so the logs are in correct order.\n       */\n      await super.log({\n        request: args.request,\n        /**\n         * @note Construct a placeholder response since SSE response\n         * is being streamed and cannot be cloned/consumed for logging.\n         */\n        response: new Response('[streaming]', SSE_RESPONSE_INIT),\n      })\n\n      this.#attachClientLogger(args.request, this.#emitter)\n    }\n\n    return matches\n  }\n\n  async log(_args: { request: Request; response: Response }): Promise<void> {\n    /**\n     * @note Skip the default `this.log()` logic so that when this handler is logged\n     * upon handling the request, nothing is printed (we log SSE requests early).\n     */\n    return\n  }\n\n  #attachClientLogger(\n    request: Request,\n    emitter: Emitter<ServerSentEventClientEventMap>,\n  ): void {\n    const publicUrl = toPublicUrl(request.url)\n\n    /* eslint-disable no-console */\n    emitter.on('message', (payload) => {\n      console.groupCollapsed(\n        devUtils.formatMessage(\n          `${getTimestamp()} SSE %s %c⇣%c ${payload.event}`,\n        ),\n        publicUrl,\n        `color:${colors.mocked}`,\n        'color:inherit',\n      )\n      console.log(payload.frames)\n      console.groupEnd()\n    })\n\n    emitter.on('error', () => {\n      console.groupCollapsed(\n        devUtils.formatMessage(`${getTimestamp()} SSE %s %c\\u00D7%c error`),\n        publicUrl,\n        `color: ${colors.system}`,\n        'color:inherit',\n      )\n      console.log('Handler:', this)\n      console.groupEnd()\n    })\n\n    emitter.on('close', () => {\n      console.groupCollapsed(\n        devUtils.formatMessage(`${getTimestamp()} SSE %s %c■%c close`),\n        publicUrl,\n        `colors:${colors.system}`,\n        'color:inherit',\n      )\n      console.log('Handler:', this)\n      console.groupEnd()\n    })\n    /* eslint-enable no-console */\n  }\n}\n\ntype Values<T> = T[keyof T]\ntype Identity<T> = { [K in keyof T]: T[K] } & unknown\ntype ToEventDiscriminatedUnion<T> = Values<{\n  [K in keyof T]: Identity<\n    (K extends 'message'\n      ? {\n          id?: string\n          event?: K\n          data?: T[K]\n          retry?: never\n        }\n      : {\n          id?: string\n          event: K\n          data?: T[K]\n          retry?: never\n        }) &\n      // Make the `data` field conditionally required through an intersection.\n      (undefined extends T[K] ? unknown : { data: unknown })\n  >\n}>\n\ntype ServerSentEventClientEventMap = {\n  message: [\n    payload: {\n      id?: string\n      event: string\n      data?: unknown\n      frames: Array<string>\n    },\n  ]\n  error: []\n  close: []\n}\n\nclass ServerSentEventClient<\n  EventMap extends EventMapConstraint = { message: unknown },\n> {\n  #encoder: TextEncoder\n  #controller: ReadableStreamDefaultController\n  #emitter: Emitter<ServerSentEventClientEventMap>\n\n  constructor(args: {\n    controller: ReadableStreamDefaultController\n    emitter: Emitter<ServerSentEventClientEventMap>\n  }) {\n    this.#encoder = new TextEncoder()\n    this.#controller = args.controller\n    this.#emitter = args.emitter\n  }\n\n  /**\n   * Sends the given payload to the intercepted `EventSource`.\n   */\n  public send(payload: ServerSentEventMessage<EventMap>): void {\n    if ('retry' in payload && payload.retry != null) {\n      this.#sendRetry(payload.retry)\n      return\n    }\n\n    this.#sendMessage({\n      id: payload.id,\n      event: payload.event,\n      data:\n        typeof payload.data === 'object'\n          ? JSON.stringify(payload.data)\n          : payload.data,\n    })\n  }\n\n  /**\n   * Dispatches the given event on the intercepted `EventSource`.\n   */\n  public dispatchEvent(event: Event) {\n    if (event instanceof MessageEvent) {\n      /**\n       * @note Use the internal send mechanism to skip normalization\n       * of the message data (already normalized by the server).\n       */\n      this.#sendMessage({\n        id: event.lastEventId || undefined,\n        event: event.type === 'message' ? undefined : event.type,\n        data: event.data,\n      })\n      return\n    }\n\n    if (event.type === 'error') {\n      this.error()\n      return\n    }\n\n    if (event.type === 'close') {\n      this.close()\n      return\n    }\n  }\n\n  /**\n   * Errors the underlying `EventSource`, closing the connection with an error.\n   * This is equivalent to aborting the connection and will produce a `TypeError: Failed to fetch`\n   * error.\n   */\n  public error(): void {\n    this.#controller.error()\n    this.#emitter.emit('error')\n  }\n\n  /**\n   * Closes the underlying `EventSource`, closing the connection.\n   */\n  public close(): void {\n    this.#controller.close()\n    this.#emitter.emit('close')\n  }\n\n  #sendRetry(retry: number): void {\n    if (typeof retry === 'number') {\n      this.#controller.enqueue(this.#encoder.encode(`retry:${retry}\\n\\n`))\n    }\n  }\n\n  #sendMessage(message: {\n    id?: string\n    event?: unknown\n    data: unknown | undefined\n  }): void {\n    const frames: Array<string> = []\n\n    if (message.id) {\n      frames.push(`id:${message.id}`)\n    }\n\n    if (message.event) {\n      frames.push(`event:${message.event.toString()}`)\n    }\n\n    if (message.data != null) {\n      /**\n       * Split data on line terminators (LF, CR, or CRLF) and translate them to individual frames.\n       * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation\n       * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#parsing-an-event-stream\n       */\n      for (const line of message.data.toString().split(/\\r\\n|\\r|\\n/)) {\n        frames.push(`data:${line}`)\n      }\n    }\n\n    frames.push('', '')\n\n    this.#controller.enqueue(this.#encoder.encode(frames.join('\\n')))\n\n    this.#emitter.emit('message', {\n      id: message.id,\n      event: message.event?.toString() || 'message',\n      data: message.data,\n      frames,\n    })\n  }\n}\n\nclass ServerSentEventServer {\n  #request: Request\n  #client: ServerSentEventClient<ServerSentEventClientEventMap>\n\n  constructor(args: { request: Request; client: ServerSentEventClient<any> }) {\n    this.#request = args.request\n    this.#client = args.client\n  }\n\n  /**\n   * Establishes the actual connection for this SSE request\n   * and returns the `EventSource` instance.\n   */\n  public connect(): EventSource {\n    const source = new ObservableEventSource(this.#request.url, {\n      withCredentials: this.#request.credentials === 'include',\n      headers: {\n        /**\n         * @note Mark this request as passthrough so it doesn't trigger\n         * an infinite loop matching against the existing request handler.\n         */\n        accept: 'msw/passthrough',\n      },\n    })\n\n    source[kOnAnyMessage] = (event) => {\n      Object.defineProperties(event, {\n        target: {\n          value: this,\n          enumerable: true,\n          writable: true,\n          configurable: true,\n        },\n      })\n\n      // Schedule the server-to-client forwarding for the next tick\n      // so the user can prevent the message event.\n      queueMicrotask(() => {\n        if (!event.defaultPrevented) {\n          this.#client.dispatchEvent(event)\n        }\n      })\n    }\n\n    // Forward stream errors from the actual server to the client.\n    source.addEventListener('error', (event) => {\n      Object.defineProperties(event, {\n        target: {\n          value: this,\n          enumerable: true,\n          writable: true,\n          configurable: true,\n        },\n      })\n\n      queueMicrotask(() => {\n        // Allow the user to opt-out from this forwarding.\n        if (!event.defaultPrevented) {\n          this.#client.dispatchEvent(event)\n        }\n      })\n    })\n\n    return source\n  }\n}\n\ninterface ObservableEventSourceInit extends EventSourceInit {\n  headers?: HeadersInit\n}\n\ntype EventHandler<EventType extends Event> = (\n  this: EventSource,\n  event: EventType,\n) => any\n\nconst kRequest = Symbol('kRequest')\nconst kReconnectionTime = Symbol('kReconnectionTime')\nconst kLastEventId = Symbol('kLastEventId')\nconst kAbortController = Symbol('kAbortController')\nconst kOnOpen = Symbol('kOnOpen')\nconst kOnMessage = Symbol('kOnMessage')\nconst kOnAnyMessage = Symbol('kOnAnyMessage')\nconst kOnError = Symbol('kOnError')\n\nclass ObservableEventSource extends EventTarget implements EventSource {\n  static readonly CONNECTING = 0\n  static readonly OPEN = 1\n  static readonly CLOSED = 2\n\n  public readonly CONNECTING = ObservableEventSource.CONNECTING\n  public readonly OPEN = ObservableEventSource.OPEN\n  public readonly CLOSED = ObservableEventSource.CLOSED\n\n  public readyState: number\n  public url: string\n  public withCredentials: boolean\n\n  private [kRequest]: Request\n  private [kReconnectionTime]: number\n  private [kLastEventId]: string\n  private [kAbortController]: AbortController\n  private [kOnOpen]: EventHandler<Event> | null = null\n  private [kOnMessage]: EventHandler<MessageEvent> | null = null\n  private [kOnAnyMessage]: EventHandler<MessageEvent> | null = null\n  private [kOnError]: EventHandler<Event> | null = null\n\n  constructor(url: string | URL, init?: ObservableEventSourceInit) {\n    super()\n\n    this.url = new URL(url).href\n    this.withCredentials = init?.withCredentials ?? false\n\n    this.readyState = this.CONNECTING\n\n    // Support custom request init.\n    const headers = new Headers(init?.headers || {})\n    headers.append('accept', 'text/event-stream')\n\n    this[kAbortController] = new AbortController()\n    this[kReconnectionTime] = 2000\n    this[kLastEventId] = ''\n    this[kRequest] = new Request(this.url, {\n      method: 'GET',\n      headers,\n      credentials: this.withCredentials ? 'include' : 'omit',\n      signal: this[kAbortController].signal,\n    })\n\n    this.connect()\n  }\n\n  get onopen(): EventHandler<Event> | null {\n    return this[kOnOpen]\n  }\n\n  set onopen(handler: EventHandler<Event>) {\n    if (this[kOnOpen]) {\n      this.removeEventListener('open', this[kOnOpen])\n    }\n    this[kOnOpen] = handler.bind(this)\n    this.addEventListener('open', this[kOnOpen])\n  }\n\n  get onmessage(): EventHandler<MessageEvent> | null {\n    return this[kOnMessage]\n  }\n  set onmessage(handler: EventHandler<MessageEvent>) {\n    if (this[kOnMessage]) {\n      this.removeEventListener('message', { handleEvent: this[kOnMessage] })\n    }\n    this[kOnMessage] = handler.bind(this)\n    this.addEventListener('message', { handleEvent: this[kOnMessage] })\n  }\n\n  get onerror(): EventHandler<Event> | null {\n    return this[kOnError]\n  }\n  set oneerror(handler: EventHandler<Event>) {\n    if (this[kOnError]) {\n      this.removeEventListener('error', { handleEvent: this[kOnError] })\n    }\n    this[kOnError] = handler.bind(this)\n    this.addEventListener('error', { handleEvent: this[kOnError] })\n  }\n\n  public addEventListener<K extends keyof EventSourceEventMap>(\n    type: K,\n    listener: EventHandler<EventSourceEventMap[K]>,\n    options?: boolean | AddEventListenerOptions,\n  ): void\n  public addEventListener(\n    type: string,\n    listener: EventHandler<MessageEvent>,\n    options?: boolean | AddEventListenerOptions,\n  ): void\n  public addEventListener(\n    type: string,\n    listener: EventListenerOrEventListenerObject,\n    options?: boolean | AddEventListenerOptions,\n  ): void\n\n  public addEventListener(\n    type: string,\n    listener: EventHandler<MessageEvent> | EventListenerOrEventListenerObject,\n    options?: boolean | AddEventListenerOptions,\n  ): void {\n    super.addEventListener(\n      type,\n      listener as EventListenerOrEventListenerObject,\n      options,\n    )\n  }\n\n  public removeEventListener<K extends keyof EventSourceEventMap>(\n    type: K,\n    listener: (this: EventSource, ev: EventSourceEventMap[K]) => any,\n    options?: boolean | EventListenerOptions,\n  ): void\n  public removeEventListener(\n    type: string,\n    listener: (this: EventSource, event: MessageEvent) => any,\n    options?: boolean | EventListenerOptions,\n  ): void\n  public removeEventListener(\n    type: string,\n    listener: EventListenerOrEventListenerObject,\n    options?: boolean | EventListenerOptions,\n  ): void\n\n  public removeEventListener(\n    type: string,\n    listener: EventHandler<MessageEvent> | EventListenerOrEventListenerObject,\n    options?: boolean | AddEventListenerOptions,\n  ): void {\n    super.removeEventListener(\n      type,\n      listener as EventListenerOrEventListenerObject,\n      options,\n    )\n  }\n\n  public dispatchEvent(event: Event): boolean {\n    return super.dispatchEvent(event)\n  }\n\n  public close(): void {\n    this[kAbortController].abort()\n    this.readyState = this.CLOSED\n  }\n\n  private async connect() {\n    await fetch(this[kRequest])\n      .then((response) => {\n        this.processResponse(response)\n      })\n      .catch(() => {\n        // Fail the connection on request errors instead of\n        // throwing a generic \"Failed to fetch\" error.\n        this.failConnection()\n      })\n  }\n\n  private processResponse(response: Response): void {\n    if (!response.body) {\n      this.failConnection()\n      return\n    }\n\n    if (isNetworkError(response)) {\n      this.reestablishConnection()\n      return\n    }\n\n    if (\n      response.status !== 200 ||\n      response.headers.get('content-type') !== 'text/event-stream'\n    ) {\n      this.failConnection()\n      return\n    }\n\n    this.announceConnection()\n    this.interpretResponseBody(response)\n  }\n\n  private announceConnection(): void {\n    queueMicrotask(() => {\n      if (this.readyState !== this.CLOSED) {\n        this.readyState = this.OPEN\n        this.dispatchEvent(new Event('open'))\n      }\n    })\n  }\n\n  private interpretResponseBody(response: Response): void {\n    const parsingStream = new EventSourceParsingStream({\n      message: (message) => {\n        if (message.id) {\n          this[kLastEventId] = message.id\n        }\n\n        if (message.retry) {\n          this[kReconnectionTime] = message.retry\n        }\n\n        const messageEvent = new MessageEvent(\n          message.event ? message.event : 'message',\n          {\n            data: message.data,\n            origin: this[kRequest].url,\n            lastEventId: this[kLastEventId],\n            cancelable: true,\n          },\n        )\n\n        this[kOnAnyMessage]?.(messageEvent)\n        this.dispatchEvent(messageEvent)\n      },\n      abort: () => {\n        throw new Error('Stream abort is not implemented')\n      },\n      close: () => {\n        this.failConnection()\n      },\n    })\n\n    response\n      .body!.pipeTo(parsingStream)\n      .then(() => {\n        this.processResponseEndOfBody(response)\n      })\n      .catch(() => {\n        this.failConnection()\n      })\n  }\n\n  private processResponseEndOfBody(response: Response): void {\n    if (!isNetworkError(response)) {\n      this.reestablishConnection()\n    }\n  }\n\n  private async reestablishConnection(): Promise<void> {\n    queueMicrotask(() => {\n      if (this.readyState === this.CLOSED) {\n        return\n      }\n\n      this.readyState = this.CONNECTING\n      this.dispatchEvent(new Event('error'))\n    })\n\n    await delay(this[kReconnectionTime])\n\n    queueMicrotask(async () => {\n      if (this.readyState !== this.CONNECTING) {\n        return\n      }\n\n      if (this[kLastEventId] !== '') {\n        this[kRequest].headers.set('last-event-id', this[kLastEventId])\n      }\n\n      await this.connect()\n    })\n  }\n\n  private failConnection(): void {\n    queueMicrotask(() => {\n      if (this.readyState !== this.CLOSED) {\n        this.readyState = this.CLOSED\n        this.dispatchEvent(new Event('error'))\n      }\n    })\n  }\n}\n\n/**\n * Checks if the given `Response` instance is a network error.\n * @see https://fetch.spec.whatwg.org/#concept-network-error\n */\nfunction isNetworkError(response: Response): boolean {\n  return (\n    response.type === 'error' &&\n    response.status === 0 &&\n    response.statusText === '' &&\n    Array.from(response.headers.entries()).length === 0 &&\n    response.body === null\n  )\n}\n\nconst enum ControlCharacters {\n  NewLine = 10,\n  CarriageReturn = 13,\n  Space = 32,\n  Colon = 58,\n}\n\ninterface EventSourceMessage {\n  id?: string\n  event?: string\n  data?: string\n  retry?: number\n}\n\nclass EventSourceParsingStream extends WritableStream {\n  private decoder: TextDecoder\n\n  private buffer?: Uint8Array\n  private position: number\n  private fieldLength?: number\n  private discardTrailingNewline = false\n\n  private message: EventSourceMessage = {\n    id: undefined,\n    event: undefined,\n    data: undefined,\n    retry: undefined,\n  }\n\n  constructor(\n    private underlyingSink: {\n      message: (message: EventSourceMessage) => void\n      abort?: (reason: any) => void\n      close?: () => void\n    },\n  ) {\n    super({\n      write: (chunk) => {\n        this.processResponseBodyChunk(chunk)\n      },\n      abort: (reason) => {\n        this.underlyingSink.abort?.(reason)\n      },\n      close: () => {\n        this.underlyingSink.close?.()\n      },\n    })\n\n    this.decoder = new TextDecoder()\n    this.position = 0\n  }\n\n  private resetMessage(): void {\n    this.message = {\n      id: undefined,\n      event: undefined,\n      data: undefined,\n      retry: undefined,\n    }\n  }\n\n  private processResponseBodyChunk(chunk: Uint8Array): void {\n    if (this.buffer == null) {\n      this.buffer = chunk\n      this.position = 0\n      this.fieldLength = -1\n    } else {\n      const nextBuffer = new Uint8Array(this.buffer.length + chunk.length)\n      nextBuffer.set(this.buffer)\n      nextBuffer.set(chunk, this.buffer.length)\n      this.buffer = nextBuffer\n    }\n\n    const bufferLength = this.buffer.length\n    let lineStart = 0\n\n    while (this.position < bufferLength) {\n      if (this.discardTrailingNewline) {\n        if (this.buffer[this.position] === ControlCharacters.NewLine) {\n          lineStart = ++this.position\n        }\n\n        this.discardTrailingNewline = false\n      }\n\n      let lineEnd = -1\n\n      for (; this.position < bufferLength && lineEnd === -1; ++this.position) {\n        switch (this.buffer[this.position]) {\n          case ControlCharacters.Colon: {\n            if (this.fieldLength === -1) {\n              this.fieldLength = this.position - lineStart\n            }\n            break\n          }\n\n          case ControlCharacters.CarriageReturn: {\n            this.discardTrailingNewline = true\n            break\n          }\n\n          case ControlCharacters.NewLine: {\n            lineEnd = this.position\n            break\n          }\n        }\n      }\n\n      if (lineEnd === -1) {\n        break\n      }\n\n      this.processLine(\n        this.buffer.subarray(lineStart, lineEnd),\n        this.fieldLength!,\n      )\n\n      lineStart = this.position\n      this.fieldLength = -1\n    }\n\n    if (lineStart === bufferLength) {\n      this.buffer = undefined\n    } else if (lineStart !== 0) {\n      this.buffer = this.buffer.subarray(lineStart)\n      this.position -= lineStart\n    }\n  }\n\n  private processLine(line: Uint8Array, fieldLength: number): void {\n    // New line indicates the end of the message. Dispatch it.\n    if (line.length === 0) {\n      // Prevent dispatching the message if the data is an empty string.\n      // That is a no-op per spec.\n      if (this.message.data === undefined) {\n        this.message.event = undefined\n        return\n      }\n\n      this.underlyingSink.message(this.message)\n      this.resetMessage()\n      return\n    }\n\n    // Otherwise, keep accumulating message fields until the new line.\n    if (fieldLength > 0) {\n      const field = this.decoder.decode(line.subarray(0, fieldLength))\n      const valueOffset =\n        fieldLength +\n        (line[fieldLength + 1] === ControlCharacters.Space ? 2 : 1)\n      const value = this.decoder.decode(line.subarray(valueOffset))\n\n      switch (field) {\n        case 'data': {\n          this.message.data = this.message.data\n            ? this.message.data + '\\n' + value\n            : value\n          break\n        }\n\n        case 'event': {\n          this.message.event = value\n          break\n        }\n\n        case 'id': {\n          this.message.id = value\n          break\n        }\n\n        case 'retry': {\n          const retry = parseInt(value, 10)\n\n          if (!isNaN(retry)) {\n            this.message.retry = retry\n          }\n          break\n        }\n      }\n    }\n  }\n}\n"],"mappings":"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","names":["ControlCharacters"]}