@ztimson/utils 0.24.6 → 0.24.9

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 CHANGED
@@ -5,6 +5,11 @@ export type CacheOptions = {
5
5
  storage?: Storage;
6
6
  /** Key cache will be stored under */
7
7
  storageKey?: string;
8
+ /** Keep or delete cached items once expired, defaults to delete */
9
+ expiryPolicy?: 'delete' | 'keep';
10
+ };
11
+ export type CachedValue<T> = T | {
12
+ _expired?: boolean;
8
13
  };
9
14
  /**
10
15
  * Map of data which tracks whether it is a complete collection & offers optional expiry of cached values
@@ -14,7 +19,7 @@ export declare class Cache<K extends string | number | symbol, T> {
14
19
  readonly options: CacheOptions;
15
20
  private store;
16
21
  /** Support index lookups */
17
- [key: string | number | symbol]: T | any;
22
+ [key: string | number | symbol]: CachedValue<T> | any;
18
23
  /** Whether cache is complete */
19
24
  complete: boolean;
20
25
  /**
@@ -24,11 +29,12 @@ export declare class Cache<K extends string | number | symbol, T> {
24
29
  */
25
30
  constructor(key?: keyof T | undefined, options?: CacheOptions);
26
31
  private getKey;
32
+ private save;
27
33
  /**
28
34
  * Get all cached items
29
35
  * @return {T[]} Array of items
30
36
  */
31
- all(): T[];
37
+ all(expired?: boolean): CachedValue<T>[];
32
38
  /**
33
39
  * Add a new item to the cache. Like set, but finds key automatically
34
40
  * @param {T} value Item to add to cache
@@ -56,23 +62,28 @@ export declare class Cache<K extends string | number | symbol, T> {
56
62
  * Return cache as an array of key-value pairs
57
63
  * @return {[K, T][]} Key-value pairs array
58
64
  */
59
- entries(): [K, T][];
65
+ entries(expired?: boolean): [K, CachedValue<T>][];
66
+ /**
67
+ * Manually expire a cached item
68
+ * @param {K} key Key to expire
69
+ */
70
+ expire(key: K): void;
60
71
  /**
61
72
  * Get item from the cache
62
73
  * @param {K} key Key to lookup
63
74
  * @return {T} Cached item
64
75
  */
65
- get(key: K): T;
76
+ get(key: K, expired?: boolean): T | null;
66
77
  /**
67
78
  * Get a list of cached keys
68
79
  * @return {K[]} Array of keys
69
80
  */
70
- keys(): K[];
81
+ keys(expired?: boolean): K[];
71
82
  /**
72
83
  * Get map of cached items
73
84
  * @return {Record<K, T>}
74
85
  */
75
- map(): Record<K, T>;
86
+ map(expired?: boolean): Record<K, CachedValue<T>>;
76
87
  /**
77
88
  * Add an item to the cache manually specifying the key
78
89
  * @param {K} key Key item will be cached under
@@ -85,5 +96,5 @@ export declare class Cache<K extends string | number | symbol, T> {
85
96
  * Get all cached items
86
97
  * @return {T[]} Array of items
87
98
  */
88
- values: T[];
99
+ values: CachedValue<T>[];
89
100
  }
package/dist/index.cjs CHANGED
@@ -426,7 +426,7 @@ ${opts.message || this.desc}`;
426
426
  return new Proxy(this, {
427
427
  get: (target, prop) => {
428
428
  if (prop in target) return target[prop];
429
- return deepCopy(target.store[prop]);
429
+ return this.get(prop, true);
430
430
  },
431
431
  set: (target, prop, value) => {
432
432
  if (prop in target) target[prop] = value;
@@ -439,12 +439,16 @@ ${opts.message || this.desc}`;
439
439
  if (!this.key) throw new Error("No key defined");
440
440
  return value[this.key];
441
441
  }
442
+ save() {
443
+ if (this.options.storageKey && this.options.storage)
444
+ this.options.storage.setItem(this.options.storageKey, JSON.stringify(this.store));
445
+ }
442
446
  /**
443
447
  * Get all cached items
444
448
  * @return {T[]} Array of items
445
449
  */
446
- all() {
447
- return deepCopy(Object.values(this.store));
450
+ all(expired) {
451
+ return deepCopy(Object.values(this.store).filter((v) => expired || !v._expired));
448
452
  }
449
453
  /**
450
454
  * Add a new item to the cache. Like set, but finds key automatically
@@ -473,6 +477,7 @@ ${opts.message || this.desc}`;
473
477
  * Remove all keys from cache
474
478
  */
475
479
  clear() {
480
+ this.complete = false;
476
481
  this.store = {};
477
482
  }
478
483
  /**
@@ -481,37 +486,51 @@ ${opts.message || this.desc}`;
481
486
  */
482
487
  delete(key) {
483
488
  delete this.store[key];
484
- if (this.options.storageKey && this.options.storage)
485
- this.options.storage.setItem(this.options.storageKey, JSON.stringify(this.store));
489
+ this.save();
486
490
  }
487
491
  /**
488
492
  * Return cache as an array of key-value pairs
489
493
  * @return {[K, T][]} Key-value pairs array
490
494
  */
491
- entries() {
492
- return Object.entries(this.store);
495
+ entries(expired) {
496
+ return deepCopy(Object.entries(this.store).filter((v) => expired || !v._expired));
497
+ }
498
+ /**
499
+ * Manually expire a cached item
500
+ * @param {K} key Key to expire
501
+ */
502
+ expire(key) {
503
+ this.complete = false;
504
+ if (this.options.expiryPolicy == "keep") this.store[key]._expired = true;
505
+ else this.delete(key);
493
506
  }
494
507
  /**
495
508
  * Get item from the cache
496
509
  * @param {K} key Key to lookup
497
510
  * @return {T} Cached item
498
511
  */
499
- get(key) {
500
- return deepCopy(this.store[key]);
512
+ get(key, expired) {
513
+ const cached = deepCopy(this.store[key] ?? null);
514
+ if (expired || !cached._expired) return cached;
515
+ return null;
501
516
  }
502
517
  /**
503
518
  * Get a list of cached keys
504
519
  * @return {K[]} Array of keys
505
520
  */
506
- keys() {
507
- return Object.keys(this.store);
521
+ keys(expired) {
522
+ return Object.keys(this.store).filter((k) => expired || !this.store[k]._expired);
508
523
  }
509
524
  /**
510
525
  * Get map of cached items
511
526
  * @return {Record<K, T>}
512
527
  */
513
- map() {
514
- return deepCopy(this.store);
528
+ map(expired) {
529
+ const copy = deepCopy(this.store);
530
+ if (!expired) Object.keys(copy).forEach((k) => {
531
+ if (copy[k]._expired) delete copy[k];
532
+ });
533
+ return copy;
515
534
  }
516
535
  /**
517
536
  * Add an item to the cache manually specifying the key
@@ -521,12 +540,12 @@ ${opts.message || this.desc}`;
521
540
  * @return {this}
522
541
  */
523
542
  set(key, value, ttl = this.options.ttl) {
543
+ if (this.options.expiryPolicy == "keep") delete this.store[key]._expired;
524
544
  this.store[key] = value;
525
- if (this.options.storageKey && this.options.storage)
526
- this.options.storage.setItem(this.options.storageKey, JSON.stringify(this.store));
545
+ this.save();
527
546
  if (ttl) setTimeout(() => {
528
- this.complete = false;
529
- this.delete(key);
547
+ this.expire(key);
548
+ this.save();
530
549
  }, ttl * 1e3);
531
550
  return this;
532
551
  }
@@ -1638,7 +1657,7 @@ ${opts.message || this.desc}`;
1638
1657
  return PathEvent.filter(target, this);
1639
1658
  }
1640
1659
  /**
1641
- * Create event string from its components
1660
+ * Create event string from its components
1642
1661
  *
1643
1662
  * @return {string} String representation of Event
1644
1663
  */
@@ -1647,18 +1666,22 @@ ${opts.message || this.desc}`;
1647
1666
  }
1648
1667
  }
1649
1668
  class PathEventEmitter {
1650
- constructor() {
1669
+ constructor(prefix = "") {
1651
1670
  __publicField(this, "listeners", []);
1671
+ this.prefix = prefix;
1652
1672
  }
1653
1673
  emit(event, ...args) {
1654
- const parsed = new PathEvent(event);
1674
+ const parsed = new PathEvent(`${this.prefix}/${typeof event == "string" ? event : event.toString()}`);
1655
1675
  this.listeners.filter((l) => PathEvent.has(l[0], event)).forEach(async (l) => l[1](parsed, ...args));
1656
1676
  }
1657
1677
  off(listener) {
1658
1678
  this.listeners = this.listeners.filter((l) => l[1] != listener);
1659
1679
  }
1660
1680
  on(event, listener) {
1661
- makeArray(event).forEach((e) => this.listeners.push([new PathEvent(e), listener]));
1681
+ makeArray(event).forEach((e) => this.listeners.push([
1682
+ new PathEvent(`${this.prefix}/${typeof e == "string" ? event : event.toString()}`),
1683
+ listener
1684
+ ]));
1662
1685
  return () => this.off(listener);
1663
1686
  }
1664
1687
  once(event, listener) {