main
js 132 lines 2.66 KB
Raw
1 let enabledGlobal = true;
2
3 /** @type {Map<string, boolean>} */
4 const enabledAreas = new Map();
5
6 /** @type {Map<string, Map<string, any>>} */
7 const cache = new Map();
8
9 export function toggle_global(enabled) {
10 enabledGlobal = !!enabled;
11 }
12
13 export function toggle_area(area, enabled) {
14 enabledAreas.set(area, !!enabled);
15 }
16
17 export function has(area, key) {
18 if (!isEnabled(area)) return false;
19 const areaCache = cache.get(area);
20 if (!areaCache) return false;
21 return areaCache.has(key);
22 }
23
24 export function add(area, key, data) {
25 if (!isEnabled(area)) return;
26 let areaCache = cache.get(area);
27 if (!areaCache) {
28 areaCache = new Map();
29 cache.set(area, areaCache);
30 }
31 areaCache.set(key, data);
32 }
33
34 export function get(area, key, defaultValue = null) {
35 if (!isEnabled(area)) return defaultValue;
36 const areaCache = cache.get(area);
37 if (!areaCache) return defaultValue;
38 return areaCache.has(key) ? areaCache.get(key) : defaultValue;
39 }
40
41 export function remove(area, key) {
42 if (!isEnabled(area)) return;
43 const areaCache = cache.get(area);
44 if (!areaCache) return;
45 areaCache.delete(key);
46 }
47
48 export function clear(area) {
49 if (hasGlob(area)) {
50 const re = globToRegExp(area);
51 for (const k of cache.keys()) {
52 if (re.test(k)) cache.delete(k);
53 }
54 return;
55 }
56 cache.delete(area);
57 }
58
59 export function clear_all() {
60 cache.clear();
61 }
62
63 function isEnabled(area) {
64 if (!enabledGlobal) return false;
65 const v = enabledAreas.get(area);
66 return v === undefined ? true : v;
67 }
68
69 function hasGlob(pattern) {
70 return /[\*\?\[]/.test(pattern);
71 }
72
73 function escapeRegExpChar(ch) {
74 return /[\\^$.*+?()[\]{}|]/.test(ch) ? `\\${ch}` : ch;
75 }
76
77 function globToRegExp(glob) {
78 let out = "^";
79 for (let i = 0; i < glob.length; i++) {
80 const ch = glob[i];
81
82 if (ch === "*") {
83 out += ".*";
84 continue;
85 }
86
87 if (ch === "?") {
88 out += ".";
89 continue;
90 }
91
92 if (ch === "[") {
93 const end = glob.indexOf("]", i + 1);
94 if (end === -1) {
95 out += "\\[";
96 continue;
97 }
98
99 const content = glob.slice(i + 1, end);
100 let cls = "";
101 let j = 0;
102 if (content[0] === "!" || content[0] === "^") {
103 cls += "^";
104 j++;
105 }
106 for (; j < content.length; j++) {
107 const c = content[j];
108 if (c === "\\") {
109 cls += "\\\\";
110 continue;
111 }
112 if (c === "]") {
113 cls += "\\]";
114 continue;
115 }
116 if (c === "-") {
117 cls += "-";
118 continue;
119 }
120 cls += escapeRegExpChar(c);
121 }
122
123 out += `[${cls}]`;
124 i = end;
125 continue;
126 }
127
128 out += escapeRegExpChar(ch);
129 }
130 out += "$";
131 return new RegExp(out);
132 }