soon-fetch 3.0.0-beta.3 → 3.0.0-beta.4
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/README.md +11 -7
- package/dist/index.cjs.js +1 -1
- package/dist/index.d.ts +27 -8
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
> - ⭐ rapid define a request api
|
|
11
11
|
> - ⌛ timeout disconnect
|
|
12
12
|
> - 🔤 automatic parse or serialization of JSON
|
|
13
|
-
> - 📏 .min size less than **
|
|
13
|
+
> - 📏 .min size less than **5K**, smaller after zip
|
|
14
14
|
> - 💡 smart type tips with Typescript
|
|
15
15
|
|
|
16
16
|
- [Example](#example)
|
|
@@ -150,7 +150,8 @@ export default function App() {
|
|
|
150
150
|
|
|
151
151
|
```typescript
|
|
152
152
|
//can be GET POST PATCH PUT DELETE
|
|
153
|
-
|
|
153
|
+
soon.GET(url:string).Query<Query>().Send<Response>()
|
|
154
|
+
soon.POST(url:string).Body<Body>().Send<Response>()
|
|
154
155
|
//define an api
|
|
155
156
|
export const getUserInfo = soon.GET("/user/:id").Send();
|
|
156
157
|
//then use in any where
|
|
@@ -347,19 +348,22 @@ export default function App() {
|
|
|
347
348
|
|
|
348
349
|
##### 快速定义 API
|
|
349
350
|
|
|
350
|
-
```
|
|
351
|
+
```ts
|
|
351
352
|
//可以是 GET POST PATCH PUT DELETE
|
|
352
353
|
//GET 请求数据传递至query,其他方法请求数据传递至body
|
|
353
|
-
soon.
|
|
354
|
+
soon.GET(url:string).Query<Query>().Send<Response>()
|
|
355
|
+
soon.POST(url:string).Body<Body>().Send<Response>()
|
|
354
356
|
|
|
355
357
|
//定义一个api
|
|
356
|
-
export const getUserInfo=soon.
|
|
358
|
+
export const getUserInfo=soon.GET('/user/:id').Send()
|
|
357
359
|
//使用
|
|
358
360
|
getUserInfo({id:2}).then(res=>console.log(res))
|
|
359
361
|
|
|
360
362
|
//用typescript,
|
|
361
|
-
export const login=soon
|
|
362
|
-
|
|
363
|
+
export const login=soon
|
|
364
|
+
.POST('/user/login')
|
|
365
|
+
.Body<{username:string,password:string}>()
|
|
366
|
+
.Send<{token:string}>()
|
|
363
367
|
//开发工具会有请求和响应的智能提醒
|
|
364
368
|
login({username:'admin',password:'123'}).then(res=>{
|
|
365
369
|
localStorage.setItem('token', res.token);
|
package/dist/index.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const e=e=>{const t=[],
|
|
1
|
+
"use strict";const e=e=>{const t=[],r=e.match(/:([^:/\d]+)\/?/g);return r&&r.forEach((e=>{t.push(e.replace(/\//g,"").replace(/:/g,""))})),t},t=(e="")=>e.endsWith("/")?e.slice(0,-1):e,r=(e="")=>e.startsWith("/")?e:"/"+e,n=(e="")=>e.startsWith("http"),o=e=>{if(!e)return[];if(e instanceof URLSearchParams||"string"==typeof e||Array.isArray(e))return Array.from(new URLSearchParams(e).entries());const t=[];return Object.keys(e).forEach((r=>{const n=e[r];(Array.isArray(n)?n:[n]).forEach((e=>{t.push([r,e??""])}))})),t},s=(s,a)=>{const{query:i,params:c,baseURL:f}=a;let p=s.trim();e(s).forEach((e=>{c&&(p=p.replace(":"+e,""+c[e]))}));const[u,l]=p.split("?"),h=new URLSearchParams([...o(l),...o(i)]);let y=((e,o)=>{if(n(e))return e;const s=n(o)?o:r(o);return t(s)+t(r(e))})(u,f);return h.size&&(y=y+"?"+h),y},a=(...e)=>{const t=new Headers;return e.forEach((e=>{e&&new Headers(e).forEach(((e,r)=>{t.set(r,e)}))})),t};function i(e,t){const r=(e??[]).filter((e=>!!e));return t&&r.push(AbortSignal.timeout(t)),r.length?AbortSignal.any(r):void 0}function c(e){return!(!e||"object"!=typeof e||(e instanceof Blob||e instanceof ArrayBuffer||e instanceof FormData||e instanceof File||e instanceof DataView||e instanceof URLSearchParams||e instanceof ReadableStream||(t=e,t instanceof Int8Array||t instanceof Uint8Array||t instanceof Uint8ClampedArray||t instanceof Int16Array||t instanceof Uint16Array||t instanceof Int32Array||t instanceof Uint32Array||t instanceof Float32Array||t instanceof Float64Array||t instanceof BigInt64Array||t instanceof BigUint64Array)));var t}function f(...e){const t=Object.assign({},...e),r=a(...e.map((e=>e?.headers)));return t.headers=r,t.signal=i(e.map((e=>e?.signal)),t.timeout),t}function p(e){const{url:t,options:r,baseURL:n,baseOptions:o}=e,a=f(o,r),p=s(t,{...a,baseURL:n}),u=a?.body,l=c(u);a.body=l?JSON.stringify(u):u,l&&a.headers.append("Content-Type","application/json");const h=new AbortController;return a.signal=i([a.signal,h.signal]),{url:p,options:a,is_body_json:l,abortController:h}}const u=["get","post","put","delete","patch"];function l(e,t){const r={};return e.forEach((e=>{r[e]=t(e)})),r}function h(t){const r=(r,n,o)=>{const s=!!e(r).length;return(...e)=>{const a=[...e],{hasBody:i,hasQuery:c}=o||{},f=s?a.shift():void 0,p=c?a.shift():void 0,u=i?a.shift():void 0,l=a.shift();return t(r,n,f,p,u,l,o?.options)}},n={};return u.forEach((e=>{const t=e.toUpperCase();n[t]=t=>({Send:n=>r(t,e,{options:n}),Body:()=>({Send:n=>r(t,e,{hasBody:!0,options:n})}),Query:()=>({Send:n=>r(t,e,{hasQuery:!0,options:n}),Body:()=>({Send:n=>r(t,e,{hasBody:!0,hasQuery:!0,options:n})})})})})),n}function y(e,t){t&&(t.pop()?.abort("race abort"),t.push(e))}function d(e){if(Array.isArray(e))return e.map(d);if("object"==typeof e&&null!==e){const t={};return Object.keys(e).sort().forEach((r=>{t[r]=d(e[r])})),t}return e}function g(e){const{url:t,options:r}=e,{headers:n,method:o,body:s,query:a,params:i}=r??{},c=d(Object.fromEntries(new Headers(n).entries()??[]));return(o??"get").toLowerCase()+t+JSON.stringify(d(a)??"")+JSON.stringify(d(i)??"")+JSON.stringify(c)+("object"==typeof s&&null!=s?JSON.stringify(d(s)):s??"")}function m(){const e={},t=[];setInterval((()=>{const r=Date.now();for(let n=t.length-1;n>=0;n--)t[n].expiredTime<r&&(delete e[t[n].key],t.splice(n,1))}),6e4);const r=e=>e instanceof Response?e.clone():"function"==typeof e||e instanceof Promise?e:structuredClone(e);function n(r){delete e[r];for(let e=t.length-1;e>=0;e--)if(t[e].key===r){t.splice(e,1);break}}return{get:function(t){const o=e[t];if(void 0!==o)return o.expiredTime>Date.now()?r(o.data):void n(t)},set:function(n,o,s){e[n]={data:r(o),expiredTime:s},t.push({key:n,expiredTime:s})},remove:n}}function b(){const e={},t=t=>e[t]=void 0;return{get:t=>e[t],set:(r,n)=>{e[r]=n,n.finally((()=>t(r)))}}}exports.createCache=m,exports.createShare=b,exports.createShortApi=h,exports.createShortMethods=l,exports.createSilentRefresh=function(e){let t=[],r=!1;return(n,o)=>{t.push({success:n,fail:o}),r||(r=!0,e().then((()=>{t.forEach((e=>e.success()))})).catch((e=>{t.forEach((e=>e.fail()))})).finally((()=>{r=!1,t=[]})))}},exports.createSoon=function(e,t){const r=m(),n=b(),o=(o,s)=>new Promise(((a,i)=>{const c=p(e(o,s)),f=g(c),{abortController:u}=c,l=new AbortController;l.signal.addEventListener("abort",(()=>{i(l.signal.reason)}));const h=t({parsed:{...c,requestKey:f}});if(c.options?.share){const e=n.get(f);if(e)return a(e)}if(y(c.options.share?l:u,c.options?.aborts),c.options?.staleTime){const e=r.get(f);if(void 0!==e)return a(e)}const d=h(o,s);c.options?.share&&n.set(f,d),d.then((e=>{a(e),c.options?.staleTime&&r.set(f,e,(new Date).getTime()+c.options.staleTime)})).catch((e=>i(e)))})),s=h(((e,t,r,n,s,a,i)=>o(e,{...i,...a,method:t,params:r,query:n,body:s}))),a=l([...u,"head","options"],(e=>(t,r)=>o(t,{...r,method:e})));return{request:o,...s,...a}},exports.deepSort=d,exports.genRequestKey=g,exports.isBodyJson=c,exports.mergeHeaders=a,exports.mergeOptions=f,exports.mergeSignals=i,exports.mergeUrl=s,exports.parseUrlOptions=function(e){const{url:t,options:r}=p(e);return[t,r]},exports.parseWithBase=p,exports.raceAbort=y;
|
package/dist/index.d.ts
CHANGED
|
@@ -24,6 +24,20 @@ declare function isBodyJson(body: any): boolean;
|
|
|
24
24
|
declare function mergeOptions<Options extends SoonOptions>(...optionsList: (Options | undefined)[]): Options & {
|
|
25
25
|
headers: Headers;
|
|
26
26
|
};
|
|
27
|
+
declare function parseWithBase<Options extends SoonOptions>(urlOptions: {
|
|
28
|
+
url: string;
|
|
29
|
+
options?: Options;
|
|
30
|
+
baseURL?: string;
|
|
31
|
+
baseOptions?: Options;
|
|
32
|
+
}): {
|
|
33
|
+
url: string;
|
|
34
|
+
options: Options & {
|
|
35
|
+
headers: Headers;
|
|
36
|
+
body?: RequestInit["body"];
|
|
37
|
+
};
|
|
38
|
+
is_body_json: boolean;
|
|
39
|
+
abortController: AbortController;
|
|
40
|
+
};
|
|
27
41
|
declare function parseUrlOptions<Options extends SoonOptions>(urlOptions: {
|
|
28
42
|
url: string;
|
|
29
43
|
options?: Options;
|
|
@@ -58,11 +72,13 @@ declare function raceAbort(abortController: AbortController, controllers?: Abort
|
|
|
58
72
|
declare function deepSort(obj: unknown): unknown;
|
|
59
73
|
declare function genRequestKey(req: {
|
|
60
74
|
url: string;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
75
|
+
options?: {
|
|
76
|
+
method?: string;
|
|
77
|
+
headers?: RequestInit["headers"];
|
|
78
|
+
body?: RequestInit["body"] | object;
|
|
79
|
+
query?: Record<string, string | number | boolean | null | undefined | (string | number | boolean | null | undefined)[]> | URLSearchParams;
|
|
80
|
+
params?: Record<string, string | number>;
|
|
81
|
+
};
|
|
66
82
|
}): string;
|
|
67
83
|
declare function createCache(): {
|
|
68
84
|
get: (key: string) => unknown;
|
|
@@ -77,15 +93,18 @@ declare function createSilentRefresh(refresh_token_fn: () => Promise<void>): (su
|
|
|
77
93
|
declare function createSoon<Options extends SoonOptions>(getConfig: (url: string, options?: Options) => {
|
|
78
94
|
url: string;
|
|
79
95
|
options?: Options;
|
|
80
|
-
baseURL
|
|
96
|
+
baseURL?: string;
|
|
81
97
|
baseOptions?: Options;
|
|
82
98
|
}, wrapper: (instance: {
|
|
83
99
|
parsed: {
|
|
84
100
|
url: string;
|
|
85
101
|
options: Options & {
|
|
86
102
|
headers: Headers;
|
|
87
|
-
body?:
|
|
103
|
+
body?: RequestInit["body"];
|
|
88
104
|
};
|
|
105
|
+
is_body_json: boolean;
|
|
106
|
+
abortController: AbortController;
|
|
107
|
+
requestKey: string;
|
|
89
108
|
};
|
|
90
109
|
}) => <T>(url: string, options?: Options) => Promise<T>): {
|
|
91
110
|
options: <T>(url: string, options?: Options) => Promise<T>;
|
|
@@ -152,4 +171,4 @@ declare function createSoon<Options extends SoonOptions>(getConfig: (url: string
|
|
|
152
171
|
request: <T>(url: string, options?: Options) => Promise<T>;
|
|
153
172
|
};
|
|
154
173
|
|
|
155
|
-
export { type SoonOptions, createCache, createShare, createShortApi, createShortMethods, createSilentRefresh, createSoon, deepSort, genRequestKey, isBodyJson, mergeHeaders, mergeOptions, mergeSignals, mergeUrl, parseUrlOptions, raceAbort };
|
|
174
|
+
export { type SoonOptions, createCache, createShare, createShortApi, createShortMethods, createSilentRefresh, createSoon, deepSort, genRequestKey, isBodyJson, mergeHeaders, mergeOptions, mergeSignals, mergeUrl, parseUrlOptions, parseWithBase, raceAbort };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const t=t=>{const e=[],n=t.match(/:([^:/\d]+)\/?/g);return n&&n.forEach((t=>{e.push(t.replace(/\//g,"").replace(/:/g,""))})),e},e=(t="")=>t.endsWith("/")?t.slice(0,-1):t,n=(t="")=>t.startsWith("/")?t:"/"+t,r=(t="")=>t.startsWith("http"),o=t=>{if(!t)return[];if(t instanceof URLSearchParams||"string"==typeof t||Array.isArray(t))return Array.from(new URLSearchParams(t).entries());const e=[];return Object.keys(t).forEach((n=>{const r=t[n];(Array.isArray(r)?r:[r]).forEach((t=>{e.push([n,t??""])}))})),e},s=(s,a)=>{const{query:i,params:c,baseURL:f}=a;let u=s.trim();t(s).forEach((t=>{c&&(u=u.replace(":"+t,""+c[t]))}));const[l,p]=u.split("?"),h=new URLSearchParams([...o(p),...o(i)]);let y=((t,o)=>{if(r(t))return t;const s=r(o)?o:n(o);return e(s)+e(n(t))})(l,f);return h.size&&(y=y+"?"+h),y},a=(...t)=>{const e=new Headers;return t.forEach((t=>{t&&new Headers(t).forEach(((t,n)=>{e.set(n,t)}))})),e};function i(t,e){const n=(t??[]).filter((t=>!!t));return e&&n.push(AbortSignal.timeout(e)),n.length?AbortSignal.any(n):void 0}function c(t){return!(!t||"object"!=typeof t||(t instanceof Blob||t instanceof ArrayBuffer||t instanceof FormData||t instanceof File||t instanceof DataView||t instanceof URLSearchParams||t instanceof ReadableStream||(e=t,e instanceof Int8Array||e instanceof Uint8Array||e instanceof Uint8ClampedArray||e instanceof Int16Array||e instanceof Uint16Array||e instanceof Int32Array||e instanceof Uint32Array||e instanceof Float32Array||e instanceof Float64Array||e instanceof BigInt64Array||e instanceof BigUint64Array)));var e}function f(...t){const e=Object.assign({},...t),n=a(...t.map((t=>t?.headers)));return e.headers=n,e.signal=i(t.map((t=>t?.signal)),e.timeout),e}function u(t){const{url:e,options:n,baseURL:r,baseOptions:o}=t,a=f(o,n),u=s(e,{...a,baseURL:r}),l=a?.body,p=c(l);
|
|
1
|
+
const t=t=>{const e=[],n=t.match(/:([^:/\d]+)\/?/g);return n&&n.forEach((t=>{e.push(t.replace(/\//g,"").replace(/:/g,""))})),e},e=(t="")=>t.endsWith("/")?t.slice(0,-1):t,n=(t="")=>t.startsWith("/")?t:"/"+t,r=(t="")=>t.startsWith("http"),o=t=>{if(!t)return[];if(t instanceof URLSearchParams||"string"==typeof t||Array.isArray(t))return Array.from(new URLSearchParams(t).entries());const e=[];return Object.keys(t).forEach((n=>{const r=t[n];(Array.isArray(r)?r:[r]).forEach((t=>{e.push([n,t??""])}))})),e},s=(s,a)=>{const{query:i,params:c,baseURL:f}=a;let u=s.trim();t(s).forEach((t=>{c&&(u=u.replace(":"+t,""+c[t]))}));const[l,p]=u.split("?"),h=new URLSearchParams([...o(p),...o(i)]);let y=((t,o)=>{if(r(t))return t;const s=r(o)?o:n(o);return e(s)+e(n(t))})(l,f);return h.size&&(y=y+"?"+h),y},a=(...t)=>{const e=new Headers;return t.forEach((t=>{t&&new Headers(t).forEach(((t,n)=>{e.set(n,t)}))})),e};function i(t,e){const n=(t??[]).filter((t=>!!t));return e&&n.push(AbortSignal.timeout(e)),n.length?AbortSignal.any(n):void 0}function c(t){return!(!t||"object"!=typeof t||(t instanceof Blob||t instanceof ArrayBuffer||t instanceof FormData||t instanceof File||t instanceof DataView||t instanceof URLSearchParams||t instanceof ReadableStream||(e=t,e instanceof Int8Array||e instanceof Uint8Array||e instanceof Uint8ClampedArray||e instanceof Int16Array||e instanceof Uint16Array||e instanceof Int32Array||e instanceof Uint32Array||e instanceof Float32Array||e instanceof Float64Array||e instanceof BigInt64Array||e instanceof BigUint64Array)));var e}function f(...t){const e=Object.assign({},...t),n=a(...t.map((t=>t?.headers)));return e.headers=n,e.signal=i(t.map((t=>t?.signal)),e.timeout),e}function u(t){const{url:e,options:n,baseURL:r,baseOptions:o}=t,a=f(o,n),u=s(e,{...a,baseURL:r}),l=a?.body,p=c(l);a.body=p?JSON.stringify(l):l,p&&a.headers.append("Content-Type","application/json");const h=new AbortController;return a.signal=i([a.signal,h.signal]),{url:u,options:a,is_body_json:p,abortController:h}}function l(t){const{url:e,options:n}=u(t);return[e,n]}const p=["get","post","put","delete","patch"];function h(t,e){const n={};return t.forEach((t=>{n[t]=e(t)})),n}function y(e){const n=(n,r,o)=>{const s=!!t(n).length;return(...t)=>{const a=[...t],{hasBody:i,hasQuery:c}=o||{},f=s?a.shift():void 0,u=c?a.shift():void 0,l=i?a.shift():void 0,p=a.shift();return e(n,r,f,u,l,p,o?.options)}},r={};return p.forEach((t=>{const e=t.toUpperCase();r[e]=e=>({Send:r=>n(e,t,{options:r}),Body:()=>({Send:r=>n(e,t,{hasBody:!0,options:r})}),Query:()=>({Send:r=>n(e,t,{hasQuery:!0,options:r}),Body:()=>({Send:r=>n(e,t,{hasBody:!0,hasQuery:!0,options:r})})})})})),r}function d(t,e){e&&(e.pop()?.abort("race abort"),e.push(t))}function m(t){if(Array.isArray(t))return t.map(m);if("object"==typeof t&&null!==t){const e={};return Object.keys(t).sort().forEach((n=>{e[n]=m(t[n])})),e}return t}function g(t){const{url:e,options:n}=t,{headers:r,method:o,body:s,query:a,params:i}=n??{},c=m(Object.fromEntries(new Headers(r).entries()??[]));return(o??"get").toLowerCase()+e+JSON.stringify(m(a)??"")+JSON.stringify(m(i)??"")+JSON.stringify(c)+("object"==typeof s&&null!=s?JSON.stringify(m(s)):s??"")}function b(){const t={},e=[];setInterval((()=>{const n=Date.now();for(let r=e.length-1;r>=0;r--)e[r].expiredTime<n&&(delete t[e[r].key],e.splice(r,1))}),6e4);const n=t=>t instanceof Response?t.clone():"function"==typeof t||t instanceof Promise?t:structuredClone(t);function r(n){delete t[n];for(let t=e.length-1;t>=0;t--)if(e[t].key===n){e.splice(t,1);break}}return{get:function(e){const o=t[e];if(void 0!==o)return o.expiredTime>Date.now()?n(o.data):void r(e)},set:function(r,o,s){t[r]={data:n(o),expiredTime:s},e.push({key:r,expiredTime:s})},remove:r}}function A(){const t={},e=e=>t[e]=void 0;return{get:e=>t[e],set:(n,r)=>{t[n]=r,r.finally((()=>e(n)))}}}function S(t){let e=[],n=!1;return(r,o)=>{e.push({success:r,fail:o}),n||(n=!0,t().then((()=>{e.forEach((t=>t.success()))})).catch((t=>{e.forEach((t=>t.fail()))})).finally((()=>{n=!1,e=[]})))}}function w(t,e){const n=b(),r=A(),o=(o,s)=>new Promise(((a,i)=>{const c=u(t(o,s)),f=g(c),{abortController:l}=c,p=new AbortController;p.signal.addEventListener("abort",(()=>{i(p.signal.reason)}));const h=e({parsed:{...c,requestKey:f}});if(c.options?.share){const t=r.get(f);if(t)return a(t)}if(d(c.options.share?p:l,c.options?.aborts),c.options?.staleTime){const t=n.get(f);if(void 0!==t)return a(t)}const y=h(o,s);c.options?.share&&r.set(f,y),y.then((t=>{a(t),c.options?.staleTime&&n.set(f,t,(new Date).getTime()+c.options.staleTime)})).catch((t=>i(t)))})),s=y(((t,e,n,r,s,a,i)=>o(t,{...i,...a,method:e,params:n,query:r,body:s}))),a=h([...p,"head","options"],(t=>(e,n)=>o(e,{...n,method:t})));return{request:o,...s,...a}}export{b as createCache,A as createShare,y as createShortApi,h as createShortMethods,S as createSilentRefresh,w as createSoon,m as deepSort,g as genRequestKey,c as isBodyJson,a as mergeHeaders,f as mergeOptions,i as mergeSignals,s as mergeUrl,l as parseUrlOptions,u as parseWithBase,d as raceAbort};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "soon-fetch",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
4
|
-
"description": "a 5Kb request lib alternative to axios",
|
|
3
|
+
"version": "3.0.0-beta.4",
|
|
4
|
+
"description": "a 5Kb request lib alternative to axios with timeout, request reusing ,cache ,race ...",
|
|
5
5
|
"homepage": "https://github.com/leafio/soon-fetch",
|
|
6
6
|
"main": "./dist/index.cjs.js",
|
|
7
7
|
"module": "/dist/index.js",
|