@lowerdeck/rpc-client 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +11 -0
- package/.turbo/turbo-test.log +35 -0
- package/dist/anonymizeIp.d.ts +10 -0
- package/dist/anonymizeIp.d.ts.map +1 -0
- package/dist/anonymizeIp.test.d.ts +2 -0
- package/dist/anonymizeIp.test.d.ts.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.modern.js +2 -0
- package/dist/index.modern.js.map +1 -0
- package/dist/index.module.js +2 -0
- package/dist/index.module.js.map +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/request.d.ts +3 -0
- package/dist/request.d.ts.map +1 -0
- package/dist/shared/clientBuilder.d.ts +15 -0
- package/dist/shared/clientBuilder.d.ts.map +1 -0
- package/dist/shared/requester.d.ts +20 -0
- package/dist/shared/requester.d.ts.map +1 -0
- package/package.json +40 -0
- package/src/index.ts +4 -0
- package/src/request.ts +194 -0
- package/src/shared/clientBuilder.ts +68 -0
- package/src/shared/requester.ts +33 -0
- package/tsconfig.json +13 -0
- package/tsup.config.js +11 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
[0m[2m[35m$[0m [2m[1mmicrobundle[0m
|
|
3
|
+
[34mBuild "@lowerdeck/anonymize-ip" to dist:[39m
|
|
4
|
+
[32m857 B[39m: [37mindex.cjs[39m.gz
|
|
5
|
+
[32m760 B[39m: [37mindex.cjs[39m.br
|
|
6
|
+
[32m798 B[39m: [37mindex.module.js[39m.gz
|
|
7
|
+
[32m713 B[39m: [37mindex.module.js[39m.br
|
|
8
|
+
[32m863 B[39m: [37mindex.module.js[39m.gz
|
|
9
|
+
[32m759 B[39m: [37mindex.module.js[39m.br
|
|
10
|
+
[32m917 B[39m: [37mindex.umd.js[39m.gz
|
|
11
|
+
[32m805 B[39m: [37mindex.umd.js[39m.br
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
[0m[2m[35m$[0m [2m[1mvitest run --passWithNoTests[0m
|
|
3
|
+
[?25l
|
|
4
|
+
[1m[46m RUN [49m[22m [36mv3.2.4 [39m[90m/Users/tobias/code/metorial/metorial-enterprise/oss/src/packages/shared/anonymize-ip[39m
|
|
5
|
+
|
|
6
|
+
[?2026h
|
|
7
|
+
[1m[33m ❯ [39m[22msrc/anonymizeIp.test.ts[2m [queued][22m
|
|
8
|
+
|
|
9
|
+
[2m Test Files [22m[1m[32m0 passed[39m[22m[90m (1)[39m
|
|
10
|
+
[2m Tests [22m[1m[32m0 passed[39m[22m[90m (0)[39m
|
|
11
|
+
[2m Start at [22m10:23:25
|
|
12
|
+
[2m Duration [22m101ms
|
|
13
|
+
[?2026l[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K [32m✓[39m src/anonymizeIp.test.ts [2m([22m[2m15 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
14
|
+
[32m✓[39m anonymizeIP[2m > [22manonymizes IPv4 with default options[32m 1[2mms[22m[39m
|
|
15
|
+
[32m✓[39m anonymizeIP[2m > [22manonymizes IPv4 with keepGroups=1[32m 0[2mms[22m[39m
|
|
16
|
+
[32m✓[39m anonymizeIP[2m > [22manonymizes IPv4 with keepGroups=3[32m 0[2mms[22m[39m
|
|
17
|
+
[32m✓[39m anonymizeIP[2m > [22manonymizes IPv4 with custom maskChar[32m 0[2mms[22m[39m
|
|
18
|
+
[32m✓[39m anonymizeIP[2m > [22mthrows error for invalid IPv4 keepGroups[32m 1[2mms[22m[39m
|
|
19
|
+
[32m✓[39m anonymizeIP[2m > [22manonymizes IPv6 with default options[32m 0[2mms[22m[39m
|
|
20
|
+
[32m✓[39m anonymizeIP[2m > [22manonymizes IPv6 with keepGroups=2[32m 0[2mms[22m[39m
|
|
21
|
+
[32m✓[39m anonymizeIP[2m > [22manonymizes IPv6 with keepGroups=7[32m 0[2mms[22m[39m
|
|
22
|
+
[32m✓[39m anonymizeIP[2m > [22manonymizes IPv6 with custom maskChar[32m 0[2mms[22m[39m
|
|
23
|
+
[32m✓[39m anonymizeIP[2m > [22mthrows error for invalid IPv6 keepGroups[32m 0[2mms[22m[39m
|
|
24
|
+
[32m✓[39m anonymizeIP[2m > [22manonymizes IPv6 compressed notation[32m 0[2mms[22m[39m
|
|
25
|
+
[32m✓[39m anonymizeIP[2m > [22manonymizes IPv6 ::[32m 0[2mms[22m[39m
|
|
26
|
+
[32m✓[39m anonymizeIP[2m > [22manonymizes IPv6 with embedded IPv4[32m 0[2mms[22m[39m
|
|
27
|
+
[32m✓[39m anonymizeIP[2m > [22mthrows error for invalid IP address[32m 0[2mms[22m[39m
|
|
28
|
+
[32m✓[39m anonymizeIP[2m > [22mtrims whitespace from IP[32m 0[2mms[22m[39m
|
|
29
|
+
|
|
30
|
+
[2m Test Files [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
|
31
|
+
[2m Tests [22m [1m[32m15 passed[39m[22m[90m (15)[39m
|
|
32
|
+
[2m Start at [22m 10:23:25
|
|
33
|
+
[2m Duration [22m 230ms[2m (transform 36ms, setup 0ms, collect 35ms, tests 4ms, environment 0ms, prepare 39ms)[22m
|
|
34
|
+
|
|
35
|
+
[?25h
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface AnonymizationOptions {
|
|
2
|
+
maskChar?: string;
|
|
3
|
+
keepGroups?: {
|
|
4
|
+
ipv4?: number;
|
|
5
|
+
ipv6?: number;
|
|
6
|
+
} | number;
|
|
7
|
+
}
|
|
8
|
+
export declare let anonymizeIP: (ip: string, options?: AnonymizationOptions) => string;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=anonymizeIp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anonymizeIp.d.ts","sourceRoot":"","sources":["../src/anonymizeIp.ts"],"names":[],"mappings":"AAQA,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EACP;QACE,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,GACD,MAAM,CAAC;CACZ;AAuHD,eAAO,IAAI,WAAW,GAAI,IAAI,MAAM,EAAE,UAAS,oBAAyB,WAwBvE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anonymizeIp.test.d.ts","sourceRoot":"","sources":["../src/anonymizeIp.test.ts"],"names":[],"mappings":""}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=require("@lowerdeck/canonicalize"),r=require("@lowerdeck/error"),n=require("@lowerdeck/serialize"),t=require("@lowerdeck/id"),o=require("@lowerdeck/memo"),i=require("@lowerdeck/proxy");function a(e,r){(null==r||r>e.length)&&(r=e.length);for(var n=0,t=Array(r);n<r;n++)t[n]=e[n];return t}function u(){return u=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var n=arguments[r];for(var t in n)({}).hasOwnProperty.call(n,t)&&(e[t]=n[t])}return e},u.apply(null,arguments)}var c=0,l=o.memo(function(){return t.generatePlainId(10)}),s="undefined"==typeof window;function d(e,r,n){if(!e.s){if(n instanceof v){if(!n.s)return void(n.o=d.bind(null,e,r));1&r&&(r=n.s),n=n.v}if(n&&n.then)return void n.then(d.bind(null,e,r),d.bind(null,e,2));e.s=r,e.v=n;var t=e.o;t&&t(e)}}var f=function(){var e;s||(e=console).log.apply(e,[].slice.call(arguments))},v=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(r,n){var t=new e,o=this.s;if(o){var i=1&o?r:n;if(i){try{d(t,1,i(this.v))}catch(e){d(t,2,e)}return t}return this}return this.o=function(e){try{var o=e.v;1&e.s?d(t,1,r?r(o):o):n?d(t,1,n(o)):d(t,2,o)}catch(e){d(t,2,e)}},t},e}();function h(e){return e instanceof v&&1&e.s}var m,y,p={},w=(m=function(t){return Promise.resolve(function(t){try{var o,i=function(e){if(o)return e;if(w)throw w;throw new r.ServiceError(r.internalServerError({message:"Unable to reach server"}))},m=function(){var e="call_"+l()+"_"+c;return c+=1,e}();f("[call:"+t.name.replace(":","-")+":"+m+"] Queued",t);var y=0,w=null;for(var b in t.headers)void 0===t.headers[b]&&delete t.headers[b];if(t.query)for(var g in t.query)void 0===t.query[g]&&delete t.query[g];var q="undefined"==typeof window?6:3,P="undefined"==typeof window?20:1e3,S=function(e,r,n){for(var t;;){var o=e();if(h(o)&&(o=o.v),!o)return i;if(o.then){t=0;break}var i=n();if(i&&i.then){if(!h(i)){t=1;break}i=i.s}}var a=new v,u=d.bind(null,a,2);return(0===t?o.then(l):1===t?i.then(c):(void 0).then(function(){(o=e())?o.then?o.then(l).then(void 0,u):l(o):d(a,1,i)})).then(void 0,u),a;function c(r){i=r;do{if(!(o=e())||h(o)&&!o.v)return void d(a,1,i);if(o.then)return void o.then(l).then(void 0,u);h(i=n())&&(i=i.v)}while(!i||!i.then);i.then(c).then(void 0,u)}function l(e){e?(i=n())&&i.then?i.then(c).then(void 0,u):c(i):d(a,1,i)}}(function(){return!o&&y<q},0,function(){function i(e){return o?e:(y+=1,Promise.resolve(new Promise(function(e){return setTimeout(e,y*P)})).then(function(){}))}var c=function(i,c){try{var l=Promise.resolve(function(t){var o=""+e.canonicalize(t.headers)+e.canonicalize(t.query)+t.endpoint;p[o]||(p[o]={calls:[],to:null});var i=p[o],c=new Promise(function(e,r){i.calls.push({call:t,resolve:e,reject:r})});return i.to&&clearTimeout(i.to),i.to=setTimeout(function(){var e=p[o].calls;p[o].calls=[],p[o].to=null;var i=new URL(t.endpoint);i.search=new URLSearchParams(t.query).toString(),fetch(i.toString(),{method:"POST",headers:u({"Content-Type":"application/rpc+json"},e[0].call.headers),body:n.serialize.encode({calls:e.map(function(e){return{id:e.call.id,name:e.call.name,payload:e.call.payload}}).sort(function(e,r){return e.name.localeCompare(r.name)})}),credentials:"include",keepalive:!1}).then(function(e){try{var r=n.serialize.decode;return Promise.resolve(e.json()).then(function(t){return{res:r.call(n.serialize,t),headers:e.headers}})}catch(e){return Promise.reject(e)}}).then(function(n){var t=n.res,o=n.headers;if("error"!=t.__typename){for(var i,u,c=function(){var e=u.value,n=t.calls.find(function(r){return r.id==e.call.id});if(!n){var i=new r.ServiceError(r.internalServerError({message:"Call not returned"}));return e.reject(i),{v:void 0}}n.status>=200&&n.status<300&&e.resolve({data:n.result,status:n.status,headers:o});var a=r.ServiceError.fromResponse(n.result);e.reject(a)},l=function(e){var r="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(r)return(r=r.call(e)).next.bind(r);if(Array.isArray(e)||(r=function(e,r){if(e){if("string"==typeof e)return a(e,r);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?a(e,r):void 0}}(e))){r&&(e=r);var n=0;return function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(e);!(u=l()).done;)if(i=c())return i.v}else{var s=r.ServiceError.fromResponse(t);e.forEach(function(e){return e.reject(s)})}}).catch(function(n){e.forEach(function(e){return e.reject(new r.ServiceError(r.internalServerError({message:"Unable to reach server"})))})})},s?0:10),c}(u({},t,{id:m})).then(function(e){return s||f("[call:"+t.name.replace(":","-")+":"+m+"] Success",e),e},function(e){throw s&&f("[call:"+t.name.replace(":","-")+":"+m+"] Queued",t),f("[call:"+t.name.replace(":","-")+":"+m+"] Error",e),e})).then(function(e){return o=1,e})}catch(e){return c(e)}return l&&l.then?l.then(void 0,c):l}(0,function(e){if(w=e,r.isServiceError(e)&&e.data.status<500)throw e});return c&&c.then?c.then(i):i(c)});return Promise.resolve(S&&S.then?S.then(i):i(S))}catch(e){return Promise.reject(e)}}(t))},void 0===y&&(y=function(e){return e({})}),function(e){return i.proxy(function(r,n,t){try{return Promise.resolve(y(function(o){try{return Promise.resolve(null==e.getHeaders?void 0:e.getHeaders()).then(function(i){var a;function c(i){return a?i:Promise.resolve(m({endpoint:e.endpoint,payload:n,name:r.join(":"),headers:l,query:null==t?void 0:t.query,context:o})).then(function(e){return e.data})}var l=u({},e.headers,i,null==t?void 0:t.headers);null==e.onRequest||e.onRequest({endpoint:e.endpoint,name:r.join(":"),payload:n,headers:l,query:null==t?void 0:t.query});var s=function(){if("getFull"==r[r.length-1])return Promise.resolve(m({endpoint:e.endpoint,payload:n,name:r.slice(0,-1).join(":"),headers:l,query:null==t?void 0:t.query,context:o})).then(function(e){return a=1,e})}();return s&&s.then?s.then(c):c(s)})}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}})});exports.createClient=w;
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/shared/requester.ts","../src/request.ts","../src/shared/clientBuilder.ts","../src/index.ts"],"sourcesContent":["import { generatePlainId } from '@lowerdeck/id';\nimport { memo } from '@lowerdeck/memo';\n\nlet index = 0;\nlet rootId = memo(() => generatePlainId(10));\n\nexport let generateRequestId = () => {\n let id = `call_${rootId()}_${index}`;\n index += 1;\n return id;\n};\n\nexport interface Call {\n id: string;\n name: string;\n payload: any;\n endpoint: string;\n headers: Record<string, string>;\n query?: Record<string, string>;\n}\n\nexport type Requester = (\n call: Omit<Call, 'id' | 'headers' | 'query'> & {\n headers: Record<string, string | undefined>;\n query?: Record<string, string | undefined>;\n context: any;\n }\n) => Promise<{\n data: any;\n status: number;\n headers: Record<string, string>;\n query?: Record<string, string>;\n}>;\n","import { canonicalize } from '@lowerdeck/canonicalize';\nimport { internalServerError, isServiceError, ServiceError } from '@lowerdeck/error';\nimport { serialize } from '@lowerdeck/serialize';\nimport { Call, generateRequestId, Requester } from './shared/requester';\n\n// @ts-ignore\nlet isServer = typeof window === 'undefined';\n\nlet log = (...args: any[]) => {\n if (!isServer) console.log(...args);\n};\n\nlet calls: {\n [key: string]: {\n calls: {\n call: Call;\n resolve: (value: any) => void;\n reject: (error: any) => void;\n }[];\n to: any;\n };\n} = {};\n\nlet performRequest = (call: Call) => {\n let key = `${canonicalize(call.headers)}${canonicalize(call.query)}${call.endpoint}`;\n\n if (!calls[key]) calls[key] = { calls: [], to: null };\n let current = calls[key];\n\n let promise = new Promise((resolve, reject) => {\n current.calls.push({ call, resolve, reject });\n });\n\n if (current.to) clearTimeout(current.to);\n\n current.to = setTimeout(\n () => {\n let c = calls[key].calls;\n calls[key].calls = [];\n calls[key].to = null;\n\n let url = new URL(call.endpoint);\n url.search = new URLSearchParams(call.query).toString();\n\n fetch(url.toString(), {\n method: 'POST',\n\n headers: {\n 'Content-Type': 'application/rpc+json',\n ...c[0].call.headers\n },\n body: serialize.encode({\n calls: c\n .map(x => ({\n id: x.call.id,\n name: x.call.name,\n payload: x.call.payload\n }))\n .sort((a, b) => a.name.localeCompare(b.name))\n }),\n credentials: 'include',\n\n // @ts-ignore\n keepalive: false\n })\n .then(async res => ({\n res: serialize.decode(\n (await res.json()) as {\n calls: {\n id: string;\n status: number;\n result: any;\n }[];\n }\n ),\n\n headers: res.headers\n }))\n .then(({ res, headers }) => {\n if (res.__typename == 'error') {\n let err = ServiceError.fromResponse(res);\n c.forEach(x => x.reject(err));\n return;\n }\n\n for (let call of c) {\n let callRes = res.calls.find((x: any) => x.id == call.call.id);\n if (!callRes) {\n let err = new ServiceError(\n internalServerError({ message: 'Call not returned' })\n );\n call.reject(err);\n return;\n }\n\n if (callRes.status >= 200 && callRes.status < 300) {\n call.resolve({\n // data: O;\n // status: number;\n // headers: Record<string, string>;\n\n data: callRes.result,\n status: callRes.status,\n headers\n });\n }\n\n let err = ServiceError.fromResponse(callRes.result);\n call.reject(err);\n }\n })\n .catch(e => {\n c.forEach(x =>\n x.reject(\n new ServiceError(internalServerError({ message: 'Unable to reach server' }))\n )\n );\n });\n },\n isServer ? 0 : 10\n );\n\n return promise;\n};\n\nlet requesterInternal: Requester = async call => {\n let id = generateRequestId();\n log(`[call:${call.name.replace(':', '-')}:${id}] Queued`, call);\n\n let tries = 0;\n let error: Error | null = null;\n\n for (let header in call.headers) {\n if (call.headers[header] === undefined) delete call.headers[header];\n }\n\n if (call.query) {\n for (let query in call.query) {\n if (call.query[query] === undefined) delete call.query[query];\n }\n }\n\n let maxTries = typeof window === 'undefined' ? 6 : 3;\n let retryDelay = typeof window === 'undefined' ? 20 : 1000;\n\n while (tries < maxTries) {\n try {\n return (await performRequest({\n ...(call as any),\n id\n }).then(\n res => {\n if (!isServer) {\n log(`[call:${call.name.replace(':', '-')}:${id}] Success`, res);\n }\n\n return res;\n },\n err => {\n if (isServer) {\n log(`[call:${call.name.replace(':', '-')}:${id}] Queued`, call);\n }\n\n log(`[call:${call.name.replace(':', '-')}:${id}] Error`, err);\n\n throw err;\n }\n )) as any;\n } catch (e: any) {\n error = e;\n\n if (isServiceError(e)) {\n // 400 errors are not retried\n if (e.data.status < 500) throw e;\n }\n }\n\n tries += 1;\n await new Promise(r => setTimeout(r, tries * retryDelay));\n }\n\n if (error) throw error;\n\n throw new ServiceError(internalServerError({ message: 'Unable to reach server' }));\n};\n\nexport let request: Requester = async call => {\n // try {\n return await requesterInternal(call);\n // } catch (e: any) {\n // Sentry.captureException(e);\n // throw e;\n // }\n};\n","import { proxy } from '@lowerdeck/proxy';\nimport { Requester } from './requester';\n\nexport interface ClientOpts {\n endpoint: string;\n headers?: Record<string, string | undefined>;\n getHeaders?: () => Promise<Record<string, string>> | Record<string, string>;\n onRequest?: (d: {\n endpoint: string;\n name: string;\n payload: any;\n headers: Record<string, string | undefined>;\n query?: Record<string, string | undefined>;\n }) => any;\n}\n\nlet noopWithContext = (cb: (ctx: any) => any) => cb({});\n\nexport let clientBuilder =\n (request: Requester, withContext: (cb: (ctx: any) => any) => any = noopWithContext) =>\n <T extends object>(clientOpts: ClientOpts) =>\n proxy<T>(\n async (\n path,\n data,\n requestOpts?: {\n headers?: Record<string, string | undefined>;\n query?: Record<string, string | undefined>;\n }\n ) =>\n await withContext(async context => {\n let headers = {\n ...clientOpts.headers,\n ...(await clientOpts.getHeaders?.()),\n ...requestOpts?.headers\n };\n\n clientOpts.onRequest?.({\n endpoint: clientOpts.endpoint,\n name: path.join(':'),\n payload: data,\n headers,\n query: requestOpts?.query\n });\n\n if (path[path.length - 1] == 'getFull') {\n return await request({\n endpoint: clientOpts.endpoint,\n payload: data,\n name: path.slice(0, -1).join(':'),\n headers,\n query: requestOpts?.query,\n context\n });\n }\n\n return (\n await request({\n endpoint: clientOpts.endpoint,\n payload: data,\n name: path.join(':'),\n headers,\n query: requestOpts?.query,\n context\n })\n ).data;\n })\n );\n","import { request } from './request';\nimport { clientBuilder } from './shared/clientBuilder';\n\nexport let createClient = clientBuilder(request);\n"],"names":["index","rootId","memo","generatePlainId","isServer","window","_settle","pact","state","value","s","_Pact","bind","v","then","o","observer","log","_console","console","apply","slice","call","arguments","prototype","onFulfilled","result","this","callback","onRejected","e","_this","thenable","request","withContext","calls","createClient","Promise","resolve","_exit","_temp4","_result2","error","ServiceError","internalServerError","message","id","generateRequestId","name","replace","tries","header","headers","undefined","query","maxTries","retryDelay","_temp3","_for","_temp2","_result","r","setTimeout","_temp","key","canonicalize","endpoint","to","current","promise","reject","push","clearTimeout","c","url","URL","search","URLSearchParams","toString","fetch","method","_extends","body","serialize","encode","map","x","payload","sort","a","b","localeCompare","credentials","keepalive","res","_decode","decode","json","_res$json","_ref","__typename","_ret","_step","_loop","callRes","find","err","status","data","fromResponse","_iterator","_createForOfIteratorHelperLoose","done","forEach","performRequest","_await$performRequest","_catch","isServiceError","requesterInternal","cb","clientOpts","proxy","path","requestOpts","context","getHeaders","_clientOpts$getHeader","join","_request","onRequest","length","_await$request"],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,eAAO,IAAI,YAAY,kFAAyB,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
let e=e=>!!/^(\d{1,3}\.){3}\d{1,3}$/.test(e)&&e.split(".").every(e=>{let r=parseInt(e,10);return r>=0&&r<=255}),r=e=>{if(e.includes("::")){let r=e.split("::");if(2!==r.length)return!1;if((r[0]?r[0].split(":").length:0)+(r[1]?r[1].split(":").length:0)>7)return!1}return/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$/.test(e)||"::"===e},t=(e,r={})=>{let{keepGroups:t=2,maskChar:s="x"}=r,n=e.split(".");if(t<1||t>3)throw new Error("keepGroups for IPv4 must be between 1 and 3");return n.map((e,r)=>r<t?e:s.repeat(e.length)).join(".")},s=(e,r,t)=>{let s=e;if(e.includes("::")){let r=e.split("::"),t=r[0]||"",n=r[1]||"",p=t?t.split(":"):[],l=n?n.split(":"):[],i=Array(8-p.length-l.length).fill("0");s=[...p,...i,...l].join(":")}return s.split(":").map((e,s)=>s<r?e:t.repeat(Math.max(1,e.length))).join(":")},n=(n,p={})=>{if(!n||"string"!=typeof n)throw new Error("IP address must be a non-empty string");let l=n.trim();var i,u;if(e(l))return t(l,{keepGroups:"number"==typeof p.keepGroups?p.keepGroups:null==(i=p.keepGroups)?void 0:i.ipv4,maskChar:p.maskChar}).replace("000","0");if((t=>{if(t.includes(".")){let s=t.split(":");if(e(s[s.length-1])){let e=t.substring(0,t.lastIndexOf(":")+1)+"0";return r(e)}}return r(t)})(l))return((r,n={})=>{let{keepGroups:p=4,maskChar:l="x"}=n;if(p<1||p>7)throw new Error("keepGroups for IPv6 must be between 1 and 7");if(r.includes(".")){let n=r.lastIndexOf(":"),i=r.substring(0,n+1),u=r.substring(n+1);if(e(u)){let e=t(u,{keepGroups:2,maskChar:l}),r=s(i+"0",p,l);return r.substring(0,r.lastIndexOf(":")+1)+e}}return s(r,p,l)})(l,{keepGroups:"number"==typeof p.keepGroups?p.keepGroups:null==(u=p.keepGroups)?void 0:u.ipv6,maskChar:p.maskChar});throw new Error("Invalid IP address format")};export{n as anonymizeIP};
|
|
2
|
+
//# sourceMappingURL=index.modern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.modern.js","sources":["../src/anonymizeIp.ts"],"sourcesContent":["interface AnonymizationOptionsSingle {\n // For IPv4: number of octets to keep (1-3, default: 2)\n // For IPv6: number of groups to keep (1-7, default: 4)\n keepGroups?: number;\n // Character to use for masking (default: 'x')\n maskChar?: string;\n}\n\ninterface AnonymizationOptions {\n maskChar?: string;\n keepGroups?:\n | {\n ipv4?: number;\n ipv6?: number;\n }\n | number;\n}\n\nlet isIPv4 = (ip: string) => {\n let ipv4Regex = /^(\\d{1,3}\\.){3}\\d{1,3}$/;\n if (!ipv4Regex.test(ip)) return false;\n\n return ip.split('.').every(octet => {\n let num = parseInt(octet, 10);\n return num >= 0 && num <= 255;\n });\n};\n\nlet isIPv6 = (ip: string) => {\n // Handle IPv6 with embedded IPv4 (e.g., ::ffff:192.0.2.1)\n if (ip.includes('.')) {\n let parts = ip.split(':');\n let lastPart = parts[parts.length - 1];\n if (isIPv4(lastPart)) {\n // Remove the IPv4 part and validate the IPv6 part\n let ipv6Part = ip.substring(0, ip.lastIndexOf(':') + 1) + '0';\n return isIPv6Simple(ipv6Part);\n }\n }\n\n return isIPv6Simple(ip);\n};\n\nlet isIPv6Simple = (ip: string) => {\n let ipv6Regex = /^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$/;\n\n if (ip.includes('::')) {\n let parts = ip.split('::');\n if (parts.length !== 2) return false;\n\n let leftGroups = parts[0] ? parts[0].split(':').length : 0;\n let rightGroups = parts[1] ? parts[1].split(':').length : 0;\n\n // Total groups should not exceed 8\n if (leftGroups + rightGroups > 7) return false;\n }\n\n return ipv6Regex.test(ip) || ip === '::';\n};\n\nlet anonymizeIPv4 = (ip: string, options: AnonymizationOptionsSingle = {}) => {\n let { keepGroups = 2, maskChar = 'x' } = options;\n let octets = ip.split('.');\n\n if (keepGroups < 1 || keepGroups > 3) {\n throw new Error('keepGroups for IPv4 must be between 1 and 3');\n }\n\n let maskedOctets = octets.map((octet, index) => {\n if (index < keepGroups) {\n return octet;\n }\n return maskChar.repeat(octet.length);\n });\n\n return maskedOctets.join('.');\n};\n\nlet anonymizeIPv6 = (ip: string, options: AnonymizationOptionsSingle = {}) => {\n let { keepGroups = 4, maskChar = 'x' } = options;\n\n if (keepGroups < 1 || keepGroups > 7) {\n throw new Error('keepGroups for IPv6 must be between 1 and 7');\n }\n\n // Handle IPv6 with embedded IPv4\n if (ip.includes('.')) {\n let lastColonIndex = ip.lastIndexOf(':');\n let ipv6Part = ip.substring(0, lastColonIndex + 1);\n let ipv4Part = ip.substring(lastColonIndex + 1);\n\n if (isIPv4(ipv4Part)) {\n let anonymizedIPv4 = anonymizeIPv4(ipv4Part, { keepGroups: 2, maskChar });\n let anonymizedIPv6Part = anonymizeIPv6Simple(ipv6Part + '0', keepGroups, maskChar);\n return (\n anonymizedIPv6Part.substring(0, anonymizedIPv6Part.lastIndexOf(':') + 1) +\n anonymizedIPv4\n );\n }\n }\n\n return anonymizeIPv6Simple(ip, keepGroups, maskChar);\n};\n\nlet anonymizeIPv6Simple = (ip: string, keepGroups: number, maskChar: string) => {\n // Expand compressed notation for easier processing\n let expanded = ip;\n\n if (ip.includes('::')) {\n let parts = ip.split('::');\n let leftPart = parts[0] || '';\n let rightPart = parts[1] || '';\n\n let leftGroups = leftPart ? leftPart.split(':') : [];\n let rightGroups = rightPart ? rightPart.split(':') : [];\n\n let missingGroups = 8 - leftGroups.length - rightGroups.length;\n let zeroGroups = Array(missingGroups).fill('0');\n\n let allGroups = [...leftGroups, ...zeroGroups, ...rightGroups];\n expanded = allGroups.join(':');\n }\n\n let groups = expanded.split(':');\n\n let maskedGroups = groups.map((group, index) => {\n if (index < keepGroups) {\n return group;\n }\n return maskChar.repeat(Math.max(1, group.length));\n });\n\n return maskedGroups.join(':');\n};\n\nexport let anonymizeIP = (ip: string, options: AnonymizationOptions = {}) => {\n if (!ip || typeof ip !== 'string') {\n throw new Error('IP address must be a non-empty string');\n }\n\n let trimmedIP = ip.trim();\n\n if (isIPv4(trimmedIP)) {\n return anonymizeIPv4(trimmedIP, {\n keepGroups:\n typeof options.keepGroups === 'number' ? options.keepGroups : options.keepGroups?.ipv4,\n maskChar: options.maskChar\n }).replace('000', '0'); // Ensure no triple zeros in IPv4\n }\n\n if (isIPv6(trimmedIP)) {\n return anonymizeIPv6(trimmedIP, {\n keepGroups:\n typeof options.keepGroups === 'number' ? options.keepGroups : options.keepGroups?.ipv6,\n maskChar: options.maskChar\n });\n }\n\n throw new Error('Invalid IP address format');\n};\n"],"names":["isIPv4","ip","test","split","every","octet","num","parseInt","isIPv6Simple","includes","parts","length","anonymizeIPv4","options","keepGroups","maskChar","octets","Error","map","index","repeat","join","anonymizeIPv6Simple","expanded","leftPart","rightPart","leftGroups","rightGroups","zeroGroups","Array","fill","group","Math","max","anonymizeIP","trimmedIP","trim","_options$keepGroups","_options$keepGroups2","ipv4","replace","ipv6Part","substring","lastIndexOf","isIPv6","anonymizeIPv6","lastColonIndex","ipv4Part","anonymizedIPv4","anonymizedIPv6Part","ipv6"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{canonicalize as e}from"@lowerdeck/canonicalize";import{ServiceError as n,internalServerError as r,isServiceError as t}from"@lowerdeck/error";import{serialize as o}from"@lowerdeck/serialize";import{generatePlainId as i}from"@lowerdeck/id";import{memo as a}from"@lowerdeck/memo";import{proxy as u}from"@lowerdeck/proxy";function c(e,n){(null==n||n>e.length)&&(n=e.length);for(var r=0,t=Array(n);r<n;r++)t[r]=e[r];return t}function l(){return l=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var r=arguments[n];for(var t in r)({}).hasOwnProperty.call(r,t)&&(e[t]=r[t])}return e},l.apply(null,arguments)}var s=0,f=a(function(){return i(10)}),d="undefined"==typeof window;function v(e,n,r){if(!e.s){if(r instanceof m){if(!r.s)return void(r.o=v.bind(null,e,n));1&n&&(n=r.s),r=r.v}if(r&&r.then)return void r.then(v.bind(null,e,n),v.bind(null,e,2));e.s=n,e.v=r;var t=e.o;t&&t(e)}}var h=function(){var e;d||(e=console).log.apply(e,[].slice.call(arguments))},m=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(n,r){var t=new e,o=this.s;if(o){var i=1&o?n:r;if(i){try{v(t,1,i(this.v))}catch(e){v(t,2,e)}return t}return this}return this.o=function(e){try{var o=e.v;1&e.s?v(t,1,n?n(o):o):r?v(t,1,r(o)):v(t,2,o)}catch(e){v(t,2,e)}},t},e}();function p(e){return e instanceof m&&1&e.s}var y,w,b={},g=(y=function(i){return Promise.resolve(function(i){try{var a,u=function(e){if(a)return e;if(g)throw g;throw new n(r({message:"Unable to reach server"}))},y=function(){var e="call_"+f()+"_"+s;return s+=1,e}();h("[call:"+i.name.replace(":","-")+":"+y+"] Queued",i);var w=0,g=null;for(var j in i.headers)void 0===i.headers[j]&&delete i.headers[j];if(i.query)for(var P in i.query)void 0===i.query[P]&&delete i.query[P];var q="undefined"==typeof window?6:3,S="undefined"==typeof window?20:1e3,k=function(e,n,r){for(var t;;){var o=e();if(p(o)&&(o=o.v),!o)return i;if(o.then){t=0;break}var i=r();if(i&&i.then){if(!p(i)){t=1;break}i=i.s}}var a=new m,u=v.bind(null,a,2);return(0===t?o.then(l):1===t?i.then(c):(void 0).then(function(){(o=e())?o.then?o.then(l).then(void 0,u):l(o):v(a,1,i)})).then(void 0,u),a;function c(n){i=n;do{if(!(o=e())||p(o)&&!o.v)return void v(a,1,i);if(o.then)return void o.then(l).then(void 0,u);p(i=r())&&(i=i.v)}while(!i||!i.then);i.then(c).then(void 0,u)}function l(e){e?(i=r())&&i.then?i.then(c).then(void 0,u):c(i):v(a,1,i)}}(function(){return!a&&w<q},0,function(){function u(e){return a?e:(w+=1,Promise.resolve(new Promise(function(e){return setTimeout(e,w*S)})).then(function(){}))}var s=function(t,u){try{var s=Promise.resolve(function(t){var i=""+e(t.headers)+e(t.query)+t.endpoint;b[i]||(b[i]={calls:[],to:null});var a=b[i],u=new Promise(function(e,n){a.calls.push({call:t,resolve:e,reject:n})});return a.to&&clearTimeout(a.to),a.to=setTimeout(function(){var e=b[i].calls;b[i].calls=[],b[i].to=null;var a=new URL(t.endpoint);a.search=new URLSearchParams(t.query).toString(),fetch(a.toString(),{method:"POST",headers:l({"Content-Type":"application/rpc+json"},e[0].call.headers),body:o.encode({calls:e.map(function(e){return{id:e.call.id,name:e.call.name,payload:e.call.payload}}).sort(function(e,n){return e.name.localeCompare(n.name)})}),credentials:"include",keepalive:!1}).then(function(e){try{var n=o.decode;return Promise.resolve(e.json()).then(function(r){return{res:n.call(o,r),headers:e.headers}})}catch(e){return Promise.reject(e)}}).then(function(t){var o=t.res,i=t.headers;if("error"!=o.__typename){for(var a,u,l=function(){var e=u.value,t=o.calls.find(function(n){return n.id==e.call.id});if(!t){var a=new n(r({message:"Call not returned"}));return e.reject(a),{v:void 0}}t.status>=200&&t.status<300&&e.resolve({data:t.result,status:t.status,headers:i});var c=n.fromResponse(t.result);e.reject(c)},s=function(e){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,n){if(e){if("string"==typeof e)return c(e,n);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?c(e,n):void 0}}(e))){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(e);!(u=s()).done;)if(a=l())return a.v}else{var f=n.fromResponse(o);e.forEach(function(e){return e.reject(f)})}}).catch(function(t){e.forEach(function(e){return e.reject(new n(r({message:"Unable to reach server"})))})})},d?0:10),u}(l({},i,{id:y})).then(function(e){return d||h("[call:"+i.name.replace(":","-")+":"+y+"] Success",e),e},function(e){throw d&&h("[call:"+i.name.replace(":","-")+":"+y+"] Queued",i),h("[call:"+i.name.replace(":","-")+":"+y+"] Error",e),e})).then(function(e){return a=1,e})}catch(e){return u(e)}return s&&s.then?s.then(void 0,u):s}(0,function(e){if(g=e,t(e)&&e.data.status<500)throw e});return s&&s.then?s.then(u):u(s)});return Promise.resolve(k&&k.then?k.then(u):u(k))}catch(e){return Promise.reject(e)}}(i))},void 0===w&&(w=function(e){return e({})}),function(e){return u(function(n,r,t){try{return Promise.resolve(w(function(o){try{return Promise.resolve(null==e.getHeaders?void 0:e.getHeaders()).then(function(i){var a;function u(i){return a?i:Promise.resolve(y({endpoint:e.endpoint,payload:r,name:n.join(":"),headers:c,query:null==t?void 0:t.query,context:o})).then(function(e){return e.data})}var c=l({},e.headers,i,null==t?void 0:t.headers);null==e.onRequest||e.onRequest({endpoint:e.endpoint,name:n.join(":"),payload:r,headers:c,query:null==t?void 0:t.query});var s=function(){if("getFull"==n[n.length-1])return Promise.resolve(y({endpoint:e.endpoint,payload:r,name:n.slice(0,-1).join(":"),headers:c,query:null==t?void 0:t.query,context:o})).then(function(e){return a=1,e})}();return s&&s.then?s.then(u):u(s)})}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}})});export{g as createClient};
|
|
2
|
+
//# sourceMappingURL=index.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.module.js","sources":["../src/shared/requester.ts","../src/request.ts","../src/shared/clientBuilder.ts","../src/index.ts"],"sourcesContent":["import { generatePlainId } from '@lowerdeck/id';\nimport { memo } from '@lowerdeck/memo';\n\nlet index = 0;\nlet rootId = memo(() => generatePlainId(10));\n\nexport let generateRequestId = () => {\n let id = `call_${rootId()}_${index}`;\n index += 1;\n return id;\n};\n\nexport interface Call {\n id: string;\n name: string;\n payload: any;\n endpoint: string;\n headers: Record<string, string>;\n query?: Record<string, string>;\n}\n\nexport type Requester = (\n call: Omit<Call, 'id' | 'headers' | 'query'> & {\n headers: Record<string, string | undefined>;\n query?: Record<string, string | undefined>;\n context: any;\n }\n) => Promise<{\n data: any;\n status: number;\n headers: Record<string, string>;\n query?: Record<string, string>;\n}>;\n","import { canonicalize } from '@lowerdeck/canonicalize';\nimport { internalServerError, isServiceError, ServiceError } from '@lowerdeck/error';\nimport { serialize } from '@lowerdeck/serialize';\nimport { Call, generateRequestId, Requester } from './shared/requester';\n\n// @ts-ignore\nlet isServer = typeof window === 'undefined';\n\nlet log = (...args: any[]) => {\n if (!isServer) console.log(...args);\n};\n\nlet calls: {\n [key: string]: {\n calls: {\n call: Call;\n resolve: (value: any) => void;\n reject: (error: any) => void;\n }[];\n to: any;\n };\n} = {};\n\nlet performRequest = (call: Call) => {\n let key = `${canonicalize(call.headers)}${canonicalize(call.query)}${call.endpoint}`;\n\n if (!calls[key]) calls[key] = { calls: [], to: null };\n let current = calls[key];\n\n let promise = new Promise((resolve, reject) => {\n current.calls.push({ call, resolve, reject });\n });\n\n if (current.to) clearTimeout(current.to);\n\n current.to = setTimeout(\n () => {\n let c = calls[key].calls;\n calls[key].calls = [];\n calls[key].to = null;\n\n let url = new URL(call.endpoint);\n url.search = new URLSearchParams(call.query).toString();\n\n fetch(url.toString(), {\n method: 'POST',\n\n headers: {\n 'Content-Type': 'application/rpc+json',\n ...c[0].call.headers\n },\n body: serialize.encode({\n calls: c\n .map(x => ({\n id: x.call.id,\n name: x.call.name,\n payload: x.call.payload\n }))\n .sort((a, b) => a.name.localeCompare(b.name))\n }),\n credentials: 'include',\n\n // @ts-ignore\n keepalive: false\n })\n .then(async res => ({\n res: serialize.decode(\n (await res.json()) as {\n calls: {\n id: string;\n status: number;\n result: any;\n }[];\n }\n ),\n\n headers: res.headers\n }))\n .then(({ res, headers }) => {\n if (res.__typename == 'error') {\n let err = ServiceError.fromResponse(res);\n c.forEach(x => x.reject(err));\n return;\n }\n\n for (let call of c) {\n let callRes = res.calls.find((x: any) => x.id == call.call.id);\n if (!callRes) {\n let err = new ServiceError(\n internalServerError({ message: 'Call not returned' })\n );\n call.reject(err);\n return;\n }\n\n if (callRes.status >= 200 && callRes.status < 300) {\n call.resolve({\n // data: O;\n // status: number;\n // headers: Record<string, string>;\n\n data: callRes.result,\n status: callRes.status,\n headers\n });\n }\n\n let err = ServiceError.fromResponse(callRes.result);\n call.reject(err);\n }\n })\n .catch(e => {\n c.forEach(x =>\n x.reject(\n new ServiceError(internalServerError({ message: 'Unable to reach server' }))\n )\n );\n });\n },\n isServer ? 0 : 10\n );\n\n return promise;\n};\n\nlet requesterInternal: Requester = async call => {\n let id = generateRequestId();\n log(`[call:${call.name.replace(':', '-')}:${id}] Queued`, call);\n\n let tries = 0;\n let error: Error | null = null;\n\n for (let header in call.headers) {\n if (call.headers[header] === undefined) delete call.headers[header];\n }\n\n if (call.query) {\n for (let query in call.query) {\n if (call.query[query] === undefined) delete call.query[query];\n }\n }\n\n let maxTries = typeof window === 'undefined' ? 6 : 3;\n let retryDelay = typeof window === 'undefined' ? 20 : 1000;\n\n while (tries < maxTries) {\n try {\n return (await performRequest({\n ...(call as any),\n id\n }).then(\n res => {\n if (!isServer) {\n log(`[call:${call.name.replace(':', '-')}:${id}] Success`, res);\n }\n\n return res;\n },\n err => {\n if (isServer) {\n log(`[call:${call.name.replace(':', '-')}:${id}] Queued`, call);\n }\n\n log(`[call:${call.name.replace(':', '-')}:${id}] Error`, err);\n\n throw err;\n }\n )) as any;\n } catch (e: any) {\n error = e;\n\n if (isServiceError(e)) {\n // 400 errors are not retried\n if (e.data.status < 500) throw e;\n }\n }\n\n tries += 1;\n await new Promise(r => setTimeout(r, tries * retryDelay));\n }\n\n if (error) throw error;\n\n throw new ServiceError(internalServerError({ message: 'Unable to reach server' }));\n};\n\nexport let request: Requester = async call => {\n // try {\n return await requesterInternal(call);\n // } catch (e: any) {\n // Sentry.captureException(e);\n // throw e;\n // }\n};\n","import { proxy } from '@lowerdeck/proxy';\nimport { Requester } from './requester';\n\nexport interface ClientOpts {\n endpoint: string;\n headers?: Record<string, string | undefined>;\n getHeaders?: () => Promise<Record<string, string>> | Record<string, string>;\n onRequest?: (d: {\n endpoint: string;\n name: string;\n payload: any;\n headers: Record<string, string | undefined>;\n query?: Record<string, string | undefined>;\n }) => any;\n}\n\nlet noopWithContext = (cb: (ctx: any) => any) => cb({});\n\nexport let clientBuilder =\n (request: Requester, withContext: (cb: (ctx: any) => any) => any = noopWithContext) =>\n <T extends object>(clientOpts: ClientOpts) =>\n proxy<T>(\n async (\n path,\n data,\n requestOpts?: {\n headers?: Record<string, string | undefined>;\n query?: Record<string, string | undefined>;\n }\n ) =>\n await withContext(async context => {\n let headers = {\n ...clientOpts.headers,\n ...(await clientOpts.getHeaders?.()),\n ...requestOpts?.headers\n };\n\n clientOpts.onRequest?.({\n endpoint: clientOpts.endpoint,\n name: path.join(':'),\n payload: data,\n headers,\n query: requestOpts?.query\n });\n\n if (path[path.length - 1] == 'getFull') {\n return await request({\n endpoint: clientOpts.endpoint,\n payload: data,\n name: path.slice(0, -1).join(':'),\n headers,\n query: requestOpts?.query,\n context\n });\n }\n\n return (\n await request({\n endpoint: clientOpts.endpoint,\n payload: data,\n name: path.join(':'),\n headers,\n query: requestOpts?.query,\n context\n })\n ).data;\n })\n );\n","import { request } from './request';\nimport { clientBuilder } from './shared/clientBuilder';\n\nexport let createClient = clientBuilder(request);\n"],"names":["index","rootId","memo","generatePlainId","isServer","window","_settle","pact","state","value","s","_Pact","bind","v","then","o","observer","log","_console","console","apply","slice","call","arguments","prototype","onFulfilled","result","this","callback","onRejected","e","_this","thenable","request","withContext","calls","createClient","Promise","resolve","_exit","_temp4","_result2","error","ServiceError","internalServerError","message","id","generateRequestId","name","replace","tries","header","headers","undefined","query","maxTries","retryDelay","_temp3","_for","_temp2","_result","r","setTimeout","_temp","key","canonicalize","endpoint","to","current","promise","reject","push","clearTimeout","c","url","URL","search","URLSearchParams","toString","fetch","method","_extends","body","serialize","encode","map","x","payload","sort","a","b","localeCompare","credentials","keepalive","res","_decode","decode","json","_res$json","_ref","__typename","_ret","_step","_loop","callRes","find","err","status","data","fromResponse","_iterator","_createForOfIteratorHelperLoose","done","forEach","performRequest","_await$performRequest","_catch","isServiceError","requesterInternal","cb","clientOpts","proxy","path","requestOpts","context","getHeaders","_clientOpts$getHeader","join","_request","onRequest","length","_await$request"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("@lowerdeck/canonicalize"),require("@lowerdeck/error"),require("@lowerdeck/serialize"),require("@lowerdeck/id"),require("@lowerdeck/memo"),require("@lowerdeck/proxy")):"function"==typeof define&&define.amd?define(["exports","@lowerdeck/canonicalize","@lowerdeck/error","@lowerdeck/serialize","@lowerdeck/id","@lowerdeck/memo","@lowerdeck/proxy"],r):r((e||self).rpcClient={},e.canonicalize,e.error,e.serialize,e.id,e.memo,e.proxy)}(this,function(e,r,n,t,o,i,a){function u(e,r){(null==r||r>e.length)&&(r=e.length);for(var n=0,t=Array(r);n<r;n++)t[n]=e[n];return t}function c(){return c=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var n=arguments[r];for(var t in n)({}).hasOwnProperty.call(n,t)&&(e[t]=n[t])}return e},c.apply(null,arguments)}var l=0,s=i.memo(function(){return o.generatePlainId(10)}),d="undefined"==typeof window;function f(e,r,n){if(!e.s){if(n instanceof h){if(!n.s)return void(n.o=f.bind(null,e,r));1&r&&(r=n.s),n=n.v}if(n&&n.then)return void n.then(f.bind(null,e,r),f.bind(null,e,2));e.s=r,e.v=n;var t=e.o;t&&t(e)}}var v=function(){var e;d||(e=console).log.apply(e,[].slice.call(arguments))},h=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(r,n){var t=new e,o=this.s;if(o){var i=1&o?r:n;if(i){try{f(t,1,i(this.v))}catch(e){f(t,2,e)}return t}return this}return this.o=function(e){try{var o=e.v;1&e.s?f(t,1,r?r(o):o):n?f(t,1,n(o)):f(t,2,o)}catch(e){f(t,2,e)}},t},e}();function m(e){return e instanceof h&&1&e.s}var p,y,w={},b=(p=function(e){return Promise.resolve(function(e){try{var o,i=function(e){if(o)return e;if(y)throw y;throw new n.ServiceError(n.internalServerError({message:"Unable to reach server"}))},a=function(){var e="call_"+s()+"_"+l;return l+=1,e}();v("[call:"+e.name.replace(":","-")+":"+a+"] Queued",e);var p=0,y=null;for(var b in e.headers)void 0===e.headers[b]&&delete e.headers[b];if(e.query)for(var g in e.query)void 0===e.query[g]&&delete e.query[g];var q="undefined"==typeof window?6:3,j="undefined"==typeof window?20:1e3,P=function(e,r,n){for(var t;;){var o=e();if(m(o)&&(o=o.v),!o)return i;if(o.then){t=0;break}var i=n();if(i&&i.then){if(!m(i)){t=1;break}i=i.s}}var a=new h,u=f.bind(null,a,2);return(0===t?o.then(l):1===t?i.then(c):(void 0).then(function(){(o=e())?o.then?o.then(l).then(void 0,u):l(o):f(a,1,i)})).then(void 0,u),a;function c(r){i=r;do{if(!(o=e())||m(o)&&!o.v)return void f(a,1,i);if(o.then)return void o.then(l).then(void 0,u);m(i=n())&&(i=i.v)}while(!i||!i.then);i.then(c).then(void 0,u)}function l(e){e?(i=n())&&i.then?i.then(c).then(void 0,u):c(i):f(a,1,i)}}(function(){return!o&&p<q},0,function(){function i(e){return o?e:(p+=1,Promise.resolve(new Promise(function(e){return setTimeout(e,p*j)})).then(function(){}))}var l=function(i,l){try{var s=Promise.resolve(function(e){var o=""+r.canonicalize(e.headers)+r.canonicalize(e.query)+e.endpoint;w[o]||(w[o]={calls:[],to:null});var i=w[o],a=new Promise(function(r,n){i.calls.push({call:e,resolve:r,reject:n})});return i.to&&clearTimeout(i.to),i.to=setTimeout(function(){var r=w[o].calls;w[o].calls=[],w[o].to=null;var i=new URL(e.endpoint);i.search=new URLSearchParams(e.query).toString(),fetch(i.toString(),{method:"POST",headers:c({"Content-Type":"application/rpc+json"},r[0].call.headers),body:t.serialize.encode({calls:r.map(function(e){return{id:e.call.id,name:e.call.name,payload:e.call.payload}}).sort(function(e,r){return e.name.localeCompare(r.name)})}),credentials:"include",keepalive:!1}).then(function(e){try{var r=t.serialize.decode;return Promise.resolve(e.json()).then(function(n){return{res:r.call(t.serialize,n),headers:e.headers}})}catch(e){return Promise.reject(e)}}).then(function(e){var t=e.res,o=e.headers;if("error"!=t.__typename){for(var i,a,c=function(){var e=a.value,r=t.calls.find(function(r){return r.id==e.call.id});if(!r){var i=new n.ServiceError(n.internalServerError({message:"Call not returned"}));return e.reject(i),{v:void 0}}r.status>=200&&r.status<300&&e.resolve({data:r.result,status:r.status,headers:o});var u=n.ServiceError.fromResponse(r.result);e.reject(u)},l=function(e){var r="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(r)return(r=r.call(e)).next.bind(r);if(Array.isArray(e)||(r=function(e,r){if(e){if("string"==typeof e)return u(e,r);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?u(e,r):void 0}}(e))){r&&(e=r);var n=0;return function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(r);!(a=l()).done;)if(i=c())return i.v}else{var s=n.ServiceError.fromResponse(t);r.forEach(function(e){return e.reject(s)})}}).catch(function(e){r.forEach(function(e){return e.reject(new n.ServiceError(n.internalServerError({message:"Unable to reach server"})))})})},d?0:10),a}(c({},e,{id:a})).then(function(r){return d||v("[call:"+e.name.replace(":","-")+":"+a+"] Success",r),r},function(r){throw d&&v("[call:"+e.name.replace(":","-")+":"+a+"] Queued",e),v("[call:"+e.name.replace(":","-")+":"+a+"] Error",r),r})).then(function(e){return o=1,e})}catch(e){return l(e)}return s&&s.then?s.then(void 0,l):s}(0,function(e){if(y=e,n.isServiceError(e)&&e.data.status<500)throw e});return l&&l.then?l.then(i):i(l)});return Promise.resolve(P&&P.then?P.then(i):i(P))}catch(e){return Promise.reject(e)}}(e))},void 0===y&&(y=function(e){return e({})}),function(e){return a.proxy(function(r,n,t){try{return Promise.resolve(y(function(o){try{return Promise.resolve(null==e.getHeaders?void 0:e.getHeaders()).then(function(i){var a;function u(i){return a?i:Promise.resolve(p({endpoint:e.endpoint,payload:n,name:r.join(":"),headers:l,query:null==t?void 0:t.query,context:o})).then(function(e){return e.data})}var l=c({},e.headers,i,null==t?void 0:t.headers);null==e.onRequest||e.onRequest({endpoint:e.endpoint,name:r.join(":"),payload:n,headers:l,query:null==t?void 0:t.query});var s=function(){if("getFull"==r[r.length-1])return Promise.resolve(p({endpoint:e.endpoint,payload:n,name:r.slice(0,-1).join(":"),headers:l,query:null==t?void 0:t.query,context:o})).then(function(e){return a=1,e})}();return s&&s.then?s.then(u):u(s)})}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}})});e.createClient=b});
|
|
2
|
+
//# sourceMappingURL=index.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.umd.js","sources":["../src/shared/requester.ts","../src/request.ts","../src/shared/clientBuilder.ts","../src/index.ts"],"sourcesContent":["import { generatePlainId } from '@lowerdeck/id';\nimport { memo } from '@lowerdeck/memo';\n\nlet index = 0;\nlet rootId = memo(() => generatePlainId(10));\n\nexport let generateRequestId = () => {\n let id = `call_${rootId()}_${index}`;\n index += 1;\n return id;\n};\n\nexport interface Call {\n id: string;\n name: string;\n payload: any;\n endpoint: string;\n headers: Record<string, string>;\n query?: Record<string, string>;\n}\n\nexport type Requester = (\n call: Omit<Call, 'id' | 'headers' | 'query'> & {\n headers: Record<string, string | undefined>;\n query?: Record<string, string | undefined>;\n context: any;\n }\n) => Promise<{\n data: any;\n status: number;\n headers: Record<string, string>;\n query?: Record<string, string>;\n}>;\n","import { canonicalize } from '@lowerdeck/canonicalize';\nimport { internalServerError, isServiceError, ServiceError } from '@lowerdeck/error';\nimport { serialize } from '@lowerdeck/serialize';\nimport { Call, generateRequestId, Requester } from './shared/requester';\n\n// @ts-ignore\nlet isServer = typeof window === 'undefined';\n\nlet log = (...args: any[]) => {\n if (!isServer) console.log(...args);\n};\n\nlet calls: {\n [key: string]: {\n calls: {\n call: Call;\n resolve: (value: any) => void;\n reject: (error: any) => void;\n }[];\n to: any;\n };\n} = {};\n\nlet performRequest = (call: Call) => {\n let key = `${canonicalize(call.headers)}${canonicalize(call.query)}${call.endpoint}`;\n\n if (!calls[key]) calls[key] = { calls: [], to: null };\n let current = calls[key];\n\n let promise = new Promise((resolve, reject) => {\n current.calls.push({ call, resolve, reject });\n });\n\n if (current.to) clearTimeout(current.to);\n\n current.to = setTimeout(\n () => {\n let c = calls[key].calls;\n calls[key].calls = [];\n calls[key].to = null;\n\n let url = new URL(call.endpoint);\n url.search = new URLSearchParams(call.query).toString();\n\n fetch(url.toString(), {\n method: 'POST',\n\n headers: {\n 'Content-Type': 'application/rpc+json',\n ...c[0].call.headers\n },\n body: serialize.encode({\n calls: c\n .map(x => ({\n id: x.call.id,\n name: x.call.name,\n payload: x.call.payload\n }))\n .sort((a, b) => a.name.localeCompare(b.name))\n }),\n credentials: 'include',\n\n // @ts-ignore\n keepalive: false\n })\n .then(async res => ({\n res: serialize.decode(\n (await res.json()) as {\n calls: {\n id: string;\n status: number;\n result: any;\n }[];\n }\n ),\n\n headers: res.headers\n }))\n .then(({ res, headers }) => {\n if (res.__typename == 'error') {\n let err = ServiceError.fromResponse(res);\n c.forEach(x => x.reject(err));\n return;\n }\n\n for (let call of c) {\n let callRes = res.calls.find((x: any) => x.id == call.call.id);\n if (!callRes) {\n let err = new ServiceError(\n internalServerError({ message: 'Call not returned' })\n );\n call.reject(err);\n return;\n }\n\n if (callRes.status >= 200 && callRes.status < 300) {\n call.resolve({\n // data: O;\n // status: number;\n // headers: Record<string, string>;\n\n data: callRes.result,\n status: callRes.status,\n headers\n });\n }\n\n let err = ServiceError.fromResponse(callRes.result);\n call.reject(err);\n }\n })\n .catch(e => {\n c.forEach(x =>\n x.reject(\n new ServiceError(internalServerError({ message: 'Unable to reach server' }))\n )\n );\n });\n },\n isServer ? 0 : 10\n );\n\n return promise;\n};\n\nlet requesterInternal: Requester = async call => {\n let id = generateRequestId();\n log(`[call:${call.name.replace(':', '-')}:${id}] Queued`, call);\n\n let tries = 0;\n let error: Error | null = null;\n\n for (let header in call.headers) {\n if (call.headers[header] === undefined) delete call.headers[header];\n }\n\n if (call.query) {\n for (let query in call.query) {\n if (call.query[query] === undefined) delete call.query[query];\n }\n }\n\n let maxTries = typeof window === 'undefined' ? 6 : 3;\n let retryDelay = typeof window === 'undefined' ? 20 : 1000;\n\n while (tries < maxTries) {\n try {\n return (await performRequest({\n ...(call as any),\n id\n }).then(\n res => {\n if (!isServer) {\n log(`[call:${call.name.replace(':', '-')}:${id}] Success`, res);\n }\n\n return res;\n },\n err => {\n if (isServer) {\n log(`[call:${call.name.replace(':', '-')}:${id}] Queued`, call);\n }\n\n log(`[call:${call.name.replace(':', '-')}:${id}] Error`, err);\n\n throw err;\n }\n )) as any;\n } catch (e: any) {\n error = e;\n\n if (isServiceError(e)) {\n // 400 errors are not retried\n if (e.data.status < 500) throw e;\n }\n }\n\n tries += 1;\n await new Promise(r => setTimeout(r, tries * retryDelay));\n }\n\n if (error) throw error;\n\n throw new ServiceError(internalServerError({ message: 'Unable to reach server' }));\n};\n\nexport let request: Requester = async call => {\n // try {\n return await requesterInternal(call);\n // } catch (e: any) {\n // Sentry.captureException(e);\n // throw e;\n // }\n};\n","import { proxy } from '@lowerdeck/proxy';\nimport { Requester } from './requester';\n\nexport interface ClientOpts {\n endpoint: string;\n headers?: Record<string, string | undefined>;\n getHeaders?: () => Promise<Record<string, string>> | Record<string, string>;\n onRequest?: (d: {\n endpoint: string;\n name: string;\n payload: any;\n headers: Record<string, string | undefined>;\n query?: Record<string, string | undefined>;\n }) => any;\n}\n\nlet noopWithContext = (cb: (ctx: any) => any) => cb({});\n\nexport let clientBuilder =\n (request: Requester, withContext: (cb: (ctx: any) => any) => any = noopWithContext) =>\n <T extends object>(clientOpts: ClientOpts) =>\n proxy<T>(\n async (\n path,\n data,\n requestOpts?: {\n headers?: Record<string, string | undefined>;\n query?: Record<string, string | undefined>;\n }\n ) =>\n await withContext(async context => {\n let headers = {\n ...clientOpts.headers,\n ...(await clientOpts.getHeaders?.()),\n ...requestOpts?.headers\n };\n\n clientOpts.onRequest?.({\n endpoint: clientOpts.endpoint,\n name: path.join(':'),\n payload: data,\n headers,\n query: requestOpts?.query\n });\n\n if (path[path.length - 1] == 'getFull') {\n return await request({\n endpoint: clientOpts.endpoint,\n payload: data,\n name: path.slice(0, -1).join(':'),\n headers,\n query: requestOpts?.query,\n context\n });\n }\n\n return (\n await request({\n endpoint: clientOpts.endpoint,\n payload: data,\n name: path.join(':'),\n headers,\n query: requestOpts?.query,\n context\n })\n ).data;\n })\n );\n","import { request } from './request';\nimport { clientBuilder } from './shared/clientBuilder';\n\nexport let createClient = clientBuilder(request);\n"],"names":["index","rootId","memo","generatePlainId","isServer","window","_settle","pact","state","value","s","_Pact","bind","v","then","o","observer","log","_console","console","apply","slice","call","arguments","prototype","onFulfilled","result","this","callback","onRejected","e","_this","thenable","request","withContext","calls","createClient","Promise","resolve","_exit","_temp4","_result2","error","ServiceError","internalServerError","message","id","generateRequestId","name","replace","tries","header","headers","undefined","query","maxTries","retryDelay","_temp3","_for","_temp2","_result","r","setTimeout","_temp","key","canonicalize","endpoint","to","current","promise","reject","push","clearTimeout","c","url","URL","search","URLSearchParams","toString","fetch","method","_extends","body","serialize","encode","map","x","payload","sort","a","b","localeCompare","credentials","keepalive","res","_decode","decode","json","_res$json","_ref","__typename","_ret","_step","_loop","callRes","find","err","status","data","fromResponse","_iterator","_createForOfIteratorHelperLoose","done","forEach","performRequest","_await$performRequest","_catch","isServiceError","requesterInternal","cb","clientOpts","proxy","path","requestOpts","context","getHeaders","_clientOpts$getHeader","join","_request","onRequest","length","_await$request"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAGA,OAAO,EAA2B,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAuLxE,eAAO,IAAI,OAAO,EAAE,SAOnB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Requester } from './requester';
|
|
2
|
+
export interface ClientOpts {
|
|
3
|
+
endpoint: string;
|
|
4
|
+
headers?: Record<string, string | undefined>;
|
|
5
|
+
getHeaders?: () => Promise<Record<string, string>> | Record<string, string>;
|
|
6
|
+
onRequest?: (d: {
|
|
7
|
+
endpoint: string;
|
|
8
|
+
name: string;
|
|
9
|
+
payload: any;
|
|
10
|
+
headers: Record<string, string | undefined>;
|
|
11
|
+
query?: Record<string, string | undefined>;
|
|
12
|
+
}) => any;
|
|
13
|
+
}
|
|
14
|
+
export declare let clientBuilder: (request: Requester, withContext?: (cb: (ctx: any) => any) => any) => <T extends object>(clientOpts: ClientOpts) => T;
|
|
15
|
+
//# sourceMappingURL=clientBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientBuilder.d.ts","sourceRoot":"","sources":["../../src/shared/clientBuilder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5E,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,GAAG,CAAC;QACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;QAC5C,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;KAC5C,KAAK,GAAG,CAAC;CACX;AAID,eAAO,IAAI,aAAa,GACrB,SAAS,SAAS,EAAE,cAAa,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,KAAK,GAAqB,MACjF,CAAC,SAAS,MAAM,EAAE,YAAY,UAAU,MA+CtC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare let generateRequestId: () => string;
|
|
2
|
+
export interface Call {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
payload: any;
|
|
6
|
+
endpoint: string;
|
|
7
|
+
headers: Record<string, string>;
|
|
8
|
+
query?: Record<string, string>;
|
|
9
|
+
}
|
|
10
|
+
export type Requester = (call: Omit<Call, 'id' | 'headers' | 'query'> & {
|
|
11
|
+
headers: Record<string, string | undefined>;
|
|
12
|
+
query?: Record<string, string | undefined>;
|
|
13
|
+
context: any;
|
|
14
|
+
}) => Promise<{
|
|
15
|
+
data: any;
|
|
16
|
+
status: number;
|
|
17
|
+
headers: Record<string, string>;
|
|
18
|
+
query?: Record<string, string>;
|
|
19
|
+
}>;
|
|
20
|
+
//# sourceMappingURL=requester.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requester.d.ts","sourceRoot":"","sources":["../../src/shared/requester.ts"],"names":[],"mappings":"AAMA,eAAO,IAAI,iBAAiB,cAI3B,CAAC;AAEF,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,GAAG,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,MAAM,SAAS,GAAG,CACtB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,GAAG;IAC7C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC3C,OAAO,EAAE,GAAG,CAAC;CACd,KACE,OAAO,CAAC;IACX,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC,CAAC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lowerdeck/rpc-client",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"author": "Tobias Herber",
|
|
8
|
+
"license": "Apache 2",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"source": "src/index.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"require": "./dist/index.cjs",
|
|
14
|
+
"import": "./dist/index.module.js",
|
|
15
|
+
"default": "./dist/index.module.js"
|
|
16
|
+
},
|
|
17
|
+
"main": "./dist/index.cjs",
|
|
18
|
+
"module": "./dist/index.module.js",
|
|
19
|
+
"types": "dist/index.d.ts",
|
|
20
|
+
"unpkg": "./dist/index.umd.js",
|
|
21
|
+
"scripts": {
|
|
22
|
+
"test": "vitest run --passWithNoTests",
|
|
23
|
+
"lint": "prettier src/**/*.ts --check",
|
|
24
|
+
"build": "microbundle"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"microbundle": "^0.15.1",
|
|
28
|
+
"@lowerdeck/tsconfig": "^1.0.0",
|
|
29
|
+
"typescript": "^5.9.3",
|
|
30
|
+
"vitest": "^3.2.4"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@lowerdeck/canonicalize": "^1.0.1",
|
|
34
|
+
"@lowerdeck/error": "^1.0.5",
|
|
35
|
+
"@lowerdeck/id": "^1.0.2",
|
|
36
|
+
"@lowerdeck/memo": "^1.0.1",
|
|
37
|
+
"@lowerdeck/proxy": "^1.0.1",
|
|
38
|
+
"@lowerdeck/serialize": "^1.0.1"
|
|
39
|
+
}
|
|
40
|
+
}
|
package/src/index.ts
ADDED
package/src/request.ts
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { canonicalize } from '@lowerdeck/canonicalize';
|
|
2
|
+
import { internalServerError, isServiceError, ServiceError } from '@lowerdeck/error';
|
|
3
|
+
import { serialize } from '@lowerdeck/serialize';
|
|
4
|
+
import { Call, generateRequestId, Requester } from './shared/requester';
|
|
5
|
+
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
let isServer = typeof window === 'undefined';
|
|
8
|
+
|
|
9
|
+
let log = (...args: any[]) => {
|
|
10
|
+
if (!isServer) console.log(...args);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
let calls: {
|
|
14
|
+
[key: string]: {
|
|
15
|
+
calls: {
|
|
16
|
+
call: Call;
|
|
17
|
+
resolve: (value: any) => void;
|
|
18
|
+
reject: (error: any) => void;
|
|
19
|
+
}[];
|
|
20
|
+
to: any;
|
|
21
|
+
};
|
|
22
|
+
} = {};
|
|
23
|
+
|
|
24
|
+
let performRequest = (call: Call) => {
|
|
25
|
+
let key = `${canonicalize(call.headers)}${canonicalize(call.query)}${call.endpoint}`;
|
|
26
|
+
|
|
27
|
+
if (!calls[key]) calls[key] = { calls: [], to: null };
|
|
28
|
+
let current = calls[key];
|
|
29
|
+
|
|
30
|
+
let promise = new Promise((resolve, reject) => {
|
|
31
|
+
current.calls.push({ call, resolve, reject });
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (current.to) clearTimeout(current.to);
|
|
35
|
+
|
|
36
|
+
current.to = setTimeout(
|
|
37
|
+
() => {
|
|
38
|
+
let c = calls[key].calls;
|
|
39
|
+
calls[key].calls = [];
|
|
40
|
+
calls[key].to = null;
|
|
41
|
+
|
|
42
|
+
let url = new URL(call.endpoint);
|
|
43
|
+
url.search = new URLSearchParams(call.query).toString();
|
|
44
|
+
|
|
45
|
+
fetch(url.toString(), {
|
|
46
|
+
method: 'POST',
|
|
47
|
+
|
|
48
|
+
headers: {
|
|
49
|
+
'Content-Type': 'application/rpc+json',
|
|
50
|
+
...c[0].call.headers
|
|
51
|
+
},
|
|
52
|
+
body: serialize.encode({
|
|
53
|
+
calls: c
|
|
54
|
+
.map(x => ({
|
|
55
|
+
id: x.call.id,
|
|
56
|
+
name: x.call.name,
|
|
57
|
+
payload: x.call.payload
|
|
58
|
+
}))
|
|
59
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
60
|
+
}),
|
|
61
|
+
credentials: 'include',
|
|
62
|
+
|
|
63
|
+
// @ts-ignore
|
|
64
|
+
keepalive: false
|
|
65
|
+
})
|
|
66
|
+
.then(async res => ({
|
|
67
|
+
res: serialize.decode(
|
|
68
|
+
(await res.json()) as {
|
|
69
|
+
calls: {
|
|
70
|
+
id: string;
|
|
71
|
+
status: number;
|
|
72
|
+
result: any;
|
|
73
|
+
}[];
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
|
|
77
|
+
headers: res.headers
|
|
78
|
+
}))
|
|
79
|
+
.then(({ res, headers }) => {
|
|
80
|
+
if (res.__typename == 'error') {
|
|
81
|
+
let err = ServiceError.fromResponse(res);
|
|
82
|
+
c.forEach(x => x.reject(err));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
for (let call of c) {
|
|
87
|
+
let callRes = res.calls.find((x: any) => x.id == call.call.id);
|
|
88
|
+
if (!callRes) {
|
|
89
|
+
let err = new ServiceError(
|
|
90
|
+
internalServerError({ message: 'Call not returned' })
|
|
91
|
+
);
|
|
92
|
+
call.reject(err);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (callRes.status >= 200 && callRes.status < 300) {
|
|
97
|
+
call.resolve({
|
|
98
|
+
// data: O;
|
|
99
|
+
// status: number;
|
|
100
|
+
// headers: Record<string, string>;
|
|
101
|
+
|
|
102
|
+
data: callRes.result,
|
|
103
|
+
status: callRes.status,
|
|
104
|
+
headers
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
let err = ServiceError.fromResponse(callRes.result);
|
|
109
|
+
call.reject(err);
|
|
110
|
+
}
|
|
111
|
+
})
|
|
112
|
+
.catch(e => {
|
|
113
|
+
c.forEach(x =>
|
|
114
|
+
x.reject(
|
|
115
|
+
new ServiceError(internalServerError({ message: 'Unable to reach server' }))
|
|
116
|
+
)
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
},
|
|
120
|
+
isServer ? 0 : 10
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
return promise;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
let requesterInternal: Requester = async call => {
|
|
127
|
+
let id = generateRequestId();
|
|
128
|
+
log(`[call:${call.name.replace(':', '-')}:${id}] Queued`, call);
|
|
129
|
+
|
|
130
|
+
let tries = 0;
|
|
131
|
+
let error: Error | null = null;
|
|
132
|
+
|
|
133
|
+
for (let header in call.headers) {
|
|
134
|
+
if (call.headers[header] === undefined) delete call.headers[header];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (call.query) {
|
|
138
|
+
for (let query in call.query) {
|
|
139
|
+
if (call.query[query] === undefined) delete call.query[query];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
let maxTries = typeof window === 'undefined' ? 6 : 3;
|
|
144
|
+
let retryDelay = typeof window === 'undefined' ? 20 : 1000;
|
|
145
|
+
|
|
146
|
+
while (tries < maxTries) {
|
|
147
|
+
try {
|
|
148
|
+
return (await performRequest({
|
|
149
|
+
...(call as any),
|
|
150
|
+
id
|
|
151
|
+
}).then(
|
|
152
|
+
res => {
|
|
153
|
+
if (!isServer) {
|
|
154
|
+
log(`[call:${call.name.replace(':', '-')}:${id}] Success`, res);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return res;
|
|
158
|
+
},
|
|
159
|
+
err => {
|
|
160
|
+
if (isServer) {
|
|
161
|
+
log(`[call:${call.name.replace(':', '-')}:${id}] Queued`, call);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
log(`[call:${call.name.replace(':', '-')}:${id}] Error`, err);
|
|
165
|
+
|
|
166
|
+
throw err;
|
|
167
|
+
}
|
|
168
|
+
)) as any;
|
|
169
|
+
} catch (e: any) {
|
|
170
|
+
error = e;
|
|
171
|
+
|
|
172
|
+
if (isServiceError(e)) {
|
|
173
|
+
// 400 errors are not retried
|
|
174
|
+
if (e.data.status < 500) throw e;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
tries += 1;
|
|
179
|
+
await new Promise(r => setTimeout(r, tries * retryDelay));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (error) throw error;
|
|
183
|
+
|
|
184
|
+
throw new ServiceError(internalServerError({ message: 'Unable to reach server' }));
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
export let request: Requester = async call => {
|
|
188
|
+
// try {
|
|
189
|
+
return await requesterInternal(call);
|
|
190
|
+
// } catch (e: any) {
|
|
191
|
+
// Sentry.captureException(e);
|
|
192
|
+
// throw e;
|
|
193
|
+
// }
|
|
194
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { proxy } from '@lowerdeck/proxy';
|
|
2
|
+
import { Requester } from './requester';
|
|
3
|
+
|
|
4
|
+
export interface ClientOpts {
|
|
5
|
+
endpoint: string;
|
|
6
|
+
headers?: Record<string, string | undefined>;
|
|
7
|
+
getHeaders?: () => Promise<Record<string, string>> | Record<string, string>;
|
|
8
|
+
onRequest?: (d: {
|
|
9
|
+
endpoint: string;
|
|
10
|
+
name: string;
|
|
11
|
+
payload: any;
|
|
12
|
+
headers: Record<string, string | undefined>;
|
|
13
|
+
query?: Record<string, string | undefined>;
|
|
14
|
+
}) => any;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let noopWithContext = (cb: (ctx: any) => any) => cb({});
|
|
18
|
+
|
|
19
|
+
export let clientBuilder =
|
|
20
|
+
(request: Requester, withContext: (cb: (ctx: any) => any) => any = noopWithContext) =>
|
|
21
|
+
<T extends object>(clientOpts: ClientOpts) =>
|
|
22
|
+
proxy<T>(
|
|
23
|
+
async (
|
|
24
|
+
path,
|
|
25
|
+
data,
|
|
26
|
+
requestOpts?: {
|
|
27
|
+
headers?: Record<string, string | undefined>;
|
|
28
|
+
query?: Record<string, string | undefined>;
|
|
29
|
+
}
|
|
30
|
+
) =>
|
|
31
|
+
await withContext(async context => {
|
|
32
|
+
let headers = {
|
|
33
|
+
...clientOpts.headers,
|
|
34
|
+
...(await clientOpts.getHeaders?.()),
|
|
35
|
+
...requestOpts?.headers
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
clientOpts.onRequest?.({
|
|
39
|
+
endpoint: clientOpts.endpoint,
|
|
40
|
+
name: path.join(':'),
|
|
41
|
+
payload: data,
|
|
42
|
+
headers,
|
|
43
|
+
query: requestOpts?.query
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
if (path[path.length - 1] == 'getFull') {
|
|
47
|
+
return await request({
|
|
48
|
+
endpoint: clientOpts.endpoint,
|
|
49
|
+
payload: data,
|
|
50
|
+
name: path.slice(0, -1).join(':'),
|
|
51
|
+
headers,
|
|
52
|
+
query: requestOpts?.query,
|
|
53
|
+
context
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
await request({
|
|
59
|
+
endpoint: clientOpts.endpoint,
|
|
60
|
+
payload: data,
|
|
61
|
+
name: path.join(':'),
|
|
62
|
+
headers,
|
|
63
|
+
query: requestOpts?.query,
|
|
64
|
+
context
|
|
65
|
+
})
|
|
66
|
+
).data;
|
|
67
|
+
})
|
|
68
|
+
);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { generatePlainId } from '@lowerdeck/id';
|
|
2
|
+
import { memo } from '@lowerdeck/memo';
|
|
3
|
+
|
|
4
|
+
let index = 0;
|
|
5
|
+
let rootId = memo(() => generatePlainId(10));
|
|
6
|
+
|
|
7
|
+
export let generateRequestId = () => {
|
|
8
|
+
let id = `call_${rootId()}_${index}`;
|
|
9
|
+
index += 1;
|
|
10
|
+
return id;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export interface Call {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
payload: any;
|
|
17
|
+
endpoint: string;
|
|
18
|
+
headers: Record<string, string>;
|
|
19
|
+
query?: Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type Requester = (
|
|
23
|
+
call: Omit<Call, 'id' | 'headers' | 'query'> & {
|
|
24
|
+
headers: Record<string, string | undefined>;
|
|
25
|
+
query?: Record<string, string | undefined>;
|
|
26
|
+
context: any;
|
|
27
|
+
}
|
|
28
|
+
) => Promise<{
|
|
29
|
+
data: any;
|
|
30
|
+
status: number;
|
|
31
|
+
headers: Record<string, string>;
|
|
32
|
+
query?: Record<string, string>;
|
|
33
|
+
}>;
|
package/tsconfig.json
ADDED