Skip to content
This repository has been archived by the owner on Jun 12, 2022. It is now read-only.

Commit

Permalink
fix(opts): simplified opts handling
Browse files Browse the repository at this point in the history
  • Loading branch information
zkat committed Mar 31, 2017
1 parent 0abb25a commit 516fd6e
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 70 deletions.
76 changes: 34 additions & 42 deletions cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,17 @@ function cacheKey (req) {
//
module.exports = class Cache {
constructor (path, opts) {
this._cachePath = path
this._cacheOpts = opts
this.Promise = opts.Promise || Promise
this._path = path
this._uid = opts && opts.uid
this._gid = opts && opts.gid
this.Promise = (opts && opts.Promise) || Promise
}

// Returns a Promise that resolves to the response associated with the first
// matching request in the Cache object.
match (request, opts) {
// TODO - opts.ignoreSearch, opts.ignoreMethod, opts.ignoreVary
request = new fetch.Request(request)
return cacache.get.info(
this._cachePath,
cacheKey(request),
this._cacheOpts
).then(info => {
return cacache.get.info(this._path, cacheKey(request)).then(info => {
if (info && matchDetails(request, info.metadata, opts)) {
return new this.Promise((resolve, reject) => {
fs.stat(info.path, (err, stat) => {
Expand All @@ -54,24 +50,18 @@ module.exports = class Cache {
}
})
}).then(stat => {
// meh
this._cacheOpts.hashAlgorithm = info.hashAlgorithm

let body
if (stat.size > MAX_MEM_SIZE) {
body = cacache.get.stream.byDigest(
this._cachePath,
info.digest,
this._cacheOpts
)
body = cacache.get.stream.byDigest(this._path, info.digest, {
hashAlgorithm: info.hashAlgorithm
})
} else {
// cacache is much faster at bulk reads
body = through()
cacache.get.byDigest(
this._cachePath,
info.digest,
this._cacheOpts
).then(data => {
cacache.get.byDigest(this._path, info.digest, {
hashAlgorithm: info.hashAlgorithm,
memoize: true
}).then(data => {
body.write(data, () => {
body.end()
})
Expand Down Expand Up @@ -113,32 +103,35 @@ module.exports = class Cache {
put (request, response) {
const req = new fetch.Request(request)
const size = response.headers.get('content-length')
this._cacheOpts.metadata = {
url: request.url,
headers: response.headers.raw()
const fitInMemory = !!size && size < MAX_MEM_SIZE
const opts = {
metadata: {
url: request.url,
headers: response.headers.raw()
},
uid: this._uid,
gid: this._gid,
size,
memoize: fitInMemory
}
let buf = []
let bufSize = 0
let cacheStream = (size && size < MAX_MEM_SIZE)
let cacheStream = fitInMemory
? to({highWaterMark: MAX_MEM_SIZE}, (chunk, enc, cb) => {
buf.push(chunk)
bufSize += chunk.length
cb()
}, done => {
cacache.put(
this._cachePath,
this._path,
cacheKey(req),
Buffer.concat(buf, bufSize),
this._cacheOpts
).then(done, done)
opts
).then(() => done(), done)
})
: cacache.put.stream(
this._cachePath,
cacheKey(req),
this._cacheOpts
)
: cacache.put.stream(this._path, cacheKey(req), opts)
const oldBody = response.body
const newBody = through()
const newBody = through({highWaterMark: fitInMemory && MAX_MEM_SIZE})
response.body = newBody
oldBody.once('error', err => newBody.emit('error', err))
newBody.once('error', err => oldBody.emit('error', err))
Expand All @@ -149,7 +142,7 @@ module.exports = class Cache {
})
}, done => {
cacheStream.end(() => newBody.end(done))
}), err => newBody.emit('error', err))
}), err => err && newBody.emit('error', err))
return response
}

Expand All @@ -159,25 +152,24 @@ module.exports = class Cache {
'delete' (request, options) {
const req = new fetch.Request(request)
return cacache.rm.entry(
this._cachePath,
cacheKey(req.url),
this._cacheOpts
this._path,
cacheKey(req.url)
// TODO - true/false
).then(() => false)
}

keys (request, options) {
return cacache.ls(this._cachePath).then(entries => Object.keys(entries))
return cacache.ls(this._path).then(entries => Object.keys(entries))
}
}

function matchDetails (req, cached, opts) {
const reqUrl = url.parse(req.url)
const cacheUrl = url.parse(cached.url)
if (!opts.ignoreSearch && (cacheUrl.search !== reqUrl.search)) {
if (!(opts && opts.ignoreSearch) && (cacheUrl.search !== reqUrl.search)) {
return false
}
if (!opts.ignoreMethod && req.method && req.method !== 'GET') {
if (!(opts && opts.ignoreMethod) && req.method && req.method !== 'GET') {
return false
}
// TODO - opts.ignoreVary?
Expand Down
53 changes: 25 additions & 28 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,40 +16,44 @@ module.exports = cachingFetch
function cachingFetch (uri, _opts) {
const opts = {}
Object.keys(_opts || {}).forEach(k => { opts[k] = _opts[k] })
if (opts.cache === 'string' && !Cache) { Cache = require('./cache') }
if (typeof opts.cache === 'string' && !Cache) { Cache = require('./cache') }
opts.cache = opts.cache && (
typeof opts.cache === 'string'
? new Cache(opts.cache, opts.cacheOpts)
: opts.cache
)
opts.cacheMode = opts.cache && (opts.cacheMode || 'default')
if (opts.cacheMode === 'default' && isConditional(opts.headers || {})) {
if (
opts.cache &&
opts.cacheMode === 'default' &&
isConditional(opts.headers || {})
) {
// If header list contains `If-Modified-Since`, `If-None-Match`,
// `If-Unmodified-Since`, `If-Match`, or `If-Range`, fetch will set cache
// mode to "no-store" if it is "default".
opts.cacheMode = 'no-store'
}
let res
if (
(!opts.method || opts.method.toLowerCase() === 'get') &&
opts.cache &&
opts.cacheMode !== 'no-store' &&
opts.cacheMode !== 'reload'
) {
res = opts.cache.match(uri, opts.cacheOpts)
return opts.cache.match(uri, opts.cacheOpts).then(res => {
if (res && opts.cacheMode === 'default' && !isStale(res)) {
return res
} else if (res && (opts.cacheMode === 'default' || opts.cacheMode === 'no-cache')) {
return condFetch(uri, res, opts)
} else if (!res && opts.cacheMode === 'only-if-cached') {
throw new Error(`request to ${uri} failed: cache mode is 'only-if-cached' but no cached response available.`)
} else {
// Missing cache entry, stale default, reload, no-store
return remoteFetch(uri, opts)
}
})
} else {
return remoteFetch(uri, opts)
}
return fetch.Promise.resolve(res).then(res => {
if (res && opts.cacheMode === 'default' && !isStale(res)) {
return res
} else if (res && (opts.cacheMode === 'default' || opts.cacheMode === 'no-cache')) {
return condFetch(uri, res, opts)
} else if (!res && opts.cacheMode === 'only-if-cached') {
throw new Error(`request to ${uri} failed: cache mode is 'only-if-cached' but no cached response available.`)
} else {
// Missing cache entry, stale default, reload, no-store
return remoteFetch(uri, opts)
}
})
}

// https://tools.ietf.org/html/rfc7234#section-4.2
Expand Down Expand Up @@ -138,18 +142,11 @@ function remoteFetch (uri, opts) {
headers[k] = opts.headers[k]
})
}
const reqOpts = Object.create(opts)
reqOpts.headers = headers
reqOpts.agent = agent
return retry((retryHandler, attemptNum) => {
const req = new fetch.Request(uri, {
agent,
body: opts.body,
compress: opts.compress,
follow: opts.follow,
headers,
method: opts.method,
redirect: opts.redirect || 'follow',
size: opts.size,
timeout: opts.timeout || 0
})
const req = new fetch.Request(uri, reqOpts)
return fetch(req).then(res => {
if (
req.method.toLowerCase() === 'get' &&
Expand All @@ -165,7 +162,7 @@ function remoteFetch (uri, opts) {
return res
}
}).catch(err => {
if (req.method !== 'POST') {
if (req.method.toLowerCase() !== 'post') {
return retryHandler(err)
} else {
throw err
Expand Down

0 comments on commit 516fd6e

Please sign in to comment.