Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | 3x 3x 168x 168x 168x 168x 168x 32x 32x 32x 136x 136x 136x 2x 2x 126x 5x 55x | import type { EncodeOptions, QRMatrix } from "./types";
import { encodeQR } from "./encode/encodeQR";
/**
* A small LRU in front of the encoder.
*
* Encoding is fast, but a React tree re-renders for reasons that have nothing
* to do with the QR code, and a component that re-encodes on every parent
* render allocates a fresh matrix each time for no benefit. Keying on the
* encode inputs makes repeat renders of the same value free.
*
* Only *encoding* is cached. Styling is not: it changes far more often (theme
* toggles, hover states) and is cheap to redo, so caching it would evict
* useful entries to store nothing of value.
*/
const CAPACITY = 32;
const cache = new Map<string, QRMatrix>();
function cacheKey(data: string | Uint8Array, options: EncodeOptions): string {
const payload =
typeof data === "string" ? `s${data}` : `b${Array.prototype.join.call(data, ",")}`;
return [
options.level ?? "M",
options.version ?? "",
options.minVersion ?? "",
options.mask ?? "",
options.eci === false ? "0" : "1",
payload,
].join(" ");
}
/**
* {@link encodeQR}, memoized on its inputs.
*
* Failures are never cached: a `QRCapacityError` is cheap to reproduce, and
* storing one would waste a slot that a working code could use.
*/
export function encodeCached(data: string | Uint8Array, options: EncodeOptions = {}): QRMatrix {
const key = cacheKey(data, options);
const hit = cache.get(key);
if (hit) {
// Refresh recency: delete + set moves the entry to the end of the Map.
cache.delete(key);
cache.set(key, hit);
return hit;
}
const matrix = encodeQR(data, options);
cache.set(key, matrix);
if (cache.size > CAPACITY) {
const oldest = cache.keys().next();
Eif (!oldest.done) cache.delete(oldest.value);
}
return matrix;
}
/** Number of cached symbols. Testing seam. */
export function cacheSize(): number {
return cache.size;
}
/** Empty the cache. Testing seam. */
export function clearCache(): void {
cache.clear();
}
|