59 lines
1.4 KiB
JavaScript
59 lines
1.4 KiB
JavaScript
'use strict'
|
|
|
|
const { asyncMap } = require('@xen-orchestra/async-map')
|
|
const { createLogger } = require('@xen-orchestra/log')
|
|
|
|
const { warn } = createLogger('vates:disposable:debounceResource')
|
|
|
|
exports.createDebounceResource = () => {
|
|
const flushers = new Set()
|
|
async function debounceResource(pDisposable, delay = debounceResource.defaultDelay) {
|
|
if (delay === 0) {
|
|
return pDisposable
|
|
}
|
|
|
|
const disposable = await pDisposable
|
|
|
|
let timeoutId
|
|
const disposeWrapper = async () => {
|
|
if (timeoutId !== undefined) {
|
|
clearTimeout(timeoutId)
|
|
timeoutId = undefined
|
|
flushers.delete(flusher)
|
|
|
|
try {
|
|
await disposable.dispose()
|
|
} catch (error) {
|
|
warn(error)
|
|
}
|
|
}
|
|
}
|
|
|
|
const flusher = () => {
|
|
const shouldDisposeNow = timeoutId !== undefined
|
|
if (shouldDisposeNow) {
|
|
return disposeWrapper()
|
|
} else {
|
|
// will dispose ASAP
|
|
delay = 0
|
|
}
|
|
}
|
|
flushers.add(flusher)
|
|
|
|
return {
|
|
dispose() {
|
|
timeoutId = setTimeout(disposeWrapper, delay)
|
|
},
|
|
value: disposable.value,
|
|
}
|
|
}
|
|
debounceResource.flushAll = () => {
|
|
// iterate on a sync way in order to not remove a flusher added on processing flushers
|
|
const promise = asyncMap(flushers, flush => flush())
|
|
flushers.clear()
|
|
return promise
|
|
}
|
|
|
|
return debounceResource
|
|
}
|