or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-functions.mdcache-management.mdfunction-memoization.mdindex.mdmethod-memoization.mdprofiling.mdweakmap-memoization.md

weakmap-memoization.mddocs/

0

# WeakMap Memoization

1

2

Memory-efficient memoization using WeakMap for garbage collection friendly caching when the first argument is expected to be an object. Cache entries are automatically garbage collected when objects are no longer referenced, preventing memory leaks in long-running applications.

3

4

## Capabilities

5

6

### WeakMap-Based Memoization

7

8

Creates memoized functions that use WeakMap for automatic garbage collection of cache entries tied to object lifetimes.

9

10

```javascript { .api }

11

/**

12

* Create WeakMap-based memoized function

13

* @param {Function} fn - Function to memoize (first argument must be an object)

14

* @param {Object} options - Configuration options (same as regular memoize)

15

* @returns {Function} WeakMap-based memoized function

16

*/

17

const weakMemoize = require("memoizee/weak");

18

const memoized = weakMemoize(fn, options);

19

```

20

21

**Usage Examples:**

22

23

```javascript

24

const weakMemoize = require("memoizee/weak");

25

26

// Object property analysis

27

function analyzeObject(obj) {

28

console.log("Analyzing object...");

29

return {

30

keys: Object.keys(obj).length,

31

hasNested: Object.values(obj).some(v => typeof v === 'object'),

32

firstKey: Object.keys(obj)[0]

33

};

34

}

35

36

const memoizedAnalyze = weakMemoize(analyzeObject);

37

38

const obj1 = { name: "Alice", age: 30 };

39

const obj2 = { name: "Bob", age: 25 };

40

41

memoizedAnalyze(obj1); // "Analyzing object...", computes result

42

memoizedAnalyze(obj1); // Returns cached result (no console output)

43

memoizedAnalyze(obj2); // "Analyzing object...", different object

44

45

// When obj1 goes out of scope and is garbage collected,

46

// its cache entry is automatically removed

47

```

48

49

### WeakMap with Multiple Arguments

50

51

Handle functions that take an object as the first argument plus additional parameters.

52

53

```javascript { .api }

54

/**

55

* WeakMap memoization with additional arguments beyond the object key

56

* The first argument becomes the WeakMap key, remaining args cached per object

57

*/

58

const memoized = weakMemoize(function(obj, ...otherArgs) {

59

// Function implementation

60

}, options);

61

```

62

63

**Usage Examples:**

64

65

```javascript

66

const weakMemoize = require("memoizee/weak");

67

68

// DOM element processing with options

69

function processElement(element, options) {

70

console.log("Processing element with options:", options);

71

return {

72

tagName: element.tagName,

73

id: element.id,

74

processed: true,

75

options: options

76

};

77

}

78

79

const memoizedProcess = weakMemoize(processElement);

80

81

const div1 = document.createElement('div');

82

const div2 = document.createElement('div');

83

84

// Same element, different options - separate cache entries per element

85

memoizedProcess(div1, { deep: true }); // Computes

86

memoizedProcess(div1, { deep: false }); // Computes (different options)

87

memoizedProcess(div1, { deep: true }); // Cache hit

88

89

// Different element

90

memoizedProcess(div2, { deep: true }); // Computes

91

92

// When DOM elements are removed from DOM and dereferenced,

93

// their cache entries are automatically cleaned up

94

```

95

96

### WeakMap with Configuration Options

97

98

Combine WeakMap memoization with other memoization features like async support and cache management.

99

100

```javascript { .api }

101

/**

102

* WeakMap memoization with advanced options

103

* All standard memoization options are supported except global cache operations

104

*/

105

const options = {

106

async: boolean, // Async function support

107

promise: boolean|string, // Promise function support

108

maxAge: number, // TTL per object (cleaned up with object)

109

max: number, // Max entries per object

110

refCounter: boolean, // Reference counting per object

111

dispose: Function, // Disposal callback

112

// Note: Global clear() is not available due to WeakMap limitations

113

};

114

```

115

116

**Usage Examples:**

117

118

```javascript

119

const weakMemoize = require("memoizee/weak");

120

121

// WeakMap with async support

122

const asyncWeakMemoized = weakMemoize(async function(obj, query) {

123

const response = await fetch(`/api/data/${obj.id}?q=${query}`);

124

return response.json();

125

}, {

126

promise: true,

127

maxAge: 60000 // Cache per object for 1 minute

128

});

129

130

// WeakMap with size limiting per object

131

const limitedWeakMemoized = weakMemoize(function(obj, operation) {

132

return performExpensiveOperation(obj, operation);

133

}, {

134

max: 10, // Max 10 cached results per object

135

dispose: (result) => {

136

if (result && result.cleanup) result.cleanup();

137

}

138

});

139

140

// User session example

141

class UserSession {

142

constructor(userId) {

143

this.userId = userId;

144

this.loginTime = Date.now();

145

}

146

}

147

148

const memoizedUserOperation = weakMemoize(function(session, operation) {

149

console.log(`Performing ${operation} for user ${session.userId}`);

150

return `${operation}_result_${session.userId}`;

151

}, {

152

maxAge: 300000 // 5 minute cache per session

153

});

154

155

const session1 = new UserSession("123");

156

memoizedUserOperation(session1, "getData"); // Computes

157

memoizedUserOperation(session1, "getData"); // Cache hit

158

159

// When session1 goes out of scope, its cache is automatically cleaned up

160

```

161

162

## WeakMap-Specific Methods

163

164

### Delete Operations

165

166

Remove cache entries for specific objects and arguments.

167

168

```javascript { .api }

169

/**

170

* Delete cache entry for specific object and remaining arguments

171

* @param {Object} obj - Object key for WeakMap

172

* @param {...any} args - Additional arguments to delete

173

*/

174

memoizedFunction.delete(obj, ...args);

175

```

176

177

**Usage Examples:**

178

179

```javascript

180

const weakMemoized = weakMemoize(processData);

181

182

const obj = { id: 1 };

183

184

weakMemoized(obj, "operation1");

185

weakMemoized(obj, "operation2");

186

187

// Delete specific operation for this object

188

weakMemoized.delete(obj, "operation1");

189

190

// Object still has cache for "operation2"

191

weakMemoized(obj, "operation2"); // Cache hit

192

weakMemoized(obj, "operation1"); // Recomputes

193

```

194

195

### Reference Counting with WeakMap

196

197

Use reference counting with automatic cleanup when objects are garbage collected.

198

199

```javascript { .api }

200

/**

201

* WeakMap with reference counting methods

202

*/

203

const options = { refCounter: true };

204

205

// Additional methods available when refCounter is enabled

206

memoizedFunction.deleteRef(obj, ...args); // Decrement reference

207

memoizedFunction.getRefCount(obj, ...args); // Get reference count

208

```

209

210

**Usage Examples:**

211

212

```javascript

213

const weakRefMemoized = weakMemoize(createResource, {

214

refCounter: true

215

});

216

217

const obj = { id: "resource-key" };

218

219

const resource1 = weakRefMemoized(obj, "config"); // refs: 1

220

const resource2 = weakRefMemoized(obj, "config"); // refs: 2 (cache hit)

221

222

console.log(weakRefMemoized.getRefCount(obj, "config")); // 2

223

224

weakRefMemoized.deleteRef(obj, "config"); // refs: 1

225

weakRefMemoized.deleteRef(obj, "config"); // refs: 0, entry deleted

226

227

// Next call creates new resource

228

const newResource = weakRefMemoized(obj, "config"); // refs: 1

229

```

230

231

## Memory Management Benefits

232

233

### Automatic Garbage Collection

234

235

WeakMap memoization provides automatic memory cleanup when objects are no longer referenced:

236

237

```javascript

238

function demonstrateGC() {

239

const weakMemoized = weakMemoize(expensiveOperation);

240

241

// Create objects and cache results

242

for (let i = 0; i < 1000; i++) {

243

const obj = { id: i, data: new Array(1000).fill(i) };

244

weakMemoized(obj, "process");

245

}

246

247

// All objects go out of scope here

248

// Cache entries will be garbage collected automatically

249

// No memory leak occurs

250

}

251

252

demonstrateGC();

253

// Memory is automatically cleaned up

254

```

255

256

### Comparison with Regular Memoization

257

258

```javascript

259

// Regular memoization - can cause memory leaks

260

const regularMemoized = memoize(function(obj, operation) {

261

return process(obj, operation);

262

});

263

264

// Objects are kept alive by the cache, preventing GC

265

const objects = [];

266

for (let i = 0; i < 1000; i++) {

267

const obj = { data: new Array(1000).fill(i) };

268

objects.push(obj);

269

regularMemoized(obj, "process");

270

}

271

// objects array and cache both hold references - memory not freed

272

273

// WeakMap memoization - automatic cleanup

274

const weakMemoized = weakMemoize(function(obj, operation) {

275

return process(obj, operation);

276

});

277

278

for (let i = 0; i < 1000; i++) {

279

const obj = { data: new Array(1000).fill(i) };

280

weakMemoized(obj, "process");

281

// obj goes out of scope, cache entry eligible for GC

282

}

283

// Memory can be freed by garbage collector

284

```

285

286

## Limitations and Considerations

287

288

### WeakMap Limitations

289

290

WeakMap-based memoization has some inherent limitations:

291

292

```javascript

293

const weakMemoized = weakMemoize(someFunction);

294

295

// ❌ Cannot iterate over cached entries

296

// Object.keys(cache) is not possible

297

298

// ❌ Cannot get cache size

299

// cache.size is not available

300

301

// ❌ Cannot clear entire cache globally

302

// weakMemoized.clear() is not available

303

304

// ✅ Can delete entries for specific objects

305

weakMemoized.delete(specificObject, "arg");

306

307

// ✅ Automatic cleanup when objects are GC'd

308

```

309

310

### Best Use Cases

311

312

WeakMap memoization is ideal for:

313

314

- **DOM element processing**: Cache computations tied to DOM elements

315

- **Object transformation**: Cache results tied to specific objects

316

- **Session-based operations**: Cache tied to user sessions or request objects

317

- **Long-running applications**: Prevent memory leaks from accumulated cache

318

- **Component-based architectures**: Cache tied to component instances

319

320

### Performance Considerations

321

322

```javascript

323

// WeakMap has some performance characteristics to consider:

324

325

// ✅ Good: Object-based keys

326

const weakMemoized = weakMemoize(fn);

327

weakMemoized(objectKey, "operation");

328

329

// ❌ Avoid: Primitive first arguments (use regular memoize instead)

330

const regularMemoized = memoize(fn, { primitive: true });

331

regularMemoized("string-key", "operation"); // More efficient for primitives

332

333

// ✅ Good: When objects have natural lifetimes

334

function processUserSession(session, action) {

335

return weakMemoized(session, action); // Cleanup when session ends

336

}

337

338

// ✅ Good: Prevent memory leaks in long-running apps

339

const elementProcessor = weakMemoize(processElement);

340

elements.forEach(el => elementProcessor(el, options));

341

// Cache cleaned up when elements are removed from DOM

342

```