@linxiraos/pi-utils 1.0.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/CHANGELOG.md +449 -0
- package/README.md +36 -0
- package/dist/types/abortable.d.ts +32 -0
- package/dist/types/acp/connection.d.ts +118 -0
- package/dist/types/acp/protocol.d.ts +526 -0
- package/dist/types/acp/schema.d.ts +41 -0
- package/dist/types/acp/stream.d.ts +8 -0
- package/dist/types/acp/transport.d.ts +81 -0
- package/dist/types/acp.d.ts +6 -0
- package/dist/types/async.d.ts +20 -0
- package/dist/types/binary.d.ts +17 -0
- package/dist/types/browsers.d.ts +68 -0
- package/dist/types/chalk.d.ts +125 -0
- package/dist/types/cli.d.ts +134 -0
- package/dist/types/color.d.ts +102 -0
- package/dist/types/dates.d.ts +7 -0
- package/dist/types/dirs.d.ts +282 -0
- package/dist/types/docx/converter.d.ts +46 -0
- package/dist/types/docx/xml.d.ts +26 -0
- package/dist/types/docx/zip.d.ts +6 -0
- package/dist/types/docx.d.ts +11 -0
- package/dist/types/dom/core.d.ts +431 -0
- package/dist/types/dom/parser.d.ts +7 -0
- package/dist/types/dom/selector.d.ts +5 -0
- package/dist/types/dom.d.ts +5 -0
- package/dist/types/env.d.ts +124 -0
- package/dist/types/fetch-retry.d.ts +96 -0
- package/dist/types/file-lock.d.ts +23 -0
- package/dist/types/format.d.ts +37 -0
- package/dist/types/frontmatter.d.ts +46 -0
- package/dist/types/fs-error.d.ts +31 -0
- package/dist/types/glob.d.ts +28 -0
- package/dist/types/headers.d.ts +34 -0
- package/dist/types/index.d.ts +39 -0
- package/dist/types/json-parse.d.ts +74 -0
- package/dist/types/json.d.ts +14 -0
- package/dist/types/logger/rotating-file.d.ts +18 -0
- package/dist/types/logger.d.ts +96 -0
- package/dist/types/loop-phase.d.ts +10 -0
- package/dist/types/lru.d.ts +46 -0
- package/dist/types/marked/core.d.ts +445 -0
- package/dist/types/marked.d.ts +2 -0
- package/dist/types/mermaid-ascii.d.ts +11 -0
- package/dist/types/mime.d.ts +29 -0
- package/dist/types/module-timer.d.ts +1 -0
- package/dist/types/path-tree.d.ts +76 -0
- package/dist/types/path.d.ts +2 -0
- package/dist/types/peek-file.d.ts +29 -0
- package/dist/types/postmortem.d.ts +104 -0
- package/dist/types/process-name.d.ts +7 -0
- package/dist/types/procmgr.d.ts +74 -0
- package/dist/types/prompt.d.ts +18 -0
- package/dist/types/ptree.d.ts +110 -0
- package/dist/types/readability/readability.d.ts +9 -0
- package/dist/types/readability/readerable.d.ts +10 -0
- package/dist/types/readability/types.d.ts +70 -0
- package/dist/types/readability.d.ts +4 -0
- package/dist/types/ring.d.ts +93 -0
- package/dist/types/runtime-install.d.ts +78 -0
- package/dist/types/sanitize-text.d.ts +29 -0
- package/dist/types/snowflake.d.ts +25 -0
- package/dist/types/stderr-guard.d.ts +22 -0
- package/dist/types/stream.d.ts +67 -0
- package/dist/types/tab-spacing.d.ts +24 -0
- package/dist/types/temp.d.ts +17 -0
- package/dist/types/template.d.ts +62 -0
- package/dist/types/timing-buffer.d.ts +22 -0
- package/dist/types/tls-fetch.d.ts +37 -0
- package/dist/types/turndown/gfm.d.ts +11 -0
- package/dist/types/turndown/html.d.ts +5 -0
- package/dist/types/turndown/service.d.ts +21 -0
- package/dist/types/turndown/types.d.ts +70 -0
- package/dist/types/turndown.d.ts +4 -0
- package/dist/types/type-guards.d.ts +5 -0
- package/dist/types/vendor/mermaid-ascii/ascii/ansi.d.ts +41 -0
- package/dist/types/vendor/mermaid-ascii/ascii/canvas.d.ts +89 -0
- package/dist/types/vendor/mermaid-ascii/ascii/class-diagram.d.ts +7 -0
- package/dist/types/vendor/mermaid-ascii/ascii/converter.d.ts +12 -0
- package/dist/types/vendor/mermaid-ascii/ascii/draw.d.ts +66 -0
- package/dist/types/vendor/mermaid-ascii/ascii/edge-bundling.d.ts +48 -0
- package/dist/types/vendor/mermaid-ascii/ascii/edge-routing.d.ts +43 -0
- package/dist/types/vendor/mermaid-ascii/ascii/er-diagram.d.ts +7 -0
- package/dist/types/vendor/mermaid-ascii/ascii/grid.d.ts +56 -0
- package/dist/types/vendor/mermaid-ascii/ascii/index.d.ts +65 -0
- package/dist/types/vendor/mermaid-ascii/ascii/multiline-utils.d.ts +27 -0
- package/dist/types/vendor/mermaid-ascii/ascii/pathfinder.d.ts +17 -0
- package/dist/types/vendor/mermaid-ascii/ascii/sequence.d.ts +7 -0
- package/dist/types/vendor/mermaid-ascii/ascii/shapes/circle.d.ts +11 -0
- package/dist/types/vendor/mermaid-ascii/ascii/shapes/corners.d.ts +34 -0
- package/dist/types/vendor/mermaid-ascii/ascii/shapes/diamond.d.ts +11 -0
- package/dist/types/vendor/mermaid-ascii/ascii/shapes/hexagon.d.ts +11 -0
- package/dist/types/vendor/mermaid-ascii/ascii/shapes/index.d.ts +26 -0
- package/dist/types/vendor/mermaid-ascii/ascii/shapes/rectangle.d.ts +31 -0
- package/dist/types/vendor/mermaid-ascii/ascii/shapes/rounded.d.ts +11 -0
- package/dist/types/vendor/mermaid-ascii/ascii/shapes/special.d.ts +59 -0
- package/dist/types/vendor/mermaid-ascii/ascii/shapes/stadium.d.ts +17 -0
- package/dist/types/vendor/mermaid-ascii/ascii/shapes/state.d.ts +30 -0
- package/dist/types/vendor/mermaid-ascii/ascii/shapes/types.d.ts +55 -0
- package/dist/types/vendor/mermaid-ascii/ascii/types.d.ts +206 -0
- package/dist/types/vendor/mermaid-ascii/ascii/validate.d.ts +51 -0
- package/dist/types/vendor/mermaid-ascii/ascii/xychart.d.ts +2 -0
- package/dist/types/vendor/mermaid-ascii/class/parser.d.ts +6 -0
- package/dist/types/vendor/mermaid-ascii/class/types.d.ts +102 -0
- package/dist/types/vendor/mermaid-ascii/er/parser.d.ts +6 -0
- package/dist/types/vendor/mermaid-ascii/er/types.d.ts +76 -0
- package/dist/types/vendor/mermaid-ascii/index.d.ts +1 -0
- package/dist/types/vendor/mermaid-ascii/multiline-utils.d.ts +9 -0
- package/dist/types/vendor/mermaid-ascii/parser.d.ts +7 -0
- package/dist/types/vendor/mermaid-ascii/sequence/parser.d.ts +6 -0
- package/dist/types/vendor/mermaid-ascii/sequence/types.d.ts +130 -0
- package/dist/types/vendor/mermaid-ascii/text-metrics.d.ts +21 -0
- package/dist/types/vendor/mermaid-ascii/types.d.ts +114 -0
- package/dist/types/vendor/mermaid-ascii/xychart/colors.d.ts +25 -0
- package/dist/types/vendor/mermaid-ascii/xychart/parser.d.ts +6 -0
- package/dist/types/vendor/mermaid-ascii/xychart/types.d.ts +145 -0
- package/dist/types/version.d.ts +18 -0
- package/dist/types/vterm/buffer.d.ts +99 -0
- package/dist/types/vterm/terminal.d.ts +44 -0
- package/dist/types/vterm.d.ts +8 -0
- package/dist/types/which.d.ts +37 -0
- package/dist/types/worker-host.d.ts +51 -0
- package/dist/types/xml.d.ts +31 -0
- package/package.json +59 -0
- package/src/abortable.ts +109 -0
- package/src/acp/connection.ts +344 -0
- package/src/acp/protocol.ts +466 -0
- package/src/acp/schema.ts +160 -0
- package/src/acp/stream.ts +82 -0
- package/src/acp/transport.ts +213 -0
- package/src/acp.ts +6 -0
- package/src/async.ts +91 -0
- package/src/binary.ts +50 -0
- package/src/browsers.ts +501 -0
- package/src/chalk.ts +312 -0
- package/src/cli.ts +529 -0
- package/src/color.ts +302 -0
- package/src/dates.ts +194 -0
- package/src/dirs.ts +1026 -0
- package/src/docx/converter.ts +681 -0
- package/src/docx/xml.ts +166 -0
- package/src/docx/zip.ts +87 -0
- package/src/docx.ts +20 -0
- package/src/dom/core.ts +1254 -0
- package/src/dom/parser.ts +370 -0
- package/src/dom/selector.ts +290 -0
- package/src/dom.ts +33 -0
- package/src/env.ts +400 -0
- package/src/fetch-retry.ts +379 -0
- package/src/file-lock.ts +69 -0
- package/src/format.ts +113 -0
- package/src/frontmatter.ts +205 -0
- package/src/fs-error.ts +56 -0
- package/src/glob.ts +189 -0
- package/src/headers.ts +167 -0
- package/src/index.ts +59 -0
- package/src/json-parse.ts +821 -0
- package/src/json.ts +23 -0
- package/src/logger/rotating-file.ts +149 -0
- package/src/logger.ts +798 -0
- package/src/loop-phase.ts +49 -0
- package/src/lru.ts +185 -0
- package/src/marked/core.ts +1576 -0
- package/src/marked.ts +2 -0
- package/src/mermaid-ascii.ts +31 -0
- package/src/mime.ts +159 -0
- package/src/module-timer.ts +148 -0
- package/src/path-tree.ts +147 -0
- package/src/path.ts +28 -0
- package/src/peek-file.ts +188 -0
- package/src/postmortem.ts +433 -0
- package/src/process-name.ts +57 -0
- package/src/procmgr.ts +247 -0
- package/src/prompt.ts +545 -0
- package/src/ptree.ts +412 -0
- package/src/readability/readability.ts +533 -0
- package/src/readability/readerable.ts +51 -0
- package/src/readability/types.ts +72 -0
- package/src/readability.ts +11 -0
- package/src/ring.ts +169 -0
- package/src/runtime-install.ts +393 -0
- package/src/sanitize-text.ts +96 -0
- package/src/snowflake.ts +121 -0
- package/src/stderr-guard.ts +155 -0
- package/src/stream.ts +454 -0
- package/src/tab-spacing.ts +336 -0
- package/src/temp.ts +134 -0
- package/src/template.ts +586 -0
- package/src/timing-buffer.ts +47 -0
- package/src/tls-fetch.ts +178 -0
- package/src/turndown/gfm.ts +106 -0
- package/src/turndown/html.ts +257 -0
- package/src/turndown/service.ts +334 -0
- package/src/turndown/types.ts +81 -0
- package/src/turndown.ts +5 -0
- package/src/type-guards.ts +17 -0
- package/src/vendor/mermaid-ascii/NOTICE +33 -0
- package/src/vendor/mermaid-ascii/ascii/ansi.ts +409 -0
- package/src/vendor/mermaid-ascii/ascii/canvas.ts +476 -0
- package/src/vendor/mermaid-ascii/ascii/class-diagram.ts +699 -0
- package/src/vendor/mermaid-ascii/ascii/converter.ts +271 -0
- package/src/vendor/mermaid-ascii/ascii/draw.ts +1382 -0
- package/src/vendor/mermaid-ascii/ascii/edge-bundling.ts +328 -0
- package/src/vendor/mermaid-ascii/ascii/edge-routing.ts +297 -0
- package/src/vendor/mermaid-ascii/ascii/er-diagram.ts +441 -0
- package/src/vendor/mermaid-ascii/ascii/grid.ts +578 -0
- package/src/vendor/mermaid-ascii/ascii/index.ts +187 -0
- package/src/vendor/mermaid-ascii/ascii/multiline-utils.ts +78 -0
- package/src/vendor/mermaid-ascii/ascii/pathfinder.ts +277 -0
- package/src/vendor/mermaid-ascii/ascii/sequence.ts +460 -0
- package/src/vendor/mermaid-ascii/ascii/shapes/circle.ts +27 -0
- package/src/vendor/mermaid-ascii/ascii/shapes/corners.ts +127 -0
- package/src/vendor/mermaid-ascii/ascii/shapes/diamond.ts +27 -0
- package/src/vendor/mermaid-ascii/ascii/shapes/hexagon.ts +27 -0
- package/src/vendor/mermaid-ascii/ascii/shapes/index.ts +101 -0
- package/src/vendor/mermaid-ascii/ascii/shapes/rectangle.ts +175 -0
- package/src/vendor/mermaid-ascii/ascii/shapes/rounded.ts +27 -0
- package/src/vendor/mermaid-ascii/ascii/shapes/special.ts +296 -0
- package/src/vendor/mermaid-ascii/ascii/shapes/stadium.ts +114 -0
- package/src/vendor/mermaid-ascii/ascii/shapes/state.ts +192 -0
- package/src/vendor/mermaid-ascii/ascii/shapes/types.ts +73 -0
- package/src/vendor/mermaid-ascii/ascii/types.ts +273 -0
- package/src/vendor/mermaid-ascii/ascii/validate.ts +120 -0
- package/src/vendor/mermaid-ascii/ascii/xychart.ts +875 -0
- package/src/vendor/mermaid-ascii/class/parser.ts +290 -0
- package/src/vendor/mermaid-ascii/class/types.ts +121 -0
- package/src/vendor/mermaid-ascii/er/parser.ts +181 -0
- package/src/vendor/mermaid-ascii/er/types.ts +91 -0
- package/src/vendor/mermaid-ascii/index.ts +14 -0
- package/src/vendor/mermaid-ascii/multiline-utils.ts +30 -0
- package/src/vendor/mermaid-ascii/parser.ts +645 -0
- package/src/vendor/mermaid-ascii/sequence/parser.ts +207 -0
- package/src/vendor/mermaid-ascii/sequence/types.ts +146 -0
- package/src/vendor/mermaid-ascii/text-metrics.ts +71 -0
- package/src/vendor/mermaid-ascii/types.ts +164 -0
- package/src/vendor/mermaid-ascii/xychart/colors.ts +140 -0
- package/src/vendor/mermaid-ascii/xychart/parser.ts +115 -0
- package/src/vendor/mermaid-ascii/xychart/types.ts +150 -0
- package/src/version.ts +99 -0
- package/src/vterm/buffer.ts +218 -0
- package/src/vterm/terminal.ts +773 -0
- package/src/vterm.ts +8 -0
- package/src/which.ts +234 -0
- package/src/worker-host.ts +100 -0
- package/src/xml.ts +313 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live event-loop phase breadcrumb. Hot synchronous paths push a short label
|
|
3
|
+
* before running and pop it after (via `try`/`finally`); the loop watchdog
|
|
4
|
+
* reads {@link takeRecentLoopPhase} when it detects a block, so a stall is
|
|
5
|
+
* logged with the work that caused it instead of an opaque "unknown".
|
|
6
|
+
*
|
|
7
|
+
* This is deliberately a process-global stack and not part of the logger span
|
|
8
|
+
* machinery: `main.ts` ends timing spans before the interactive TUI starts, so
|
|
9
|
+
* `logger.openSpanPath()` is empty in a live session.
|
|
10
|
+
*
|
|
11
|
+
* Correctness constraint: each `pushLoopPhase` must be balanced by a
|
|
12
|
+
* `popLoopPhase` within the SAME synchronous execution (always via `try`/
|
|
13
|
+
* `finally`). The stack is global and shared, so a label held across an
|
|
14
|
+
* `await`/async boundary — or interleaved between concurrent tasks — would
|
|
15
|
+
* misattribute or leak phases. Instrument only synchronous spans; for async
|
|
16
|
+
* work, push/pop around each synchronous chunk, not across the await.
|
|
17
|
+
*/
|
|
18
|
+
const stack: string[] = [];
|
|
19
|
+
// The most recent label pushed, retained after it is popped. A hot path pushes
|
|
20
|
+
// and pops a phase entirely within one synchronous macrotask, so by the time
|
|
21
|
+
// the watchdog's delayed tick runs the stack is already empty; this slot keeps
|
|
22
|
+
// the culprit available for that one tick. Consumed (cleared) on read so it
|
|
23
|
+
// only attributes the just-elapsed interval.
|
|
24
|
+
let recentPhase: string | undefined;
|
|
25
|
+
|
|
26
|
+
export function pushLoopPhase(label: string): void {
|
|
27
|
+
stack.push(label);
|
|
28
|
+
recentPhase = label;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function popLoopPhase(): void {
|
|
32
|
+
stack.pop();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function currentLoopPhase(): string | undefined {
|
|
36
|
+
return stack[stack.length - 1];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Phase to blame for a just-detected loop block: the live top phase if one is
|
|
41
|
+
* still held, else the most recent phase pushed since the last call. Clears the
|
|
42
|
+
* recent slot so a block in a later, phase-less interval is not misattributed
|
|
43
|
+
* to a phase that already finished.
|
|
44
|
+
*/
|
|
45
|
+
export function takeRecentLoopPhase(): string | undefined {
|
|
46
|
+
const phase = stack[stack.length - 1] ?? recentPhase;
|
|
47
|
+
recentPhase = undefined;
|
|
48
|
+
return phase;
|
|
49
|
+
}
|
package/src/lru.ts
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/** Behavior-compatible reimplementation of lru-cache's used surface. */
|
|
2
|
+
|
|
3
|
+
/** Why an entry left the cache. */
|
|
4
|
+
export type DisposeReason = "evict" | "set" | "delete" | "expire";
|
|
5
|
+
|
|
6
|
+
/** Options supported by {@link LRUCache}. */
|
|
7
|
+
export interface LRUCacheOptions<K, V> {
|
|
8
|
+
/** Maximum number of retained entries. */
|
|
9
|
+
max?: number;
|
|
10
|
+
/** Maximum aggregate calculated size. */
|
|
11
|
+
maxSize?: number;
|
|
12
|
+
/** Maximum calculated size of one entry. */
|
|
13
|
+
maxEntrySize?: number;
|
|
14
|
+
/** Calculates an entry's size. */
|
|
15
|
+
sizeCalculation?: (value: V, key: K) => number;
|
|
16
|
+
/** Entry lifetime in milliseconds; zero disables expiry. */
|
|
17
|
+
ttl?: number;
|
|
18
|
+
/** Refreshes an entry's lifetime when it is read. */
|
|
19
|
+
updateAgeOnGet?: boolean;
|
|
20
|
+
/** Called synchronously before an entry is removed. */
|
|
21
|
+
dispose?: (value: V, key: K, reason: DisposeReason) => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface Entry<V> {
|
|
25
|
+
value: V;
|
|
26
|
+
size: number;
|
|
27
|
+
start: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function positiveInteger(value: number | undefined, name: string): number {
|
|
31
|
+
if (value === undefined) return 0;
|
|
32
|
+
if (!Number.isInteger(value) || value < 0) throw new TypeError(`${name} must be a non-negative integer`);
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** A bounded least-recently-used cache with optional size and lifetime limits. */
|
|
37
|
+
export class LRUCache<K, V> {
|
|
38
|
+
readonly #entries = new Map<K, Entry<V>>();
|
|
39
|
+
readonly #max: number;
|
|
40
|
+
readonly #maxSize: number;
|
|
41
|
+
readonly #maxEntrySize: number;
|
|
42
|
+
readonly #sizeCalculation: ((value: V, key: K) => number) | undefined;
|
|
43
|
+
readonly #ttl: number;
|
|
44
|
+
readonly #updateAgeOnGet: boolean;
|
|
45
|
+
readonly #dispose: ((value: V, key: K, reason: DisposeReason) => void) | undefined;
|
|
46
|
+
#calculatedSize = 0;
|
|
47
|
+
|
|
48
|
+
/** Creates an empty cache. */
|
|
49
|
+
constructor(options: LRUCacheOptions<K, V>) {
|
|
50
|
+
this.#max = positiveInteger(options.max, "max");
|
|
51
|
+
this.#maxSize = positiveInteger(options.maxSize, "maxSize");
|
|
52
|
+
const explicitMaxEntrySize = positiveInteger(options.maxEntrySize, "maxEntrySize");
|
|
53
|
+
this.#maxEntrySize = explicitMaxEntrySize || this.#maxSize;
|
|
54
|
+
this.#ttl = positiveInteger(options.ttl, "ttl");
|
|
55
|
+
if (this.#max === 0 && this.#maxSize === 0 && this.#ttl === 0) {
|
|
56
|
+
throw new TypeError("At least one of max, maxSize, or ttl is required");
|
|
57
|
+
}
|
|
58
|
+
if ((this.#maxSize !== 0 || this.#maxEntrySize !== 0) && options.sizeCalculation === undefined) {
|
|
59
|
+
throw new TypeError("sizeCalculation is required when a size limit is set");
|
|
60
|
+
}
|
|
61
|
+
this.#sizeCalculation = options.sizeCalculation;
|
|
62
|
+
this.#updateAgeOnGet = options.updateAgeOnGet === true;
|
|
63
|
+
this.#dispose = options.dispose;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Number of entries, including stale entries not yet removed by `get`. */
|
|
67
|
+
get size(): number {
|
|
68
|
+
return this.#entries.size;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Aggregate calculated size of retained entries. */
|
|
72
|
+
get calculatedSize(): number {
|
|
73
|
+
return this.#calculatedSize;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Stores a value and makes it most recently used. */
|
|
77
|
+
set(key: K, value: V | undefined): this {
|
|
78
|
+
if (value === undefined) {
|
|
79
|
+
this.delete(key);
|
|
80
|
+
return this;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const size = this.#entrySize(value, key);
|
|
84
|
+
const previous = this.#entries.get(key);
|
|
85
|
+
if (this.#maxEntrySize !== 0 && size > this.#maxEntrySize) {
|
|
86
|
+
if (previous !== undefined) this.#remove(key, previous, "set");
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (previous !== undefined) {
|
|
91
|
+
if (previous.value !== value) this.#dispose?.(previous.value, key, "set");
|
|
92
|
+
this.#calculatedSize -= previous.size;
|
|
93
|
+
this.#entries.delete(key);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
while (
|
|
97
|
+
(this.#max !== 0 && this.#entries.size >= this.#max) ||
|
|
98
|
+
(this.#maxSize !== 0 && this.#calculatedSize + size > this.#maxSize)
|
|
99
|
+
) {
|
|
100
|
+
const oldest = this.#entries.entries().next().value as [K, Entry<V>] | undefined;
|
|
101
|
+
if (oldest === undefined) break;
|
|
102
|
+
this.#remove(oldest[0], oldest[1], "evict");
|
|
103
|
+
}
|
|
104
|
+
this.#entries.set(key, { value, size, start: this.#ttl === 0 ? 0 : performance.now() });
|
|
105
|
+
this.#calculatedSize += size;
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Returns a value and makes a fresh entry most recently used. */
|
|
110
|
+
get(key: K): V | undefined {
|
|
111
|
+
const entry = this.#entries.get(key);
|
|
112
|
+
if (entry === undefined) return undefined;
|
|
113
|
+
if (this.#isStale(entry)) {
|
|
114
|
+
this.#remove(key, entry, "expire");
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
if (this.#updateAgeOnGet && this.#ttl !== 0) entry.start = performance.now();
|
|
118
|
+
this.#entries.delete(key);
|
|
119
|
+
this.#entries.set(key, entry);
|
|
120
|
+
return entry.value;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Reports whether a fresh value is present without changing recency. */
|
|
124
|
+
has(key: K): boolean {
|
|
125
|
+
const entry = this.#entries.get(key);
|
|
126
|
+
return entry !== undefined && !this.#isStale(entry);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Returns a fresh value without changing recency or removing stale data. */
|
|
130
|
+
peek(key: K): V | undefined {
|
|
131
|
+
const entry = this.#entries.get(key);
|
|
132
|
+
return entry === undefined || this.#isStale(entry) ? undefined : entry.value;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Removes a value, returning whether one was present. */
|
|
136
|
+
delete(key: K): boolean {
|
|
137
|
+
const entry = this.#entries.get(key);
|
|
138
|
+
if (entry === undefined) return false;
|
|
139
|
+
this.#remove(key, entry, "delete");
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Removes every value from least to most recently used. */
|
|
144
|
+
clear(): void {
|
|
145
|
+
for (const [key, entry] of this.#entries) this.#dispose?.(entry.value, key, "delete");
|
|
146
|
+
this.#entries.clear();
|
|
147
|
+
this.#calculatedSize = 0;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Iterates fresh keys from most to least recently used. */
|
|
151
|
+
*keys(): Generator<K, void, unknown> {
|
|
152
|
+
const entries = [...this.#entries.entries()];
|
|
153
|
+
for (let index = entries.length - 1; index >= 0; index--) {
|
|
154
|
+
const [key, entry] = entries[index]!;
|
|
155
|
+
if (!this.#isStale(entry)) yield key;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Iterates fresh values from most to least recently used. */
|
|
160
|
+
*values(): Generator<V, void, unknown> {
|
|
161
|
+
const entries = [...this.#entries.values()];
|
|
162
|
+
for (let index = entries.length - 1; index >= 0; index--) {
|
|
163
|
+
const entry = entries[index]!;
|
|
164
|
+
if (!this.#isStale(entry)) yield entry.value;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
#entrySize(value: V, key: K): number {
|
|
169
|
+
if (this.#sizeCalculation === undefined) return 0;
|
|
170
|
+
const size = this.#sizeCalculation(value, key);
|
|
171
|
+
if (!Number.isInteger(size) || size <= 0)
|
|
172
|
+
throw new TypeError("sizeCalculation return invalid (expect positive integer)");
|
|
173
|
+
return size;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
#isStale(entry: Entry<V>): boolean {
|
|
177
|
+
return this.#ttl !== 0 && performance.now() - entry.start > this.#ttl;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
#remove(key: K, entry: Entry<V>, reason: DisposeReason): void {
|
|
181
|
+
this.#dispose?.(entry.value, key, reason);
|
|
182
|
+
this.#entries.delete(key);
|
|
183
|
+
this.#calculatedSize -= entry.size;
|
|
184
|
+
}
|
|
185
|
+
}
|