get.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. 'use strict'
  2. const Collect = require('minipass-collect')
  3. const { Minipass } = require('minipass')
  4. const Pipeline = require('minipass-pipeline')
  5. const index = require('./entry-index')
  6. const memo = require('./memoization')
  7. const read = require('./content/read')
  8. async function getData (cache, key, opts = {}) {
  9. const { integrity, memoize, size } = opts
  10. const memoized = memo.get(cache, key, opts)
  11. if (memoized && memoize !== false) {
  12. return {
  13. metadata: memoized.entry.metadata,
  14. data: memoized.data,
  15. integrity: memoized.entry.integrity,
  16. size: memoized.entry.size,
  17. }
  18. }
  19. const entry = await index.find(cache, key, opts)
  20. if (!entry) {
  21. throw new index.NotFoundError(cache, key)
  22. }
  23. const data = await read(cache, entry.integrity, { integrity, size })
  24. if (memoize) {
  25. memo.put(cache, entry, data, opts)
  26. }
  27. return {
  28. data,
  29. metadata: entry.metadata,
  30. size: entry.size,
  31. integrity: entry.integrity,
  32. }
  33. }
  34. module.exports = getData
  35. async function getDataByDigest (cache, key, opts = {}) {
  36. const { integrity, memoize, size } = opts
  37. const memoized = memo.get.byDigest(cache, key, opts)
  38. if (memoized && memoize !== false) {
  39. return memoized
  40. }
  41. const res = await read(cache, key, { integrity, size })
  42. if (memoize) {
  43. memo.put.byDigest(cache, key, res, opts)
  44. }
  45. return res
  46. }
  47. module.exports.byDigest = getDataByDigest
  48. const getMemoizedStream = (memoized) => {
  49. const stream = new Minipass()
  50. stream.on('newListener', function (ev, cb) {
  51. ev === 'metadata' && cb(memoized.entry.metadata)
  52. ev === 'integrity' && cb(memoized.entry.integrity)
  53. ev === 'size' && cb(memoized.entry.size)
  54. })
  55. stream.end(memoized.data)
  56. return stream
  57. }
  58. function getStream (cache, key, opts = {}) {
  59. const { memoize, size } = opts
  60. const memoized = memo.get(cache, key, opts)
  61. if (memoized && memoize !== false) {
  62. return getMemoizedStream(memoized)
  63. }
  64. const stream = new Pipeline()
  65. // Set all this up to run on the stream and then just return the stream
  66. Promise.resolve().then(async () => {
  67. const entry = await index.find(cache, key)
  68. if (!entry) {
  69. throw new index.NotFoundError(cache, key)
  70. }
  71. stream.emit('metadata', entry.metadata)
  72. stream.emit('integrity', entry.integrity)
  73. stream.emit('size', entry.size)
  74. stream.on('newListener', function (ev, cb) {
  75. ev === 'metadata' && cb(entry.metadata)
  76. ev === 'integrity' && cb(entry.integrity)
  77. ev === 'size' && cb(entry.size)
  78. })
  79. const src = read.readStream(
  80. cache,
  81. entry.integrity,
  82. { ...opts, size: typeof size !== 'number' ? entry.size : size }
  83. )
  84. if (memoize) {
  85. const memoStream = new Collect.PassThrough()
  86. memoStream.on('collect', data => memo.put(cache, entry, data, opts))
  87. stream.unshift(memoStream)
  88. }
  89. stream.unshift(src)
  90. return stream
  91. }).catch((err) => stream.emit('error', err))
  92. return stream
  93. }
  94. module.exports.stream = getStream
  95. function getStreamDigest (cache, integrity, opts = {}) {
  96. const { memoize } = opts
  97. const memoized = memo.get.byDigest(cache, integrity, opts)
  98. if (memoized && memoize !== false) {
  99. const stream = new Minipass()
  100. stream.end(memoized)
  101. return stream
  102. } else {
  103. const stream = read.readStream(cache, integrity, opts)
  104. if (!memoize) {
  105. return stream
  106. }
  107. const memoStream = new Collect.PassThrough()
  108. memoStream.on('collect', data => memo.put.byDigest(
  109. cache,
  110. integrity,
  111. data,
  112. opts
  113. ))
  114. return new Pipeline(stream, memoStream)
  115. }
  116. }
  117. module.exports.stream.byDigest = getStreamDigest
  118. function info (cache, key, opts = {}) {
  119. const { memoize } = opts
  120. const memoized = memo.get(cache, key, opts)
  121. if (memoized && memoize !== false) {
  122. return Promise.resolve(memoized.entry)
  123. } else {
  124. return index.find(cache, key)
  125. }
  126. }
  127. module.exports.info = info
  128. async function copy (cache, key, dest, opts = {}) {
  129. const entry = await index.find(cache, key, opts)
  130. if (!entry) {
  131. throw new index.NotFoundError(cache, key)
  132. }
  133. await read.copy(cache, entry.integrity, dest, opts)
  134. return {
  135. metadata: entry.metadata,
  136. size: entry.size,
  137. integrity: entry.integrity,
  138. }
  139. }
  140. module.exports.copy = copy
  141. async function copyByDigest (cache, key, dest, opts = {}) {
  142. await read.copy(cache, key, dest, opts)
  143. return key
  144. }
  145. module.exports.copy.byDigest = copyByDigest
  146. module.exports.hasContent = read.hasContent