diff --git a/.eslintrc.json b/.eslintrc.json index 3de38b4..45ef023 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,19 +1,9 @@ { "env": { - "es6": true, + "es2022": true, "node": true }, "extends": "eslint:recommended", - "globals": { - "Atomics": "readable", - "BigInt": "readable", - "BigInt64Array": "readable", - "BigUint64Array": "readable", - "queueMicrotask": "readable", - "SharedArrayBuffer": "readable", - "TextEncoder": "readable", - "TextDecoder": "readable" - }, "overrides": [ { "files": ["*.mjs"], @@ -44,9 +34,8 @@ } } ], - "parser": "babel-eslint", "parserOptions": { - "ecmaVersion": 10, + "ecmaVersion": 13, "ecmaFeatures": { "globalReturn": true }, diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 67fede4..11d1fc0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,6 +24,10 @@ jobs: - name: Lint run: npm run lint + - name: Lint types + run: npm run lint-types + + test: name: Test runs-on: ${{ matrix.os }} diff --git a/lib/lru.js b/lib/lru.js index 454e2b1..c0998fe 100644 --- a/lib/lru.js +++ b/lib/lru.js @@ -10,18 +10,20 @@ const assert = require('bsert'); /** * LRU Cache + * @template K - Key type + * @template V - Value type */ class LRU { - /** @type {Map} */ + /** @type {Map>} */ map; /** * Create an LRU cache. * @constructor * @param {Number} capacity - * @param {Function?} getSize - * @param {Function?} CustomMap + * @param {Function} [getSize] + * @param {Function} [CustomMap] */ constructor(capacity, getSize, CustomMap) { @@ -34,8 +36,11 @@ class LRU { this.map = CustomMap ? new CustomMap() : new Map(); this.size = 0; this.items = 0; + /** @type {LRUItem?} */ this.head = null; + /** @type {LRUItem?} */ this.tail = null; + /** @type {LRUBatch?} */ this.pending = null; this.capacity = capacity; @@ -45,7 +50,7 @@ class LRU { /** * Calculate size of an item. * @private - * @param {LRUItem} item + * @param {LRUItem} item * @returns {Number} Size. */ @@ -65,7 +70,9 @@ class LRU { if (this.size <= this.capacity) return; + /** @type {LRUItem?} */ let item = null; + /** @type {LRUItem?} */ let next = null; for (item = this.head; item; item = next) { @@ -116,8 +123,8 @@ class LRU { /** * Add an item to the cache. - * @param {String|Number} key - * @param {Object} value + * @param {K} key + * @param {V} value */ set(key, value) { @@ -150,8 +157,8 @@ class LRU { /** * Retrieve an item from the cache. - * @param {String|Number} key - * @returns {Object} Item. + * @param {K} key + * @returns {V} Item. */ get(key) { @@ -171,7 +178,7 @@ class LRU { /** * Test whether the cache contains a key. - * @param {String|Number} key + * @param {K} key * @returns {Boolean} */ @@ -183,7 +190,7 @@ class LRU { /** * Remove an item from the cache. - * @param {String|Number} key + * @param {K} key * @returns {Boolean} Whether an item was removed. */ @@ -209,7 +216,7 @@ class LRU { /** * Append an item to the linked list (sets new tail). * @private - * @param {LRUItem} item + * @param {LRUItem} item */ _appendList(item) { @@ -219,8 +226,8 @@ class LRU { /** * Insert item into the linked list. * @private - * @param {LRUItem|null} ref - * @param {LRUItem} item + * @param {LRUItem?} ref + * @param {LRUItem} item */ _insertList(ref, item) { @@ -253,7 +260,7 @@ class LRU { /** * Remove item from the linked list. * @private - * @param {LRUItem} item + * @param {LRUItem} item */ _removeList(item) { @@ -281,7 +288,7 @@ class LRU { /** * Collect all keys in the cache, sorted by LRU. - * @returns {String[]} + * @returns {K[]} */ keys() { @@ -302,7 +309,7 @@ class LRU { /** * Collect all values in the cache, sorted by LRU. - * @returns {String[]} + * @returns {V[]} */ values() { @@ -316,7 +323,7 @@ class LRU { /** * Convert the LRU cache to an array of items. - * @returns {Object[]} + * @returns {LRUItem[]} */ toArray() { @@ -331,7 +338,7 @@ class LRU { /** * Create an atomic batch for the lru * (used for caching database writes). - * @returns {LRUBatch} + * @returns {LRUBatch} */ batch() { @@ -377,8 +384,8 @@ class LRU { /** * Push an item onto the pending batch. - * @param {String} key - * @param {Object} value + * @param {K} key + * @param {V} value */ push(key, value) { @@ -392,7 +399,7 @@ class LRU { /** * Push a removal onto the pending batch. - * @param {String} key + * @param {K} key */ unpush(key) { @@ -408,20 +415,24 @@ class LRU { /** * LRU Item * @alias module:utils.LRUItem + * @template K - Key type + * @template V - Value type */ class LRUItem { /** * Create an LRU item. * @constructor - * @param {String|Number} key - * @param {Object} value + * @param {K} key + * @param {V} value */ constructor(key, value) { this.key = key; this.value = value; + /** @type {LRUItem?} */ this.next = null; + /** @type {LRUItem?} */ this.prev = null; } } @@ -429,24 +440,27 @@ class LRUItem { /** * LRU Batch * @alias module:utils.LRUBatch + * @template K - Key type + * @template V - Value type */ class LRUBatch { /** * Create an LRU batch. * @constructor - * @param {LRU} lru + * @param {LRU} lru */ constructor(lru) { this.lru = lru; + /** @type {LRUOp[]} */ this.ops = []; } /** * Push an item onto the batch. - * @param {String} key - * @param {Object} value + * @param {K} key + * @param {V} value */ set(key, value) { @@ -455,7 +469,7 @@ class LRUBatch { /** * Push a removal onto the batch. - * @param {String} key + * @param {K} key */ remove(key) { @@ -490,6 +504,8 @@ class LRUBatch { /** * LRU Op * @alias module:utils.LRUOp + * @template K + * @template V * @private */ @@ -498,8 +514,8 @@ class LRUOp { * Create an LRU op. * @constructor * @param {Boolean} remove - * @param {String} key - * @param {Object} value + * @param {K} key + * @param {V} value */ constructor(remove, key, value) {