{"version":3,"file":"comlink.min.mjs","sources":["../../src/comlink.ts"],"sourcesContent":["/**\n * Copyright 2019 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *     http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n  Endpoint,\n  EventSource,\n  Message,\n  MessageType,\n  PostMessageWithOrigin,\n  WireValue,\n  WireValueType,\n} from \"./protocol\";\nexport { Endpoint };\n\nexport const proxyMarker = Symbol(\"Comlink.proxy\");\nexport const createEndpoint = Symbol(\"Comlink.endpoint\");\nexport const releaseProxy = Symbol(\"Comlink.releaseProxy\");\n\nconst throwMarker = Symbol(\"Comlink.thrown\");\n\n/**\n * Interface of values that were marked to be proxied with `comlink.proxy()`.\n * Can also be implemented by classes.\n */\nexport interface ProxyMarked {\n  [proxyMarker]: true;\n}\n\n/**\n * Takes a type and wraps it in a Promise, if it not already is one.\n * This is to avoid `Promise<Promise<T>>`.\n *\n * This is the inverse of `Unpromisify<T>`.\n */\ntype Promisify<T> = T extends Promise<unknown> ? T : Promise<T>;\n/**\n * Takes a type that may be Promise and unwraps the Promise type.\n * If `P` is not a Promise, it returns `P`.\n *\n * This is the inverse of `Promisify<T>`.\n */\ntype Unpromisify<P> = P extends Promise<infer T> ? T : P;\n\n/**\n * Takes the raw type of a remote property and returns the type that is visible to the local thread on the proxy.\n *\n * Note: This needs to be its own type alias, otherwise it will not distribute over unions.\n * See https://www.typescriptlang.org/docs/handbook/advanced-types.html#distributive-conditional-types\n */\ntype RemoteProperty<T> =\n  // If the value is a method, comlink will proxy it automatically.\n  // Objects are only proxied if they are marked to be proxied.\n  // Otherwise, the property is converted to a Promise that resolves the cloned value.\n  T extends Function | ProxyMarked ? Remote<T> : Promisify<T>;\n\n/**\n * Takes the raw type of a property as a remote thread would see it through a proxy (e.g. when passed in as a function\n * argument) and returns the type that the local thread has to supply.\n *\n * This is the inverse of `RemoteProperty<T>`.\n *\n * Note: This needs to be its own type alias, otherwise it will not distribute over unions. See\n * https://www.typescriptlang.org/docs/handbook/advanced-types.html#distributive-conditional-types\n */\ntype LocalProperty<T> = T extends Function | ProxyMarked\n  ? Local<T>\n  : Unpromisify<T>;\n\n/**\n * Proxies `T` if it is a `ProxyMarked`, clones it otherwise (as handled by structured cloning and transfer handlers).\n */\nexport type ProxyOrClone<T> = T extends ProxyMarked ? Remote<T> : T;\n/**\n * Inverse of `ProxyOrClone<T>`.\n */\nexport type UnproxyOrClone<T> = T extends RemoteObject<ProxyMarked>\n  ? Local<T>\n  : T;\n\n/**\n * Takes the raw type of a remote object in the other thread and returns the type as it is visible to the local thread\n * when proxied with `Comlink.proxy()`.\n *\n * This does not handle call signatures, which is handled by the more general `Remote<T>` type.\n *\n * @template T The raw type of a remote object as seen in the other thread.\n */\nexport type RemoteObject<T> = { [P in keyof T]: RemoteProperty<T[P]> };\n/**\n * Takes the type of an object as a remote thread would see it through a proxy (e.g. when passed in as a function\n * argument) and returns the type that the local thread has to supply.\n *\n * This does not handle call signatures, which is handled by the more general `Local<T>` type.\n *\n * This is the inverse of `RemoteObject<T>`.\n *\n * @template T The type of a proxied object.\n */\nexport type LocalObject<T> = { [P in keyof T]: LocalProperty<T[P]> };\n\n/**\n * Additional special comlink methods available on each proxy returned by `Comlink.wrap()`.\n */\nexport interface ProxyMethods {\n  [createEndpoint]: () => Promise<MessagePort>;\n  [releaseProxy]: () => void;\n}\n\n/**\n * Takes the raw type of a remote object, function or class in the other thread and returns the type as it is visible to\n * the local thread from the proxy return value of `Comlink.wrap()` or `Comlink.proxy()`.\n */\nexport type Remote<T> =\n  // Handle properties\n  RemoteObject<T> &\n    // Handle call signature (if present)\n    (T extends (...args: infer TArguments) => infer TReturn\n      ? (\n          ...args: { [I in keyof TArguments]: UnproxyOrClone<TArguments[I]> }\n        ) => Promisify<ProxyOrClone<Unpromisify<TReturn>>>\n      : unknown) &\n    // Handle construct signature (if present)\n    // The return of construct signatures is always proxied (whether marked or not)\n    (T extends { new (...args: infer TArguments): infer TInstance }\n      ? {\n          new (\n            ...args: {\n              [I in keyof TArguments]: UnproxyOrClone<TArguments[I]>;\n            }\n          ): Promisify<Remote<TInstance>>;\n        }\n      : unknown) &\n    // Include additional special comlink methods available on the proxy.\n    ProxyMethods;\n\n/**\n * Expresses that a type can be either a sync or async.\n */\ntype MaybePromise<T> = Promise<T> | T;\n\n/**\n * Takes the raw type of a remote object, function or class as a remote thread would see it through a proxy (e.g. when\n * passed in as a function argument) and returns the type the local thread has to supply.\n *\n * This is the inverse of `Remote<T>`. It takes a `Remote<T>` and returns its original input `T`.\n */\nexport type Local<T> =\n  // Omit the special proxy methods (they don't need to be supplied, comlink adds them)\n  Omit<LocalObject<T>, keyof ProxyMethods> &\n    // Handle call signatures (if present)\n    (T extends (...args: infer TArguments) => infer TReturn\n      ? (\n          ...args: { [I in keyof TArguments]: ProxyOrClone<TArguments[I]> }\n        ) => // The raw function could either be sync or async, but is always proxied automatically\n        MaybePromise<UnproxyOrClone<Unpromisify<TReturn>>>\n      : unknown) &\n    // Handle construct signature (if present)\n    // The return of construct signatures is always proxied (whether marked or not)\n    (T extends { new (...args: infer TArguments): infer TInstance }\n      ? {\n          new (\n            ...args: {\n              [I in keyof TArguments]: ProxyOrClone<TArguments[I]>;\n            }\n          ): // The raw constructor could either be sync or async, but is always proxied automatically\n          MaybePromise<Local<Unpromisify<TInstance>>>;\n        }\n      : unknown);\n\nconst isObject = (val: unknown): val is object =>\n  (typeof val === \"object\" && val !== null) || typeof val === \"function\";\n\n/**\n * Customizes the serialization of certain values as determined by `canHandle()`.\n *\n * @template T The input type being handled by this transfer handler.\n * @template S The serialized type sent over the wire.\n */\nexport interface TransferHandler<T, S> {\n  /**\n   * Gets called for every value to determine whether this transfer handler\n   * should serialize the value, which includes checking that it is of the right\n   * type (but can perform checks beyond that as well).\n   */\n  canHandle(value: unknown): value is T;\n\n  /**\n   * Gets called with the value if `canHandle()` returned `true` to produce a\n   * value that can be sent in a message, consisting of structured-cloneable\n   * values and/or transferrable objects.\n   */\n  serialize(value: T): [S, Transferable[]];\n\n  /**\n   * Gets called to deserialize an incoming value that was serialized in the\n   * other thread with this transfer handler (known through the name it was\n   * registered under).\n   */\n  deserialize(value: S): T;\n}\n\n/**\n * Internal transfer handle to handle objects marked to proxy.\n */\nconst proxyTransferHandler: TransferHandler<object, MessagePort> = {\n  canHandle: (val): val is ProxyMarked =>\n    isObject(val) && (val as ProxyMarked)[proxyMarker],\n  serialize(obj) {\n    const { port1, port2 } = new MessageChannel();\n    expose(obj, port1);\n    return [port2, [port2]];\n  },\n  deserialize(port) {\n    port.start();\n    return wrap(port);\n  },\n};\n\ninterface ThrownValue {\n  [throwMarker]: unknown; // just needs to be present\n  value: unknown;\n}\ntype SerializedThrownValue =\n  | { isError: true; value: Error }\n  | { isError: false; value: unknown };\n\n/**\n * Internal transfer handler to handle thrown exceptions.\n */\nconst throwTransferHandler: TransferHandler<\n  ThrownValue,\n  SerializedThrownValue\n> = {\n  canHandle: (value): value is ThrownValue =>\n    isObject(value) && throwMarker in value,\n  serialize({ value }) {\n    let serialized: SerializedThrownValue;\n    if (value instanceof Error) {\n      serialized = {\n        isError: true,\n        value: {\n          message: value.message,\n          name: value.name,\n          stack: value.stack,\n        },\n      };\n    } else {\n      serialized = { isError: false, value };\n    }\n    return [serialized, []];\n  },\n  deserialize(serialized) {\n    if (serialized.isError) {\n      throw Object.assign(\n        new Error(serialized.value.message),\n        serialized.value\n      );\n    }\n    throw serialized.value;\n  },\n};\n\n/**\n * Allows customizing the serialization of certain values.\n */\nexport const transferHandlers = new Map<\n  string,\n  TransferHandler<unknown, unknown>\n>([\n  [\"proxy\", proxyTransferHandler],\n  [\"throw\", throwTransferHandler],\n]);\n\nexport function expose(obj: any, ep: Endpoint = self as any) {\n  ep.addEventListener(\"message\", function callback(ev: MessageEvent) {\n    if (!ev || !ev.data) {\n      return;\n    }\n    const { id, type, path } = {\n      path: [] as string[],\n      ...(ev.data as Message),\n    };\n    const argumentList = (ev.data.argumentList || []).map(fromWireValue);\n    let returnValue;\n    try {\n      const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);\n      const rawValue = path.reduce((obj, prop) => obj[prop], obj);\n      switch (type) {\n        case MessageType.GET:\n          {\n            returnValue = rawValue;\n          }\n          break;\n        case MessageType.SET:\n          {\n            parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);\n            returnValue = true;\n          }\n          break;\n        case MessageType.APPLY:\n          {\n            returnValue = rawValue.apply(parent, argumentList);\n          }\n          break;\n        case MessageType.CONSTRUCT:\n          {\n            const value = new rawValue(...argumentList);\n            returnValue = proxy(value);\n          }\n          break;\n        case MessageType.ENDPOINT:\n          {\n            const { port1, port2 } = new MessageChannel();\n            expose(obj, port2);\n            returnValue = transfer(port1, [port1]);\n          }\n          break;\n        case MessageType.RELEASE:\n          {\n            returnValue = undefined;\n          }\n          break;\n        default:\n          return;\n      }\n    } catch (value) {\n      returnValue = { value, [throwMarker]: 0 };\n    }\n    Promise.resolve(returnValue)\n      .catch((value) => {\n        return { value, [throwMarker]: 0 };\n      })\n      .then((returnValue) => {\n        const [wireValue, transferables] = toWireValue(returnValue);\n        ep.postMessage({ ...wireValue, id }, transferables);\n        if (type === MessageType.RELEASE) {\n          // detach and deactive after sending release response above.\n          ep.removeEventListener(\"message\", callback as any);\n          closeEndPoint(ep);\n        }\n      });\n  } as any);\n  if (ep.start) {\n    ep.start();\n  }\n}\n\nfunction isMessagePort(endpoint: Endpoint): endpoint is MessagePort {\n  return endpoint.constructor.name === \"MessagePort\";\n}\n\nfunction closeEndPoint(endpoint: Endpoint) {\n  if (isMessagePort(endpoint)) endpoint.close();\n}\n\nexport function wrap<T>(ep: Endpoint, target?: any): Remote<T> {\n  return createProxy<T>(ep, [], target) as any;\n}\n\nfunction throwIfProxyReleased(isReleased: boolean) {\n  if (isReleased) {\n    throw new Error(\"Proxy has been released and is not useable\");\n  }\n}\n\nfunction createProxy<T>(\n  ep: Endpoint,\n  path: (string | number | symbol)[] = [],\n  target: object = function () {}\n): Remote<T> {\n  let isProxyReleased = false;\n  const proxy = new Proxy(target, {\n    get(_target, prop) {\n      throwIfProxyReleased(isProxyReleased);\n      if (prop === releaseProxy) {\n        return () => {\n          return requestResponseMessage(ep, {\n            type: MessageType.RELEASE,\n            path: path.map((p) => p.toString()),\n          }).then(() => {\n            closeEndPoint(ep);\n            isProxyReleased = true;\n          });\n        };\n      }\n      if (prop === \"then\") {\n        if (path.length === 0) {\n          return { then: () => proxy };\n        }\n        const r = requestResponseMessage(ep, {\n          type: MessageType.GET,\n          path: path.map((p) => p.toString()),\n        }).then(fromWireValue);\n        return r.then.bind(r);\n      }\n      return createProxy(ep, [...path, prop]);\n    },\n    set(_target, prop, rawValue) {\n      throwIfProxyReleased(isProxyReleased);\n      // FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n      // boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n      const [value, transferables] = toWireValue(rawValue);\n      return requestResponseMessage(\n        ep,\n        {\n          type: MessageType.SET,\n          path: [...path, prop].map((p) => p.toString()),\n          value,\n        },\n        transferables\n      ).then(fromWireValue) as any;\n    },\n    apply(_target, _thisArg, rawArgumentList) {\n      throwIfProxyReleased(isProxyReleased);\n      const last = path[path.length - 1];\n      if ((last as any) === createEndpoint) {\n        return requestResponseMessage(ep, {\n          type: MessageType.ENDPOINT,\n        }).then(fromWireValue);\n      }\n      // We just pretend that `bind()` didn’t happen.\n      if (last === \"bind\") {\n        return createProxy(ep, path.slice(0, -1));\n      }\n      const [argumentList, transferables] = processArguments(rawArgumentList);\n      return requestResponseMessage(\n        ep,\n        {\n          type: MessageType.APPLY,\n          path: path.map((p) => p.toString()),\n          argumentList,\n        },\n        transferables\n      ).then(fromWireValue);\n    },\n    construct(_target, rawArgumentList) {\n      throwIfProxyReleased(isProxyReleased);\n      const [argumentList, transferables] = processArguments(rawArgumentList);\n      return requestResponseMessage(\n        ep,\n        {\n          type: MessageType.CONSTRUCT,\n          path: path.map((p) => p.toString()),\n          argumentList,\n        },\n        transferables\n      ).then(fromWireValue);\n    },\n  });\n  return proxy as any;\n}\n\nfunction myFlat<T>(arr: (T | T[])[]): T[] {\n  return Array.prototype.concat.apply([], arr);\n}\n\nfunction processArguments(argumentList: any[]): [WireValue[], Transferable[]] {\n  const processed = argumentList.map(toWireValue);\n  return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n}\n\nconst transferCache = new WeakMap<any, Transferable[]>();\nexport function transfer<T>(obj: T, transfers: Transferable[]): T {\n  transferCache.set(obj, transfers);\n  return obj;\n}\n\nexport function proxy<T>(obj: T): T & ProxyMarked {\n  return Object.assign(obj, { [proxyMarker]: true }) as any;\n}\n\nexport function windowEndpoint(\n  w: PostMessageWithOrigin,\n  context: EventSource = self,\n  targetOrigin = \"*\"\n): Endpoint {\n  return {\n    postMessage: (msg: any, transferables: Transferable[]) =>\n      w.postMessage(msg, targetOrigin, transferables),\n    addEventListener: context.addEventListener.bind(context),\n    removeEventListener: context.removeEventListener.bind(context),\n  };\n}\n\nfunction toWireValue(value: any): [WireValue, Transferable[]] {\n  for (const [name, handler] of transferHandlers) {\n    if (handler.canHandle(value)) {\n      const [serializedValue, transferables] = handler.serialize(value);\n      return [\n        {\n          type: WireValueType.HANDLER,\n          name,\n          value: serializedValue,\n        },\n        transferables,\n      ];\n    }\n  }\n  return [\n    {\n      type: WireValueType.RAW,\n      value,\n    },\n    transferCache.get(value) || [],\n  ];\n}\n\nfunction fromWireValue(value: WireValue): any {\n  switch (value.type) {\n    case WireValueType.HANDLER:\n      return transferHandlers.get(value.name)!.deserialize(value.value);\n    case WireValueType.RAW:\n      return value.value;\n  }\n}\n\nfunction requestResponseMessage(\n  ep: Endpoint,\n  msg: Message,\n  transfers?: Transferable[]\n): Promise<WireValue> {\n  return new Promise((resolve) => {\n    const id = generateUUID();\n    ep.addEventListener(\"message\", function l(ev: MessageEvent) {\n      if (!ev.data || !ev.data.id || ev.data.id !== id) {\n        return;\n      }\n      ep.removeEventListener(\"message\", l as any);\n      resolve(ev.data);\n    } as any);\n    if (ep.start) {\n      ep.start();\n    }\n    ep.postMessage({ id, ...msg }, transfers);\n  });\n}\n\nfunction generateUUID(): string {\n  return new Array(4)\n    .fill(0)\n    .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))\n    .join(\"-\");\n}\n"],"names":["proxyMarker","Symbol","createEndpoint","releaseProxy","throwMarker","isObject","val","transferHandlers","Map","canHandle","[object Object]","obj","port1","port2","MessageChannel","expose","deserialize","port","start","wrap","value","serialized","Error","isError","message","name","stack","Object","assign","ep","self","addEventListener","callback","ev","data","id","type","path","argumentList","map","fromWireValue","returnValue","parent","slice","reduce","prop","rawValue","apply","proxy","transfer","undefined","Promise","resolve","catch","then","wireValue","transferables","toWireValue","postMessage","removeEventListener","closeEndPoint","endpoint","constructor","isMessagePort","close","target","createProxy","isProxyReleased","Proxy","_target","throwIfProxyReleased","requestResponseMessage","p","toString","length","r","bind","_thisArg","rawArgumentList","last","processArguments","isReleased","processed","v","arr","Array","prototype","concat","transferCache","WeakMap","transfers","set","windowEndpoint","w","context","targetOrigin","msg","handler","serializedValue","serialize","get","fill","Math","floor","random","Number","MAX_SAFE_INTEGER","join","l"],"mappings":"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"}