@raketa-cloud/next 1.0.3 → 1.0.4

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/package.json +1 -2
  2. package/src/Cache.js +40 -22
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raketa-cloud/next",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "main": "src/index.js",
5
5
  "scripts": {
6
6
  "check-types": "tsc --noEmit",
@@ -18,7 +18,6 @@
18
18
  "dependencies": {
19
19
  "graphql-request": "7.1.2",
20
20
  "lru-cache": "11.0.2",
21
- "object-sizeof": "^2.6.5",
22
21
  "react": "^19.0.0",
23
22
  "react-dom": "^19.0.0"
24
23
  }
package/src/Cache.js CHANGED
@@ -1,46 +1,64 @@
1
1
  import { LRUCache } from "lru-cache";
2
- import sizeof from "object-sizeof";
3
2
 
4
3
  const NULL_SENTINEL = Symbol.for("raketa_cache_null");
5
4
 
6
- function getKeySize(key) {
7
- if (typeof key === 'string') {
8
- // Account for UTF-16 encoding
9
- return Buffer.from(key, 'utf16le').length;
10
- }
5
+ function getApproximateMemoryUsage(obj) {
6
+ // Use a WeakSet to track objects we've already seen to avoid infinite loops on circular references
7
+ const seen = new WeakSet();
11
8
 
12
- if (typeof key === 'number') {
13
- return 8; // 64-bit number
14
- }
9
+ function sizeOf(value) {
10
+ // 1. Handle null and undefined explicitly (This fixes your error!)
11
+ if (value === null || value === undefined) return 0;
12
+
13
+ // 2. Handle primitives based on JS specs
14
+ if (typeof value === 'boolean') return 4;
15
+ if (typeof value === 'number') return 8; // Double-precision floats
16
+ if (typeof value === 'string') return value.length * 2; // UTF-16 strings take 2 bytes per char
17
+
18
+ // 3. Skip functions and symbols (they live in a shared memory pool)
19
+ if (typeof value !== 'object') return 0;
15
20
 
16
- if (typeof key === 'object') {
17
- return sizeof(key);
21
+ // 4. Handle circular references
22
+ if (seen.has(value)) return 0;
23
+
24
+ seen.add(value);
25
+
26
+ let bytes = 0;
27
+
28
+ // 5. Traverse the object's keys and values
29
+ for (const key in value) {
30
+ if (Object.prototype.hasOwnProperty.call(value, key)) {
31
+ bytes += key.length * 2; // Add the size of the key itself
32
+ bytes += sizeOf(value[key]); // Recursively add the size of the value
33
+ }
34
+ }
35
+
36
+ return bytes;
18
37
  }
19
38
 
20
- return 0;
39
+ return sizeOf(obj);
21
40
  }
22
41
 
23
42
  export default class Cache {
24
43
  constructor(opts = {}) {
44
+ const self = this;
45
+
25
46
  const cacheOptions = {
26
47
  max: opts.max || 5000, // Items count
27
48
  ttl: opts.ttl || 1000 * 60 * 5, // 5 minutes
28
- maxSize: opts.maxSize || 500 * 1024 * 1024, // 500 MB
29
49
  allowStale: true,
30
50
  noDeleteOnStaleGet: true,
31
51
  };
32
52
 
33
- cacheOptions.sizeCalculation = (value, key) => {
34
- const keySize = getKeySize(key);
53
+ // Conditionally use the memrory calculation since it is veery flaky and inaccurate...
54
+ if (opts.maxSize) {
55
+ cacheOptions.maxSize = opts.maxSize;
35
56
 
36
- if (value === null || value === undefined) {
37
- return keySize;
38
- }
57
+ cacheOptions.sizeCalculation = (value, key) => {
58
+ return getApproximateMemoryUsage(key) + getApproximateMemoryUsage(value);
59
+ };
39
60
 
40
- if (value === NULL_SENTINEL) return keySize + 1;
41
-
42
- return keySize + sizeof(value);
43
- };
61
+ }
44
62
 
45
63
  this.debugMode = opts.debugMode || false;
46
64
  this.cacheInstance = new LRUCache(cacheOptions);