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