@nxtedition/lib 23.9.10 → 23.9.12

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/app.js CHANGED
@@ -314,7 +314,7 @@ export function makeApp(appConfig, onTerminate) {
314
314
  setInterval(() => {
315
315
  let currentLag = Math.max(0, histogram.mean / 1e6 - resolution)
316
316
  if (Number.isNaN(currentLag)) {
317
- currentLag = 0
317
+ currentLag = Infinity
318
318
  }
319
319
  histogram.reset()
320
320
 
package/cache.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { LRUCache } from 'lru-cache'
2
2
 
3
3
  export class AsyncCache {
4
+ /** @type LRUCache<string, { expire: Number, value: any } **/
4
5
  #lru
5
6
  #valueSelector
6
7
  #keySelector
@@ -102,6 +103,10 @@ export class AsyncCache {
102
103
  return value
103
104
  }
104
105
 
106
+ /**
107
+ * @param {string} key
108
+ * @param {any} value
109
+ */
105
110
  set(key, value) {
106
111
  if (typeof key !== 'string' || key.length === 0) {
107
112
  throw new TypeError('key must be a non-empty string')
@@ -116,6 +121,9 @@ export class AsyncCache {
116
121
  this.#dedupe.delete(key)
117
122
  }
118
123
 
124
+ /**
125
+ * @param {string} key
126
+ */
119
127
  delete(key) {
120
128
  if (typeof key !== 'string' || key.length === 0) {
121
129
  throw new TypeError('key must be a non-empty string')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/lib",
3
- "version": "23.9.10",
3
+ "version": "23.9.12",
4
4
  "license": "MIT",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "type": "module",
@@ -44,7 +44,8 @@
44
44
  "transcript.js",
45
45
  "docker-secrets.js",
46
46
  "wordwrap.js",
47
- "under-pressure.js"
47
+ "under-pressure.js",
48
+ "yield.js"
48
49
  ],
49
50
  "scripts": {
50
51
  "prepublishOnly": "pinst --disable",
package/under-pressure.js CHANGED
@@ -16,46 +16,33 @@ export default function (opts = {}) {
16
16
  const maxRssBytes = opts.maxRssBytes || 0
17
17
  const maxEventLoopUtilization = opts.maxEventLoopUtilization || 0
18
18
 
19
- const checkMaxEventLoopDelay = maxEventLoopDelay > 0
20
- const checkMaxHeapUsedBytes = maxHeapUsedBytes > 0
21
- const checkMaxRssBytes = maxRssBytes > 0
22
- const checkMaxEventLoopUtilization = maxEventLoopUtilization > 0
23
19
  const pressure$ = new rxjs.BehaviorSubject(null)
24
20
 
25
21
  let heapUsedBytes = 0
26
22
  let rssBytes = 0
27
23
  let eventLoopDelay = 0
28
- let elu
29
24
  let eventLoopUtilized = 0
30
25
 
31
- const histogram = monitorEventLoopDelay({ resolution })
32
- histogram.enable()
33
-
34
- if (performance.eventLoopUtilization) {
35
- elu = performance.eventLoopUtilization()
36
- }
37
-
38
- if (
39
- checkMaxEventLoopUtilization === false &&
40
- checkMaxEventLoopDelay === false &&
41
- checkMaxHeapUsedBytes === false &&
42
- checkMaxRssBytes === false
43
- ) {
26
+ if (!maxEventLoopDelay && !maxHeapUsedBytes && !maxRssBytes && !maxEventLoopUtilization) {
44
27
  return
45
28
  }
46
29
 
30
+ const histogram = maxEventLoopDelay ? monitorEventLoopDelay({ resolution }) : null
31
+ histogram?.enable()
32
+ const elu = maxEventLoopUtilization ? performance.eventLoopUtilization?.() : null
33
+
47
34
  function updateEventLoopDelay() {
48
- eventLoopDelay = Math.max(0, histogram.mean / 1e6 - resolution)
49
- if (Number.isNaN(eventLoopDelay)) eventLoopDelay = Infinity
50
- histogram.reset()
35
+ if (histogram) {
36
+ eventLoopDelay = Math.max(0, histogram.mean / 1e6 - resolution)
37
+ if (Number.isNaN(eventLoopDelay)) {
38
+ eventLoopDelay = Infinity
39
+ }
40
+ histogram.reset()
41
+ }
51
42
  }
52
43
 
53
44
  function updateEventLoopUtilization() {
54
- if (elu) {
55
- eventLoopUtilized = performance.eventLoopUtilization(elu).utilization
56
- } else {
57
- eventLoopUtilized = 0
58
- }
45
+ eventLoopUtilized = elu ? performance.eventLoopUtilization(elu).utilization : 0
59
46
  }
60
47
 
61
48
  const timer = setTimeout(update, sampleInterval).unref()
@@ -71,19 +58,23 @@ export default function (opts = {}) {
71
58
  }
72
59
 
73
60
  function isUnderPressure() {
74
- if (checkMaxEventLoopDelay && eventLoopDelay > maxEventLoopDelay) {
61
+ if (maxEventLoopDelay && eventLoopDelay > maxEventLoopDelay) {
62
+ return true
63
+ }
64
+
65
+ if (maxHeapUsedBytes && heapUsedBytes > maxHeapUsedBytes) {
75
66
  return true
76
67
  }
77
68
 
78
- if (checkMaxHeapUsedBytes && heapUsedBytes > maxHeapUsedBytes) {
69
+ if (maxRssBytes && rssBytes > maxRssBytes) {
79
70
  return true
80
71
  }
81
72
 
82
- if (checkMaxRssBytes && rssBytes > maxRssBytes) {
73
+ if (maxEventLoopUtilization && eventLoopUtilized > maxEventLoopUtilization) {
83
74
  return true
84
75
  }
85
76
 
86
- return checkMaxEventLoopUtilization && eventLoopUtilized > maxEventLoopUtilization
77
+ return false
87
78
  }
88
79
 
89
80
  function getPressure() {
package/yield.js ADDED
@@ -0,0 +1,23 @@
1
+ let yieldTime = performance.now()
2
+
3
+ export function maybeYield(opts) {
4
+ const timeout = opts?.timeout ?? 50
5
+ if (performance.now() - yieldTime > timeout) {
6
+ return doYield(opts)
7
+ }
8
+ opts?.signal?.throwIfAborted()
9
+ }
10
+
11
+ export async function doYield(opts) {
12
+ await new Promise((resolve) => setImmediate(resolve))
13
+ resetYield(opts)
14
+ }
15
+
16
+ function resetYield(opts) {
17
+ yieldTime = performance.now()
18
+ opts?.signal?.throwIfAborted()
19
+ }
20
+
21
+ setInterval(() => {
22
+ yieldTime = performance.now()
23
+ }, 500).unref()