diff --git a/packages/diffhtml/lib/util/memory.js b/packages/diffhtml/lib/util/memory.js
index 69bc7085..9cc98aaa 100644
--- a/packages/diffhtml/lib/util/memory.js
+++ b/packages/diffhtml/lib/util/memory.js
@@ -1,5 +1,5 @@
import Pool from './pool';
-import { NodeCache } from './types';
+import { EMPTY, NodeCache } from './types';
const { protect, unprotect, memory } = Pool;
@@ -56,6 +56,7 @@ export function gc() {
// Scrub a VTree of attributes and childNodes to avoid ever increasing RAM.
vTree.attributes = {};
vTree.childNodes.length = 0;
+ vTree.key = EMPTY.STR;
// Make the VTree available for future renders.
memory.free.add(vTree);
diff --git a/packages/diffhtml/lib/util/pool.js b/packages/diffhtml/lib/util/pool.js
index 088b35f3..9fdd6713 100644
--- a/packages/diffhtml/lib/util/pool.js
+++ b/packages/diffhtml/lib/util/pool.js
@@ -53,6 +53,10 @@ const Pool = {
},
/**
+ *
+ * Moves a VTree from the "free" state to the "allocated" state. If the pool
+ * is empty, it creates a new object.
+ *
* @return {VTree}
*/
get() {
@@ -72,6 +76,9 @@ const Pool = {
},
/**
+ * Moves a VTree from "allocated" state to "protected" state. This means that
+ * the VTrees will persist between transactions.
+ *
* @param {VTree} vTree - Virtual Tree to protect
*/
protect(vTree) {
@@ -80,13 +87,15 @@ const Pool = {
},
/**
+ * Moves a VTree from "protected" state to "allocated" state. They will be
+ * brought back into "free" circulation during a GC.
+ *
* @param {VTree} vTree - Virtual Tree to unprotect and deallocate
*/
unprotect(vTree) {
if (protect.has(vTree) || allocate.has(vTree)) {
protect.delete(vTree);
- allocate.delete(vTree);
- free.add(vTree);
+ allocate.add(vTree);
}
},
};
diff --git a/packages/diffhtml/test/util.js b/packages/diffhtml/test/util.js
index c22e0a8a..2995103e 100644
--- a/packages/diffhtml/test/util.js
+++ b/packages/diffhtml/test/util.js
@@ -1166,6 +1166,51 @@ describe('Util', () => {
strictEqual(Pool.memory.protected.size, 0);
});
+ it('will only reset attributes once garbage collected', () => {
+ const expected = 'somestr';
+ const vTree = createTree('div', { someAttr: expected });
+
+ protectVTree(vTree);
+ strictEqual(vTree.attributes.someAttr, expected);
+
+ unprotectVTree(vTree);
+ strictEqual(vTree.attributes.someAttr, expected);
+
+ gc();
+
+ strictEqual(vTree.attributes.someAttr, undefined);
+ });
+
+ it('will only reset childNodes once garbage collected', () => {
+ const expected = 'somestr';
+ const vTree = createTree('div', null, createTree('span'));
+
+ protectVTree(vTree);
+ strictEqual(vTree.childNodes.length, 1);
+
+ unprotectVTree(vTree);
+ strictEqual(vTree.childNodes.length, 1);
+
+ gc();
+
+ strictEqual(vTree.childNodes.length, 0);
+ });
+
+ it('will only reset key once garbage collected', () => {
+ const expected = 'somestr';
+ const vTree = createTree('div', { key: expected });
+
+ protectVTree(vTree);
+ strictEqual(vTree.key, expected);
+
+ unprotectVTree(vTree);
+ strictEqual(vTree.key, expected);
+
+ gc();
+
+ strictEqual(vTree.key, '');
+ });
+
it('will garbage collect DOM Node associations', () => {
const domNode = document.createElement('div');
const vTree = createTree(domNode);