|
|
- 'use strict'
-
- const BB = require('bluebird')
-
- const figgyPudding = require('figgy-pudding')
- const fs = require('fs')
- const index = require('./lib/entry-index')
- const memo = require('./lib/memoization')
- const pipe = require('mississippi').pipe
- const pipeline = require('mississippi').pipeline
- const read = require('./lib/content/read')
- const through = require('mississippi').through
-
- const GetOpts = figgyPudding({
- integrity: {},
- memoize: {},
- size: {}
- })
-
- module.exports = function get (cache, key, opts) {
- return getData(false, cache, key, opts)
- }
- module.exports.byDigest = function getByDigest (cache, digest, opts) {
- return getData(true, cache, digest, opts)
- }
- function getData (byDigest, cache, key, opts) {
- opts = GetOpts(opts)
- const memoized = (
- byDigest
- ? memo.get.byDigest(cache, key, opts)
- : memo.get(cache, key, opts)
- )
- if (memoized && opts.memoize !== false) {
- return BB.resolve(byDigest ? memoized : {
- metadata: memoized.entry.metadata,
- data: memoized.data,
- integrity: memoized.entry.integrity,
- size: memoized.entry.size
- })
- }
- return (
- byDigest ? BB.resolve(null) : index.find(cache, key, opts)
- ).then(entry => {
- if (!entry && !byDigest) {
- throw new index.NotFoundError(cache, key)
- }
- return read(cache, byDigest ? key : entry.integrity, {
- integrity: opts.integrity,
- size: opts.size
- }).then(data => byDigest ? data : {
- metadata: entry.metadata,
- data: data,
- size: entry.size,
- integrity: entry.integrity
- }).then(res => {
- if (opts.memoize && byDigest) {
- memo.put.byDigest(cache, key, res, opts)
- } else if (opts.memoize) {
- memo.put(cache, entry, res.data, opts)
- }
- return res
- })
- })
- }
-
- module.exports.sync = function get (cache, key, opts) {
- return getDataSync(false, cache, key, opts)
- }
- module.exports.sync.byDigest = function getByDigest (cache, digest, opts) {
- return getDataSync(true, cache, digest, opts)
- }
- function getDataSync (byDigest, cache, key, opts) {
- opts = GetOpts(opts)
- const memoized = (
- byDigest
- ? memo.get.byDigest(cache, key, opts)
- : memo.get(cache, key, opts)
- )
- if (memoized && opts.memoize !== false) {
- return byDigest ? memoized : {
- metadata: memoized.entry.metadata,
- data: memoized.data,
- integrity: memoized.entry.integrity,
- size: memoized.entry.size
- }
- }
- const entry = !byDigest && index.find.sync(cache, key, opts)
- if (!entry && !byDigest) {
- throw new index.NotFoundError(cache, key)
- }
- const data = read.sync(
- cache,
- byDigest ? key : entry.integrity,
- {
- integrity: opts.integrity,
- size: opts.size
- }
- )
- const res = byDigest
- ? data
- : {
- metadata: entry.metadata,
- data: data,
- size: entry.size,
- integrity: entry.integrity
- }
- if (opts.memoize && byDigest) {
- memo.put.byDigest(cache, key, res, opts)
- } else if (opts.memoize) {
- memo.put(cache, entry, res.data, opts)
- }
- return res
- }
-
- module.exports.stream = getStream
- function getStream (cache, key, opts) {
- opts = GetOpts(opts)
- let stream = through()
- const memoized = memo.get(cache, key, opts)
- if (memoized && opts.memoize !== false) {
- stream.on('newListener', function (ev, cb) {
- ev === 'metadata' && cb(memoized.entry.metadata)
- ev === 'integrity' && cb(memoized.entry.integrity)
- ev === 'size' && cb(memoized.entry.size)
- })
- stream.write(memoized.data, () => stream.end())
- return stream
- }
- index.find(cache, key).then(entry => {
- if (!entry) {
- return stream.emit(
- 'error', new index.NotFoundError(cache, key)
- )
- }
- let memoStream
- if (opts.memoize) {
- let memoData = []
- let memoLength = 0
- memoStream = through((c, en, cb) => {
- memoData && memoData.push(c)
- memoLength += c.length
- cb(null, c, en)
- }, cb => {
- memoData && memo.put(cache, entry, Buffer.concat(memoData, memoLength), opts)
- cb()
- })
- } else {
- memoStream = through()
- }
- stream.emit('metadata', entry.metadata)
- stream.emit('integrity', entry.integrity)
- stream.emit('size', entry.size)
- stream.on('newListener', function (ev, cb) {
- ev === 'metadata' && cb(entry.metadata)
- ev === 'integrity' && cb(entry.integrity)
- ev === 'size' && cb(entry.size)
- })
- pipe(
- read.readStream(cache, entry.integrity, opts.concat({
- size: opts.size == null ? entry.size : opts.size
- })),
- memoStream,
- stream
- )
- }).catch(err => stream.emit('error', err))
- return stream
- }
-
- module.exports.stream.byDigest = getStreamDigest
- function getStreamDigest (cache, integrity, opts) {
- opts = GetOpts(opts)
- const memoized = memo.get.byDigest(cache, integrity, opts)
- if (memoized && opts.memoize !== false) {
- const stream = through()
- stream.write(memoized, () => stream.end())
- return stream
- } else {
- let stream = read.readStream(cache, integrity, opts)
- if (opts.memoize) {
- let memoData = []
- let memoLength = 0
- const memoStream = through((c, en, cb) => {
- memoData && memoData.push(c)
- memoLength += c.length
- cb(null, c, en)
- }, cb => {
- memoData && memo.put.byDigest(
- cache,
- integrity,
- Buffer.concat(memoData, memoLength),
- opts
- )
- cb()
- })
- stream = pipeline(stream, memoStream)
- }
- return stream
- }
- }
-
- module.exports.info = info
- function info (cache, key, opts) {
- opts = GetOpts(opts)
- const memoized = memo.get(cache, key, opts)
- if (memoized && opts.memoize !== false) {
- return BB.resolve(memoized.entry)
- } else {
- return index.find(cache, key)
- }
- }
-
- module.exports.hasContent = read.hasContent
-
- module.exports.copy = function cp (cache, key, dest, opts) {
- return copy(false, cache, key, dest, opts)
- }
- module.exports.copy.byDigest = function cpDigest (cache, digest, dest, opts) {
- return copy(true, cache, digest, dest, opts)
- }
- function copy (byDigest, cache, key, dest, opts) {
- opts = GetOpts(opts)
- if (read.copy) {
- return (
- byDigest ? BB.resolve(null) : index.find(cache, key, opts)
- ).then(entry => {
- if (!entry && !byDigest) {
- throw new index.NotFoundError(cache, key)
- }
- return read.copy(
- cache, byDigest ? key : entry.integrity, dest, opts
- ).then(() => byDigest ? key : {
- metadata: entry.metadata,
- size: entry.size,
- integrity: entry.integrity
- })
- })
- } else {
- return getData(byDigest, cache, key, opts).then(res => {
- return fs.writeFileAsync(dest, byDigest ? res : res.data)
- .then(() => byDigest ? key : {
- metadata: res.metadata,
- size: res.size,
- integrity: res.integrity
- })
- })
- }
- }
|