quasar-ui-danx 0.4.69 → 0.4.71
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/dist/danx.es.js +422 -406
- package/dist/danx.es.js.map +1 -1
- package/dist/danx.umd.js +39 -39
- package/dist/danx.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/helpers/request.ts +60 -32
- package/src/helpers/routes.ts +1 -0
- package/src/types/requests.d.ts +8 -1
package/package.json
CHANGED
package/src/helpers/request.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Ref } from "vue";
|
2
2
|
import { danxOptions } from "../config";
|
3
|
-
import { HttpResponse, RequestApi } from "../types";
|
3
|
+
import { ActiveRequest, HttpResponse, RequestApi } from "../types";
|
4
4
|
import { sleep } from "./utils";
|
5
5
|
|
6
6
|
/**
|
@@ -21,16 +21,18 @@ export const request: RequestApi = {
|
|
21
21
|
options = options || {};
|
22
22
|
const requestKey = options?.requestKey || url + JSON.stringify(options.params || "");
|
23
23
|
const waitOnPrevious = !!options?.waitOnPrevious;
|
24
|
-
const
|
24
|
+
const useMostRecentResponse = !!options?.useMostRecentResponse;
|
25
|
+
const shouldAbortPrevious = !waitOnPrevious;
|
25
26
|
const timestamp = Date.now();
|
26
27
|
|
27
28
|
// If there was a request with the same key made that is still active, track that here
|
28
29
|
const previousRequest = request.activeRequests[requestKey];
|
29
30
|
|
30
31
|
// Set the current active request to this one
|
31
|
-
|
32
|
+
const currentRequest: ActiveRequest = { timestamp };
|
33
|
+
request.activeRequests[requestKey] = currentRequest;
|
32
34
|
|
33
|
-
if (
|
35
|
+
if (shouldAbortPrevious) {
|
34
36
|
// If there is already an abort controller set for this key, abort it
|
35
37
|
if (previousRequest) {
|
36
38
|
previousRequest.abortController?.abort("Request was aborted due to a newer request being made");
|
@@ -38,7 +40,7 @@ export const request: RequestApi = {
|
|
38
40
|
|
39
41
|
const abortController = new AbortController();
|
40
42
|
// Set the new abort controller for this key
|
41
|
-
|
43
|
+
currentRequest.abortController = abortController;
|
42
44
|
options.signal = abortController.signal;
|
43
45
|
}
|
44
46
|
|
@@ -54,59 +56,85 @@ export const request: RequestApi = {
|
|
54
56
|
delete options.params;
|
55
57
|
}
|
56
58
|
|
57
|
-
let
|
58
|
-
|
59
|
-
|
60
|
-
|
59
|
+
let resolvePromise!: (value: any) => any;
|
60
|
+
let rejectPromise!: (reason?: any) => any;
|
61
|
+
currentRequest.requestPromise = new Promise((resolve, reject) => {
|
62
|
+
resolvePromise = resolve;
|
63
|
+
rejectPromise = reject;
|
64
|
+
});
|
65
|
+
|
66
|
+
// If there is a previous request still active, wait for it to finish before proceeding (if the waitForPrevious flag is set)
|
67
|
+
if (waitOnPrevious && previousRequest?.requestPromise) {
|
68
|
+
try {
|
61
69
|
await previousRequest.requestPromise;
|
70
|
+
} catch (e) {
|
71
|
+
// We don't care if it fails, we just need to wait for it to complete
|
62
72
|
}
|
73
|
+
}
|
63
74
|
|
64
|
-
|
65
|
-
|
66
|
-
|
75
|
+
// Wait to finish the request before proceeding
|
76
|
+
let response: Response;
|
77
|
+
try {
|
78
|
+
response = await fetch(request.url(url), options);
|
67
79
|
} catch (e) {
|
68
80
|
if (options.ignoreAbort && (e + "").match(/Request was aborted/)) {
|
69
|
-
|
81
|
+
const abortResponse = { abort: true };
|
82
|
+
resolvePromise(abortResponse);
|
83
|
+
return abortResponse;
|
70
84
|
}
|
85
|
+
rejectPromise(e);
|
71
86
|
throw e;
|
72
87
|
}
|
73
88
|
|
74
89
|
// Verify the app version of the client and server are matching
|
75
90
|
checkAppVersion(response);
|
76
91
|
|
77
|
-
//
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
92
|
+
// Track the most recent request (maybe another request with the same key was made after this request started)
|
93
|
+
let mostRecentRequest = request.activeRequests[requestKey];
|
94
|
+
|
95
|
+
// Always fetch the result
|
96
|
+
let responseJson = await response.json();
|
97
|
+
|
98
|
+
// Send the real JSON response to the promise in case other requests are waiting on this request result
|
99
|
+
resolvePromise(responseJson);
|
100
|
+
|
101
|
+
// If this request is not the most recent request...
|
102
|
+
if (mostRecentRequest.timestamp !== timestamp) {
|
103
|
+
// and it should be aborted but was aborted too late, return an aborted response
|
104
|
+
if (shouldAbortPrevious) {
|
105
|
+
responseJson = { abort: true };
|
106
|
+
} else if (useMostRecentResponse) {
|
107
|
+
// or if there is a more recent request, and the useMoreRecentResponse flag is set, update this response to the more recent one
|
108
|
+
do {
|
109
|
+
// Always update on each iteration to make sure we're checking the current most recent
|
110
|
+
// (maybe additional requests will be made before the current most recent finishes)
|
111
|
+
mostRecentRequest = request.activeRequests[requestKey];
|
112
|
+
responseJson = await mostRecentRequest.requestPromise;
|
113
|
+
|
114
|
+
// If the most recent request is the same as this one, break out of the loop
|
115
|
+
if (request.activeRequests[requestKey].timestamp === mostRecentRequest.timestamp) {
|
116
|
+
break;
|
117
|
+
}
|
118
|
+
} while (mostRecentRequest.timestamp !== request.activeRequests[requestKey].timestamp);
|
83
119
|
}
|
84
120
|
}
|
85
121
|
|
86
|
-
// If this request is the active request for the requestKey, we can clear this key from active requests
|
87
|
-
if (request.activeRequests[requestKey].timestamp === timestamp) {
|
88
|
-
// Remove the request from the active requests list
|
89
|
-
delete request.activeRequests[requestKey];
|
90
|
-
}
|
91
|
-
|
92
|
-
const result = await response.json();
|
93
|
-
|
94
122
|
if (response.status === 401) {
|
95
123
|
const onUnauthorized = danxOptions.value.request?.onUnauthorized;
|
96
|
-
return onUnauthorized ? onUnauthorized(
|
124
|
+
return onUnauthorized ? onUnauthorized(responseJson, response) : {
|
97
125
|
error: true,
|
98
126
|
message: "Unauthorized",
|
99
|
-
...
|
127
|
+
...responseJson
|
100
128
|
};
|
101
129
|
}
|
102
130
|
|
103
131
|
if (response.status > 400) {
|
104
|
-
if (
|
105
|
-
|
132
|
+
if (responseJson.exception && !responseJson.error) {
|
133
|
+
responseJson.error = true;
|
106
134
|
}
|
107
135
|
}
|
108
136
|
|
109
|
-
return
|
137
|
+
return responseJson;
|
110
138
|
},
|
111
139
|
|
112
140
|
async poll(url: string, options, interval, fnUntil) {
|
package/src/helpers/routes.ts
CHANGED
package/src/types/requests.d.ts
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
import { AnyObject } from "./shared";
|
2
2
|
|
3
|
+
export interface ActiveRequest {
|
4
|
+
requestPromise?: Promise<any>,
|
5
|
+
abortController?: AbortController,
|
6
|
+
timestamp: number
|
7
|
+
}
|
8
|
+
|
3
9
|
export interface RequestApi {
|
4
10
|
activeRequests: {
|
5
|
-
[key: string]:
|
11
|
+
[key: string]: ActiveRequest
|
6
12
|
};
|
7
13
|
|
8
14
|
url(url: string): string;
|
@@ -34,6 +40,7 @@ export interface RequestOptions {
|
|
34
40
|
export interface RequestCallOptions extends RequestInit {
|
35
41
|
requestKey?: string;
|
36
42
|
waitOnPrevious?: boolean;
|
43
|
+
useMostRecentResponse?: boolean;
|
37
44
|
ignoreAbort?: boolean;
|
38
45
|
params?: AnyObject;
|
39
46
|
}
|