{"version":3,"sources":["../../src/remoteValue/exposeToRemote.ts"],"sourcesContent":["import { Adaptor, AdaptorPackageData } from '../adaptor'\r\nimport { RemoteError, response } from '../response'\r\nimport { RemoteCallData } from './type'\r\n\r\ntype AdaptorData = AdaptorPackageData<RemoteCallData>\r\n\r\ninterface ExposeProps {\r\n  globalName: string\r\n  adaptor: Adaptor\r\n  /**\r\n   * ['*'] or ['device_id_1', 'device_id_2']\r\n   */\r\n  exposeTo: string[]\r\n  /**\r\n   * 你可以在该回调中抛错，以阻止远程调用，\r\n   * 也可以修改传入的 data\r\n   */\r\n  onRequest?: (e: AdaptorData) => RemoteCallData | Promise<RemoteCallData>\r\n  /**\r\n   * 如果你想要自定义处理函数,\r\n   * 需要谨慎且完善地处理各种 paths, args,\r\n   * 以避免远程调用时出现未预期的错误。\r\n   *\r\n   * ---\r\n   *\r\n   * 我的默认处理程序谨供参考:\r\n   * ``` ts\r\n   * let target = obj\r\n   * for (let i = 0; i < data.paths.length; i += 1) {\r\n   *   target = target[data.paths[i] as keyof typeof target] as typeof target\r\n   * }\r\n   * if (target instanceof Function) {\r\n   *   return target(...data.args)\r\n   * }\r\n   * return target\r\n   * ```\r\n   *\r\n   * @returns 返回值将会被发送给远程调用方，可以是立即数，也可以是 Promise（Promise 会 await 后再返回）\r\n   */\r\n  handler?: (e: AdaptorData) => unknown\r\n}\r\n\r\nfunction defaultOnRequest(e: AdaptorData) {\r\n  return e.data\r\n}\r\n\r\nconst geneDefaultHandler: <T>(obj: T) => (data: AdaptorData) => unknown =\r\n  (obj) =>\r\n  ({ data }) => {\r\n    let target = obj\r\n    for (let i = 0; i < data.paths.length; i += 1) {\r\n      target = target[data.paths[i] as keyof typeof target] as typeof target\r\n    }\r\n    if (target instanceof Function) {\r\n      return target(...data.args)\r\n    }\r\n    return target\r\n  }\r\n\r\nexport function isRemoteValueEvent(eventName: string) {\r\n  return eventName.startsWith('__REMOTE_VALUE_REQ__')\r\n}\r\n\r\nexport function exposeToRemote<T extends object>(obj: T, options: ExposeProps) {\r\n  const {\r\n    globalName,\r\n    adaptor,\r\n    exposeTo,\r\n    handler: inputHandler,\r\n    onRequest = defaultOnRequest,\r\n  } = options\r\n  const callback = async (e: AdaptorPackageData) => {\r\n    try {\r\n      const data = await onRequest(e as AdaptorData)\r\n      if (!exposeTo.includes(e.deviceId) && !exposeTo.includes('*')) {\r\n        throw new RemoteError('permission denied')\r\n      }\r\n      const handler = inputHandler ?? geneDefaultHandler(obj)\r\n      const res = await handler({\r\n        ...e,\r\n        data,\r\n      })\r\n      adaptor.emit({\r\n        name: e.callbackName ?? 'IMPOSSIBLE_NO_CALLBACK_NAME',\r\n        deviceId: e.targetDeviceId,\r\n        targetDeviceId: e.deviceId,\r\n        data: response.success(res),\r\n      })\r\n    } catch (error) {\r\n      adaptor.emit({\r\n        name: e.callbackName ?? 'IMPOSSIBLE_NO_CALLBACK_NAME',\r\n        deviceId: e.targetDeviceId,\r\n        targetDeviceId: e.deviceId,\r\n        data: response.error(RemoteError.fromError(error)),\r\n      })\r\n    }\r\n  }\r\n  adaptor.on(`__REMOTE_VALUE_REQ__${globalName}`, callback)\r\n  return () => {\r\n    adaptor.off(`__REMOTE_VALUE_REQ__${globalName}`, callback)\r\n  }\r\n}\r\n"],"mappings":"AACA,OAAS,eAAAA,EAAa,YAAAC,MAAgB,cAyCtC,SAASC,EAAiBC,EAAgB,CACxC,OAAOA,EAAE,IACX,CAEA,MAAMC,EACHC,GACD,CAAC,CAAE,KAAAC,CAAK,IAAM,CACZ,IAAIC,EAASF,EACb,QAASG,EAAI,EAAGA,EAAIF,EAAK,MAAM,OAAQE,GAAK,EAC1CD,EAASA,EAAOD,EAAK,MAAME,CAAC,CAAwB,EAEtD,OAAID,aAAkB,SACbA,EAAO,GAAGD,EAAK,IAAI,EAErBC,CACT,EAEK,SAASE,EAAmBC,EAAmB,CACpD,OAAOA,EAAU,WAAW,sBAAsB,CACpD,CAEO,SAASC,EAAiCN,EAAQO,EAAsB,CAC7E,KAAM,CACJ,WAAAC,EACA,QAAAC,EACA,SAAAC,EACA,QAASC,EACT,UAAAC,EAAYf,CACd,EAAIU,EACEM,EAAW,MAAO,GAA0B,CAChD,GAAI,CACF,MAAMZ,EAAO,MAAMW,EAAU,CAAgB,EAC7C,GAAI,CAACF,EAAS,SAAS,EAAE,QAAQ,GAAK,CAACA,EAAS,SAAS,GAAG,EAC1D,MAAM,IAAIf,EAAY,mBAAmB,EAG3C,MAAMmB,EAAM,MADIH,GAAgBZ,EAAmBC,CAAG,GAC5B,CACxB,GAAG,EACH,KAAAC,CACF,CAAC,EACDQ,EAAQ,KAAK,CACX,KAAM,EAAE,cAAgB,8BACxB,SAAU,EAAE,eACZ,eAAgB,EAAE,SAClB,KAAMb,EAAS,QAAQkB,CAAG,CAC5B,CAAC,CACH,OAASC,EAAO,CACdN,EAAQ,KAAK,CACX,KAAM,EAAE,cAAgB,8BACxB,SAAU,EAAE,eACZ,eAAgB,EAAE,SAClB,KAAMb,EAAS,MAAMD,EAAY,UAAUoB,CAAK,CAAC,CACnD,CAAC,CACH,CACF,EACA,OAAAN,EAAQ,GAAG,uBAAuBD,CAAU,GAAIK,CAAQ,EACjD,IAAM,CACXJ,EAAQ,IAAI,uBAAuBD,CAAU,GAAIK,CAAQ,CAC3D,CACF","names":["RemoteError","response","defaultOnRequest","e","geneDefaultHandler","obj","data","target","i","isRemoteValueEvent","eventName","exposeToRemote","options","globalName","adaptor","exposeTo","inputHandler","onRequest","callback","res","error"]}