/opt/canhelp/node_modules/next/dist/esm/server/lib
NameSizeModeActions
cache-handlers/-0755rm
experimental/-0755rm
incremental-cache/-0755rm
module-loader/-0755rm
router-utils/-0755rm
server-ipc/-0755rm
trace/-0755rm
app-dir-module.js11640644editdlrm
app-dir-module.js.map25980644editdlrm
app-info-log.js27230644editdlrm
app-info-log.js.map58270644editdlrm
async-callback-set.js5190644editdlrm
async-callback-set.js.map10970644editdlrm
cache-control.js5830644editdlrm
cache-control.js.map16220644editdlrm
chrome-devtools-workspace.js22970644editdlrm
chrome-devtools-workspace.js.map41450644editdlrm
clone-response.js28830644editdlrm
clone-response.js.map44410644editdlrm
cpu-profile.js10200644editdlrm
cpu-profile.js.map20610644editdlrm
decode-query-path-parameter.js4580644editdlrm
decode-query-path-parameter.js.map7400644editdlrm
dedupe-fetch.js50850644editdlrm
dedupe-fetch.js.map73740644editdlrm
dev-bundler-service.js31100644editdlrm
dev-bundler-service.js.map58380644editdlrm
disk-lru-cache.external.js18570644editdlrm
disk-lru-cache.external.js.map31490644editdlrm
etag.js11480644editdlrm
etag.js.map21650644editdlrm
find-page-file.js54450644editdlrm
find-page-file.js.map94800644editdlrm
fix-mojibake.js5230644editdlrm
fix-mojibake.js.map10260644editdlrm
format-hostname.js3320644editdlrm
format-hostname.js.map6160644editdlrm
i18n-provider.js55310644editdlrm
i18n-provider.js.map90410644editdlrm
implicit-tags.js24500644editdlrm
implicit-tags.js.map52380644editdlrm
is-ipv6.js20900644editdlrm
is-ipv6.js.map33880644editdlrm
lazy-result.js9390644editdlrm
lazy-result.js.map18690644editdlrm
lru-cache.js71480644editdlrm
lru-cache.js.map113740644editdlrm
match-next-data-pathname.js3120644editdlrm
match-next-data-pathname.js.map6290644editdlrm
mock-request.js137530644editdlrm
mock-request.js.map212240644editdlrm
node-fs-methods.js3640644editdlrm
node-fs-methods.js.map9460644editdlrm
parse-stack.js15610644editdlrm
parse-stack.js.map29830644editdlrm
patch-fetch.js449390644editdlrm
patch-fetch.js.map647210644editdlrm
patch-set-header.js13680644editdlrm
patch-set-header.js.map24710644editdlrm
render-server.js29880644editdlrm
render-server.js.map62760644editdlrm
router-server.js300290644editdlrm
router-server.js.map467520644editdlrm
server-action-request-meta.js15300644editdlrm
server-action-request-meta.js.map30300644editdlrm
source-maps.js81720644editdlrm
source-maps.js.map148120644editdlrm
start-server.js167970644editdlrm
start-server.js.map277270644editdlrm
streaming-metadata.js7620644editdlrm
streaming-metadata.js.map15820644editdlrm
to-route.js5820644editdlrm
to-route.js.map8480644editdlrm
types.js460644editdlrm
types.js.map4510644editdlrm
utils.js85160644editdlrm
utils.js.map136270644editdlrm
worker-utils.js7550644editdlrm
worker-utils.js.map11200644editdlrm
Edit: /opt/canhelp/node_modules/next/dist/esm/server/lib/lru-cache.js (7148B)
/** * Node in the doubly-linked list used for LRU tracking. * Each node represents a cache entry with bidirectional pointers. */ class LRUNode { constructor(key, data, size){ this.prev = null; this.next = null; this.key = key; this.data = data; this.size = size; } } /** * Sentinel node used for head/tail boundaries. * These nodes don't contain actual cache data but simplify list operations. */ class SentinelNode { constructor(){ this.prev = null; this.next = null; } } /** * LRU (Least Recently Used) Cache implementation using a doubly-linked list * and hash map for O(1) operations. * * Algorithm: * - Uses a doubly-linked list to maintain access order (most recent at head) * - Hash map provides O(1) key-to-node lookup * - Sentinel head/tail nodes simplify edge case handling * - Size-based eviction supports custom size calculation functions * * Data Structure Layout: * HEAD <-> [most recent] <-> ... <-> [least recent] <-> TAIL * * Operations: * - get(): Move accessed node to head (mark as most recent) * - set(): Add new node at head, evict from tail if over capacity * - Eviction: Remove least recent node (tail.prev) when size exceeds limit */ export class LRUCache { constructor(maxSize, calculateSize, onEvict){ this.cache = new Map(); this.totalSize = 0; this.maxSize = maxSize; this.calculateSize = calculateSize; this.onEvict = onEvict; // Create sentinel nodes to simplify doubly-linked list operations // HEAD <-> TAIL (empty list) this.head = new SentinelNode(); this.tail = new SentinelNode(); this.head.next = this.tail; this.tail.prev = this.head; } /** * 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) */ addToHead(node) { node.prev = this.head; node.next = this.head.next; // head.next is always non-null (points to tail or another node) this.head.next.prev = node; this.head.next = node; } /** * 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) */ removeNode(node) { // Connected nodes always have non-null prev/next node.prev.next = node.next; node.next.prev = node.prev; } /** * Moves an existing node to the head position (marks as most recently used). * This is the core LRU operation - accessed items become most recent. */ moveToHead(node) { this.removeNode(node); this.addToHead(node); } /** * 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) */ removeTail() { const lastNode = this.tail.prev; // tail.prev is always non-null and always LRUNode when cache is not empty this.removeNode(lastNode); return lastNode; } /** * Sets a key-value pair in the cache. * If the key exists, updates the value and moves to head. * If new, adds at head and evicts from tail if necessary. * * Time Complexity: * - O(1) for uniform item sizes * - O(k) where k is the number of items evicted (can be O(N) for variable sizes) */ set(key, value) { const size = (this.calculateSize == null ? void 0 : this.calculateSize.call(this, value)) ?? 1; if (size <= 0) { throw Object.defineProperty(new Error(`LRUCache: calculateSize returned ${size}, but size must be > 0. ` + `Items with size 0 would never be evicted, causing unbounded cache growth.`), "__NEXT_ERROR_CODE", { value: "E789", enumerable: false, configurable: true }); } if (size > this.maxSize) { console.warn('Single item size exceeds maxSize'); return false; } const existing = this.cache.get(key); if (existing) { // Update existing node: adjust size and move to head (most recent) existing.data = value; this.totalSize = this.totalSize - existing.size + size; existing.size = size; this.moveToHead(existing); } else { // Add new node at head (most recent position) const newNode = new LRUNode(key, value, size); this.cache.set(key, newNode); this.addToHead(newNode); this.totalSize += size; } // Evict least recently used items until under capacity while(this.totalSize > this.maxSize && this.cache.size > 0){ const tail = this.removeTail(); this.cache.delete(tail.key); this.totalSize -= tail.size; this.onEvict == null ? void 0 : this.onEvict.call(this, tail.key, tail.data); } return true; } /** * Checks if a key exists in the cache. * This is a pure query operation - does NOT update LRU order. * * Time Complexity: O(1) */ has(key) { return this.cache.has(key); } /** * Retrieves a value by key and marks it as most recently used. * Moving to head maintains the LRU property for future evictions. * * Time Complexity: O(1) */ get(key) { const node = this.cache.get(key); if (!node) return undefined; // Mark as most recently used by moving to head this.moveToHead(node); return node.data; } /** * Returns an iterator over the cache entries. The order is outputted in the * order of most recently used to least recently used. */ *[Symbol.iterator]() { let current = this.head.next; while(current && current !== this.tail){ // Between head and tail, current is always LRUNode const node = current; yield [ node.key, node.data ]; current = current.next; } } /** * Removes a specific key from the cache. * Updates both the hash map and doubly-linked list. * * Note: This is an explicit removal and does NOT trigger the `onEvict` * callback. Use this for intentional deletions where eviction tracking * is not needed. * * Time Complexity: O(1) */ remove(key) { const node = this.cache.get(key); if (!node) return; this.removeNode(node); this.cache.delete(key); this.totalSize -= node.size; } /** * Returns the number of items in the cache. */ get size() { return this.cache.size; } /** * Returns the current total size of all cached items. * This uses the custom size calculation if provided. */ get currentSize() { return this.totalSize; } } //# sourceMappingURL=lru-cache.js.map