cacache 12.0.2 → 13.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +100 -1
- package/README.md +3 -27
- package/get.js +158 -139
- package/index.js +39 -1
- package/lib/content/path.js +7 -5
- package/lib/content/read.js +120 -54
- package/lib/content/rm.js +5 -4
- package/lib/content/write.js +120 -97
- package/lib/entry-index.js +135 -112
- package/lib/memoization.js +15 -10
- package/lib/util/disposer.js +30 -0
- package/lib/util/fix-owner.js +42 -19
- package/lib/util/hash-to-segments.js +1 -5
- package/lib/util/move-file.js +29 -24
- package/lib/util/tmp.js +8 -3
- package/lib/verify.js +161 -97
- package/ls.js +1 -1
- package/package.json +20 -22
- package/put.js +56 -48
- package/rm.js +5 -2
- package/README.es.md +0 -628
- package/en.js +0 -3
- package/es.js +0 -3
- package/lib/util/y.js +0 -25
- package/locales/en.js +0 -47
- package/locales/en.json +0 -7
- package/locales/es.js +0 -49
- package/locales/es.json +0 -6
package/lib/util/tmp.js
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const util = require('util')
|
|
4
4
|
|
|
5
5
|
const figgyPudding = require('figgy-pudding')
|
|
6
6
|
const fixOwner = require('./fix-owner')
|
|
7
7
|
const path = require('path')
|
|
8
|
-
const rimraf =
|
|
8
|
+
const rimraf = util.promisify(require('rimraf'))
|
|
9
9
|
const uniqueFilename = require('unique-filename')
|
|
10
|
+
const { disposer } = require('./disposer')
|
|
10
11
|
|
|
11
12
|
const TmpOpts = figgyPudding({
|
|
12
13
|
tmpPrefix: {}
|
|
13
14
|
})
|
|
14
15
|
|
|
15
16
|
module.exports.mkdir = mktmpdir
|
|
17
|
+
|
|
16
18
|
function mktmpdir (cache, opts) {
|
|
17
19
|
opts = TmpOpts(opts)
|
|
18
20
|
const tmpTarget = uniqueFilename(path.join(cache, 'tmp'), opts.tmpPrefix)
|
|
@@ -22,16 +24,19 @@ function mktmpdir (cache, opts) {
|
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
module.exports.withTmp = withTmp
|
|
27
|
+
|
|
25
28
|
function withTmp (cache, opts, cb) {
|
|
26
29
|
if (!cb) {
|
|
27
30
|
cb = opts
|
|
28
31
|
opts = null
|
|
29
32
|
}
|
|
30
33
|
opts = TmpOpts(opts)
|
|
31
|
-
|
|
34
|
+
|
|
35
|
+
return disposer(mktmpdir(cache, opts), rimraf, cb)
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
module.exports.fix = fixtmpdir
|
|
39
|
+
|
|
35
40
|
function fixtmpdir (cache) {
|
|
36
41
|
return fixOwner(cache, path.join(cache, 'tmp'))
|
|
37
42
|
}
|
package/lib/verify.js
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const util = require('util')
|
|
4
4
|
|
|
5
|
+
const pMap = require('p-map')
|
|
5
6
|
const contentPath = require('./content/path')
|
|
6
7
|
const figgyPudding = require('figgy-pudding')
|
|
7
|
-
const finished = BB.promisify(require('mississippi').finished)
|
|
8
8
|
const fixOwner = require('./util/fix-owner')
|
|
9
9
|
const fs = require('graceful-fs')
|
|
10
|
-
const
|
|
10
|
+
const fsm = require('fs-minipass')
|
|
11
|
+
const glob = util.promisify(require('glob'))
|
|
11
12
|
const index = require('./entry-index')
|
|
12
13
|
const path = require('path')
|
|
13
|
-
const rimraf =
|
|
14
|
+
const rimraf = util.promisify(require('rimraf'))
|
|
14
15
|
const ssri = require('ssri')
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
const hasOwnProperty = (obj, key) =>
|
|
18
|
+
Object.prototype.hasOwnProperty.call(obj, key)
|
|
19
|
+
|
|
20
|
+
const stat = util.promisify(fs.stat)
|
|
21
|
+
const truncate = util.promisify(fs.truncate)
|
|
22
|
+
const writeFile = util.promisify(fs.writeFile)
|
|
23
|
+
const readFile = util.promisify(fs.readFile)
|
|
17
24
|
|
|
18
25
|
const VerifyOpts = figgyPudding({
|
|
19
26
|
concurrency: {
|
|
@@ -26,10 +33,12 @@ const VerifyOpts = figgyPudding({
|
|
|
26
33
|
})
|
|
27
34
|
|
|
28
35
|
module.exports = verify
|
|
36
|
+
|
|
29
37
|
function verify (cache, opts) {
|
|
30
38
|
opts = VerifyOpts(opts)
|
|
31
39
|
opts.log.silly('verify', 'verifying cache at', cache)
|
|
32
|
-
|
|
40
|
+
|
|
41
|
+
const steps = [
|
|
33
42
|
markStartTime,
|
|
34
43
|
fixPerms,
|
|
35
44
|
garbageCollect,
|
|
@@ -37,38 +46,57 @@ function verify (cache, opts) {
|
|
|
37
46
|
cleanTmp,
|
|
38
47
|
writeVerifile,
|
|
39
48
|
markEndTime
|
|
40
|
-
]
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
return steps
|
|
52
|
+
.reduce((promise, step, i) => {
|
|
53
|
+
const label = step.name || `step #${i}`
|
|
54
|
+
const start = new Date()
|
|
55
|
+
return promise.then((stats) => {
|
|
56
|
+
return step(cache, opts).then((s) => {
|
|
57
|
+
s &&
|
|
58
|
+
Object.keys(s).forEach((k) => {
|
|
59
|
+
stats[k] = s[k]
|
|
60
|
+
})
|
|
61
|
+
const end = new Date()
|
|
62
|
+
if (!stats.runTime) {
|
|
63
|
+
stats.runTime = {}
|
|
64
|
+
}
|
|
65
|
+
stats.runTime[label] = end - start
|
|
66
|
+
return Promise.resolve(stats)
|
|
67
|
+
})
|
|
46
68
|
})
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
stats.runTime
|
|
69
|
+
}, Promise.resolve({}))
|
|
70
|
+
.then((stats) => {
|
|
71
|
+
stats.runTime.total = stats.endTime - stats.startTime
|
|
72
|
+
opts.log.silly(
|
|
73
|
+
'verify',
|
|
74
|
+
'verification finished for',
|
|
75
|
+
cache,
|
|
76
|
+
'in',
|
|
77
|
+
`${stats.runTime.total}ms`
|
|
78
|
+
)
|
|
50
79
|
return stats
|
|
51
80
|
})
|
|
52
|
-
}, {}).tap(stats => {
|
|
53
|
-
stats.runTime.total = stats.endTime - stats.startTime
|
|
54
|
-
opts.log.silly('verify', 'verification finished for', cache, 'in', `${stats.runTime.total}ms`)
|
|
55
|
-
})
|
|
56
81
|
}
|
|
57
82
|
|
|
58
83
|
function markStartTime (cache, opts) {
|
|
59
|
-
return { startTime: new Date() }
|
|
84
|
+
return Promise.resolve({ startTime: new Date() })
|
|
60
85
|
}
|
|
61
86
|
|
|
62
87
|
function markEndTime (cache, opts) {
|
|
63
|
-
return { endTime: new Date() }
|
|
88
|
+
return Promise.resolve({ endTime: new Date() })
|
|
64
89
|
}
|
|
65
90
|
|
|
66
91
|
function fixPerms (cache, opts) {
|
|
67
92
|
opts.log.silly('verify', 'fixing cache permissions')
|
|
68
|
-
return fixOwner
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
93
|
+
return fixOwner
|
|
94
|
+
.mkdirfix(cache, cache)
|
|
95
|
+
.then(() => {
|
|
96
|
+
// TODO - fix file permissions too
|
|
97
|
+
return fixOwner.chownr(cache, cache)
|
|
98
|
+
})
|
|
99
|
+
.then(() => null)
|
|
72
100
|
}
|
|
73
101
|
|
|
74
102
|
// Implements a naive mark-and-sweep tracing garbage collector.
|
|
@@ -84,85 +112,104 @@ function garbageCollect (cache, opts) {
|
|
|
84
112
|
opts.log.silly('verify', 'garbage collecting content')
|
|
85
113
|
const indexStream = index.lsStream(cache)
|
|
86
114
|
const liveContent = new Set()
|
|
87
|
-
indexStream.on('data', entry => {
|
|
88
|
-
if (opts.filter && !opts.filter(entry)) {
|
|
115
|
+
indexStream.on('data', (entry) => {
|
|
116
|
+
if (opts.filter && !opts.filter(entry)) {
|
|
117
|
+
return
|
|
118
|
+
}
|
|
89
119
|
liveContent.add(entry.integrity.toString())
|
|
90
120
|
})
|
|
91
|
-
return
|
|
92
|
-
|
|
121
|
+
return new Promise((resolve, reject) => {
|
|
122
|
+
indexStream.on('end', resolve).on('error', reject)
|
|
123
|
+
}).then(() => {
|
|
124
|
+
const contentDir = contentPath.contentDir(cache)
|
|
93
125
|
return glob(path.join(contentDir, '**'), {
|
|
94
126
|
follow: false,
|
|
95
127
|
nodir: true,
|
|
96
128
|
nosort: true
|
|
97
|
-
}).then(files => {
|
|
98
|
-
return
|
|
129
|
+
}).then((files) => {
|
|
130
|
+
return Promise.resolve({
|
|
99
131
|
verifiedContent: 0,
|
|
100
132
|
reclaimedCount: 0,
|
|
101
133
|
reclaimedSize: 0,
|
|
102
134
|
badContentCount: 0,
|
|
103
135
|
keptSize: 0
|
|
104
|
-
}).
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
136
|
+
}).then((stats) =>
|
|
137
|
+
pMap(
|
|
138
|
+
files,
|
|
139
|
+
(f) => {
|
|
140
|
+
const split = f.split(/[/\\]/)
|
|
141
|
+
const digest = split.slice(split.length - 3).join('')
|
|
142
|
+
const algo = split[split.length - 4]
|
|
143
|
+
const integrity = ssri.fromHex(digest, algo)
|
|
144
|
+
if (liveContent.has(integrity.toString())) {
|
|
145
|
+
return verifyContent(f, integrity).then((info) => {
|
|
146
|
+
if (!info.valid) {
|
|
147
|
+
stats.reclaimedCount++
|
|
148
|
+
stats.badContentCount++
|
|
149
|
+
stats.reclaimedSize += info.size
|
|
150
|
+
} else {
|
|
151
|
+
stats.verifiedContent++
|
|
152
|
+
stats.keptSize += info.size
|
|
153
|
+
}
|
|
154
|
+
return stats
|
|
155
|
+
})
|
|
115
156
|
} else {
|
|
116
|
-
|
|
117
|
-
stats.
|
|
157
|
+
// No entries refer to this content. We can delete.
|
|
158
|
+
stats.reclaimedCount++
|
|
159
|
+
return stat(f).then((s) => {
|
|
160
|
+
return rimraf(f).then(() => {
|
|
161
|
+
stats.reclaimedSize += s.size
|
|
162
|
+
return stats
|
|
163
|
+
})
|
|
164
|
+
})
|
|
118
165
|
}
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
stats.reclaimedCount++
|
|
124
|
-
return fs.statAsync(f).then(s => {
|
|
125
|
-
return rimraf(f).then(() => {
|
|
126
|
-
stats.reclaimedSize += s.size
|
|
127
|
-
return stats
|
|
128
|
-
})
|
|
129
|
-
})
|
|
130
|
-
}
|
|
131
|
-
}, { concurrency: opts.concurrency }))
|
|
166
|
+
},
|
|
167
|
+
{ concurrency: opts.concurrency }
|
|
168
|
+
).then(() => stats)
|
|
169
|
+
)
|
|
132
170
|
})
|
|
133
171
|
})
|
|
134
172
|
}
|
|
135
173
|
|
|
136
174
|
function verifyContent (filepath, sri) {
|
|
137
|
-
return
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
175
|
+
return stat(filepath)
|
|
176
|
+
.then((s) => {
|
|
177
|
+
const contentInfo = {
|
|
178
|
+
size: s.size,
|
|
179
|
+
valid: true
|
|
180
|
+
}
|
|
181
|
+
return ssri
|
|
182
|
+
.checkStream(new fsm.ReadStream(filepath), sri)
|
|
183
|
+
.catch((err) => {
|
|
184
|
+
if (err.code !== 'EINTEGRITY') {
|
|
185
|
+
throw err
|
|
186
|
+
}
|
|
187
|
+
return rimraf(filepath).then(() => {
|
|
188
|
+
contentInfo.valid = false
|
|
189
|
+
})
|
|
190
|
+
})
|
|
191
|
+
.then(() => contentInfo)
|
|
192
|
+
})
|
|
193
|
+
.catch((err) => {
|
|
194
|
+
if (err.code === 'ENOENT') {
|
|
195
|
+
return { size: 0, valid: false }
|
|
196
|
+
}
|
|
197
|
+
throw err
|
|
198
|
+
})
|
|
152
199
|
}
|
|
153
200
|
|
|
154
201
|
function rebuildIndex (cache, opts) {
|
|
155
202
|
opts.log.silly('verify', 'rebuilding index')
|
|
156
|
-
return index.ls(cache).then(entries => {
|
|
203
|
+
return index.ls(cache).then((entries) => {
|
|
157
204
|
const stats = {
|
|
158
205
|
missingContent: 0,
|
|
159
206
|
rejectedEntries: 0,
|
|
160
207
|
totalEntries: 0
|
|
161
208
|
}
|
|
162
209
|
const buckets = {}
|
|
163
|
-
for (
|
|
164
|
-
if (
|
|
165
|
-
const hashed = index.
|
|
210
|
+
for (const k in entries) {
|
|
211
|
+
if (hasOwnProperty(entries, k)) {
|
|
212
|
+
const hashed = index.hashKey(k)
|
|
166
213
|
const entry = entries[k]
|
|
167
214
|
const excluded = opts.filter && !opts.filter(entry)
|
|
168
215
|
excluded && stats.rejectedEntries++
|
|
@@ -172,35 +219,51 @@ function rebuildIndex (cache, opts) {
|
|
|
172
219
|
// skip
|
|
173
220
|
} else if (excluded) {
|
|
174
221
|
buckets[hashed] = []
|
|
175
|
-
buckets[hashed]._path = index.
|
|
222
|
+
buckets[hashed]._path = index.bucketPath(cache, k)
|
|
176
223
|
} else {
|
|
177
224
|
buckets[hashed] = [entry]
|
|
178
|
-
buckets[hashed]._path = index.
|
|
225
|
+
buckets[hashed]._path = index.bucketPath(cache, k)
|
|
179
226
|
}
|
|
180
227
|
}
|
|
181
228
|
}
|
|
182
|
-
return
|
|
183
|
-
|
|
184
|
-
|
|
229
|
+
return pMap(
|
|
230
|
+
Object.keys(buckets),
|
|
231
|
+
(key) => {
|
|
232
|
+
return rebuildBucket(cache, buckets[key], stats, opts)
|
|
233
|
+
},
|
|
234
|
+
{ concurrency: opts.concurrency }
|
|
235
|
+
).then(() => stats)
|
|
185
236
|
})
|
|
186
237
|
}
|
|
187
238
|
|
|
188
239
|
function rebuildBucket (cache, bucket, stats, opts) {
|
|
189
|
-
return
|
|
240
|
+
return truncate(bucket._path).then(() => {
|
|
190
241
|
// This needs to be serialized because cacache explicitly
|
|
191
242
|
// lets very racy bucket conflicts clobber each other.
|
|
192
|
-
return
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
return
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
243
|
+
return bucket.reduce((promise, entry) => {
|
|
244
|
+
return promise.then(() => {
|
|
245
|
+
const content = contentPath(cache, entry.integrity)
|
|
246
|
+
return stat(content)
|
|
247
|
+
.then(() => {
|
|
248
|
+
return index
|
|
249
|
+
.insert(cache, entry.key, entry.integrity, {
|
|
250
|
+
metadata: entry.metadata,
|
|
251
|
+
size: entry.size
|
|
252
|
+
})
|
|
253
|
+
.then(() => {
|
|
254
|
+
stats.totalEntries++
|
|
255
|
+
})
|
|
256
|
+
})
|
|
257
|
+
.catch((err) => {
|
|
258
|
+
if (err.code === 'ENOENT') {
|
|
259
|
+
stats.rejectedEntries++
|
|
260
|
+
stats.missingContent++
|
|
261
|
+
return
|
|
262
|
+
}
|
|
263
|
+
throw err
|
|
264
|
+
})
|
|
202
265
|
})
|
|
203
|
-
})
|
|
266
|
+
}, Promise.resolve())
|
|
204
267
|
})
|
|
205
268
|
}
|
|
206
269
|
|
|
@@ -213,15 +276,16 @@ function writeVerifile (cache, opts) {
|
|
|
213
276
|
const verifile = path.join(cache, '_lastverified')
|
|
214
277
|
opts.log.silly('verify', 'writing verifile to ' + verifile)
|
|
215
278
|
try {
|
|
216
|
-
return
|
|
279
|
+
return writeFile(verifile, '' + +new Date())
|
|
217
280
|
} finally {
|
|
218
281
|
fixOwner.chownr.sync(cache, verifile)
|
|
219
282
|
}
|
|
220
283
|
}
|
|
221
284
|
|
|
222
285
|
module.exports.lastRun = lastRun
|
|
286
|
+
|
|
223
287
|
function lastRun (cache) {
|
|
224
|
-
return
|
|
225
|
-
|
|
226
|
-
)
|
|
288
|
+
return readFile(path.join(cache, '_lastverified'), 'utf8').then(
|
|
289
|
+
(data) => new Date(+data)
|
|
290
|
+
)
|
|
227
291
|
}
|
package/ls.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cacache",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "13.0.1",
|
|
4
4
|
"cache-version": {
|
|
5
5
|
"content": "2",
|
|
6
6
|
"index": "5"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"postrelease": "npm publish && git push --follow-tags",
|
|
19
19
|
"pretest": "standard",
|
|
20
20
|
"release": "standard-version -s",
|
|
21
|
-
"test": "
|
|
21
|
+
"test": "tap test/*.js",
|
|
22
22
|
"test-docker": "docker run -it --rm --name pacotest -v \"$PWD\":/tmp -w /tmp node:latest npm test",
|
|
23
23
|
"update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'",
|
|
24
24
|
"update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'"
|
|
@@ -58,40 +58,38 @@
|
|
|
58
58
|
],
|
|
59
59
|
"license": "ISC",
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"
|
|
62
|
-
"chownr": "^1.1.1",
|
|
61
|
+
"chownr": "^1.1.2",
|
|
63
62
|
"figgy-pudding": "^3.5.1",
|
|
63
|
+
"fs-minipass": "^2.0.0",
|
|
64
64
|
"glob": "^7.1.4",
|
|
65
|
-
"graceful-fs": "^4.
|
|
66
|
-
"infer-owner": "^1.0.
|
|
65
|
+
"graceful-fs": "^4.2.2",
|
|
66
|
+
"infer-owner": "^1.0.4",
|
|
67
67
|
"lru-cache": "^5.1.1",
|
|
68
|
-
"
|
|
68
|
+
"minipass": "^3.0.0",
|
|
69
|
+
"minipass-collect": "^1.0.2",
|
|
70
|
+
"minipass-flush": "^1.0.5",
|
|
71
|
+
"minipass-pipeline": "^1.2.2",
|
|
69
72
|
"mkdirp": "^0.5.1",
|
|
70
73
|
"move-concurrently": "^1.0.1",
|
|
74
|
+
"p-map": "^3.0.0",
|
|
71
75
|
"promise-inflight": "^1.0.1",
|
|
72
|
-
"rimraf": "^2.
|
|
73
|
-
"ssri": "^
|
|
74
|
-
"unique-filename": "^1.1.1"
|
|
75
|
-
"y18n": "^4.0.0"
|
|
76
|
+
"rimraf": "^2.7.1",
|
|
77
|
+
"ssri": "^7.0.0",
|
|
78
|
+
"unique-filename": "^1.1.1"
|
|
76
79
|
},
|
|
77
80
|
"devDependencies": {
|
|
78
81
|
"benchmark": "^2.1.4",
|
|
79
82
|
"chalk": "^2.4.2",
|
|
80
|
-
"cross-env": "^5.1
|
|
83
|
+
"cross-env": "^5.2.1",
|
|
81
84
|
"require-inject": "^1.4.4",
|
|
82
|
-
"standard": "^
|
|
83
|
-
"standard-version": "^
|
|
85
|
+
"standard": "^14.3.0",
|
|
86
|
+
"standard-version": "^7.0.0",
|
|
84
87
|
"tacks": "^1.3.0",
|
|
85
|
-
"tap": "^
|
|
88
|
+
"tap": "^14.6.9",
|
|
86
89
|
"weallbehave": "^1.2.0",
|
|
87
90
|
"weallcontribute": "^1.0.9"
|
|
88
91
|
},
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
"exclude": [
|
|
92
|
-
"node_modules/**",
|
|
93
|
-
"test/**"
|
|
94
|
-
]
|
|
95
|
-
}
|
|
92
|
+
"engines": {
|
|
93
|
+
"node": ">= 8"
|
|
96
94
|
}
|
|
97
95
|
}
|
package/put.js
CHANGED
|
@@ -4,7 +4,9 @@ const figgyPudding = require('figgy-pudding')
|
|
|
4
4
|
const index = require('./lib/entry-index')
|
|
5
5
|
const memo = require('./lib/memoization')
|
|
6
6
|
const write = require('./lib/content/write')
|
|
7
|
-
const
|
|
7
|
+
const Flush = require('minipass-flush')
|
|
8
|
+
const { PassThrough } = require('minipass-collect')
|
|
9
|
+
const Pipeline = require('minipass-pipeline')
|
|
8
10
|
|
|
9
11
|
const PutOpts = figgyPudding({
|
|
10
12
|
algorithms: {
|
|
@@ -23,64 +25,70 @@ const PutOpts = figgyPudding({
|
|
|
23
25
|
})
|
|
24
26
|
|
|
25
27
|
module.exports = putData
|
|
28
|
+
|
|
26
29
|
function putData (cache, key, data, opts) {
|
|
27
30
|
opts = PutOpts(opts)
|
|
28
|
-
return write(cache, data, opts).then(res => {
|
|
29
|
-
return index
|
|
30
|
-
cache, key, res.integrity, opts.concat({ size: res.size })
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
return write(cache, data, opts).then((res) => {
|
|
32
|
+
return index
|
|
33
|
+
.insert(cache, key, res.integrity, opts.concat({ size: res.size }))
|
|
34
|
+
.then((entry) => {
|
|
35
|
+
if (opts.memoize) {
|
|
36
|
+
memo.put(cache, entry, data, opts)
|
|
37
|
+
}
|
|
38
|
+
return res.integrity
|
|
39
|
+
})
|
|
37
40
|
})
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
module.exports.stream = putStream
|
|
44
|
+
|
|
41
45
|
function putStream (cache, key, opts) {
|
|
42
46
|
opts = PutOpts(opts)
|
|
43
47
|
let integrity
|
|
44
48
|
let size
|
|
45
|
-
|
|
46
|
-
cache, opts
|
|
47
|
-
).on('integrity', int => {
|
|
48
|
-
integrity = int
|
|
49
|
-
}).on('size', s => {
|
|
50
|
-
size = s
|
|
51
|
-
})
|
|
49
|
+
|
|
52
50
|
let memoData
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
memoTotal += chunk.length
|
|
60
|
-
}
|
|
61
|
-
cb()
|
|
51
|
+
const pipeline = new Pipeline()
|
|
52
|
+
// first item in the pipeline is the memoizer, because we need
|
|
53
|
+
// that to end first and get the collected data.
|
|
54
|
+
if (opts.memoize) {
|
|
55
|
+
const memoizer = new PassThrough().on('collect', data => {
|
|
56
|
+
memoData = data
|
|
62
57
|
})
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
})
|
|
58
|
+
pipeline.push(memoizer)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// contentStream is a write-only, not a passthrough
|
|
62
|
+
// no data comes out of it.
|
|
63
|
+
const contentStream = write.stream(cache, opts)
|
|
64
|
+
.on('integrity', (int) => {
|
|
65
|
+
integrity = int
|
|
72
66
|
})
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
67
|
+
.on('size', (s) => {
|
|
68
|
+
size = s
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
pipeline.push(contentStream)
|
|
72
|
+
|
|
73
|
+
// last but not least, we write the index and emit hash and size,
|
|
74
|
+
// and memoize if we're doing that
|
|
75
|
+
pipeline.push(new Flush({
|
|
76
|
+
flush () {
|
|
77
|
+
return index
|
|
78
|
+
.insert(cache, key, integrity, opts.concat({ size }))
|
|
79
|
+
.then((entry) => {
|
|
80
|
+
if (opts.memoize && memoData) {
|
|
81
|
+
memo.put(cache, entry, memoData, opts)
|
|
82
|
+
}
|
|
83
|
+
if (integrity) {
|
|
84
|
+
pipeline.emit('integrity', integrity)
|
|
85
|
+
}
|
|
86
|
+
if (size) {
|
|
87
|
+
pipeline.emit('size', size)
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
}))
|
|
92
|
+
|
|
93
|
+
return pipeline
|
|
86
94
|
}
|
package/rm.js
CHANGED
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const util = require('util')
|
|
4
4
|
|
|
5
5
|
const index = require('./lib/entry-index')
|
|
6
6
|
const memo = require('./lib/memoization')
|
|
7
7
|
const path = require('path')
|
|
8
|
-
const rimraf =
|
|
8
|
+
const rimraf = util.promisify(require('rimraf'))
|
|
9
9
|
const rmContent = require('./lib/content/rm')
|
|
10
10
|
|
|
11
11
|
module.exports = entry
|
|
12
12
|
module.exports.entry = entry
|
|
13
|
+
|
|
13
14
|
function entry (cache, key) {
|
|
14
15
|
memo.clearMemoized()
|
|
15
16
|
return index.delete(cache, key)
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
module.exports.content = content
|
|
20
|
+
|
|
19
21
|
function content (cache, integrity) {
|
|
20
22
|
memo.clearMemoized()
|
|
21
23
|
return rmContent(cache, integrity)
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
module.exports.all = all
|
|
27
|
+
|
|
25
28
|
function all (cache) {
|
|
26
29
|
memo.clearMemoized()
|
|
27
30
|
return rimraf(path.join(cache, '*(content-*|index-*)'))
|