Qache
Zero-dependency, lightweight caching module for Node.js and the browser - built with Typescript
Table of contents
About The Project
Qache at its core is a simple key-value store. Its USP lies in the ability to keep collections of items in sync with single entries. The feature was heavily inspired by Apollo's caching system. I also added a validation system to prevent faulty values from sneaking in.
The module's structured like this:
I built Qache as a secure and lightweight HTTP cache for my Vue apps. It can also be used on the serverside using ES6 module imports.
Getting Started
Qache has a tiny footprint and no dependencies. It can be used in any Browser or Node (v14+) environment that supports ES6 module imports.
Installation
Run the following command in a project of your choice:
npm install @tq-bit/qache
You can then import the module into your project:
// Using ES6 modules:
import Qache from '@tq-bit/qache';
// Using CommonJS (untested, may not support intellisense properly):
const Qache = require('@tq-bit/qache')['default'];
// You can then start using it in your code:
const cache = new Qache({cacheKey: 'posts'});
Development
Clone the repository to your local machine. You can find:
- The source code in the
src
folder - Automated Mocha tests in the
test
folder - Its documentation in the
docs
folder
Note: Parts of the documentation are automatically created during build time.
index
is equal toreadme.md
api
is extracted from JSDoc comments in the built files
Build the project + docs (recommended)
The following command build the project and the documentation files. It applies configured linting rules and runs registered automated tests.
npm run pre-release
Run the automated test suite
Unit tests are written using Mocha + Chai. Run them using:
npm run test
Run the documentation locally
Qache is documented using Vitepress. You can run the documentation locally:
npm run docs:dev
Deploy the documentation to GitHub Pages
You can find the release documentation under https://tq-bit.github.io/qache. To build it, use:
npm run docs:deploy
# Alternatively, you can just buidl the docs and serve them locally
npm run docs:build && npm run docs:serve
Create a new NPM release
This command runs the pre-release
command and pushes a new, built version on NPM
Note: This command requires a 2fa confirmation
npm run release
Usage
Besides caching, Qache keeps related entries in sync and ensures type safety. As a consequence, it comes with a few opinionated (but optional) features:
-
Schema validation -> The first entry that is added into the cache defines the schema for other entries. You can optionally pass an
original
- property into the configuration to build up the schema. -
- One cache per API resource -> Each cache can be equipped with a validation schema. To avoid conflicts, resources you work with should have their dedicated cache instance.
- Type safety -> You can use Typescript Generics to supercharge Qache's type safety.
- Automatic cache updates -> When a single entry is created or updated by its key, Qache will try to update related entries. See Automatic cache updates
Default configuration example
This is the default configuration used by the Qache constructor. I'd recommend you give each cache at least a unique cacheKey
property.
{
cacheKey = 'default',
entryKey = 'id',
lifetime = 1000 * 60 * 5,
validate = false,
debug = false,
original = null
}
Create a new cache instance
Once you've installed Qache, you can start creating cache instances in your project.
import Cache from '@tq-bit/qache'
// Create a basic cache instance
const cache = new Cache();
// Add a custom configuration
const customCache = new Cache({
cacheKey: 'posts', // = the key of the cache instance
entryKey: 'id', // = the key-property of single cache entries to keep entries in sync
lifetime: 1000 * 60 * 5 // = assign an entry lifetime of 5 minutes,
})
// For TS users: Add a generic interface for improved type safety
interface Post {
id: number;
title: string;
body: string;
}
const typedCache = new Cache<Post>({
cacheKey: 'posts',
entryKey: 'id',
lifetime: 1000 * 60 * 5
});
// If a cache object is available during cache creation, it can be passed in as an 'original'
const typedCacheWithOriginal = new Cache<Post>({
cacheKey: 'posts',
entryKey: 'id',
lifetime: 1000 * 60 * 5,
original: { id: 3, title: 'Hello', body: 'World' },
});
Add and modify cache entries
Each cache entry is saved a simple Javascript Object. It is identified by a key
and has a dedicated timeout
instance.
Note: This approach might be replaced by a single check period to remove redundant entries.
New entries can be created the same way updates are done.
cache.set('api/posts/1', {
id: 1,
title: 'Lorem Ipsum',
body: 'Lorem ipsum dolor sit amet'
});
// You can also cache an array of entries
cache.set('api/posts/', [
{
id: 1,
title: 'Lorem Ipsum',
body: 'Lorem ipsum dolor sit amet',
},
{
id: 2,
title: 'Lorem Ipsum',
body: 'Lorem ipsum dolor sit amet',
},
]);
Automatic cache updates
When a single entry is created or updated, all related cached entries are automatically updated as well. Qache will iterate through all array-like entries in the cache, try to find matches and update them accordingly. It works like this:
- A new entry is added to the cache
- Qache will check if there are one or more collection items (=
Arrays
) in its cache-map - It will then either
add
orupdate
entries into these collection types
Deleting entries works analogous. If a single entry is removed from the cache, all collections will be updated accordingly.
Check out the docs for examples
Roadmap
- [x] Release v0.1.0
- [x] Add a 'strict' mode in which types of entries are validated
- [x] Make it possible to create a manual validation schema
- [x] Add a more complex validation algorithm
- [x] Add logic to prevent automatic cache updates, if not necessary
- [ ] Remove the necessity to validate
- [ ] Improve logging messages for when validation fails (requires complex validation logic)
License
Distributed under the MIT License. See LICENSE
for more information.
Contact
Mail: tobi@q-bit.me - Twitter: @qbitme
Project Link: https://github.com/tq-bit/qache