PageSourceSearch

https://nstatus.org/noice/js/util.js

js nstatus.org collected 2026-09-24 14:30:30 UTC 3,169 bytes, 100 lines download raw bytes

1export class Semaphore {
2    constructor(initialPermits = 1) {
3        this.permits = initialPermits;
4        this.queue = [];
5    }
6
7    async acquire() {
8        return new Promise((resolve) => {
9            if (this.permits > 0) {
10                this.permits--;
11                resolve();
12            } else {
13                this.queue.push(resolve);
14            }
15        });
16    }
17
18    release() {
19        if (this.queue.length > 0) {
20            const resolve = this.queue.shift();
21            resolve();
22        } else {
23            this.permits++;
24        }
25    }
26}
27
28export class MovingByteRate {
29    constructor(windowSize = 1) {
30        this.windowSize = windowSize * 5000; // Window size in milliseconds
31        this.bytes = []; // Stores timestamps and byte counts for window
32    }
33
34    addBytes(bytes) {
35        this.bytes.push({ timestamp: Date.now(), bytes });
36    }
37
38    getByteRate() {
39        const now = Date.now();
40        this.bytes = this.bytes.filter(entry => now - entry.timestamp <= this.windowSize); // Filter out old entries
41
42        const totalBytes = this.bytes.reduce((sum, entry) => sum + entry.bytes, 0);
43        const elapsedTime = Math.min(this.windowSize, now - this.bytes[0]?.timestamp || 0); // Consider window limit or actual time
44        return totalBytes / (elapsedTime / 1000); // Average in bytes/second
45    }
46}
47
48
49export class Utility {
50    /**
51     * Format bytes as human-readable text.
52     * 
53     * @param bytes Number of bytes.
54     * @param si True to use metric (SI) units, aka powers of 1000. False to use 
55     *           binary (IEC), aka powers of 1024.
56     * @param dp Number of decimal places to display.
57     * 
58     * @return Formatted string.
59     */
60    static humanFileSize(bytes, si = false, dp = 1) {
61        const thresh = si ? 1000 : 1024;
62
63        if (Math.abs(bytes) < thresh) {
64            return bytes + ' B';
65        }
66
67        const units = si
68            ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
69            : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
70        let u = -1;
71        const r = 10 ** dp;
72
73        do {
74            bytes /= thresh;
75            ++u;
76        } while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1);
77
78
79        return bytes.toFixed(dp) + ' ' + units[u];
80    }
81
82    static sleep(ms) {
83        return new Promise(resolve => setTimeout(resolve, ms));
84    }
85
86    static appendUint8Array(accumulationBuffer, dataToAppend) {
87        // Create a new Uint8Array with sufficient capacity to hold both arrays
88        const newBuffer = new Uint8Array(accumulationBuffer.byteLength + dataToAppend.byteLength);
89
90        // Copy the existing accumulation buffer into the new buffer
91        newBuffer.set(accumulationBuffer);
92
93        // Copy the new data to append into the new buffer, starting at the offset where the accumulation buffer ends
94        newBuffer.set(dataToAppend, accumulationBuffer.byteLength);
95
96        // Return the new combined buffer, which becomes the new accumulation buffer
97        return newBuffer;
98    }
99}
100

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.