history.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. 'use strict'
  2. const DEFAULT_MAXAGE = 60000
  3. const expiration = {}
  4. const history = {}
  5. const expireListeners = {}
  6. let size = 0
  7. let interval = null
  8. function get (pid, maxage) {
  9. if (maxage <= 0) {
  10. return
  11. }
  12. if (history[pid] !== undefined) {
  13. expiration[pid] = Date.now() + (maxage || DEFAULT_MAXAGE)
  14. }
  15. return history[pid]
  16. }
  17. function set (pid, object, maxage, onExpire) {
  18. if (object === undefined || maxage <= 0) return
  19. expiration[pid] = Date.now() + (maxage || DEFAULT_MAXAGE)
  20. if (history[pid] === undefined) {
  21. size++
  22. sheduleInvalidator(maxage)
  23. }
  24. history[pid] = object
  25. if (onExpire) {
  26. expireListeners[pid] = onExpire
  27. }
  28. }
  29. function sheduleInvalidator (maxage) {
  30. if (size > 0) {
  31. if (interval === null) {
  32. interval = setInterval(runInvalidator, (maxage || DEFAULT_MAXAGE) / 2)
  33. if (typeof interval.unref === 'function') {
  34. interval.unref()
  35. }
  36. }
  37. return
  38. }
  39. if (interval !== null) {
  40. clearInterval(interval)
  41. interval = null
  42. }
  43. }
  44. function runInvalidator () {
  45. const now = Date.now()
  46. const pids = Object.keys(expiration)
  47. for (let i = 0; i < pids.length; i++) {
  48. const pid = pids[i]
  49. if (expiration[pid] < now) {
  50. size--
  51. if (expireListeners[pid]) {
  52. expireListeners[pid](history[pid])
  53. }
  54. delete history[pid]
  55. delete expiration[pid]
  56. delete expireListeners[pid]
  57. }
  58. }
  59. sheduleInvalidator()
  60. }
  61. function deleteLoop (obj) { for (const i in obj) { delete obj[i] } }
  62. function clear () {
  63. if (interval !== null) {
  64. clearInterval(interval)
  65. interval = null
  66. }
  67. deleteLoop(history)
  68. deleteLoop(expiration)
  69. deleteLoop(expireListeners)
  70. }
  71. module.exports = {
  72. get: get,
  73. set: set,
  74. clear: clear
  75. }