🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

memory-cache-node

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

memory-cache-node - npm Package Compare versions

Comparing version

to
1.3.0

17

lib/MemoryCache.d.ts

@@ -1,4 +0,4 @@

export declare type ItemValueWrapper<V> = {
itemValue: V;
expirationTimestampInMillisSinceEpoch: number | undefined;
export declare type ValueWrapper<V> = {
readonly value: V;
readonly expirationTimestampInMillis: number | undefined;
};

@@ -9,10 +9,12 @@ export default class MemoryCache<K, V> {

private static readonly EXPIRATION_PROCESSING_ITEM_BATCH_SIZE;
private readonly itemKeyToItemValueWrapperMap;
private readonly itemKeyToValueWrapperMap;
private timer;
private itemCount;
constructor(itemsExpirationCheckIntervalInSecs: number, maxItemCount: number);
storePermanentItem(itemKey: K, itemValue: V): void;
storeExpiringItem(itemKey: K, itemValue: V, timeToLiveInSecs: number): void;
storePermanentItem(key: K, value: V): void;
storeExpiringItem(key: K, value: V, timeToLiveInSecs: number): void;
getItemCount(): number;
hasItem(itemKey: K): boolean;
getValues(): V[];
getItems(): [K, V][];
retrieveItemValue(itemKey: K): V | undefined;

@@ -23,4 +25,7 @@ getItemExpirationTimestampInMillisSinceEpoch(itemKey: K): number | undefined;

destroy(): void;
exportItemsToJson(): string;
importPermanentItemsFrom(json: string): void;
importExpiringItemsFrom(json: string, timeToLiveInSecs: number): void;
private readonly deleteExpiredItems;
private deleteExpiredItemsFromBatch;
}

@@ -7,7 +7,7 @@ "use strict";

this.maxItemCount = maxItemCount;
this.itemKeyToItemValueWrapperMap = new Map();
this.itemKeyToValueWrapperMap = new Map();
this.itemCount = 0;
this.deleteExpiredItems = () => {
const currentTimestampInMillisSinceEpoch = Date.now();
const iterator = this.itemKeyToItemValueWrapperMap.entries();
const iterator = this.itemKeyToValueWrapperMap.entries();
this.deleteExpiredItemsFromBatch(iterator, currentTimestampInMillisSinceEpoch);

@@ -17,6 +17,6 @@ };

}
storePermanentItem(itemKey, itemValue) {
this.storeExpiringItem(itemKey, itemValue, 0);
storePermanentItem(key, value) {
this.storeExpiringItem(key, value, 0);
}
storeExpiringItem(itemKey, itemValue, timeToLiveInSecs) {
storeExpiringItem(key, value, timeToLiveInSecs) {
if (this.timer === null) {

@@ -26,7 +26,5 @@ throw new Error('Cache is destroyed. Cannot store items anymore.');

if (this.itemCount < this.maxItemCount) {
this.itemKeyToItemValueWrapperMap.set(itemKey, {
itemValue,
expirationTimestampInMillisSinceEpoch: timeToLiveInSecs
? Date.now() + timeToLiveInSecs * 1000
: undefined,
this.itemKeyToValueWrapperMap.set(key, {
value,
expirationTimestampInMillis: timeToLiveInSecs ? Date.now() + timeToLiveInSecs * 1000 : undefined,
});

@@ -40,15 +38,24 @@ this.itemCount++;

hasItem(itemKey) {
return this.itemKeyToItemValueWrapperMap.has(itemKey);
return this.itemKeyToValueWrapperMap.has(itemKey);
}
getValues() {
return Array.from(this.itemKeyToValueWrapperMap.values()).map((valueWrapper) => valueWrapper.value);
}
getItems() {
return Array.from(this.itemKeyToValueWrapperMap.entries()).map(([key, valueWrapper]) => [
key,
valueWrapper.value,
]);
}
retrieveItemValue(itemKey) {
var _a;
return (_a = this.itemKeyToItemValueWrapperMap.get(itemKey)) === null || _a === void 0 ? void 0 : _a.itemValue;
return (_a = this.itemKeyToValueWrapperMap.get(itemKey)) === null || _a === void 0 ? void 0 : _a.value;
}
getItemExpirationTimestampInMillisSinceEpoch(itemKey) {
var _a;
return (_a = this.itemKeyToItemValueWrapperMap.get(itemKey)) === null || _a === void 0 ? void 0 : _a.expirationTimestampInMillisSinceEpoch;
return (_a = this.itemKeyToValueWrapperMap.get(itemKey)) === null || _a === void 0 ? void 0 : _a.expirationTimestampInMillis;
}
removeItem(itemKey) {
if (this.hasItem(itemKey)) {
this.itemKeyToItemValueWrapperMap.delete(itemKey);
this.itemKeyToValueWrapperMap.delete(itemKey);
this.itemCount--;

@@ -58,3 +65,3 @@ }

clear() {
this.itemKeyToItemValueWrapperMap.clear();
this.itemKeyToValueWrapperMap.clear();
this.itemCount = 0;

@@ -69,2 +76,19 @@ }

}
exportItemsToJson() {
const itemsObject = Array.from(this.itemKeyToValueWrapperMap.entries()).reduce((object, [key, { value }]) => ({
...object,
[key]: value,
}), {});
return JSON.stringify(itemsObject);
}
importPermanentItemsFrom(json) {
Object.entries(JSON.parse(json)).forEach(([key, value]) => {
this.storePermanentItem(key, value);
});
}
importExpiringItemsFrom(json, timeToLiveInSecs) {
Object.entries(JSON.parse(json)).forEach(([key, value]) => {
this.storeExpiringItem(key, value, timeToLiveInSecs);
});
}
deleteExpiredItemsFromBatch(iterator, currentTimestampInMillisSinceEpoch) {

@@ -77,5 +101,5 @@ for (let i = 0; i < MemoryCache.EXPIRATION_PROCESSING_ITEM_BATCH_SIZE; i++) {

const [itemKey, valueWrapper] = iteratorResult.value;
if (valueWrapper.expirationTimestampInMillisSinceEpoch &&
valueWrapper.expirationTimestampInMillisSinceEpoch < currentTimestampInMillisSinceEpoch) {
this.itemKeyToItemValueWrapperMap.delete(itemKey);
if (valueWrapper.expirationTimestampInMillis &&
valueWrapper.expirationTimestampInMillis < currentTimestampInMillisSinceEpoch) {
this.itemKeyToValueWrapperMap.delete(itemKey);
this.itemCount--;

@@ -82,0 +106,0 @@ }

@@ -16,3 +16,3 @@ "use strict";

memoryCache = new MemoryCache_1.default(1, 10);
expect(memoryCache.itemKeyToItemValueWrapperMap.size).toBe(0);
expect(memoryCache.itemKeyToValueWrapperMap.size).toBe(0);
});

@@ -33,3 +33,3 @@ });

expect(memoryCache.hasItem('key')).toBe(true);
expect(memoryCache.itemKeyToItemValueWrapperMap.size).toBe(1);
expect(memoryCache.itemKeyToValueWrapperMap.size).toBe(1);
});

@@ -40,3 +40,3 @@ it('should not store item in the cache if cache is full', () => {

memoryCache.storeExpiringItem('key', 2, 10);
expect(memoryCache.itemKeyToItemValueWrapperMap.size).toBe(1);
expect(memoryCache.itemKeyToValueWrapperMap.size).toBe(1);
});

@@ -82,2 +82,28 @@ it('should replace an existing item in the cache', () => {

});
describe('getValues', () => {
it('should return an empty array if cache is empty', () => {
memoryCache = new MemoryCache_1.default(1, 10);
expect(memoryCache.getValues()).toEqual([]);
});
it('should return an array of values in cache', () => {
memoryCache = new MemoryCache_1.default(1, 10);
memoryCache.storePermanentItem('key', 1);
memoryCache.storePermanentItem('key2', 2);
memoryCache.removeItem('key2');
expect(memoryCache.getValues()).toEqual([1]);
});
});
describe('getItems', () => {
it('should return an empty array if cache is empty', () => {
memoryCache = new MemoryCache_1.default(1, 10);
expect(memoryCache.getItems()).toEqual([]);
});
it('should return an array of items in cache', () => {
memoryCache = new MemoryCache_1.default(1, 10);
memoryCache.storePermanentItem('key', 1);
memoryCache.storePermanentItem('key2', 2);
memoryCache.removeItem('key2');
expect(memoryCache.getItems()).toEqual([['key', 1]]);
});
});
describe('retrieveItemValue', () => {

@@ -98,4 +124,3 @@ it('should return the item value if cache contains item with given key', () => {

memoryCache.storeExpiringItem('key', 2, 60);
expect(memoryCache.getItemExpirationTimestampInMillisSinceEpoch('key'))
.toBeGreaterThan(Date.now());
expect(memoryCache.getItemExpirationTimestampInMillisSinceEpoch('key')).toBeGreaterThan(Date.now());
});

@@ -112,3 +137,3 @@ it('should return undefined if cache does not contain item with given key', () => {

memoryCache.removeItem('key');
expect(memoryCache.itemKeyToItemValueWrapperMap.size).toBe(0);
expect(memoryCache.itemKeyToValueWrapperMap.size).toBe(0);
});

@@ -119,5 +144,40 @@ it('should not decrement item count if cache does not contain item with given key', () => {

memoryCache.removeItem('key2');
expect(memoryCache.itemKeyToItemValueWrapperMap.size).toBe(1);
expect(memoryCache.itemKeyToValueWrapperMap.size).toBe(1);
});
});
describe('exportItemsToJson', () => {
it('should return an empty JSON object if cache is empty', () => {
memoryCache = new MemoryCache_1.default(1, 10);
expect(memoryCache.exportItemsToJson()).toEqual('{}');
});
it('should return a JSON object with cache items', () => {
memoryCache = new MemoryCache_1.default(1, 10);
expect(memoryCache.exportItemsToJson()).toEqual('{}');
memoryCache.storePermanentItem('key', 1);
memoryCache.storePermanentItem('key2', 2);
expect(JSON.parse(memoryCache.exportItemsToJson())).toEqual({ key: 1, key2: 2 });
});
});
describe('importPermanentItemsFrom', () => {
it('should add items from JSON to the cache', () => {
memoryCache = new MemoryCache_1.default(1, 10);
memoryCache.importPermanentItemsFrom('{ "key": 1, "key2": 2 }');
expect(memoryCache.getItemCount()).toBe(2);
expect(memoryCache.retrieveItemValue('key')).toEqual(1);
expect(memoryCache.retrieveItemValue('key2')).toEqual(2);
expect(memoryCache.getItemExpirationTimestampInMillisSinceEpoch('key')).toBeUndefined();
expect(memoryCache.getItemExpirationTimestampInMillisSinceEpoch('key2')).toBeUndefined();
});
});
describe('importExpiringItemsFrom', () => {
it('should add items from JSON to the cache', () => {
memoryCache = new MemoryCache_1.default(1, 10);
memoryCache.importExpiringItemsFrom('{ "key": 1, "key2": 2 }', 10);
expect(memoryCache.getItemCount()).toBe(2);
expect(memoryCache.retrieveItemValue('key')).toEqual(1);
expect(memoryCache.retrieveItemValue('key2')).toEqual(2);
expect(memoryCache.getItemExpirationTimestampInMillisSinceEpoch('key')).toBeDefined();
expect(memoryCache.getItemExpirationTimestampInMillisSinceEpoch('key2')).toBeDefined();
});
});
describe('clear', () => {

@@ -128,3 +188,3 @@ it('it should clear the cache', () => {

memoryCache.clear();
expect(memoryCache.itemKeyToItemValueWrapperMap.size).toBe(0);
expect(memoryCache.itemKeyToValueWrapperMap.size).toBe(0);
});

@@ -171,3 +231,3 @@ it('it should set the item count to zero', () => {

expect(memoryCache.getItemCount()).toBe(1);
expect(memoryCache.itemKeyToItemValueWrapperMap.size).toBe(1);
expect(memoryCache.itemKeyToValueWrapperMap.size).toBe(1);
done();

@@ -181,3 +241,3 @@ }, 3000);

expect(memoryCache.getItemCount()).toBe(1);
expect(memoryCache.itemKeyToItemValueWrapperMap.size).toBe(1);
expect(memoryCache.itemKeyToValueWrapperMap.size).toBe(1);
done();

@@ -196,3 +256,3 @@ }, 3000);

expect(memoryCache.getItemCount()).toBe(0);
expect(memoryCache.itemKeyToItemValueWrapperMap.size).toBe(0);
expect(memoryCache.itemKeyToValueWrapperMap.size).toBe(0);
done();

@@ -199,0 +259,0 @@ }, 5000);

{
"name": "memory-cache-node",
"version": "1.2.0",
"version": "1.3.0",
"description": "Fast, modern and event loop non-blocking memory cache for Node.js and browse",

@@ -5,0 +5,0 @@ "author": {

@@ -150,5 +150,13 @@ # memory-cache-node

hasItem(itemKey: K): boolean;
getValues(): V[];
getItems(): [K, V][];
retrieveItemValue(itemKey: K): V | undefined;
getItemExpirationTimestampInMillisSinceEpoch(itemKey: K): number | undefined;
removeItem(itemKey: K): void;
exportItemsToJson(): string;
// Use below two functions only with JSON output from exportItemsToJson method
importPermanentItemsFrom(json: string): void; // Can throw if JSON is invalid
importExpiringItemsFrom(json: string, timeToLiveInSecs: number): void; // Can throw if JSON is invalid
clear(): void;

@@ -155,0 +163,0 @@ destroy(): void;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet