@stryke/helpers 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +11 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +1 -1
- package/dist/lru-cache.cjs +82 -0
- package/dist/lru-cache.d.ts +99 -0
- package/dist/lru-cache.mjs +1 -0
- package/package.json +19 -5
package/dist/index.cjs
CHANGED
|
@@ -135,6 +135,17 @@ Object.keys(_isEqual).forEach(function (key) {
|
|
|
135
135
|
}
|
|
136
136
|
});
|
|
137
137
|
});
|
|
138
|
+
var _lruCache = require("./lru-cache.cjs");
|
|
139
|
+
Object.keys(_lruCache).forEach(function (key) {
|
|
140
|
+
if (key === "default" || key === "__esModule") return;
|
|
141
|
+
if (key in exports && exports[key] === _lruCache[key]) return;
|
|
142
|
+
Object.defineProperty(exports, key, {
|
|
143
|
+
enumerable: true,
|
|
144
|
+
get: function () {
|
|
145
|
+
return _lruCache[key];
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
});
|
|
138
149
|
var _matchSorter = require("./match-sorter.cjs");
|
|
139
150
|
Object.keys(_matchSorter).forEach(function (key) {
|
|
140
151
|
if (key === "default" || key === "__esModule") return;
|
package/dist/index.d.ts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./arg-identity";export*from"./debounce";export*from"./deep-clone";export*from"./deep-merge";export*from"./delay";export*from"./filter-empty";export*from"./flatten-object";export*from"./get-field";export*from"./get-ordered-by";export*from"./get-unique";export*from"./identity";export*from"./is-equal";export*from"./match-sorter";export*from"./memoize";export*from"./mutex";export*from"./noop";export*from"./omit";export*from"./once";export*from"./pick";export*from"./remove-accents";export*from"./remove-empty-items";export*from"./semaphore";export*from"./set-field";export*from"./throttle";export*from"./timeout";export*from"./to-deep-key";export*from"./to-path";export*from"./unflatten-object";export*from"./union";export*from"./with-timeout";
|
|
1
|
+
export*from"./arg-identity";export*from"./debounce";export*from"./deep-clone";export*from"./deep-merge";export*from"./delay";export*from"./filter-empty";export*from"./flatten-object";export*from"./get-field";export*from"./get-ordered-by";export*from"./get-unique";export*from"./identity";export*from"./is-equal";export*from"./lru-cache";export*from"./match-sorter";export*from"./memoize";export*from"./mutex";export*from"./noop";export*from"./omit";export*from"./once";export*from"./pick";export*from"./remove-accents";export*from"./remove-empty-items";export*from"./semaphore";export*from"./set-field";export*from"./throttle";export*from"./timeout";export*from"./to-deep-key";export*from"./to-path";export*from"./unflatten-object";export*from"./union";export*from"./with-timeout";
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.LRUCache = void 0;
|
|
7
|
+
class r {
|
|
8
|
+
key;
|
|
9
|
+
data;
|
|
10
|
+
size;
|
|
11
|
+
prev = null;
|
|
12
|
+
next = null;
|
|
13
|
+
constructor(e, t, i) {
|
|
14
|
+
this.key = e, this.data = t, this.size = i;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
class l {
|
|
18
|
+
prev = null;
|
|
19
|
+
next = null;
|
|
20
|
+
}
|
|
21
|
+
class LRUCache {
|
|
22
|
+
cache = new Map();
|
|
23
|
+
head;
|
|
24
|
+
tail;
|
|
25
|
+
totalSize = 0;
|
|
26
|
+
maxSize;
|
|
27
|
+
calculateSize;
|
|
28
|
+
constructor(e, t) {
|
|
29
|
+
this.maxSize = e, this.calculateSize = t, this.head = new l(), this.tail = new l(), this.head.next = this.tail, this.tail.prev = this.head;
|
|
30
|
+
}
|
|
31
|
+
addToHead(e) {
|
|
32
|
+
e.prev = this.head, e.next = this.head.next, this.head.next.prev = e, this.head.next = e;
|
|
33
|
+
}
|
|
34
|
+
removeNode(e) {
|
|
35
|
+
e.prev.next = e.next, e.next.prev = e.prev;
|
|
36
|
+
}
|
|
37
|
+
moveToHead(e) {
|
|
38
|
+
this.removeNode(e), this.addToHead(e);
|
|
39
|
+
}
|
|
40
|
+
removeTail() {
|
|
41
|
+
const e = this.tail.prev;
|
|
42
|
+
return this.removeNode(e), e;
|
|
43
|
+
}
|
|
44
|
+
set(e, t) {
|
|
45
|
+
const i = this.calculateSize?.(t) ?? 1;
|
|
46
|
+
if (i > this.maxSize) return;
|
|
47
|
+
const a = this.cache.get(e);
|
|
48
|
+
if (a) a.data = t, this.totalSize = this.totalSize - a.size + i, a.size = i, this.moveToHead(a);else {
|
|
49
|
+
const s = new r(e, t, i);
|
|
50
|
+
this.cache.set(e, s), this.addToHead(s), this.totalSize += i;
|
|
51
|
+
}
|
|
52
|
+
for (; this.totalSize > this.maxSize && this.cache.size > 0;) {
|
|
53
|
+
const s = this.removeTail();
|
|
54
|
+
this.cache.delete(s.key), this.totalSize -= s.size;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
has(e) {
|
|
58
|
+
return this.cache.has(e);
|
|
59
|
+
}
|
|
60
|
+
get(e) {
|
|
61
|
+
const t = this.cache.get(e);
|
|
62
|
+
if (t) return this.moveToHead(t), t.data;
|
|
63
|
+
}
|
|
64
|
+
*[Symbol.iterator]() {
|
|
65
|
+
let e = this.head.next;
|
|
66
|
+
for (; e && e !== this.tail;) {
|
|
67
|
+
const t = e;
|
|
68
|
+
yield [t.key, t.data], e = e.next;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
remove(e) {
|
|
72
|
+
const t = this.cache.get(e);
|
|
73
|
+
t && (this.removeNode(t), this.cache.delete(e), this.totalSize -= t.size);
|
|
74
|
+
}
|
|
75
|
+
get size() {
|
|
76
|
+
return this.cache.size;
|
|
77
|
+
}
|
|
78
|
+
get currentSize() {
|
|
79
|
+
return this.totalSize;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.LRUCache = LRUCache;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LRU (Least Recently Used) Cache implementation using a doubly-linked list
|
|
3
|
+
* and hash map for O(1) operations.
|
|
4
|
+
*
|
|
5
|
+
* Algorithm:
|
|
6
|
+
* - Uses a doubly-linked list to maintain access order (most recent at head)
|
|
7
|
+
* - Hash map provides O(1) key-to-node lookup
|
|
8
|
+
* - Sentinel head/tail nodes simplify edge case handling
|
|
9
|
+
* - Size-based eviction supports custom size calculation functions
|
|
10
|
+
*
|
|
11
|
+
* Data Structure Layout:
|
|
12
|
+
* HEAD \<-\> [most recent] \<-\> ... \<-\> [least recent] \<-\> TAIL
|
|
13
|
+
*
|
|
14
|
+
* Operations:
|
|
15
|
+
* - get(): Move accessed node to head (mark as most recent)
|
|
16
|
+
* - set(): Add new node at head, evict from tail if over capacity
|
|
17
|
+
* - Eviction: Remove least recent node (tail.prev) when size exceeds limit
|
|
18
|
+
*/
|
|
19
|
+
export declare class LRUCache<T> {
|
|
20
|
+
private readonly cache;
|
|
21
|
+
private readonly head;
|
|
22
|
+
private readonly tail;
|
|
23
|
+
private totalSize;
|
|
24
|
+
private readonly maxSize;
|
|
25
|
+
private readonly calculateSize;
|
|
26
|
+
constructor(maxSize: number, calculateSize?: (value: T) => number);
|
|
27
|
+
/**
|
|
28
|
+
* Adds a node immediately after the head (marks as most recently used). Used when inserting new items or when an item is accessed. **PRECONDITION:** node must be disconnected (prev/next should be null)
|
|
29
|
+
*
|
|
30
|
+
* @param node - The node to add after the head.
|
|
31
|
+
*/
|
|
32
|
+
private addToHead;
|
|
33
|
+
/**
|
|
34
|
+
* Removes a node from its current position in the doubly-linked list. Updates the prev/next pointers of adjacent nodes to maintain list integrity. **PRECONDITION:** node must be connected (prev/next are non-null)
|
|
35
|
+
*
|
|
36
|
+
* @param node - The node to remove from the list.
|
|
37
|
+
*/
|
|
38
|
+
private removeNode;
|
|
39
|
+
/**
|
|
40
|
+
* Moves an existing node to the head position (marks as most recently used). This is the core LRU operation - accessed items become most recent.
|
|
41
|
+
*
|
|
42
|
+
* @param node - The node to move to the head.
|
|
43
|
+
*/
|
|
44
|
+
private moveToHead;
|
|
45
|
+
/**
|
|
46
|
+
* Removes and returns the least recently used node (the one before tail). This is called during eviction when the cache exceeds capacity. **PRECONDITION:** cache is not empty (ensured by caller)
|
|
47
|
+
*
|
|
48
|
+
* @returns The removed least recently used node.
|
|
49
|
+
*/
|
|
50
|
+
private removeTail;
|
|
51
|
+
/**
|
|
52
|
+
* Sets a key-value pair in the cache.
|
|
53
|
+
* If the key exists, updates the value and moves to head.
|
|
54
|
+
* If new, adds at head and evicts from tail if necessary.
|
|
55
|
+
*
|
|
56
|
+
* Time Complexity:
|
|
57
|
+
* - O(1) for uniform item sizes
|
|
58
|
+
* - O(k) where k is the number of items evicted (can be O(N) for variable sizes)
|
|
59
|
+
*
|
|
60
|
+
* @param key - The key to set.
|
|
61
|
+
* @param value - The value to set.
|
|
62
|
+
*/
|
|
63
|
+
set(key: string, value: T): void;
|
|
64
|
+
/**
|
|
65
|
+
* Checks if a key exists in the cache.
|
|
66
|
+
* This is a pure query operation - does NOT update LRU order.
|
|
67
|
+
*
|
|
68
|
+
* Time Complexity: O(1)
|
|
69
|
+
*/
|
|
70
|
+
has(key: string): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Retrieves a value by key and marks it as most recently used.
|
|
73
|
+
* Moving to head maintains the LRU property for future evictions.
|
|
74
|
+
*
|
|
75
|
+
* Time Complexity: O(1)
|
|
76
|
+
*/
|
|
77
|
+
get(key: string): T | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* Returns an iterator over the cache entries. The order is outputted in the
|
|
80
|
+
* order of most recently used to least recently used.
|
|
81
|
+
*/
|
|
82
|
+
[Symbol.iterator](): IterableIterator<[string, T]>;
|
|
83
|
+
/**
|
|
84
|
+
* Removes a specific key from the cache.
|
|
85
|
+
* Updates both the hash map and doubly-linked list.
|
|
86
|
+
*
|
|
87
|
+
* Time Complexity: O(1)
|
|
88
|
+
*/
|
|
89
|
+
remove(key: string): void;
|
|
90
|
+
/**
|
|
91
|
+
* Returns the number of items in the cache.
|
|
92
|
+
*/
|
|
93
|
+
get size(): number;
|
|
94
|
+
/**
|
|
95
|
+
* Returns the current total size of all cached items.
|
|
96
|
+
* This uses the custom size calculation if provided.
|
|
97
|
+
*/
|
|
98
|
+
get currentSize(): number;
|
|
99
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class r{key;data;size;prev=null;next=null;constructor(e,t,i){this.key=e,this.data=t,this.size=i}}class l{prev=null;next=null}export class LRUCache{cache=new Map;head;tail;totalSize=0;maxSize;calculateSize;constructor(e,t){this.maxSize=e,this.calculateSize=t,this.head=new l,this.tail=new l,this.head.next=this.tail,this.tail.prev=this.head}addToHead(e){e.prev=this.head,e.next=this.head.next,this.head.next.prev=e,this.head.next=e}removeNode(e){e.prev.next=e.next,e.next.prev=e.prev}moveToHead(e){this.removeNode(e),this.addToHead(e)}removeTail(){const e=this.tail.prev;return this.removeNode(e),e}set(e,t){const i=this.calculateSize?.(t)??1;if(i>this.maxSize)return;const a=this.cache.get(e);if(a)a.data=t,this.totalSize=this.totalSize-a.size+i,a.size=i,this.moveToHead(a);else{const s=new r(e,t,i);this.cache.set(e,s),this.addToHead(s),this.totalSize+=i}for(;this.totalSize>this.maxSize&&this.cache.size>0;){const s=this.removeTail();this.cache.delete(s.key),this.totalSize-=s.size}}has(e){return this.cache.has(e)}get(e){const t=this.cache.get(e);if(t)return this.moveToHead(t),t.data}*[Symbol.iterator](){let e=this.head.next;for(;e&&e!==this.tail;){const t=e;yield[t.key,t.data],e=e.next}}remove(e){const t=this.cache.get(e);t&&(this.removeNode(t),this.cache.delete(e),this.totalSize-=t.size)}get size(){return this.cache.size}get currentSize(){return this.totalSize}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stryke/helpers",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A package containing miscellaneous helper functions that are used across many different Storm Software projects.",
|
|
6
6
|
"repository": {
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
"private": false,
|
|
12
12
|
"publishConfig": { "access": "public" },
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@stryke/convert": "^0.
|
|
15
|
-
"@stryke/type-checks": "^0.3.
|
|
16
|
-
"@stryke/types": "^0.
|
|
14
|
+
"@stryke/convert": "^0.6.0",
|
|
15
|
+
"@stryke/type-checks": "^0.3.10",
|
|
16
|
+
"@stryke/types": "^0.9.0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {},
|
|
19
19
|
"sideEffects": false,
|
|
@@ -263,6 +263,20 @@
|
|
|
263
263
|
"default": "./dist/match-sorter.mjs"
|
|
264
264
|
}
|
|
265
265
|
},
|
|
266
|
+
"./lru-cache": {
|
|
267
|
+
"import": {
|
|
268
|
+
"types": "./dist/lru-cache.d.ts",
|
|
269
|
+
"default": "./dist/lru-cache.mjs"
|
|
270
|
+
},
|
|
271
|
+
"require": {
|
|
272
|
+
"types": "./dist/lru-cache.d.ts",
|
|
273
|
+
"default": "./dist/lru-cache.cjs"
|
|
274
|
+
},
|
|
275
|
+
"default": {
|
|
276
|
+
"types": "./dist/lru-cache.d.ts",
|
|
277
|
+
"default": "./dist/lru-cache.mjs"
|
|
278
|
+
}
|
|
279
|
+
},
|
|
266
280
|
"./is-equal": {
|
|
267
281
|
"import": {
|
|
268
282
|
"types": "./dist/is-equal.d.ts",
|
|
@@ -460,5 +474,5 @@
|
|
|
460
474
|
"main": "./dist/index.cjs",
|
|
461
475
|
"module": "./dist/index.mjs",
|
|
462
476
|
"types": "./dist/index.d.ts",
|
|
463
|
-
"gitHead": "
|
|
477
|
+
"gitHead": "4074c4a56f6e2c42ca4c39c30df5309c19024c7b"
|
|
464
478
|
}
|