@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.
Files changed (2) hide show
  1. package/composables/rest.ts +82 -24
  2. package/package.json +1 -1
@@ -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
- let urlForHash: string = url
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
- const requestHash = stringHash(
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
- eventBus.emit('main-loading', false)
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
- if (getMode() === 'ssr') {
72
- serverRouter.addResult(
73
- requestHash,
74
- JSON.parse(JSON.stringify(restResult)),
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
- eventBus.emit('main-loading', false)
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: ResultType = error as ResultType
86
- if (getMode() === 'ssr') {
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)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fy-/fws-vue",
3
- "version": "2.3.30",
3
+ "version": "2.3.32",
4
4
  "author": "Florian 'Fy' Gasquez <m@fy.to>",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/fy-to/FWJS#readme",