progressEventReducer.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import speedometer from './speedometer.js';
  2. import throttle from './throttle.js';
  3. import utils from '../utils.js';
  4. export const progressEventReducer = (listener, isDownloadStream, freq = 3) => {
  5. let bytesNotified = 0;
  6. const _speedometer = speedometer(50, 250);
  7. return throttle((e) => {
  8. const loaded = e.loaded;
  9. const total = e.lengthComputable ? e.total : undefined;
  10. const progressBytes = loaded - bytesNotified;
  11. const rate = _speedometer(progressBytes);
  12. const inRange = loaded <= total;
  13. bytesNotified = loaded;
  14. const data = {
  15. loaded,
  16. total,
  17. progress: total ? loaded / total : undefined,
  18. bytes: progressBytes,
  19. rate: rate ? rate : undefined,
  20. estimated: rate && total && inRange ? (total - loaded) / rate : undefined,
  21. event: e,
  22. lengthComputable: total != null,
  23. [isDownloadStream ? 'download' : 'upload']: true,
  24. };
  25. listener(data);
  26. }, freq);
  27. };
  28. export const progressEventDecorator = (total, throttled) => {
  29. const lengthComputable = total != null;
  30. return [
  31. (loaded) =>
  32. throttled[0]({
  33. lengthComputable,
  34. total,
  35. loaded,
  36. }),
  37. throttled[1],
  38. ];
  39. };
  40. export const asyncDecorator =
  41. (fn) =>
  42. (...args) =>
  43. utils.asap(() => fn(...args));