{"version":3,"file":"createRPCClient.cjs","sources":["../../../src/client/createRPCClient.ts"],"sourcesContent":["import { encode, decode } from \"@msgpack/msgpack\";\n\nimport { isErrorLike } from \"../lib/isErrorLike\";\nimport { isR19ErrorLike } from \"../lib/isR19ErrorLike\";\nimport { replaceLeaves } from \"../lib/replaceLeaves\";\n\nimport { Procedures, Procedure, ProcedureCallServerResponse } from \"../types\";\nimport { R19Error } from \"../R19Error\";\n\nconst createArbitrarilyNestedFunction = <T>(\n\thandler: (path: string[], args: unknown[]) => unknown,\n\tpath: string[] = [],\n): T => {\n\treturn new Proxy(() => void 0, {\n\t\tapply(_target, _this, args) {\n\t\t\treturn handler(path, args);\n\t\t},\n\t\tget(_target, property) {\n\t\t\treturn createArbitrarilyNestedFunction(handler, [\n\t\t\t\t...path,\n\t\t\t\tproperty.toString(),\n\t\t\t]);\n\t\t},\n\t}) as T;\n};\n\n// `RPCClient` is currently a clone of `TransformProcedures`, but that could\n// change in the future.\nexport type RPCClient<TProcedures extends Procedures> =\n\tTransformProcedures<TProcedures>;\n\ntype TransformProcedures<TProcedures> =\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tTProcedures extends Procedures\n\t\t? { [P in keyof TProcedures]: TransformProcedures<TProcedures[P]> }\n\t\t: // eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tTProcedures extends Procedure<any>\n\t\t\t? TransformProcedure<TProcedures>\n\t\t\t: TProcedures;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype TransformProcedure<TProcedure extends Procedure<any>> = (\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t...args: TransformProcedureArgs<Parameters<TProcedure>> extends any[]\n\t\t? TransformProcedureArgs<Parameters<TProcedure>>\n\t\t: []\n) => Promise<TransformProcedureReturnType<Awaited<ReturnType<TProcedure>>>>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype TransformProcedureArgs<TArgs extends any[]> = {\n\t[P in keyof TArgs]: TransformProcedureArg<TArgs[P]>;\n};\n\ntype TransformProcedureArg<TArg> = TArg extends\n\t| Record<string, unknown>\n\t| unknown[]\n\t? {\n\t\t\t[P in keyof TArg]: TransformProcedureArg<TArg[P]>;\n\t\t}\n\t: TArg extends Buffer\n\t\t? Blob\n\t\t: TArg;\n\ntype TransformProcedureReturnType<TReturnType> = TReturnType extends\n\t| Record<string, unknown>\n\t| unknown[]\n\t? {\n\t\t\t[P in keyof TReturnType]: TransformProcedureReturnType<TReturnType[P]>;\n\t\t}\n\t: TReturnType extends Buffer\n\t\t? Blob\n\t\t: TReturnType extends Error\n\t\t\t? {\n\t\t\t\t\tname: string;\n\t\t\t\t\tmessage: string;\n\t\t\t\t}\n\t\t\t: TReturnType;\n\nexport type ResponseLike = {\n\tarrayBuffer: () => Promise<ArrayBuffer>;\n};\nexport type FetchLike = (\n\tinput: string,\n\tinit: {\n\t\tmethod: \"POST\";\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\tbody: any;\n\t\theaders: Record<string, string>;\n\t},\n) => Promise<ResponseLike>;\n\nexport type CreateRPCClientArgs = {\n\tserverURL: string;\n\tfetch?: FetchLike;\n};\n\nexport const createRPCClient = <TProcedures extends Procedures>(\n\targs: CreateRPCClientArgs,\n): RPCClient<TProcedures> => {\n\tconst resolvedFetch: FetchLike =\n\t\targs.fetch || globalThis.fetch.bind(globalThis);\n\n\treturn createArbitrarilyNestedFunction(\n\t\tasync (procedurePath, procedureArgs) => {\n\t\t\tconst preparedProcedureArgs = await replaceLeaves(\n\t\t\t\tprocedureArgs,\n\t\t\t\tasync (value) => {\n\t\t\t\t\tif (value instanceof Blob) {\n\t\t\t\t\t\treturn new Uint8Array(await value.arrayBuffer());\n\t\t\t\t\t}\n\n\t\t\t\t\tif (typeof value === \"function\") {\n\t\t\t\t\t\tthrow new R19Error(\"r19 does not support function arguments.\", {\n\t\t\t\t\t\t\tprocedurePath,\n\t\t\t\t\t\t\tprocedureArgs,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\treturn value;\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst body = encode(\n\t\t\t\t{\n\t\t\t\t\tprocedurePath: procedurePath,\n\t\t\t\t\tprocedureArgs: preparedProcedureArgs,\n\t\t\t\t},\n\t\t\t\t{ ignoreUndefined: true },\n\t\t\t);\n\n\t\t\tconst res = await resolvedFetch(args.serverURL, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tbody,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/msgpack\",\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst arrayBuffer = await res.arrayBuffer();\n\t\t\tconst resObject = decode(\n\t\t\t\tnew Uint8Array(arrayBuffer),\n\t\t\t) as ProcedureCallServerResponse;\n\n\t\t\tif (\"error\" in resObject) {\n\t\t\t\tconst resError = resObject.error;\n\n\t\t\t\tif (isR19ErrorLike(resError)) {\n\t\t\t\t\tconst error = new R19Error(resError.message, {\n\t\t\t\t\t\tprocedurePath,\n\t\t\t\t\t\tprocedureArgs,\n\t\t\t\t\t});\n\t\t\t\t\terror.stack = resError.stack;\n\n\t\t\t\t\tthrow error;\n\t\t\t\t} else if (isErrorLike(resError)) {\n\t\t\t\t\tconst error = new Error(resError.message);\n\t\t\t\t\terror.name = resError.name;\n\t\t\t\t\terror.stack = resError.stack;\n\n\t\t\t\t\tthrow error;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new R19Error(\n\t\t\t\t\t\t\"An unexpected response was received from the RPC server.\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tprocedurePath,\n\t\t\t\t\t\t\tprocedureArgs,\n\t\t\t\t\t\t\tcause: resObject,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn replaceLeaves(resObject.data, async (value) => {\n\t\t\t\t\tif (value instanceof Uint8Array) {\n\t\t\t\t\t\treturn new Blob([value]);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn value;\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t);\n};\n"],"names":["replaceLeaves","R19Error","encode","decode","isR19ErrorLike","isErrorLike"],"mappings":";;;;;;;AASA,MAAM,kCAAkC,CACvC,SACA,OAAiB,OACX;AACC,SAAA,IAAI,MAAM,MAAM,QAAQ;AAAA,IAC9B,MAAM,SAAS,OAAO,MAAI;AAClB,aAAA,QAAQ,MAAM,IAAI;AAAA,IAC1B;AAAA,IACA,IAAI,SAAS,UAAQ;AACpB,aAAO,gCAAgC,SAAS;AAAA,QAC/C,GAAG;AAAA,QACH,SAAS,SAAU;AAAA,MAAA,CACnB;AAAA,IACF;AAAA,EAAA,CACA;AACF;AAwEa,MAAA,kBAAkB,CAC9B,SAC2B;AAC3B,QAAM,gBACL,KAAK,SAAS,WAAW,MAAM,KAAK,UAAU;AAExC,SAAA,gCACN,OAAO,eAAe,kBAAiB;AACtC,UAAM,wBAAwB,MAAMA,cAAAA,cACnC,eACA,OAAO,UAAS;AACf,UAAI,iBAAiB,MAAM;AAC1B,eAAO,IAAI,WAAW,MAAM,MAAM,YAAa,CAAA;AAAA,MAC/C;AAEG,UAAA,OAAO,UAAU,YAAY;AAC1B,cAAA,IAAIC,kBAAS,4CAA4C;AAAA,UAC9D;AAAA,UACA;AAAA,QAAA,CACA;AAAA,MACD;AAEM,aAAA;AAAA,IAAA,CACP;AAGF,UAAM,OAAOC,QAAAA,OACZ;AAAA,MACC;AAAA,MACA,eAAe;AAAA,IAAA,GAEhB,EAAE,iBAAiB,KAAA,CAAM;AAG1B,UAAM,MAAM,MAAM,cAAc,KAAK,WAAW;AAAA,MAC/C,QAAQ;AAAA,MACR;AAAA,MACA,SAAS;AAAA,QACR,gBAAgB;AAAA,MAChB;AAAA,IAAA,CACD;AAEK,UAAA,cAAc,MAAM,IAAI;AAC9B,UAAM,YAAYC,QAAA,OACjB,IAAI,WAAW,WAAW,CAAC;AAG5B,QAAI,WAAW,WAAW;AACzB,YAAM,WAAW,UAAU;AAEvB,UAAAC,eAAAA,eAAe,QAAQ,GAAG;AAC7B,cAAM,QAAQ,IAAIH,kBAAS,SAAS,SAAS;AAAA,UAC5C;AAAA,UACA;AAAA,QAAA,CACA;AACD,cAAM,QAAQ,SAAS;AAEjB,cAAA;AAAA,MAAA,WACII,YAAAA,YAAY,QAAQ,GAAG;AACjC,cAAM,QAAQ,IAAI,MAAM,SAAS,OAAO;AACxC,cAAM,OAAO,SAAS;AACtB,cAAM,QAAQ,SAAS;AAEjB,cAAA;AAAA,MAAA,OACA;AACA,cAAA,IAAIJ,kBACT,4DACA;AAAA,UACC;AAAA,UACA;AAAA,UACA,OAAO;AAAA,QAAA,CACP;AAAA,MAEF;AAAA,IAAA,OACK;AACN,aAAOD,4BAAc,UAAU,MAAM,OAAO,UAAS;AACpD,YAAI,iBAAiB,YAAY;AAChC,iBAAO,IAAI,KAAK,CAAC,KAAK,CAAC;AAAA,QACvB;AAEM,eAAA;AAAA,MAAA,CACP;AAAA,IACD;AAAA,EAAA,CACD;AAEH;;"}