Skip to content

Commit

Permalink
Add cashClear to ctx (#98)
Browse files Browse the repository at this point in the history
* chore: update supertest

* chore: update readme

* feat: add cashClear

* chore: cleanup test
  • Loading branch information
rek authored Sep 13, 2022
1 parent 6f68010 commit c7e07b5
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 108 deletions.
22 changes: 15 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ Table of Contents
* [`get()`](#get)
* [`set()`](#set)
* [Example](#example)
* [Max age](#max-age)
* [Max age (optional)](#max-age-optional)
* [CashClear](#cashclear)
* [Notes](#notes)
* [Usage](#usage-1)
* [Contributors](#contributors)
* [License](#license)
* [Links](#links)
Expand Down Expand Up @@ -174,24 +174,32 @@ app.use(koaCash({

See [@ladjs/koa-cache-responses](https://github.com/ladjs/koa-cache-responses) test folder more examples (e.g. Redis with `ioredis`).

### Max age
### Max age (optional)

const cached = await ctx.cashed(\[maxAge])
```js
const cached = await ctx.cashed(maxAge) // maxAge is passed to your caching strategy
```

This is how you enable a route to be cached. If you don't call `await ctx.cashed()`, then this route will not be cached nor will it attempt to serve the request from the cache.

`maxAge` is the max age passed to `get()`.

If `cached` is `true`, then the current request has been served from cache and **you should early `return`**. Otherwise, continue setting `ctx.body=` and this will cache the response.

### CashClear

```js
ctx.cashClear('/')
```

This is a special method available on the ctx that you can use to clear the cache for a specific key.

## Notes

* Only `GET` and `HEAD` requests are cached.
* Only `GET` and `HEAD` requests are cached. (Unless overridden)
* Only `200` responses are cached. Don't set `304` status codes on these routes - this middleware will handle it for you
* The underlying store should be able to handle `Date` objects as well as `Buffer` objects. Otherwise, you may have to serialize/deserialize yourself.

## Usage

## Contributors

| Name | Website |
Expand Down
7 changes: 7 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ module.exports = function(options) {
if (!get) throw new Error('.get not defined');
if (!set) throw new Error('.set not defined');

// allow for manual cache clearing
function cashClear(key) {
// console.log(`Removing cache key: ${key}`);
set(key, false);
}

// ctx.cashed(maxAge) => boolean
async function cashed(maxAge) {
// uncacheable request method
Expand Down Expand Up @@ -84,6 +90,7 @@ module.exports = function(options) {
async function middleware(ctx, next) {
ctx.vary('Accept-Encoding');
ctx.cashed = cashed.bind(ctx);
ctx.cashClear = cashClear.bind(ctx);

await next();

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"nyc": "latest",
"remark-cli": "latest",
"remark-preset-github": "latest",
"supertest": "1.x",
"supertest": "latest",
"xo": "0.25"
},
"engines": {
Expand Down
33 changes: 33 additions & 0 deletions test/when-cached.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,36 @@ test.cb('when cached when the response is fresh it should 304', t => {
.set('If-None-Match', '"lol"')
.expect(304, t.end);
});

test.cb(
'when cached when the method is GET it should serve from cache until cleared',
t => {
const app = createApp(c);

app.use(async function(ctx) {
if (await ctx.cashed()) return ctx.cashClear('/');
ctx.body = 'no lols';
});

request(app.listen())
.get('/')
.expect(200)
.expect('Content-Type', 'text/lol; charset=utf-8')
.expect('Content-Encoding', 'identity')
.expect('ETag', '"lol"')
// eslint-disable-next-line promise/prefer-await-to-then
.then(resp => {
t.is(resp.text, 'lol');
});

request(app.listen())
.get('/')
.expect(200)
.expect('Content-Type', 'text/plain; charset=utf-8')
// eslint-disable-next-line promise/prefer-await-to-then
.then(resp => {
t.is(resp.text, 'no lols');
t.end();
});
}
);
5 changes: 2 additions & 3 deletions test/when-not-cached.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ test.cb('when the body is a buffer it should cache the response', t => {
request(app.listen())
.get('/')
.expect(200)
.expect('lol', err => {
.end(function(err) {
if (err) return t.end(err);

t.is(c.get('/').body.toString('utf8'), 'lol');
Expand Down Expand Up @@ -130,7 +130,7 @@ test.cb('when the body is a stream it should cache the response', t => {
request(app.listen())
.get('/')
.expect(200)
.expect('lol', err => {
.end(function(err) {
if (err) return t.end(err);

t.is(c.get('/').body.toString('utf8'), 'lol');
Expand Down Expand Up @@ -259,7 +259,6 @@ test.cb('when the method is HEAD it should cache the response', t => {

request(app.listen())
.head('/')
.expect('')
.expect(200, err => {
if (err) return t.end(err);

Expand Down
Loading

0 comments on commit c7e07b5

Please sign in to comment.