UNPKG

2.19 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const createHash = require("../util/createHash");
9
10/** @typedef {import("../util/Hash")} Hash */
11/** @typedef {typeof import("../util/Hash")} HashConstructor */
12
13/**
14 * @typedef {Object} HashableObject
15 * @property {function(Hash): void} updateHash
16 */
17
18class LazyHashedEtag {
19 /**
20 * @param {HashableObject} obj object with updateHash method
21 * @param {string | HashConstructor} hashFunction the hash function to use
22 */
23 constructor(obj, hashFunction = "md4") {
24 this._obj = obj;
25 this._hash = undefined;
26 this._hashFunction = hashFunction;
27 }
28
29 /**
30 * @returns {string} hash of object
31 */
32 toString() {
33 if (this._hash === undefined) {
34 const hash = createHash(this._hashFunction);
35 this._obj.updateHash(hash);
36 this._hash = /** @type {string} */ (hash.digest("base64"));
37 }
38 return this._hash;
39 }
40}
41
42/** @type {Map<string | HashConstructor, WeakMap<HashableObject, LazyHashedEtag>>} */
43const mapStrings = new Map();
44
45/** @type {WeakMap<HashConstructor, WeakMap<HashableObject, LazyHashedEtag>>} */
46const mapObjects = new WeakMap();
47
48/**
49 * @param {HashableObject} obj object with updateHash method
50 * @param {string | HashConstructor} hashFunction the hash function to use
51 * @returns {LazyHashedEtag} etag
52 */
53const getter = (obj, hashFunction = "md4") => {
54 let innerMap;
55 if (typeof hashFunction === "string") {
56 innerMap = mapStrings.get(hashFunction);
57 if (innerMap === undefined) {
58 const newHash = new LazyHashedEtag(obj, hashFunction);
59 innerMap = new WeakMap();
60 innerMap.set(obj, newHash);
61 mapStrings.set(hashFunction, innerMap);
62 return newHash;
63 }
64 } else {
65 innerMap = mapObjects.get(hashFunction);
66 if (innerMap === undefined) {
67 const newHash = new LazyHashedEtag(obj, hashFunction);
68 innerMap = new WeakMap();
69 innerMap.set(obj, newHash);
70 mapObjects.set(hashFunction, innerMap);
71 return newHash;
72 }
73 }
74 const hash = innerMap.get(obj);
75 if (hash !== undefined) return hash;
76 const newHash = new LazyHashedEtag(obj, hashFunction);
77 innerMap.set(obj, newHash);
78 return newHash;
79};
80
81module.exports = getter;