@ztimson/utils 0.27.9 → 0.27.11
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/dist/cache.d.ts +11 -52
- package/dist/index.cjs +182 -107
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +182 -107
- package/dist/index.mjs.map +1 -1
- package/dist/path-events.d.ts +37 -10
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -182,6 +182,9 @@ function clean(obj, undefinedOnly = false) {
|
|
|
182
182
|
return obj;
|
|
183
183
|
}
|
|
184
184
|
function deepCopy(value) {
|
|
185
|
+
if (value == null) return value;
|
|
186
|
+
const t = typeof value;
|
|
187
|
+
if (t === "string" || t === "number" || t === "boolean" || t === "function") return value;
|
|
185
188
|
try {
|
|
186
189
|
return structuredClone(value);
|
|
187
190
|
} catch {
|
|
@@ -463,10 +466,7 @@ class Cache {
|
|
|
463
466
|
__publicField(this, "complete", false);
|
|
464
467
|
/** Await initial loading */
|
|
465
468
|
__publicField(this, "loading", new Promise((r) => this._loading = r));
|
|
466
|
-
/**
|
|
467
|
-
* Get all cached items
|
|
468
|
-
* @return {T[]} Array of items
|
|
469
|
-
*/
|
|
469
|
+
/** Get all cached items */
|
|
470
470
|
__publicField(this, "values", this.all);
|
|
471
471
|
var _a, _b, _c, _d;
|
|
472
472
|
this.key = key;
|
|
@@ -514,6 +514,7 @@ class Cache {
|
|
|
514
514
|
if (value[this.key] === void 0) throw new Error(`${this.key.toString()} Doesn't exist on ${JSON.stringify(value, null, 2)}`);
|
|
515
515
|
return value[this.key];
|
|
516
516
|
}
|
|
517
|
+
/** Save item to storage */
|
|
517
518
|
save(key) {
|
|
518
519
|
var _a, _b;
|
|
519
520
|
const persists = this.options.persistentStorage;
|
|
@@ -567,9 +568,6 @@ class Cache {
|
|
|
567
568
|
}
|
|
568
569
|
/**
|
|
569
570
|
* Add a new item to the cache. Like set, but finds key automatically
|
|
570
|
-
* @param {T} value Item to add to cache
|
|
571
|
-
* @param {number | undefined} ttl Override default expiry
|
|
572
|
-
* @return {this}
|
|
573
571
|
*/
|
|
574
572
|
add(value, ttl = this.ttl) {
|
|
575
573
|
const key = this.getKey(value);
|
|
@@ -578,9 +576,6 @@ class Cache {
|
|
|
578
576
|
}
|
|
579
577
|
/**
|
|
580
578
|
* Add several rows to the cache
|
|
581
|
-
* @param {T[]} rows Several items that will be cached using the default key
|
|
582
|
-
* @param complete Mark cache as complete & reliable, defaults to true
|
|
583
|
-
* @return {this}
|
|
584
579
|
*/
|
|
585
580
|
addAll(rows, complete = true) {
|
|
586
581
|
this.clear();
|
|
@@ -588,9 +583,7 @@ class Cache {
|
|
|
588
583
|
this.complete = complete;
|
|
589
584
|
return this;
|
|
590
585
|
}
|
|
591
|
-
/**
|
|
592
|
-
* Remove all keys from cache
|
|
593
|
-
*/
|
|
586
|
+
/** Remove all keys */
|
|
594
587
|
clear() {
|
|
595
588
|
this.complete = false;
|
|
596
589
|
for (const [k, t] of this.timers) clearTimeout(t);
|
|
@@ -600,10 +593,7 @@ class Cache {
|
|
|
600
593
|
this.save();
|
|
601
594
|
return this;
|
|
602
595
|
}
|
|
603
|
-
/**
|
|
604
|
-
* Delete an item from the cache
|
|
605
|
-
* @param {K} key Item's primary key
|
|
606
|
-
*/
|
|
596
|
+
/** Delete a cached item */
|
|
607
597
|
delete(key) {
|
|
608
598
|
this.clearTimer(key);
|
|
609
599
|
const idx = this.lruOrder.indexOf(key);
|
|
@@ -612,10 +602,7 @@ class Cache {
|
|
|
612
602
|
this.save(key);
|
|
613
603
|
return this;
|
|
614
604
|
}
|
|
615
|
-
/**
|
|
616
|
-
* Return cache as an array of key-value pairs
|
|
617
|
-
* @return {[K, T][]} Key-value pairs array
|
|
618
|
-
*/
|
|
605
|
+
/** Return entries as array */
|
|
619
606
|
entries(expired) {
|
|
620
607
|
const out = [];
|
|
621
608
|
for (const [k, v] of this.store.entries()) {
|
|
@@ -624,10 +611,7 @@ class Cache {
|
|
|
624
611
|
}
|
|
625
612
|
return out;
|
|
626
613
|
}
|
|
627
|
-
/**
|
|
628
|
-
* Manually expire a cached item
|
|
629
|
-
* @param {K} key Key to expire
|
|
630
|
-
*/
|
|
614
|
+
/** Manually expire a cached item */
|
|
631
615
|
expire(key) {
|
|
632
616
|
this.complete = false;
|
|
633
617
|
if (this.options.expiryPolicy == "keep") {
|
|
@@ -640,12 +624,7 @@ class Cache {
|
|
|
640
624
|
} else this.delete(key);
|
|
641
625
|
return this;
|
|
642
626
|
}
|
|
643
|
-
/**
|
|
644
|
-
* Find the first cached item to match a filter
|
|
645
|
-
* @param {Partial<T>} filter Partial item to match
|
|
646
|
-
* @param {Boolean} expired Include expired items, defaults to false
|
|
647
|
-
* @returns {T | undefined} Cached item or undefined if nothing matched
|
|
648
|
-
*/
|
|
627
|
+
/** Find first matching item */
|
|
649
628
|
find(filter, expired) {
|
|
650
629
|
for (const v of this.store.values()) {
|
|
651
630
|
const row = v;
|
|
@@ -653,24 +632,16 @@ class Cache {
|
|
|
653
632
|
}
|
|
654
633
|
return void 0;
|
|
655
634
|
}
|
|
656
|
-
/**
|
|
657
|
-
* Get item from the cache
|
|
658
|
-
* @param {K} key Key to lookup
|
|
659
|
-
* @param expired Include expired items
|
|
660
|
-
* @return {T} Cached item
|
|
661
|
-
*/
|
|
635
|
+
/** Get cached item by key */
|
|
662
636
|
get(key, expired) {
|
|
663
637
|
const raw = this.store.get(key);
|
|
664
638
|
if (raw == null) return null;
|
|
665
|
-
const cached = deepCopy(raw);
|
|
666
639
|
this.touchLRU(key);
|
|
667
|
-
|
|
640
|
+
const isExpired = raw == null ? void 0 : raw._expired;
|
|
641
|
+
if (expired || !isExpired) return deepCopy(raw);
|
|
668
642
|
return null;
|
|
669
643
|
}
|
|
670
|
-
/**
|
|
671
|
-
* Get a list of cached keys
|
|
672
|
-
* @return {K[]} Array of keys
|
|
673
|
-
*/
|
|
644
|
+
/** Return list of keys */
|
|
674
645
|
keys(expired) {
|
|
675
646
|
const out = [];
|
|
676
647
|
for (const [k, v] of this.store.entries()) {
|
|
@@ -679,10 +650,7 @@ class Cache {
|
|
|
679
650
|
}
|
|
680
651
|
return out;
|
|
681
652
|
}
|
|
682
|
-
/**
|
|
683
|
-
* Get map of cached items
|
|
684
|
-
* @return {Record<K, T>}
|
|
685
|
-
*/
|
|
653
|
+
/** Return map of key → item */
|
|
686
654
|
map(expired) {
|
|
687
655
|
const copy = {};
|
|
688
656
|
for (const [k, v] of this.store.entries()) {
|
|
@@ -691,13 +659,7 @@ class Cache {
|
|
|
691
659
|
}
|
|
692
660
|
return copy;
|
|
693
661
|
}
|
|
694
|
-
/**
|
|
695
|
-
* Add an item to the cache manually specifying the key
|
|
696
|
-
* @param {K} key Key item will be cached under
|
|
697
|
-
* @param {T} value Item to cache
|
|
698
|
-
* @param {number | undefined} ttl Override default expiry in seconds
|
|
699
|
-
* @return {this}
|
|
700
|
-
*/
|
|
662
|
+
/** Add item manually specifying the key */
|
|
701
663
|
set(key, value, ttl = this.options.ttl) {
|
|
702
664
|
if (this.options.expiryPolicy == "keep") delete value._expired;
|
|
703
665
|
this.clearTimer(key);
|
|
@@ -708,7 +670,7 @@ class Cache {
|
|
|
708
670
|
const t = setTimeout(() => {
|
|
709
671
|
this.expire(key);
|
|
710
672
|
this.save(key);
|
|
711
|
-
},
|
|
673
|
+
}, ttl * 1e3);
|
|
712
674
|
this.timers.set(key, t);
|
|
713
675
|
}
|
|
714
676
|
return this;
|
|
@@ -1953,10 +1915,12 @@ const _PathEvent = class _PathEvent {
|
|
|
1953
1915
|
__publicField(this, "fullPath");
|
|
1954
1916
|
/** Path including the name, excluding the module */
|
|
1955
1917
|
__publicField(this, "path");
|
|
1956
|
-
/** Last
|
|
1918
|
+
/** Last segment of path */
|
|
1957
1919
|
__publicField(this, "name");
|
|
1958
1920
|
/** List of methods */
|
|
1959
1921
|
__publicField(this, "methods");
|
|
1922
|
+
/** Whether this path contains glob patterns */
|
|
1923
|
+
__publicField(this, "hasGlob");
|
|
1960
1924
|
if (typeof e == "object") {
|
|
1961
1925
|
Object.assign(this, e);
|
|
1962
1926
|
return;
|
|
@@ -1965,17 +1929,34 @@ const _PathEvent = class _PathEvent {
|
|
|
1965
1929
|
Object.assign(this, _PathEvent.pathEventCache.get(e));
|
|
1966
1930
|
return;
|
|
1967
1931
|
}
|
|
1968
|
-
let [p,
|
|
1969
|
-
if (!method) method =
|
|
1970
|
-
if (p
|
|
1971
|
-
|
|
1972
|
-
|
|
1932
|
+
let [p, method] = e.replaceAll(/\/{2,}/g, "/").split(":");
|
|
1933
|
+
if (!method) method = "*";
|
|
1934
|
+
if (p === "" || p === void 0) {
|
|
1935
|
+
this.module = "";
|
|
1936
|
+
this.path = "";
|
|
1937
|
+
this.fullPath = "";
|
|
1938
|
+
this.name = "";
|
|
1939
|
+
this.methods = new ASet(["n"]);
|
|
1940
|
+
this.hasGlob = false;
|
|
1941
|
+
_PathEvent.pathEventCache.set(e, this);
|
|
1942
|
+
return;
|
|
1943
|
+
}
|
|
1944
|
+
if (p === "*") {
|
|
1945
|
+
this.module = "";
|
|
1946
|
+
this.path = "";
|
|
1947
|
+
this.fullPath = "**";
|
|
1948
|
+
this.name = "";
|
|
1949
|
+
this.methods = new ASet(["*"]);
|
|
1950
|
+
this.hasGlob = true;
|
|
1951
|
+
_PathEvent.pathEventCache.set(e, this);
|
|
1952
|
+
return;
|
|
1973
1953
|
}
|
|
1974
1954
|
let temp = p.split("/").filter((p2) => !!p2);
|
|
1975
1955
|
this.module = temp.splice(0, 1)[0] || "";
|
|
1976
1956
|
this.path = temp.join("/");
|
|
1977
1957
|
this.fullPath = `${this.module}${this.module && this.path ? "/" : ""}${this.path}`;
|
|
1978
1958
|
this.name = temp.pop() || "";
|
|
1959
|
+
this.hasGlob = this.fullPath.includes("*");
|
|
1979
1960
|
this.methods = new ASet(method.split(""));
|
|
1980
1961
|
_PathEvent.pathEventCache.set(e, this);
|
|
1981
1962
|
}
|
|
@@ -2000,6 +1981,13 @@ const _PathEvent = class _PathEvent {
|
|
|
2000
1981
|
set create(v) {
|
|
2001
1982
|
v ? this.methods.delete("n").delete("*").add("c") : this.methods.delete("c");
|
|
2002
1983
|
}
|
|
1984
|
+
/** Execute method specified */
|
|
1985
|
+
get execute() {
|
|
1986
|
+
return !this.methods.has("n") && (this.methods.has("*") || this.methods.has("x"));
|
|
1987
|
+
}
|
|
1988
|
+
set execute(v) {
|
|
1989
|
+
v ? this.methods.delete("n").delete("*").add("x") : this.methods.delete("x");
|
|
1990
|
+
}
|
|
2003
1991
|
/** Read method specified */
|
|
2004
1992
|
get read() {
|
|
2005
1993
|
return !this.methods.has("n") && (this.methods.has("*") || this.methods.has("r"));
|
|
@@ -2025,6 +2013,64 @@ const _PathEvent = class _PathEvent {
|
|
|
2025
2013
|
static clearCache() {
|
|
2026
2014
|
_PathEvent.pathEventCache.clear();
|
|
2027
2015
|
}
|
|
2016
|
+
/** Clear the permission cache */
|
|
2017
|
+
static clearPermissionCache() {
|
|
2018
|
+
_PathEvent.permissionCache.clear();
|
|
2019
|
+
}
|
|
2020
|
+
/**
|
|
2021
|
+
* Score a path for specificity ranking (lower = more specific = higher priority)
|
|
2022
|
+
* @private
|
|
2023
|
+
*/
|
|
2024
|
+
static scoreSpecificity(path) {
|
|
2025
|
+
if (path === "**" || path === "") return Number.MAX_SAFE_INTEGER;
|
|
2026
|
+
const segments = path.split("/").filter((p) => !!p);
|
|
2027
|
+
let score = -segments.length;
|
|
2028
|
+
segments.forEach((seg) => {
|
|
2029
|
+
if (seg === "**") score += 0.5;
|
|
2030
|
+
else if (seg === "*") score += 0.25;
|
|
2031
|
+
});
|
|
2032
|
+
return score;
|
|
2033
|
+
}
|
|
2034
|
+
/**
|
|
2035
|
+
* Check if a path matches a glob pattern
|
|
2036
|
+
* @private
|
|
2037
|
+
*/
|
|
2038
|
+
static pathMatchesGlob(path, pattern) {
|
|
2039
|
+
if (pattern === path) return true;
|
|
2040
|
+
const pathParts = path.split("/").filter((p) => !!p);
|
|
2041
|
+
const patternParts = pattern.split("/").filter((p) => !!p);
|
|
2042
|
+
let pathIdx = 0;
|
|
2043
|
+
let patternIdx = 0;
|
|
2044
|
+
while (patternIdx < patternParts.length && pathIdx < pathParts.length) {
|
|
2045
|
+
const patternPart = patternParts[patternIdx];
|
|
2046
|
+
if (patternPart === "**") {
|
|
2047
|
+
if (patternIdx === patternParts.length - 1) {
|
|
2048
|
+
return true;
|
|
2049
|
+
}
|
|
2050
|
+
patternParts[patternIdx + 1];
|
|
2051
|
+
while (pathIdx < pathParts.length) {
|
|
2052
|
+
if (_PathEvent.pathMatchesGlob(pathParts.slice(pathIdx).join("/"), patternParts.slice(patternIdx + 1).join("/"))) {
|
|
2053
|
+
return true;
|
|
2054
|
+
}
|
|
2055
|
+
pathIdx++;
|
|
2056
|
+
}
|
|
2057
|
+
return false;
|
|
2058
|
+
} else if (patternPart === "*") {
|
|
2059
|
+
pathIdx++;
|
|
2060
|
+
patternIdx++;
|
|
2061
|
+
} else {
|
|
2062
|
+
if (patternPart !== pathParts[pathIdx]) {
|
|
2063
|
+
return false;
|
|
2064
|
+
}
|
|
2065
|
+
pathIdx++;
|
|
2066
|
+
patternIdx++;
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
if (patternIdx < patternParts.length) {
|
|
2070
|
+
return patternParts.slice(patternIdx).every((p) => p === "**");
|
|
2071
|
+
}
|
|
2072
|
+
return pathIdx === pathParts.length;
|
|
2073
|
+
}
|
|
2028
2074
|
/**
|
|
2029
2075
|
* Combine multiple events into one parsed object. Longest path takes precedent, but all subsequent methods are
|
|
2030
2076
|
* combined until a "none" is reached
|
|
@@ -2033,38 +2079,58 @@ const _PathEvent = class _PathEvent {
|
|
|
2033
2079
|
* @return {PathEvent} Final combined permission
|
|
2034
2080
|
*/
|
|
2035
2081
|
static combine(...paths) {
|
|
2036
|
-
|
|
2037
|
-
const
|
|
2038
|
-
const
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
if (
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2082
|
+
const parsed = paths.map((p) => p instanceof _PathEvent ? p : new _PathEvent(p));
|
|
2083
|
+
const sorted = parsed.toSorted((p1, p2) => {
|
|
2084
|
+
const score1 = _PathEvent.scoreSpecificity(p1.fullPath);
|
|
2085
|
+
const score2 = _PathEvent.scoreSpecificity(p2.fullPath);
|
|
2086
|
+
return score1 - score2;
|
|
2087
|
+
});
|
|
2088
|
+
let result = null;
|
|
2089
|
+
for (const p of sorted) {
|
|
2090
|
+
if (!result) {
|
|
2091
|
+
result = p;
|
|
2092
|
+
} else {
|
|
2093
|
+
if (result.fullPath.startsWith(p.fullPath)) {
|
|
2094
|
+
if (p.none) {
|
|
2095
|
+
break;
|
|
2096
|
+
}
|
|
2097
|
+
result.methods = new ASet([...result.methods, ...p.methods]);
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
return result || new _PathEvent("");
|
|
2049
2102
|
}
|
|
2050
2103
|
/**
|
|
2051
2104
|
* Filter a set of paths based on the target
|
|
2052
2105
|
*
|
|
2053
2106
|
* @param {string | PathEvent | (string | PathEvent)[]} target Array of events that will filtered
|
|
2054
|
-
* @param filter {...PathEvent} Must
|
|
2055
|
-
* @return {
|
|
2107
|
+
* @param filter {...PathEvent} Must contain one of
|
|
2108
|
+
* @return {PathEvent[]} Filtered results
|
|
2056
2109
|
*/
|
|
2057
2110
|
static filter(target, ...filter) {
|
|
2058
2111
|
const parsedTarget = makeArray(target).map((pe) => pe instanceof _PathEvent ? pe : new _PathEvent(pe));
|
|
2059
2112
|
const parsedFilter = makeArray(filter).map((pe) => pe instanceof _PathEvent ? pe : new _PathEvent(pe));
|
|
2060
|
-
return parsedTarget.filter((t) =>
|
|
2061
|
-
const
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2113
|
+
return parsedTarget.filter((t) => {
|
|
2114
|
+
const combined = _PathEvent.combine(t);
|
|
2115
|
+
return !!parsedFilter.find((r) => _PathEvent.matches(r, combined));
|
|
2116
|
+
});
|
|
2117
|
+
}
|
|
2118
|
+
/**
|
|
2119
|
+
* Check if a filter pattern matches a target path
|
|
2120
|
+
* @private
|
|
2121
|
+
*/
|
|
2122
|
+
static matches(pattern, target) {
|
|
2123
|
+
if (pattern.fullPath === "" || target.fullPath === "") return false;
|
|
2124
|
+
if (pattern.fullPath === "*" || target.fullPath === "*") return pattern.methods.has("*") || target.methods.has("*") || pattern.methods.intersection(target.methods).length > 0;
|
|
2125
|
+
const methodsMatch = pattern.all || target.all || pattern.methods.intersection(target.methods).length > 0;
|
|
2126
|
+
if (!methodsMatch) return false;
|
|
2127
|
+
if (!pattern.hasGlob && !target.hasGlob) {
|
|
2128
|
+
return pattern.fullPath === target.fullPath;
|
|
2129
|
+
}
|
|
2130
|
+
if (pattern.hasGlob) {
|
|
2131
|
+
return this.pathMatchesGlob(target.fullPath, pattern.fullPath);
|
|
2132
|
+
}
|
|
2133
|
+
return this.pathMatchesGlob(pattern.fullPath, target.fullPath);
|
|
2068
2134
|
}
|
|
2069
2135
|
/**
|
|
2070
2136
|
* Squash 2 sets of paths & return true if any overlap is found
|
|
@@ -2076,21 +2142,15 @@ const _PathEvent = class _PathEvent {
|
|
|
2076
2142
|
static has(target, ...has) {
|
|
2077
2143
|
const parsedTarget = makeArray(target).map((pe) => pe instanceof _PathEvent ? pe : new _PathEvent(pe));
|
|
2078
2144
|
const parsedRequired = makeArray(has).map((pe) => pe instanceof _PathEvent ? pe : new _PathEvent(pe));
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
const p1 = r.fullPath.includes("*") ? r.fullPath.slice(0, r.fullPath.indexOf("*")) : r.fullPath;
|
|
2082
|
-
const p2 = t.fullPath.includes("*") ? t.fullPath.slice(0, t.fullPath.indexOf("*")) : t.fullPath;
|
|
2083
|
-
const scope = p1.startsWith(p2);
|
|
2084
|
-
const methods = r.all || t.all || r.methods.intersection(t.methods).length;
|
|
2085
|
-
return (wildcard || scope) && methods;
|
|
2086
|
-
}));
|
|
2145
|
+
const effectiveTarget = parsedTarget.length === 1 ? parsedTarget[0] : _PathEvent.combine(...parsedTarget);
|
|
2146
|
+
return !!parsedRequired.find((r) => _PathEvent.matches(r, effectiveTarget));
|
|
2087
2147
|
}
|
|
2088
2148
|
/**
|
|
2089
2149
|
* Squash 2 sets of paths & return true if the target has all paths
|
|
2090
2150
|
*
|
|
2091
2151
|
* @param {string | PathEvent | (string | PathEvent)[]} target Array of Events as strings or pre-parsed
|
|
2092
2152
|
* @param has Target must have all these paths
|
|
2093
|
-
* @return {boolean} Whether
|
|
2153
|
+
* @return {boolean} Whether all are present
|
|
2094
2154
|
*/
|
|
2095
2155
|
static hasAll(target, ...has) {
|
|
2096
2156
|
return has.filter((h) => _PathEvent.has(target, h)).length == has.length;
|
|
@@ -2098,7 +2158,7 @@ const _PathEvent = class _PathEvent {
|
|
|
2098
2158
|
/**
|
|
2099
2159
|
* Same as `has` but raises an error if there is no overlap
|
|
2100
2160
|
*
|
|
2101
|
-
* @param {string | string[]} target Array of Events as strings or pre-parsed
|
|
2161
|
+
* @param {string | PathEvent | (string | PathEvent)[]} target Array of Events as strings or pre-parsed
|
|
2102
2162
|
* @param has Target must have at least one of these path
|
|
2103
2163
|
*/
|
|
2104
2164
|
static hasFatal(target, ...has) {
|
|
@@ -2107,7 +2167,7 @@ const _PathEvent = class _PathEvent {
|
|
|
2107
2167
|
/**
|
|
2108
2168
|
* Same as `hasAll` but raises an error if the target is missing any paths
|
|
2109
2169
|
*
|
|
2110
|
-
* @param {string | string[]} target Array of Events as strings or pre-parsed
|
|
2170
|
+
* @param {string | PathEvent | (string | PathEvent)[]} target Array of Events as strings or pre-parsed
|
|
2111
2171
|
* @param has Target must have all these paths
|
|
2112
2172
|
*/
|
|
2113
2173
|
static hasAllFatal(target, ...has) {
|
|
@@ -2139,7 +2199,7 @@ const _PathEvent = class _PathEvent {
|
|
|
2139
2199
|
* Squash 2 sets of paths & return true if the target has all paths
|
|
2140
2200
|
*
|
|
2141
2201
|
* @param has Target must have all these paths
|
|
2142
|
-
* @return {boolean} Whether
|
|
2202
|
+
* @return {boolean} Whether all are present
|
|
2143
2203
|
*/
|
|
2144
2204
|
hasAll(...has) {
|
|
2145
2205
|
return _PathEvent.hasAll(this, ...has);
|
|
@@ -2164,7 +2224,7 @@ const _PathEvent = class _PathEvent {
|
|
|
2164
2224
|
* Filter a set of paths based on this event
|
|
2165
2225
|
*
|
|
2166
2226
|
* @param {string | PathEvent | (string | PathEvent)[]} target Array of events that will filtered
|
|
2167
|
-
* @return {
|
|
2227
|
+
* @return {PathEvent[]} Filtered results
|
|
2168
2228
|
*/
|
|
2169
2229
|
filter(target) {
|
|
2170
2230
|
return _PathEvent.filter(target, this);
|
|
@@ -2180,6 +2240,10 @@ const _PathEvent = class _PathEvent {
|
|
|
2180
2240
|
};
|
|
2181
2241
|
/** Internal cache for PathEvent instances to avoid redundant parsing */
|
|
2182
2242
|
__publicField(_PathEvent, "pathEventCache", /* @__PURE__ */ new Map());
|
|
2243
|
+
/** Cache for compiled permissions (path + required permissions → result) */
|
|
2244
|
+
__publicField(_PathEvent, "permissionCache", /* @__PURE__ */ new Map());
|
|
2245
|
+
/** Max size for permission cache before LRU eviction */
|
|
2246
|
+
__publicField(_PathEvent, "MAX_PERMISSION_CACHE_SIZE", 1e3);
|
|
2183
2247
|
let PathEvent = _PathEvent;
|
|
2184
2248
|
class PathEventEmitter {
|
|
2185
2249
|
constructor(prefix = "") {
|
|
@@ -2188,16 +2252,27 @@ class PathEventEmitter {
|
|
|
2188
2252
|
}
|
|
2189
2253
|
emit(event, ...args) {
|
|
2190
2254
|
const parsed = event instanceof PathEvent ? event : new PathEvent(`${this.prefix}/${event}`);
|
|
2191
|
-
this.listeners.filter((l) => PathEvent.has(l[0], parsed)).forEach(
|
|
2255
|
+
this.listeners.filter((l) => PathEvent.has(l[0], parsed)).forEach((l) => l[1](parsed, ...args));
|
|
2192
2256
|
}
|
|
2193
2257
|
off(listener) {
|
|
2194
2258
|
this.listeners = this.listeners.filter((l) => l[1] != listener);
|
|
2195
2259
|
}
|
|
2196
2260
|
on(event, listener) {
|
|
2197
2261
|
makeArray(event).forEach((e) => {
|
|
2198
|
-
|
|
2262
|
+
let fullEvent;
|
|
2263
|
+
if (typeof e === "string") {
|
|
2264
|
+
if (e[0] === ":" && this.prefix) {
|
|
2265
|
+
fullEvent = `${this.prefix}${e}`;
|
|
2266
|
+
} else if (this.prefix) {
|
|
2267
|
+
fullEvent = `${this.prefix}/${e}`;
|
|
2268
|
+
} else {
|
|
2269
|
+
fullEvent = e;
|
|
2270
|
+
}
|
|
2271
|
+
} else {
|
|
2272
|
+
fullEvent = e instanceof PathEvent ? PathEvent.toString(e.fullPath, e.methods) : e;
|
|
2273
|
+
}
|
|
2199
2274
|
this.listeners.push([
|
|
2200
|
-
|
|
2275
|
+
new PathEvent(fullEvent),
|
|
2201
2276
|
listener
|
|
2202
2277
|
]);
|
|
2203
2278
|
});
|
|
@@ -2213,7 +2288,7 @@ class PathEventEmitter {
|
|
|
2213
2288
|
});
|
|
2214
2289
|
}
|
|
2215
2290
|
relayEvents(emitter) {
|
|
2216
|
-
emitter.on("
|
|
2291
|
+
emitter.on("**", (event, ...args) => this.emit(event, ...args));
|
|
2217
2292
|
}
|
|
2218
2293
|
}
|
|
2219
2294
|
function search(rows, search2, regex, transform = (r) => r) {
|
|
@@ -2422,7 +2497,7 @@ class MemoryStorage {
|
|
|
2422
2497
|
}
|
|
2423
2498
|
}
|
|
2424
2499
|
memoryStorage.MemoryStorage = MemoryStorage;
|
|
2425
|
-
(function(exports) {
|
|
2500
|
+
(function(exports$1) {
|
|
2426
2501
|
var __createBinding = commonjsGlobal && commonjsGlobal.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
2427
2502
|
if (k2 === void 0) k2 = k;
|
|
2428
2503
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -2436,12 +2511,12 @@ memoryStorage.MemoryStorage = MemoryStorage;
|
|
|
2436
2511
|
if (k2 === void 0) k2 = k;
|
|
2437
2512
|
o[k2] = m[k];
|
|
2438
2513
|
});
|
|
2439
|
-
var __exportStar = commonjsGlobal && commonjsGlobal.__exportStar || function(m,
|
|
2440
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(
|
|
2514
|
+
var __exportStar = commonjsGlobal && commonjsGlobal.__exportStar || function(m, exports$12) {
|
|
2515
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$12, p)) __createBinding(exports$12, m, p);
|
|
2441
2516
|
};
|
|
2442
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2443
|
-
__exportStar(persist$1, exports);
|
|
2444
|
-
__exportStar(memoryStorage, exports);
|
|
2517
|
+
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
2518
|
+
__exportStar(persist$1, exports$1);
|
|
2519
|
+
__exportStar(memoryStorage, exports$1);
|
|
2445
2520
|
})(dist);
|
|
2446
2521
|
export {
|
|
2447
2522
|
ASet,
|