@xen-orchestra/web-core 0.48.0 → 0.48.2
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.
|
@@ -48,6 +48,48 @@ const useMyResource = defineRemoteResource({
|
|
|
48
48
|
const { myResource, customProp } = useMyResource()
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
### State
|
|
52
|
+
|
|
53
|
+
When managing arrays, avoid using `computed` inside the `state` function. This can cause performance issues because each call to `computed` will perform a full iteration over `data` every time it's updated. For example, for a large collection of 10,000 elements, three calls to `computed` based on `data` will generate 30,000 iterations. Instead, use `watch` and a `forEach` loop, and distribute your data across multiple references (`ref`) so that `data` is only iterated over once with each modification.
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
const useMyResource = defineRemoteResource({
|
|
57
|
+
url: '/api/path/to/resource',
|
|
58
|
+
initialData: () => [] as MyResource[],
|
|
59
|
+
state: (data) => {
|
|
60
|
+
const filteredResources = ref<MyResource[]>([])
|
|
61
|
+
const anotherFilteredResources = ref<MyResource[]>([])
|
|
62
|
+
|
|
63
|
+
watch(data, _data => {
|
|
64
|
+
const tmpFilteredResources: MyResource[] = []
|
|
65
|
+
const tmpAnotherFilteredResources: MyResource[] = []
|
|
66
|
+
|
|
67
|
+
_data.forEach(value => {
|
|
68
|
+
if(value.foo === 'Foo'){
|
|
69
|
+
tmpFilteredResources.push(value)
|
|
70
|
+
} else if (value.foo === 'Bar'){
|
|
71
|
+
tmpAnotherFilteredResources.push(value)
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
filteredResources.value = tmpFilteredResources
|
|
76
|
+
anotherFilteredResources.value = tmpAnotherFilteredResources
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
myResource: data,
|
|
81
|
+
filteredResources,
|
|
82
|
+
anotherFilteredResources
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
onDataReceived: (currentData, receivedData) => {
|
|
86
|
+
deepMerge(currentData.value, receivedData)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
|
|
51
93
|
## Context
|
|
52
94
|
|
|
53
95
|
The context is available in the `$context` property of the returned state.
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import type { ResourceContext, UseRemoteResource } from '@core/packages/remote-resource/types.ts'
|
|
8
8
|
import type { VoidFunction } from '@core/types/utility.type.ts'
|
|
9
9
|
import { ifElse } from '@core/utils/if-else.utils.ts'
|
|
10
|
-
import { type MaybeRef, noop, useTimeoutPoll } from '@vueuse/core'
|
|
10
|
+
import { type MaybeRef, noop, useDebounceFn, useTimeoutPoll } from '@vueuse/core'
|
|
11
11
|
import { merge, remove } from 'lodash-es'
|
|
12
12
|
import readNDJSONStream from 'ndjson-readablestream'
|
|
13
13
|
import {
|
|
@@ -20,6 +20,8 @@ import {
|
|
|
20
20
|
reactive,
|
|
21
21
|
type Ref,
|
|
22
22
|
ref,
|
|
23
|
+
shallowRef,
|
|
24
|
+
triggerRef,
|
|
23
25
|
toRef,
|
|
24
26
|
toValue,
|
|
25
27
|
watch,
|
|
@@ -255,7 +257,20 @@ export function defineRemoteResource<
|
|
|
255
257
|
|
|
256
258
|
const hasError = computed(() => lastError.value !== undefined)
|
|
257
259
|
|
|
258
|
-
const data =
|
|
260
|
+
const data = shallowRef(buildData()) as Ref<TData>
|
|
261
|
+
// trigger reactivity on data when no more updates since 100ms or after 500ms
|
|
262
|
+
const flushData = useDebounceFn(
|
|
263
|
+
() => {
|
|
264
|
+
if (Array.isArray(data.value)) {
|
|
265
|
+
triggerRef(data)
|
|
266
|
+
} else if (data.value != null) {
|
|
267
|
+
// create a new JS reference to ensure vueJS detect the change
|
|
268
|
+
data.value = { ...data.value }
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
100,
|
|
272
|
+
{ maxWait: 500 }
|
|
273
|
+
)
|
|
259
274
|
|
|
260
275
|
async function execute() {
|
|
261
276
|
try {
|
|
@@ -275,9 +290,11 @@ export function defineRemoteResource<
|
|
|
275
290
|
if (config.stream) {
|
|
276
291
|
for await (const event of readNDJSONStream(response.body)) {
|
|
277
292
|
onDataReceived(data, event)
|
|
293
|
+
flushData()
|
|
278
294
|
}
|
|
279
295
|
} else {
|
|
280
296
|
onDataReceived(data, await response.json())
|
|
297
|
+
flushData()
|
|
281
298
|
}
|
|
282
299
|
|
|
283
300
|
isReady.value = true
|
|
@@ -302,8 +319,14 @@ export function defineRemoteResource<
|
|
|
302
319
|
handleWatching,
|
|
303
320
|
handlePost,
|
|
304
321
|
resource,
|
|
305
|
-
onDataReceived: receivedData =>
|
|
306
|
-
|
|
322
|
+
onDataReceived: receivedData => {
|
|
323
|
+
onDataReceived(data, receivedData, context)
|
|
324
|
+
flushData()
|
|
325
|
+
},
|
|
326
|
+
onDataRemoved: receivedData => {
|
|
327
|
+
onDataRemoved(data, receivedData, context)
|
|
328
|
+
flushData()
|
|
329
|
+
},
|
|
307
330
|
})
|
|
308
331
|
await execute()
|
|
309
332
|
}
|