New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

keyv

Package Overview
Dependencies
Maintainers
0
Versions
67
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

keyv - npm Package Compare versions

Comparing version 5.2.3 to 5.3.0

67

dist/index.d.ts

@@ -47,3 +47,3 @@ type EventListener = (...arguments_: any[]) => void;

};
interface CompressionAdapter {
type CompressionAdapter = {
compress(value: any, options?: any): Promise<any>;

@@ -53,3 +53,3 @@ decompress(value: any, options?: any): Promise<any>;

deserialize<Value>(data: string): Promise<DeserializedData<Value> | undefined> | DeserializedData<Value> | undefined;
}
};
type Serialize = <Value>(data: DeserializedData<Value>) => Promise<string> | string;

@@ -67,9 +67,23 @@ type Deserialize = <Value>(data: string) => Promise<DeserializedData<Value> | undefined> | DeserializedData<Value> | undefined;

}
type KeyvEntry = {
/**
* Key to set.
*/
key: string;
/**
* Value to set.
*/
value: any;
/**
* Time to live in milliseconds.
*/
ttl?: number;
};
type StoredDataNoRaw<Value> = Value | undefined;
type StoredDataRaw<Value> = DeserializedData<Value> | undefined;
type StoredData<Value> = StoredDataNoRaw<Value> | StoredDataRaw<Value>;
interface IEventEmitter {
on(event: string, listener: (...arguments_: any[]) => void): this;
}
interface KeyvStoreAdapter extends IEventEmitter {
type IEventEmitter = {
on(event: string, listener: (...arguments_: any[]) => void): IEventEmitter;
};
type KeyvStoreAdapter = {
opts: any;

@@ -82,7 +96,9 @@ namespace?: string;

has?(key: string): Promise<boolean>;
hasMany?(keys: string[]): Promise<boolean[]>;
getMany?<Value>(keys: string[]): Promise<Array<StoredData<Value | undefined>>>;
disconnect?(): Promise<void>;
deleteMany?(key: string[]): Promise<boolean>;
setMany?(data: KeyvEntry[]): Promise<boolean[]>;
iterator?<Value>(namespace?: string): AsyncGenerator<Array<string | Awaited<Value> | undefined>, void>;
}
} & IEventEmitter;
type KeyvOptions = {

@@ -223,3 +239,3 @@ /** Emit errors */

* @param {string | string[]} key passing in a single key or multiple as an array
* @param [options] can pass in to return the raw value by setting { raw: true }
* @param {{raw: boolean} | undefined} options can pass in to return the raw value by setting { raw: true }
*/

@@ -239,4 +255,15 @@ get<Value = GenericValue>(key: string, options?: {

/**
* Get many values of keys
* @param {string[]} keys passing in a single key or multiple as an array
* @param {{raw: boolean} | undefined} options can pass in to return the raw value by setting { raw: true }
*/
getMany<Value = GenericValue>(keys: string[], options?: {
raw: false;
}): Promise<Array<StoredDataNoRaw<Value>>>;
getMany<Value = GenericValue>(keys: string[], options?: {
raw: true;
}): Promise<Array<StoredDataRaw<Value>>>;
/**
* Set an item to the store
* @param {string} key the key to use
* @param {string | Array<KeyvEntry>} key the key to use. If you pass in an array of KeyvEntry it will set many items
* @param {Value} value the value of the key

@@ -246,4 +273,11 @@ * @param {number} [ttl] time to live in milliseconds

*/
set<Value = GenericValue>(key: KeyvEntry[]): Promise<boolean[]>;
set<Value = GenericValue>(key: string, value: Value, ttl?: number): Promise<boolean>;
/**
* Set many items to the store
* @param {Array<KeyvEntry>} entries the entries to set
* @returns {boolean[]} will return an array of booleans if it sets then it will return a true. On failure will return false.
*/
setMany<Value = GenericValue>(entries: KeyvEntry[]): Promise<boolean[]>;
/**
* Delete an Entry

@@ -255,2 +289,8 @@ * @param {string | string[]} key the key to be deleted. if an array it will delete many items

/**
* Delete many items from the store
* @param {string[]} keys the keys to be deleted
* @returns {boolean} will return true if item or items are deleted. false if there is an error
*/
deleteMany(keys: string[]): Promise<boolean>;
/**
* Clear the store

@@ -265,4 +305,11 @@ * @returns {void}

*/
has(key: string[]): Promise<boolean[]>;
has(key: string): Promise<boolean>;
/**
* Check if many keys exist
* @param {string[]} keys the keys to check
* @returns {boolean[]} will return an array of booleans if the keys exist
*/
hasMany(keys: string[]): Promise<boolean[]>;
/**
* Will disconnect the store. This is only available if the store has a disconnect method

@@ -277,2 +324,2 @@ * @returns {Promise<void>}

export { type CompressionAdapter, type Deserialize, type DeserializedData, type IEventEmitter, Keyv, KeyvHooks, type KeyvOptions, type KeyvStoreAdapter, type Serialize, type StoredData, type StoredDataNoRaw, type StoredDataRaw, Keyv as default };
export { type CompressionAdapter, type Deserialize, type DeserializedData, type IEventEmitter, Keyv, type KeyvEntry, KeyvHooks, type KeyvOptions, type KeyvStoreAdapter, type Serialize, type StoredData, type StoredDataNoRaw, type StoredDataRaw, Keyv as default };

198

dist/index.js

@@ -465,48 +465,6 @@ // src/index.ts

if (isArray) {
this.hooks.trigger("preGetMany" /* PRE_GET_MANY */, { keys: keyPrefixed });
if (store.getMany === void 0) {
const promises = keyPrefixed.map(async (key2) => {
const rawData3 = await store.get(key2);
const deserializedRow = typeof rawData3 === "string" || this.opts.compression ? await this.deserializeData(rawData3) : rawData3;
if (deserializedRow === void 0 || deserializedRow === null) {
return void 0;
}
if (isDataExpired(deserializedRow)) {
await this.delete(key2);
return void 0;
}
return options?.raw ? deserializedRow : deserializedRow.value;
});
const deserializedRows = await Promise.allSettled(promises);
const result2 = deserializedRows.map((row) => row.value);
this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result2);
if (result2.length > 0) {
this.stats.hit();
}
return result2;
if (options?.raw === true) {
return this.getMany(key, { raw: true });
}
const rawData2 = await store.getMany(keyPrefixed);
const result = [];
for (const index in rawData2) {
let row = rawData2[index];
if (typeof row === "string") {
row = await this.deserializeData(row);
}
if (row === void 0 || row === null) {
result.push(void 0);
continue;
}
if (isDataExpired(row)) {
await this.delete(key[index]);
result.push(void 0);
continue;
}
const value = options?.raw ? row : row.value;
result.push(value);
}
this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result);
if (result.length > 0) {
this.stats.hit();
}
return result;
return this.getMany(key, { raw: false });
}

@@ -529,13 +487,60 @@ this.hooks.trigger("preGet" /* PRE_GET */, { key: keyPrefixed });

}
/**
* Set an item to the store
* @param {string} key the key to use
* @param {Value} value the value of the key
* @param {number} [ttl] time to live in milliseconds
* @returns {boolean} if it sets then it will return a true. On failure will return false.
*/
async getMany(keys, options) {
const { store } = this.opts;
const keyPrefixed = this._getKeyPrefixArray(keys);
const isDataExpired = (data) => typeof data.expires === "number" && Date.now() > data.expires;
this.hooks.trigger("preGetMany" /* PRE_GET_MANY */, { keys: keyPrefixed });
if (store.getMany === void 0) {
const promises = keyPrefixed.map(async (key) => {
const rawData2 = await store.get(key);
const deserializedRow = typeof rawData2 === "string" || this.opts.compression ? await this.deserializeData(rawData2) : rawData2;
if (deserializedRow === void 0 || deserializedRow === null) {
return void 0;
}
if (isDataExpired(deserializedRow)) {
await this.delete(key);
return void 0;
}
return options?.raw ? deserializedRow : deserializedRow.value;
});
const deserializedRows = await Promise.allSettled(promises);
const result2 = deserializedRows.map((row) => row.value);
this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result2);
if (result2.length > 0) {
this.stats.hit();
}
return result2;
}
const rawData = await store.getMany(keyPrefixed);
const result = [];
for (const index in rawData) {
let row = rawData[index];
if (typeof row === "string") {
row = await this.deserializeData(row);
}
if (row === void 0 || row === null) {
result.push(void 0);
continue;
}
if (isDataExpired(row)) {
await this.delete(keys[index]);
result.push(void 0);
continue;
}
const value = options?.raw ? row : row.value;
result.push(value);
}
this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result);
if (result.length > 0) {
this.stats.hit();
}
return result;
}
async set(key, value, ttl) {
if (Array.isArray(key)) {
return this.setMany(key);
}
this.hooks.trigger("preSet" /* PRE_SET */, { key, value, ttl });
const keyPrefixed = this._getKeyPrefix(key);
if (typeof ttl === "undefined") {
if (ttl === void 0) {
ttl = this._ttl;

@@ -568,2 +573,26 @@ }

/**
* Set many items to the store
* @param {Array<KeyvEntry>} entries the entries to set
* @returns {boolean[]} will return an array of booleans if it sets then it will return a true. On failure will return false.
*/
async setMany(entries) {
let results = [];
try {
if (this._store.setMany !== void 0) {
results = await this._store.setMany(entries);
return results;
}
const promises = [];
for (const entry of entries) {
promises.push(this.set(entry.key, entry.value, entry.ttl));
}
const promiseResults = await Promise.allSettled(promises);
results = promiseResults.map((result) => result.value);
} catch (error) {
this.emit("error", error);
results = entries.map(() => false);
}
return results;
}
/**
* Delete an Entry

@@ -576,12 +605,3 @@ * @param {string | string[]} key the key to be deleted. if an array it will delete many items

if (Array.isArray(key)) {
const keyPrefixed2 = this._getKeyPrefixArray(key);
this.hooks.trigger("preDelete" /* PRE_DELETE */, { key: keyPrefixed2 });
if (store.deleteMany !== void 0) {
return store.deleteMany(keyPrefixed2);
}
const promises = keyPrefixed2.map(async (key2) => store.delete(key2));
const results = await Promise.allSettled(promises);
const returnResult = results.every((x) => x.value === true);
this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed2, value: returnResult });
return returnResult;
return this.deleteMany(key);
}

@@ -605,2 +625,25 @@ const keyPrefixed = this._getKeyPrefix(key);

/**
* Delete many items from the store
* @param {string[]} keys the keys to be deleted
* @returns {boolean} will return true if item or items are deleted. false if there is an error
*/
async deleteMany(keys) {
try {
const { store } = this.opts;
const keyPrefixed = this._getKeyPrefixArray(keys);
this.hooks.trigger("preDelete" /* PRE_DELETE */, { key: keyPrefixed });
if (store.deleteMany !== void 0) {
return await store.deleteMany(keyPrefixed);
}
const promises = keyPrefixed.map(async (key) => store.delete(key));
const results = await Promise.allSettled(promises);
const returnResult = results.every((x) => x.value === true);
this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed, value: returnResult });
return returnResult;
} catch (error) {
this.emit("error", error);
return false;
}
}
/**
* Clear the store

@@ -618,8 +661,6 @@ * @returns {void}

}
/**
* Has a key
* @param {string} key the key to check
* @returns {boolean} will return true if the key exists
*/
async has(key) {
if (Array.isArray(key)) {
return this.hasMany(key);
}
const keyPrefixed = this._getKeyPrefix(key);

@@ -648,2 +689,19 @@ const { store } = this.opts;

/**
* Check if many keys exist
* @param {string[]} keys the keys to check
* @returns {boolean[]} will return an array of booleans if the keys exist
*/
async hasMany(keys) {
const keyPrefixed = this._getKeyPrefixArray(keys);
const { store } = this.opts;
if (store.hasMany !== void 0) {
return store.hasMany(keyPrefixed);
}
const results = [];
for (const key of keyPrefixed) {
results.push(await this.has(key));
}
return results;
}
/**
* Will disconnect the store. This is only available if the store has a disconnect method

@@ -688,7 +746,7 @@ * @returns {Promise<void>}

};
var src_default = Keyv;
var index_default = Keyv;
export {
Keyv,
KeyvHooks,
src_default as default
index_default as default
};
{
"name": "keyv",
"version": "5.2.3",
"version": "5.3.0",
"description": "Simple key-value storage with support for multiple backends",

@@ -17,23 +17,8 @@ "type": "module",

"rules": {
"import/no-named-as-default": "off",
"unicorn/prefer-module": "off",
"unicorn/prefer-node-protocol": "off",
"@typescript-eslint/consistent-type-definitions": "off",
"unicorn/no-typeof-undefined": "off",
"unicorn/prefer-event-target": "off",
"import/no-extraneous-dependencies": "off",
"import/extensions": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-for-in-array": "off",
"guard-for-in": "off",
"no-await-in-loop": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-argument": "off",
"@typescript-eslint/naming-convention": "off",
"@typescript-eslint/consistent-type-assertions": "off",
"@typescript-eslint/no-confusing-void-expression": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/prefer-ts-expect-error": "off"
"@typescript-eslint/no-confusing-void-expression": "off"
}

@@ -73,15 +58,19 @@ },

"dependencies": {
"@keyv/serialize": "^1.0.2"
"@keyv/serialize": "^1.0.3"
},
"devDependencies": {
"@faker-js/faker": "^9.5.1",
"@vitest/coverage-v8": "^3.0.7",
"rimraf": "^6.0.1",
"timekeeper": "^2.3.1",
"tsd": "^0.31.2",
"vitest": "^3.0.7",
"xo": "^0.60.0",
"@keyv/compress-brotli": "^2.0.2",
"@keyv/compress-brotli": "^2.0.3",
"@keyv/compress-gzip": "^2.0.2",
"@keyv/memcache": "^2.0.1",
"@keyv/compress-lz4": "^1.0.0",
"@keyv/mongo": "^3.0.1",
"@keyv/sqlite": "^4.0.1",
"@keyv/test-suite": "^2.0.3"
"@keyv/test-suite": "^2.0.5"
},

@@ -88,0 +77,0 @@ "tsd": {

@@ -292,3 +292,3 @@ <h1 align="center"><img width="250" src="https://jaredwray.com/images/keyv.svg" alt="keyv"></h1>

Keyv supports `gzip` and `brotli` compression. To enable compression, pass the `compress` option to the constructor.
Keyv supports `gzip`, `brotli` and `lz4` compression. To enable compression, pass the `compress` option to the constructor.

@@ -300,5 +300,21 @@ ```js

const keyvGzip = new KeyvGzip();
const keyv = new Keyv({ compression: KeyvGzip });
const keyv = new Keyv({ compression: keyvGzip });
```
```js
import Keyv from 'keyv';
import KeyvBrotli from '@keyv/compress-brotli';
const keyvBrotli = new KeyvBrotli();
const keyv = new Keyv({ compression: keyvBrotli });
```
```js
import Keyv from 'keyv';
import KeyvLz4 from '@keyv/compress-lz4';
const keyvLz4 = new KeyvLz4();
const keyv = new Keyv({ compression: keyvLz4 });
```
You can also pass a custom compression function to the `compression` option. Following the pattern of the official compression adapters.

@@ -412,2 +428,6 @@

## .setMany(entries)
Set multiple values using KeyvEntrys `{ key: string, value: any, ttl?: number }`.
## .get(key, [options])

@@ -417,2 +437,6 @@

## .getMany(keys, [options])
Returns a promise which resolves to an array of retrieved values.
### options.raw

@@ -433,2 +457,6 @@

## .deleteMany(keys)
Deletes multiple entries.
Returns a promise which resolves to an array of booleans indicating if the key existed or not.
## .clear()

@@ -435,0 +463,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc