@fy-/fws-vue 2.3.30 → 2.3.32
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/composables/rest.ts +82 -24
- package/package.json +1 -1
package/composables/rest.ts
CHANGED
|
@@ -27,6 +27,42 @@ export interface APIResult {
|
|
|
27
27
|
status?: number
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
// Cache for URL parsing to avoid repeated parsing of the same URL
|
|
31
|
+
const urlParseCache = new Map<string, string>()
|
|
32
|
+
|
|
33
|
+
// Memoized function to extract URL pathname and search for hashing
|
|
34
|
+
function getUrlForHash(url: string): string {
|
|
35
|
+
if (urlParseCache.has(url)) {
|
|
36
|
+
return urlParseCache.get(url)!
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let urlForHash: string
|
|
40
|
+
try {
|
|
41
|
+
const urlParse = new URL(url)
|
|
42
|
+
urlForHash = urlParse.pathname + urlParse.search
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
urlForHash = url
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
urlParseCache.set(url, urlForHash)
|
|
49
|
+
return urlForHash
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Detect if we're in SSR mode once and cache the result
|
|
53
|
+
let isSSRMode: boolean | null = null
|
|
54
|
+
function checkSSRMode(): boolean {
|
|
55
|
+
if (isSSRMode === null) {
|
|
56
|
+
isSSRMode = getMode() === 'ssr'
|
|
57
|
+
}
|
|
58
|
+
return isSSRMode
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Optimized JSON.stringify for params
|
|
62
|
+
function stringifyParams(params?: RestParams): string {
|
|
63
|
+
return params ? JSON.stringify(params) : ''
|
|
64
|
+
}
|
|
65
|
+
|
|
30
66
|
export function useRest(): <ResultType extends APIResult>(
|
|
31
67
|
url: string,
|
|
32
68
|
method: RestMethod,
|
|
@@ -35,57 +71,79 @@ params?: RestParams,
|
|
|
35
71
|
const serverRouter = useServerRouter()
|
|
36
72
|
const eventBus = useEventBus()
|
|
37
73
|
|
|
74
|
+
// Cache for request hash computations
|
|
75
|
+
const hashCache = new Map<string, number>()
|
|
76
|
+
|
|
77
|
+
// Function to compute and cache request hash
|
|
78
|
+
function computeRequestHash(url: string, method: RestMethod, params?: RestParams): number {
|
|
79
|
+
const cacheKey = `${url}|${method}|${stringifyParams(params)}`
|
|
80
|
+
|
|
81
|
+
if (hashCache.has(cacheKey)) {
|
|
82
|
+
return hashCache.get(cacheKey)!
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const urlForHash = getUrlForHash(url)
|
|
86
|
+
const hash = stringHash(urlForHash + method + stringifyParams(params))
|
|
87
|
+
|
|
88
|
+
hashCache.set(cacheKey, hash)
|
|
89
|
+
return hash
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Handle API error response consistently
|
|
93
|
+
function handleErrorResult<ResultType extends APIResult>(result: ResultType): Promise<ResultType> {
|
|
94
|
+
eventBus.emit('main-loading', false)
|
|
95
|
+
eventBus.emit('rest-error', result)
|
|
96
|
+
return Promise.reject(result)
|
|
97
|
+
}
|
|
98
|
+
|
|
38
99
|
return async <ResultType extends APIResult>(
|
|
39
100
|
url: string,
|
|
40
101
|
method: RestMethod,
|
|
41
102
|
params?: RestParams,
|
|
42
103
|
): Promise<ResultType> => {
|
|
43
|
-
|
|
44
|
-
try {
|
|
45
|
-
const urlParse = new URL(url)
|
|
46
|
-
urlForHash = urlParse.pathname + urlParse.search
|
|
47
|
-
}
|
|
48
|
-
catch {
|
|
49
|
-
urlForHash = url
|
|
50
|
-
}
|
|
104
|
+
const requestHash = computeRequestHash(url, method, params)
|
|
51
105
|
|
|
52
|
-
|
|
53
|
-
urlForHash + method + JSON.stringify(params),
|
|
54
|
-
)
|
|
106
|
+
// Check for server-rendered results first
|
|
55
107
|
if (isServerRendered()) {
|
|
56
108
|
const hasResult = serverRouter.getResult(requestHash)
|
|
57
109
|
if (hasResult !== undefined) {
|
|
58
110
|
const result = hasResult as ResultType
|
|
59
111
|
serverRouter.removeResult(requestHash)
|
|
112
|
+
|
|
60
113
|
if (result.result === 'error') {
|
|
61
|
-
|
|
62
|
-
eventBus.emit('rest-error', result)
|
|
63
|
-
return Promise.reject(result)
|
|
114
|
+
return handleErrorResult(result)
|
|
64
115
|
}
|
|
116
|
+
|
|
65
117
|
return Promise.resolve(result)
|
|
66
118
|
}
|
|
67
119
|
}
|
|
68
120
|
|
|
69
121
|
try {
|
|
70
122
|
const restResult: ResultType = await rest(url, method, params)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
123
|
+
|
|
124
|
+
// Store result in server router if in SSR mode
|
|
125
|
+
if (checkSSRMode()) {
|
|
126
|
+
// Use structuredClone if available for better performance than JSON.parse/stringify
|
|
127
|
+
const resultCopy = typeof structuredClone !== 'undefined'
|
|
128
|
+
? structuredClone(restResult)
|
|
129
|
+
: JSON.parse(JSON.stringify(restResult))
|
|
130
|
+
|
|
131
|
+
serverRouter.addResult(requestHash, resultCopy)
|
|
76
132
|
}
|
|
133
|
+
|
|
77
134
|
if (restResult.result === 'error') {
|
|
78
|
-
|
|
79
|
-
eventBus.emit('rest-error', restResult)
|
|
80
|
-
return Promise.reject(restResult)
|
|
135
|
+
return handleErrorResult(restResult)
|
|
81
136
|
}
|
|
137
|
+
|
|
82
138
|
return Promise.resolve(restResult)
|
|
83
139
|
}
|
|
84
140
|
catch (error) {
|
|
85
|
-
const restError
|
|
86
|
-
|
|
141
|
+
const restError = error as ResultType
|
|
142
|
+
|
|
143
|
+
if (checkSSRMode()) {
|
|
87
144
|
serverRouter.addResult(requestHash, restError)
|
|
88
145
|
}
|
|
146
|
+
|
|
89
147
|
eventBus.emit('main-loading', false)
|
|
90
148
|
eventBus.emit('rest-error', restError)
|
|
91
149
|
return Promise.resolve(restError)
|