Skip to content

Commit

Permalink
feat: sqlite cache store (#3657)
Browse files Browse the repository at this point in the history
Signed-off-by: flakey5 <[email protected]>
  • Loading branch information
flakey5 authored Nov 22, 2024
1 parent 0d06552 commit e90e128
Show file tree
Hide file tree
Showing 10 changed files with 717 additions and 34 deletions.
14 changes: 13 additions & 1 deletion docs/docs/api/CacheStore.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,21 @@ The `MemoryCacheStore` stores the responses in-memory.

**Options**

- `maxEntries` - The maximum amount of responses to store. Default `Infinity`.
- `maxCount` - The maximum amount of responses to store. Default `Infinity`.
- `maxEntrySize` - The maximum size in bytes that a response's body can be. If a response's body is greater than or equal to this, the response will not be cached.

### `SqliteCacheStore`

The `SqliteCacheStore` stores the responses in a SQLite database.
Under the hood, it uses Node.js' [`node:sqlite`](https://nodejs.org/api/sqlite.html) api.
The `SqliteCacheStore` is only exposed if the `node:sqlite` api is present.

**Options**

- `location` - The location of the SQLite database to use. Default `:memory:`.
- `maxCount` - The maximum number of entries to store in the database. Default `Infinity`.
- `maxEntrySize` - The maximum size in bytes that a resposne's body can be. If a response's body is greater than or equal to this, the response will not be cached. Default `Infinity`.

## Defining a Custom Cache Store

The store must implement the following functions:
Expand Down
9 changes: 9 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ module.exports.cacheStores = {
MemoryCacheStore: require('./lib/cache/memory-cache-store')
}

try {
const SqliteCacheStore = require('./lib/cache/sqlite-cache-store')
module.exports.cacheStores.SqliteCacheStore = SqliteCacheStore
} catch (err) {
if (err.code !== 'ERR_UNKNOWN_BUILTIN_MODULE') {
throw err
}
}

module.exports.buildConnector = buildConnector
module.exports.errors = errors
module.exports.util = {
Expand Down
26 changes: 5 additions & 21 deletions lib/cache/memory-cache-store.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'

const { Writable } = require('node:stream')
const { assertCacheKey, assertCacheValue } = require('../util/cache.js')

/**
* @typedef {import('../../types/cache-interceptor.d.ts').default.CacheKey} CacheKey
Expand Down Expand Up @@ -41,17 +42,6 @@ class MemoryCacheStore {
this.#maxCount = opts.maxCount
}

if (opts.maxSize !== undefined) {
if (
typeof opts.maxSize !== 'number' ||
!Number.isInteger(opts.maxSize) ||
opts.maxSize < 0
) {
throw new TypeError('MemoryCacheStore options.maxSize must be a non-negative integer')
}
this.#maxSize = opts.maxSize
}

if (opts.maxEntrySize !== undefined) {
if (
typeof opts.maxEntrySize !== 'number' ||
Expand All @@ -70,9 +60,7 @@ class MemoryCacheStore {
* @returns {import('../../types/cache-interceptor.d.ts').default.GetResult | undefined}
*/
get (key) {
if (typeof key !== 'object') {
throw new TypeError(`expected key to be object, got ${typeof key}`)
}
assertCacheKey(key)

const topLevelKey = `${key.origin}:${key.path}`

Expand Down Expand Up @@ -103,12 +91,8 @@ class MemoryCacheStore {
* @returns {Writable | undefined}
*/
createWriteStream (key, val) {
if (typeof key !== 'object') {
throw new TypeError(`expected key to be object, got ${typeof key}`)
}
if (typeof val !== 'object') {
throw new TypeError(`expected value to be object, got ${typeof val}`)
}
assertCacheKey(key)
assertCacheValue(val)

const topLevelKey = `${key.origin}:${key.path}`

Expand Down Expand Up @@ -142,7 +126,7 @@ class MemoryCacheStore {
store.#size += entry.size
store.#count += 1

if (store.#size > store.#maxSize || store.#count > store.#maxCount) {
if (store.#size > store.#maxEntrySize || store.#count > store.#maxCount) {
for (const [key, entries] of store.#entries) {
for (const entry of entries.splice(0, entries.length / 2)) {
store.#size -= entry.size
Expand Down
Loading

0 comments on commit e90e128

Please sign in to comment.