@nxtedition/lib 23.4.0 → 23.4.1

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.
Files changed (2) hide show
  1. package/cache.js +32 -8
  2. package/package.json +1 -1
package/cache.js CHANGED
@@ -2,24 +2,44 @@ import { LRU } from 'lru-cache'
2
2
 
3
3
  export class AsyncCache {
4
4
  #lru
5
- #keySelector
5
+ #prefix
6
6
  #valueSelector
7
+ #keySelector
7
8
  #dedupe = new Map()
8
9
  #ttl
9
10
  #stale
10
11
 
11
- constructor(valueSelector, opts) {
12
+ constructor(valueSelector, keySelector, opts) {
12
13
  this.#lru = new LRU({ max: 1024 })
13
- this.#keySelector = opts?.keySelector ?? ((...args) => args[0])
14
14
  this.#valueSelector = valueSelector
15
15
 
16
+ if (typeof valueSelector === 'function') {
17
+ this.#valueSelector = valueSelector
18
+ } else {
19
+ throw new TypeError('valueSelector must be a function')
20
+ }
21
+
22
+ if (typeof keySelector === 'function' || keySelector === undefined) {
23
+ this.#keySelector = keySelector ?? ((...args) => JSON.stringify(args))
24
+ } else {
25
+ throw new TypeError('keySelector must be a function')
26
+ }
27
+
28
+ if (opts?.location === undefined) {
29
+ this.#prefix = (opts?.location ?? Math.random().toString(36)) + ':'
30
+ } else if (typeof opts?.location === 'string') {
31
+ this.#prefix = opts.location
32
+ } else {
33
+ throw new TypeError('location must be undefined or a string')
34
+ }
35
+
16
36
  if (typeof opts?.ttl === 'number' || opts?.ttl === undefined) {
17
37
  const ttl = opts.ttl
18
- return (val, key) => ttl
38
+ this.#ttl = (val, key) => ttl
19
39
  } else if (typeof opts?.ttl === 'function') {
20
40
  this.#ttl = opts.ttl
21
41
  } else {
22
- throw new TypeError('ttl must be a number or a function')
42
+ throw new TypeError('ttl must be a undefined, number or a function')
23
43
  }
24
44
 
25
45
  if (typeof opts?.stale === 'number' || opts?.stale === undefined) {
@@ -28,17 +48,21 @@ export class AsyncCache {
28
48
  } else if (typeof opts?.stale === 'function') {
29
49
  this.#stale = opts.stale
30
50
  } else {
31
- throw new TypeError('stale must be a number or a function')
51
+ throw new TypeError('stale must be a undefined, number or a function')
32
52
  }
33
53
  }
34
54
 
35
55
  async get(...args) {
36
56
  const key = this.#keySelector(...args)
37
57
 
58
+ if (typeof key !== 'string' || key.length === 0) {
59
+ throw new TypeError('keySelector must return a non-empty string')
60
+ }
61
+
38
62
  let cached = this.#lru.get(key)
39
63
 
40
64
  if (!cached) {
41
- const raw = globalThis.localStorage.getItem(key)
65
+ const raw = globalThis.localStorage.getItem(this.#prefix + key)
42
66
  cached = raw ? JSON.parse(raw) : null
43
67
  }
44
68
 
@@ -64,7 +88,7 @@ export class AsyncCache {
64
88
  value,
65
89
  }
66
90
 
67
- globalThis.localStorage.setItem(key, JSON.stringify(cached))
91
+ globalThis.localStorage.setItem(this.#prefix + key, JSON.stringify(cached))
68
92
  this.#lru.set(key, cached)
69
93
 
70
94
  return value
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/lib",
3
- "version": "23.4.0",
3
+ "version": "23.4.1",
4
4
  "license": "MIT",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "type": "module",