{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import ReconnectingWebSocket from \"./ws\";\n\nimport type * as RWS from \"./ws\";\n\ntype Maybe<T> = T | null | undefined;\ntype Params = Record<string, Maybe<string>>;\nconst valueIsNotNil = <T>(\n  keyValuePair: [string, Maybe<T>]\n): keyValuePair is [string, T] =>\n  keyValuePair[1] !== null && keyValuePair[1] !== undefined;\n\nexport type PartySocketOptions = Omit<RWS.Options, \"constructor\"> & {\n  id?: string; // the id of the client\n  host: string; // base url for the party\n  room?: string; // the room to connect to\n  party?: string; // the party to connect to (defaults to main)\n  basePath?: string; // the base path to use for the party\n  prefix?: string; // the prefix to use for the party\n  protocol?: \"ws\" | \"wss\";\n  protocols?: string[];\n  path?: string; // the path to connect to\n  query?: Params | (() => Params | Promise<Params>);\n  // headers\n};\n\nexport type PartyFetchOptions = {\n  host: string; // base url for the party\n  room: string; // the room to connect to\n  party?: string; // the party to fetch from (defaults to main)\n  basePath?: string; // the base path to use for the party\n  prefix?: string; // the prefix to use for the party\n  path?: string; // the path to fetch from\n  protocol?: \"http\" | \"https\";\n  query?: Params | (() => Params | Promise<Params>);\n  fetch?: typeof fetch;\n};\n\nfunction generateUUID(): string {\n  // Public Domain/MIT\n  if (typeof crypto !== \"undefined\" && crypto.randomUUID) {\n    return crypto.randomUUID();\n  }\n  let d = new Date().getTime(); //Timestamp\n  let d2 =\n    (typeof performance !== \"undefined\" &&\n      performance.now &&\n      performance.now() * 1000) ||\n    0; //Time in microseconds since page-load or 0 if unsupported\n  // biome-ignore lint/complexity/useArrowFunction: <explanation>\n  return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function (c) {\n    let r = Math.random() * 16; //random number between 0 and 16\n    if (d > 0) {\n      //Use timestamp until depleted\n      r = (d + r) % 16 | 0;\n      d = Math.floor(d / 16);\n    } else {\n      //Use microseconds since page-load if supported\n      r = (d2 + r) % 16 | 0;\n      d2 = Math.floor(d2 / 16);\n    }\n    return (c === \"x\" ? r : (r & 0x3) | 0x8).toString(16);\n  });\n}\n\nfunction getPartyInfo(\n  partySocketOptions: PartySocketOptions | PartyFetchOptions,\n  defaultProtocol: \"http\" | \"ws\",\n  defaultParams: Record<string, string> = {}\n) {\n  const {\n    host: rawHost,\n    path: rawPath,\n    protocol: rawProtocol,\n    room,\n    party,\n    basePath,\n    prefix,\n    query\n  } = partySocketOptions;\n\n  // strip the protocol from the beginning of `host` if any\n  let host = rawHost.replace(/^(http|https|ws|wss):\\/\\//, \"\");\n  // if user provided a trailing slash, remove it\n  if (host.endsWith(\"/\")) {\n    host = host.slice(0, -1);\n  }\n\n  if (rawPath?.startsWith(\"/\")) {\n    throw new Error(\"path must not start with a slash\");\n  }\n\n  const name = party ?? \"main\";\n  const path = rawPath ? `/${rawPath}` : \"\";\n  const protocol =\n    rawProtocol ||\n    (host.startsWith(\"localhost:\") ||\n    host.startsWith(\"127.0.0.1:\") ||\n    host.startsWith(\"192.168.\") ||\n    host.startsWith(\"10.\") ||\n    (host.startsWith(\"172.\") &&\n      host.split(\".\")[1] >= \"16\" &&\n      host.split(\".\")[1] <= \"31\") ||\n    host.startsWith(\"[::ffff:7f00:1]:\")\n      ? // http / ws\n        defaultProtocol\n      : // https / wss\n        `${defaultProtocol}s`);\n\n  const baseUrl = `${protocol}://${host}/${basePath || `${prefix || \"parties\"}/${name}/${room}`}${path}`;\n\n  const makeUrl = (query: Params = {}) =>\n    `${baseUrl}?${new URLSearchParams([\n      ...Object.entries(defaultParams),\n      ...Object.entries(query).filter(valueIsNotNil)\n    ])}`;\n\n  // allow urls to be defined as functions\n  const urlProvider =\n    typeof query === \"function\"\n      ? async () => makeUrl(await query())\n      : makeUrl(query);\n\n  return {\n    host,\n    path,\n    room,\n    name,\n    protocol,\n    partyUrl: baseUrl,\n    urlProvider\n  };\n}\n\n// things that nathanboktae/robust-websocket claims are better:\n// doesn't do anything in offline mode (?)\n// \"natively aware of error codes\"\n// can do custom reconnect strategies\n\n// TODO: incorporate the above notes\nexport default class PartySocket extends ReconnectingWebSocket {\n  _pk!: string;\n  _pkurl!: string;\n  name!: string;\n  room?: string;\n  host!: string;\n  path!: string;\n\n  constructor(readonly partySocketOptions: PartySocketOptions) {\n    const wsOptions = getWSOptions(partySocketOptions);\n\n    super(wsOptions.urlProvider, wsOptions.protocols, wsOptions.socketOptions);\n\n    this.setWSProperties(wsOptions);\n  }\n\n  public updateProperties(partySocketOptions: Partial<PartySocketOptions>) {\n    const wsOptions = getWSOptions({\n      ...this.partySocketOptions,\n      ...partySocketOptions,\n      host: partySocketOptions.host ?? this.host,\n      room: partySocketOptions.room ?? this.room,\n      path: partySocketOptions.path ?? this.path\n    });\n\n    this._url = wsOptions.urlProvider;\n    this._protocols = wsOptions.protocols;\n    this._options = wsOptions.socketOptions;\n\n    this.setWSProperties(wsOptions);\n  }\n\n  private setWSProperties(wsOptions: ReturnType<typeof getWSOptions>) {\n    const { _pk, _pkurl, name, room, host, path } = wsOptions;\n\n    this._pk = _pk;\n    this._pkurl = _pkurl;\n    this.name = name;\n    this.room = room;\n    this.host = host;\n    this.path = path;\n  }\n\n  public reconnect(\n    code?: number | undefined,\n    reason?: string | undefined\n  ): void {\n    if (!this.room || !this.host) {\n      throw new Error(\n        \"The room and host must be set before connecting, use `updateProperties` method to set them or pass them to the constructor.\"\n      );\n    }\n    super.reconnect(code, reason);\n  }\n\n  get id() {\n    return this._pk;\n  }\n\n  /**\n   * Exposes the static PartyKit room URL without applying query parameters.\n   * To access the currently connected WebSocket url, use PartySocket#url.\n   */\n  get roomUrl(): string {\n    return this._pkurl;\n  }\n\n  // a `fetch` method that uses (almost) the same options as `PartySocket`\n  static async fetch(\n    options: PartyFetchOptions,\n    init?: RequestInit\n  ): Promise<Response> {\n    const party = getPartyInfo(options, \"http\");\n    const url =\n      typeof party.urlProvider === \"string\"\n        ? party.urlProvider\n        : await party.urlProvider();\n    const doFetch = options.fetch ?? fetch;\n    return doFetch(url, init);\n  }\n}\n\nexport { PartySocket };\n\nexport { ReconnectingWebSocket as WebSocket };\n\nfunction getWSOptions(partySocketOptions: PartySocketOptions) {\n  const {\n    id,\n    host: _host,\n    path: _path,\n    party: _party,\n    room: _room,\n    protocol: _protocol,\n    query: _query,\n    protocols,\n    ...socketOptions\n  } = partySocketOptions;\n\n  const _pk = id || generateUUID();\n  const party = getPartyInfo(partySocketOptions, \"ws\", { _pk });\n\n  return {\n    _pk: _pk,\n    _pkurl: party.partyUrl,\n    name: party.name,\n    room: party.room,\n    host: party.host,\n    path: party.path,\n    protocols: protocols,\n    socketOptions: socketOptions,\n    urlProvider: party.urlProvider\n  };\n}\n"],"mappings":"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","names":["query"]}