Skip to content

Commit ef974dc

Browse files
committed
Fix memory leak with WeakMap + String objects
- Replace unbounded cache with WeakMap - Return String objects instead of primitives - String objects can be WeakMap keys and are GC'd automatically - No eviction issues - entries only released when truly unreferenced - Requires calling .valueOf() on final result before serialization This approach is based on PR developit#43 but adapted for server-side usage.
1 parent 0b9c0e2 commit ef974dc

2 files changed

Lines changed: 7 additions & 14 deletions

File tree

package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,5 @@
6969
"rollup-plugin-babel": "^2.4.0",
7070
"rollup-plugin-es3": "^1.0.3",
7171
"uglify-js": "^2.6.2"
72-
},
73-
"dependencies": {
74-
"lru-cache": "11.2.2"
7572
}
7673
}

src/vhtml.js

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import emptyTags from './empty-tags.js';
2-
import { LRUCache } from 'lru-cache';
32

43
// escape an attribute
54
let esc = str => String(str).replace(/[&<>"']/g, s=>`&${map[s]};`);
@@ -10,14 +9,9 @@ let DOMAttributeNames = {
109
htmlFor: 'for'
1110
};
1211

13-
// LRU cache with TTL to prevent unbounded memory growth
14-
// Large max (100k) prevents eviction during HTML composition
15-
// TTL (60s) handles automatic cleanup
16-
let sanitized = new LRUCache({
17-
max: 100000,
18-
ttl: 60 * 1000, // 60 seconds
19-
updateAgeOnGet: false
20-
});
12+
// WeakMap to track sanitized HTML fragments
13+
// String objects can be keys, and they're automatically GC'd when unreferenced
14+
let sanitized = new WeakMap();
2115

2216
/** Hyperscript reviver that constructs a sanitized HTML string. */
2317
export default function h(name, attrs) {
@@ -63,6 +57,8 @@ export default function h(name, attrs) {
6357
s += name ? `</${name}>` : '';
6458
}
6559

66-
sanitized.set(s, true);
67-
return s;
60+
// Wrap result in String object so it can be used as WeakMap key
61+
let result = new String(s);
62+
sanitized.set(result, true);
63+
return result;
6864
}

0 commit comments

Comments
 (0)