bun-sqlite-key-value
Advanced tools
Comparing version 1.3.8 to 1.3.9
{ | ||
"name": "bun-sqlite-key-value", | ||
"description": "A super fast key-value store with SQLite that uses bun:sqlite and v8 as faster JSON replacement.", | ||
"version": "1.3.8", | ||
"version": "1.3.9", | ||
"author": "Gerold Penz<gerold@gp-softwaretechnik.at>", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/gerold-penz/bun-sqlite-key-value.git" | ||
}, | ||
"module": "src/index.ts", | ||
"type": "module", | ||
"scripts": { | ||
"test": "bun test", | ||
"test:watch": "bun test --watch", | ||
"increment_package_version": "npm version patch --no-git-tag-version", | ||
"prepublishOnly": "bun run test && bun run increment_package_version", | ||
"npm:publish": "npm publish --access public" | ||
}, | ||
"devDependencies": { | ||
@@ -21,6 +16,7 @@ "@types/bun": "latest" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/gerold-penz/bun-sqlite-key-value.git" | ||
"bugs": { | ||
"url": "https://github.com/gerold-penz/bun-sqlite-key-value/issues" | ||
}, | ||
"description": "A super fast key-value store with SQLite that uses bun:sqlite and v8 as faster JSON replacement.", | ||
"homepage": "https://github.com/gerold-penz/bun-sqlite-key-value", | ||
"keywords": [ | ||
@@ -45,6 +41,10 @@ "Bun", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/gerold-penz/bun-sqlite-key-value/issues" | ||
"scripts": { | ||
"test": "bun test", | ||
"test:watch": "bun test --watch", | ||
"increment_package_version": "npm version patch --no-git-tag-version", | ||
"prepublishOnly": "bun run test && bun run increment_package_version", | ||
"npm:publish": "npm publish --access public" | ||
}, | ||
"homepage": "https://github.com/gerold-penz/bun-sqlite-key-value" | ||
"type": "module" | ||
} |
141
README.md
@@ -38,6 +38,7 @@ # Bun SQLite Key Value | ||
store.set("my-key", {foo: "bar", baz: [1, 2, 3, 4]}) | ||
store.set("my-key", [1, 2, 3, 4]) | ||
const value = store.get("my-key") | ||
console.log(value) // -> {foo: "bar", baz: [ 1, 2, 3, 4 ]} | ||
console.log(value) // -> [ 1, 2, 3, 4 ] | ||
``` | ||
@@ -54,11 +55,24 @@ | ||
- `filename`: | ||
Opens and creates the SQLite database either in memory or on the file system. | ||
#### filename (optional) | ||
The full path of the SQLite database to open. | ||
Pass an empty string (`""`) or `":memory:"` or undefined for an in-memory database. | ||
- `options`: | ||
Defaults to `{readwrite: true, create: true}`. | ||
If a number, then it's treated as `SQLITE_OPEN_*` constant flags. | ||
#### options (optional) | ||
`readonly?: boolean`: | ||
Open the database as read-only (default: false). | ||
`create?: boolean`: | ||
Allow creating a new database (default: true) | ||
`readwrite?: boolean`: | ||
Open the database as read-write (default: true) | ||
`ttlMs?: boolean`: | ||
Standard time period in milliseconds before | ||
an entry written to the DB becomes invalid. | ||
#### Example | ||
@@ -69,5 +83,11 @@ | ||
const store = new BunSqliteKeyValue() | ||
// In-memory | ||
const store1 = new BunSqliteKeyValue() | ||
// In-memory with 30 seconds default expiration timeout | ||
const store2 = new BunSqliteKeyValue(undefined, {ttlMs: 30000}) | ||
// Store items in file system | ||
const store3 = new BunSqliteKeyValue("./store3.sqlite") | ||
``` | ||
### Write Value | ||
@@ -77,9 +97,12 @@ | ||
set(key: string, value: any, [ttlMs: number]): void | ||
setValue(key: string, value: any, [ttlMs: number]) // alias for set() | ||
``` | ||
- `key`: | ||
Writes a value into the database. | ||
#### key | ||
The key must be a string. | ||
- `value`: | ||
#### value | ||
The value can be any object that can be serialized with | ||
@@ -92,6 +115,8 @@ [v8](https://github.com/nodejs/node/blob/main/doc/api/v8.md#serialization-api). | ||
- `ttlMs` (optional): | ||
#### ttlMs (optional) | ||
"Time to live" in milliseconds. After this time, | ||
the item becomes invalid and is deleted from the database | ||
the next time it is accessed or when the application is started. | ||
Set the value to 0 if you want to explicitly deactivate the process. | ||
@@ -113,2 +138,3 @@ #### Example | ||
### Read Value | ||
@@ -118,9 +144,10 @@ | ||
get(key: string): any | ||
getValue(key: string) // alias for get() | ||
``` | ||
- `key`: | ||
Reads a value from the database. | ||
#### key | ||
The key must be a string. | ||
#### Example | ||
@@ -141,2 +168,4 @@ | ||
Reads the key and the value from the database. | ||
```typescript | ||
@@ -146,6 +175,6 @@ getItem(key: string): {key: string, value: any} | ||
- `key`: | ||
#### key | ||
The key must be a string. | ||
#### Example | ||
@@ -166,19 +195,21 @@ | ||
Returns all values in an array whose keys begin with the passed string. | ||
If you plan the names of the keys well, more complex data can be stored. | ||
```typescript | ||
getValues(startsWithOrKeys: string | string[]): any[] | ||
getValuesArray(startsWithOrKeys: string | string[]): any[] | ||
``` | ||
- `startsWithOrKeys`: | ||
- **string**: String with which the keys whose values are to be returned begin. | ||
It is advisable to divide keys into ranges using separators. | ||
For example `"language:de"`, `"language:en"`, `"language:it"`. | ||
A search for `"language:"` would return all languages. | ||
- **string[]**: Array with keys. The returned array is exactly | ||
the same size as the passed array. | ||
Entries that are not found are returned as `undefined`. | ||
Reads the data from the database and returns an array with the values. | ||
#### startsWithOrKeys | ||
`string`: Returns all values in an array whose keys begin with the passed string. | ||
If you plan the names of the keys well, more complex data can be stored. | ||
It is advisable to divide keys into ranges using separators. | ||
For example `"language:de"`, `"language:en"`, `"language:it"`. | ||
A search for `"language:"` would return all languages. | ||
`string[]`: Array with keys. The returned array is exactly | ||
the same size as the passed array. | ||
Entries that are not found are returned as `undefined`. | ||
Only exact matches with the keys are returned. | ||
#### Example | ||
@@ -202,20 +233,21 @@ | ||
Returns all items (key, value) in an array whose keys begin with the passed string. | ||
If you plan the names of the keys well, more complex data can be stored. | ||
```typescript | ||
getItems(startsWithOrKeys: string | string[]): {key: string, value: any}[] | ||
getItemsArray(startsWithOrKeys: string | string[]): {key: string, value: any}[] | ||
``` | ||
Reads the data from the database and returns entries in an array as key-value pairs. | ||
- `startsWithOrKeys`: | ||
- **string**: String with which the keys whose items are to be returned begin. | ||
It is advisable to divide keys into ranges using separators. | ||
For example `"language:de"`, `"language:en"`, `"language:it"`. | ||
A search for `"language:"` would return all languages. | ||
- **string[]**: Array with keys. The returned array is exactly | ||
the same size as the passed array. | ||
Entries that are not found are returned as `undefined`. | ||
#### startsWithOrKeys | ||
`string`: Returns all items (key, value) in an array whose keys begin with | ||
the passed string. | ||
If you plan the names of the keys well, more complex data can be stored. | ||
It is advisable to divide keys into ranges using separators. | ||
For example `"language:de"`, `"language:en"`, `"language:it"`. | ||
A search for `"language:"` would return all languages. | ||
`string[]`: Array with keys. The returned array is exactly | ||
the same size as the passed array. | ||
Entries that are not found are returned as `undefined`. | ||
Only exact matches with the keys are returned. | ||
#### Example | ||
@@ -241,2 +273,3 @@ | ||
### Multiple Databases | ||
@@ -246,3 +279,2 @@ | ||
#### Example | ||
@@ -321,5 +353,6 @@ | ||
### Read and write binary files | ||
### Read and write binary files (images) | ||
SQLite has no problem with large images/binaries. | ||
SQLite has no problem with images and other binaries. | ||
The maximum size of a binary file in SQLite is 2 GB. | ||
@@ -346,1 +379,23 @@ | ||
``` | ||
### Cache values with TTL | ||
You can specify a caching period when you open the database. | ||
This period in milliseconds is then added with each write. | ||
If you read the value within this period, the value is returned. | ||
If the value is read after this period, `undefined` is returned. | ||
#### Example | ||
```typescript | ||
import { BunSqliteKeyValue } from "bun-sqlite-key-value" | ||
const store: BunSqliteKeyValue = new BunSqliteKeyValue(undefined, {ttlMs: 1000}) | ||
const KEY = "cache-key" | ||
store.set(KEY, 12345) | ||
await Bun.sleep(500) | ||
console.log(store.get(KEY)) // --> 12345 | ||
await Bun.sleep(1000) | ||
console.log(store.get(KEY)) // --> undefined | ||
``` |
@@ -18,2 +18,15 @@ import { Database, type Statement } from "bun:sqlite" | ||
interface Options { | ||
readonly?: boolean | ||
create?: boolean // Defaults to true | ||
readwrite?: boolean // Defaults to true | ||
ttlMs?: number // Default TTL milliseconds | ||
} | ||
interface DbOptions extends Omit<Options, "ttlMs"> { | ||
strict: boolean | ||
} | ||
export class BunSqliteKeyValue { | ||
@@ -34,24 +47,19 @@ | ||
// @param filename: The full path of the SQLite database to open. | ||
// Pass an empty string (`""`) or `":memory:"` or undefined for an in-memory database. | ||
constructor( | ||
filename?: string, | ||
options?: { | ||
readonly?: boolean | ||
create?: boolean // Defaults to true | ||
readwrite?: boolean // Defaults to true | ||
safeInteger?: boolean | ||
strict?: boolean // Defaults to true | ||
ttlMs?: number // Default TTL milliseconds | ||
// - `filename`: The full path of the SQLite database to open. | ||
// Pass an empty string (`""`) or `":memory:"` or undefined for an in-memory database. | ||
// - `options`: | ||
// - ... | ||
// - `ttlMs?: boolean`: Standard time period in milliseconds before | ||
// an entry written to the DB becomes invalid. | ||
constructor(filename?: string, options?: Options) { | ||
// Parse options | ||
const {ttlMs, ...otherOptions} = options ?? {} | ||
this.ttlMs = ttlMs | ||
const dbOptions: DbOptions = { | ||
...otherOptions, | ||
strict: true, | ||
readwrite: otherOptions?.readwrite ?? true, | ||
create: otherOptions?.create ?? true, | ||
} | ||
) { | ||
// Options and ttlMs | ||
options = options ?? {} | ||
options.readwrite = options.readwrite ?? true | ||
options.create = options.create ?? true | ||
options.strict = options.strict ?? true | ||
const {ttlMs, ...dbOptions} = options | ||
this.ttlMs = ttlMs | ||
// Open database | ||
@@ -58,0 +66,0 @@ this.db = new Database(filename, dbOptions) |
@@ -277,1 +277,15 @@ import { expect, test } from "bun:test" | ||
}) | ||
test("Caching with implicite TTL", async () => { | ||
const store: BunSqliteKeyValue = new BunSqliteKeyValue(undefined, {ttlMs: 40}) | ||
store.set(KEY_1, STRING_VALUE_1) | ||
store.set(KEY_2, STRING_VALUE_2) | ||
store.set(KEY_3, STRING_VALUE_3) | ||
await Bun.sleep(60) | ||
expect(store.get(KEY_1)).toBeUndefined() | ||
expect(store.get(KEY_2)).toBeUndefined() | ||
expect(store.get(KEY_3)).toBeUndefined() | ||
}) | ||
{ | ||
"compilerOptions": { | ||
// Enable latest features | ||
"lib": ["ESNext", "DOM"], | ||
"lib": [ | ||
"ESNext", | ||
"DOM" | ||
], | ||
"target": "ESNext", | ||
@@ -10,3 +13,5 @@ "module": "ESNext", | ||
"allowJs": true, | ||
// Generate d.ts files | ||
"declaration": true, | ||
"outDir": "dist", | ||
// Bundler mode | ||
@@ -17,3 +22,2 @@ "moduleResolution": "bundler", | ||
"noEmit": true, | ||
// Best practices | ||
@@ -23,3 +27,2 @@ "strict": true, | ||
"noFallthroughCasesInSwitch": true, | ||
// Some stricter flags (disabled by default) | ||
@@ -26,0 +29,0 @@ "noUnusedLocals": false, |
Sorry, the diff of this file is not supported yet
44215
23
682
387