mutts 1.0.2 → 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 (104) hide show
  1. package/README.md +14 -6
  2. package/dist/chunks/{_tslib-C-cuVLvZ.js → _tslib-BgjropY9.js} +9 -1
  3. package/dist/chunks/_tslib-BgjropY9.js.map +1 -0
  4. package/dist/chunks/{_tslib-CMEnd0VE.esm.js → _tslib-Mzh1rNsX.esm.js} +9 -2
  5. package/dist/chunks/_tslib-Mzh1rNsX.esm.js.map +1 -0
  6. package/dist/chunks/{decorator-D4DU97Zg.js → decorator-DLvrD0UF.js} +42 -19
  7. package/dist/chunks/decorator-DLvrD0UF.js.map +1 -0
  8. package/dist/chunks/{decorator-GnHw1Az7.esm.js → decorator-DqiszP7i.esm.js} +42 -19
  9. package/dist/chunks/decorator-DqiszP7i.esm.js.map +1 -0
  10. package/dist/chunks/index-79Kk8D6e.esm.js +4857 -0
  11. package/dist/chunks/index-79Kk8D6e.esm.js.map +1 -0
  12. package/dist/chunks/index-GRBSx0mB.js +4908 -0
  13. package/dist/chunks/index-GRBSx0mB.js.map +1 -0
  14. package/dist/decorator.esm.js +1 -1
  15. package/dist/decorator.js +1 -1
  16. package/dist/destroyable.d.ts +1 -1
  17. package/dist/destroyable.esm.js +1 -1
  18. package/dist/destroyable.esm.js.map +1 -1
  19. package/dist/destroyable.js +1 -1
  20. package/dist/destroyable.js.map +1 -1
  21. package/dist/devtools/devtools.html +9 -0
  22. package/dist/devtools/devtools.js +5 -0
  23. package/dist/devtools/devtools.js.map +1 -0
  24. package/dist/devtools/manifest.json +8 -0
  25. package/dist/devtools/panel.css +72 -0
  26. package/dist/devtools/panel.html +31 -0
  27. package/dist/devtools/panel.js +13048 -0
  28. package/dist/devtools/panel.js.map +1 -0
  29. package/dist/eventful.esm.js +1 -1
  30. package/dist/eventful.js +1 -1
  31. package/dist/index.d.ts +18 -63
  32. package/dist/index.esm.js +4 -4
  33. package/dist/index.js +37 -11
  34. package/dist/index.js.map +1 -1
  35. package/dist/indexable.d.ts +187 -1
  36. package/dist/indexable.esm.js +197 -3
  37. package/dist/indexable.esm.js.map +1 -1
  38. package/dist/indexable.js +198 -2
  39. package/dist/indexable.js.map +1 -1
  40. package/dist/mutts.umd.js +1 -1
  41. package/dist/mutts.umd.js.map +1 -1
  42. package/dist/mutts.umd.min.js +1 -1
  43. package/dist/mutts.umd.min.js.map +1 -1
  44. package/dist/promiseChain.esm.js.map +1 -1
  45. package/dist/promiseChain.js.map +1 -1
  46. package/dist/reactive.d.ts +602 -97
  47. package/dist/reactive.esm.js +3 -3
  48. package/dist/reactive.js +32 -10
  49. package/dist/reactive.js.map +1 -1
  50. package/dist/std-decorators.esm.js +1 -1
  51. package/dist/std-decorators.js +1 -1
  52. package/docs/ai/api-reference.md +133 -0
  53. package/docs/ai/manual.md +105 -0
  54. package/docs/iterableWeak.md +646 -0
  55. package/docs/reactive/advanced.md +1280 -0
  56. package/docs/reactive/collections.md +767 -0
  57. package/docs/reactive/core.md +973 -0
  58. package/docs/reactive.md +21 -9545
  59. package/package.json +18 -5
  60. package/src/decorator.ts +266 -0
  61. package/src/destroyable.ts +199 -0
  62. package/src/eventful.ts +77 -0
  63. package/src/index.d.ts +9 -0
  64. package/src/index.ts +9 -0
  65. package/src/indexable.ts +484 -0
  66. package/src/introspection.ts +59 -0
  67. package/src/iterableWeak.ts +233 -0
  68. package/src/mixins.ts +123 -0
  69. package/src/promiseChain.ts +110 -0
  70. package/src/reactive/array.ts +414 -0
  71. package/src/reactive/change.ts +134 -0
  72. package/src/reactive/debug.ts +517 -0
  73. package/src/reactive/deep-touch.ts +268 -0
  74. package/src/reactive/deep-watch-state.ts +82 -0
  75. package/src/reactive/deep-watch.ts +168 -0
  76. package/src/reactive/effect-context.ts +94 -0
  77. package/src/reactive/effects.ts +1345 -0
  78. package/src/reactive/index.ts +76 -0
  79. package/src/reactive/interface.ts +223 -0
  80. package/src/reactive/map.ts +171 -0
  81. package/src/reactive/mapped.ts +130 -0
  82. package/src/reactive/memoize.ts +107 -0
  83. package/src/reactive/non-reactive-state.ts +49 -0
  84. package/src/reactive/non-reactive.ts +43 -0
  85. package/src/reactive/project.project.md +93 -0
  86. package/src/reactive/project.ts +335 -0
  87. package/src/reactive/proxy-state.ts +27 -0
  88. package/src/reactive/proxy.ts +289 -0
  89. package/src/reactive/record.ts +196 -0
  90. package/src/reactive/register.ts +421 -0
  91. package/src/reactive/set.ts +144 -0
  92. package/src/reactive/tracking.ts +101 -0
  93. package/src/reactive/types.ts +358 -0
  94. package/src/reactive/zone.ts +208 -0
  95. package/src/std-decorators.ts +217 -0
  96. package/src/utils.ts +117 -0
  97. package/dist/chunks/_tslib-C-cuVLvZ.js.map +0 -1
  98. package/dist/chunks/_tslib-CMEnd0VE.esm.js.map +0 -1
  99. package/dist/chunks/decorator-D4DU97Zg.js.map +0 -1
  100. package/dist/chunks/decorator-GnHw1Az7.esm.js.map +0 -1
  101. package/dist/chunks/index-DBScoeCX.esm.js +0 -1960
  102. package/dist/chunks/index-DBScoeCX.esm.js.map +0 -1
  103. package/dist/chunks/index-DOTmXL89.js +0 -1983
  104. package/dist/chunks/index-DOTmXL89.js.map +0 -1
@@ -0,0 +1,646 @@
1
+ # IterableWeak
2
+
3
+ A TypeScript library that provides `IterableWeakMap` and `IterableWeakSet` - data structures that combine the benefits of weak references with the ability to iterate over their contents.
4
+
5
+ ## Overview
6
+
7
+ The `iterableWeak` module provides two classes that use weak references to store keys/values while still allowing iteration. Unlike standard `WeakMap` and `WeakSet`, these classes allow you to iterate through their contents, making them useful for scenarios where you need both weak reference semantics and iteration capabilities.
8
+
9
+ **Important Note:** The behavior of these classes is highly dependent on the garbage collector. Some entries may be collected during iteration - don't attempt to "resuscitate" them by creating new references to collected keys.
10
+
11
+ ## Key Features
12
+
13
+ - **Weak References**: Keys are stored using `WeakRef`, allowing garbage collection when keys are no longer referenced
14
+ - **Iteration Support**: Unlike standard `WeakMap`/`WeakSet`, you can iterate over entries
15
+ - **Map/Set Compatibility**: Implements the standard `Map` and `Set` interfaces
16
+ - **Set Operations**: `IterableWeakSet` includes advanced set operations (union, intersection, difference, etc.)
17
+ - **Automatic Cleanup**: Garbage collected entries are automatically removed during iteration
18
+ - **Type Safety**: Full TypeScript support with proper generic types
19
+
20
+ ## API Reference
21
+
22
+ ### `IterableWeakMap<K, V>`
23
+
24
+ A map-like data structure that uses weak references for keys while allowing iteration.
25
+
26
+ **Generic Parameters:**
27
+ - `K`: The key type (must extend `WeakKey` - objects, functions, or symbols)
28
+ - `V`: The value type
29
+
30
+ **Example:**
31
+ ```typescript
32
+ import { IterableWeakMap } from 'mutts'
33
+
34
+ const map = new IterableWeakMap<object, string>()
35
+ const key = {}
36
+ map.set(key, 'value')
37
+ ```
38
+
39
+ #### Constructor
40
+
41
+ ```typescript
42
+ constructor(entries?: Iterable<[K, V]>)
43
+ ```
44
+
45
+ Creates a new `IterableWeakMap` instance, optionally initialized with entries.
46
+
47
+ **Parameters:**
48
+ - `entries`: Optional iterable of key-value pairs to initialize the map
49
+
50
+ **Example:**
51
+ ```typescript
52
+ const key1 = {}
53
+ const key2 = {}
54
+ const map = new IterableWeakMap([
55
+ [key1, 'value1'],
56
+ [key2, 'value2']
57
+ ])
58
+ ```
59
+
60
+ #### Methods
61
+
62
+ ##### `set(key: K, value: V): this`
63
+
64
+ Sets the value for the given key. If the key already exists, updates its value.
65
+
66
+ **Parameters:**
67
+ - `key`: The key to set
68
+ - `value`: The value to associate with the key
69
+
70
+ **Returns:** The map instance for chaining
71
+
72
+ **Example:**
73
+ ```typescript
74
+ map.set(key, 'new value')
75
+ map.set(key1, 'value1').set(key2, 'value2')
76
+ ```
77
+
78
+ ##### `get(key: K): V | undefined`
79
+
80
+ Retrieves the value associated with the given key.
81
+
82
+ **Parameters:**
83
+ - `key`: The key to look up
84
+
85
+ **Returns:** The associated value, or `undefined` if the key doesn't exist
86
+
87
+ **Example:**
88
+ ```typescript
89
+ const value = map.get(key)
90
+ if (value !== undefined) {
91
+ console.log('Found:', value)
92
+ }
93
+ ```
94
+
95
+ ##### `has(key: K): boolean`
96
+
97
+ Checks whether a key exists in the map.
98
+
99
+ **Parameters:**
100
+ - `key`: The key to check
101
+
102
+ **Returns:** `true` if the key exists, `false` otherwise
103
+
104
+ **Example:**
105
+ ```typescript
106
+ if (map.has(key)) {
107
+ console.log('Key exists')
108
+ }
109
+ ```
110
+
111
+ ##### `delete(key: K): boolean`
112
+
113
+ Removes a key-value pair from the map.
114
+
115
+ **Parameters:**
116
+ - `key`: The key to remove
117
+
118
+ **Returns:** `true` if the key existed and was removed, `false` otherwise
119
+
120
+ **Example:**
121
+ ```typescript
122
+ if (map.delete(key)) {
123
+ console.log('Key removed')
124
+ }
125
+ ```
126
+
127
+ ##### `clear(): void`
128
+
129
+ Removes all entries from the map.
130
+
131
+ **Example:**
132
+ ```typescript
133
+ map.clear()
134
+ ```
135
+
136
+ ##### `forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void`
137
+
138
+ Executes a callback for each key-value pair in the map.
139
+
140
+ **Parameters:**
141
+ - `callbackfn`: Function to execute for each entry
142
+ - `thisArg`: Optional value to use as `this` when executing the callback
143
+
144
+ **Example:**
145
+ ```typescript
146
+ map.forEach((value, key) => {
147
+ console.log(`${key}: ${value}`)
148
+ })
149
+ ```
150
+
151
+ ##### `entries(): MapIterator<[K, V]>`
152
+
153
+ Returns an iterator over key-value pairs.
154
+
155
+ **Returns:** An iterator that yields `[key, value]` tuples
156
+
157
+ **Example:**
158
+ ```typescript
159
+ for (const [key, value] of map.entries()) {
160
+ console.log(key, value)
161
+ }
162
+ ```
163
+
164
+ ##### `keys(): MapIterator<K>`
165
+
166
+ Returns an iterator over keys.
167
+
168
+ **Returns:** An iterator that yields keys
169
+
170
+ **Example:**
171
+ ```typescript
172
+ for (const key of map.keys()) {
173
+ console.log(key)
174
+ }
175
+ ```
176
+
177
+ ##### `values(): MapIterator<V>`
178
+
179
+ Returns an iterator over values.
180
+
181
+ **Returns:** An iterator that yields values
182
+
183
+ **Example:**
184
+ ```typescript
185
+ for (const value of map.values()) {
186
+ console.log(value)
187
+ }
188
+ ```
189
+
190
+ ##### `[Symbol.iterator](): MapIterator<[K, V]>`
191
+
192
+ Allows the map to be iterated directly using `for...of` loops.
193
+
194
+ **Example:**
195
+ ```typescript
196
+ for (const [key, value] of map) {
197
+ console.log(key, value)
198
+ }
199
+ ```
200
+
201
+ #### Properties
202
+
203
+ ##### `size: number`
204
+
205
+ Returns the number of entries in the map. **Note:** This property computes the size by iterating, so it may exclude garbage-collected entries.
206
+
207
+ **Example:**
208
+ ```typescript
209
+ console.log(`Map has ${map.size} entries`)
210
+ ```
211
+
212
+ ---
213
+
214
+ ### `IterableWeakSet<K>`
215
+
216
+ A set-like data structure that uses weak references for values while allowing iteration.
217
+
218
+ **Generic Parameters:**
219
+ - `K`: The value type (must extend `WeakKey` - objects, functions, or symbols)
220
+
221
+ **Example:**
222
+ ```typescript
223
+ import { IterableWeakSet } from 'mutts'
224
+
225
+ const set = new IterableWeakSet<object>()
226
+ const value = {}
227
+ set.add(value)
228
+ ```
229
+
230
+ #### Constructor
231
+
232
+ ```typescript
233
+ constructor(entries?: Iterable<K>)
234
+ ```
235
+
236
+ Creates a new `IterableWeakSet` instance, optionally initialized with entries.
237
+
238
+ **Parameters:**
239
+ - `entries`: Optional iterable of values to initialize the set
240
+
241
+ **Example:**
242
+ ```typescript
243
+ const value1 = {}
244
+ const value2 = {}
245
+ const set = new IterableWeakSet([value1, value2])
246
+ ```
247
+
248
+ #### Methods
249
+
250
+ ##### `add(value: K): this`
251
+
252
+ Adds a value to the set. If the value already exists, does nothing.
253
+
254
+ **Parameters:**
255
+ - `value`: The value to add
256
+
257
+ **Returns:** The set instance for chaining
258
+
259
+ **Example:**
260
+ ```typescript
261
+ set.add(value)
262
+ set.add(value1).add(value2)
263
+ ```
264
+
265
+ ##### `has(value: K): boolean`
266
+
267
+ Checks whether a value exists in the set.
268
+
269
+ **Parameters:**
270
+ - `value`: The value to check
271
+
272
+ **Returns:** `true` if the value exists, `false` otherwise
273
+
274
+ **Example:**
275
+ ```typescript
276
+ if (set.has(value)) {
277
+ console.log('Value exists')
278
+ }
279
+ ```
280
+
281
+ ##### `delete(value: K): boolean`
282
+
283
+ Removes a value from the set.
284
+
285
+ **Parameters:**
286
+ - `value`: The value to remove
287
+
288
+ **Returns:** `true` if the value existed and was removed, `false` otherwise
289
+
290
+ **Example:**
291
+ ```typescript
292
+ if (set.delete(value)) {
293
+ console.log('Value removed')
294
+ }
295
+ ```
296
+
297
+ ##### `clear(): void`
298
+
299
+ Removes all entries from the set.
300
+
301
+ **Example:**
302
+ ```typescript
303
+ set.clear()
304
+ ```
305
+
306
+ ##### `forEach(callbackfn: (value: K, value2: K, set: Set<K>) => void, thisArg?: any): void`
307
+
308
+ Executes a callback for each value in the set.
309
+
310
+ **Parameters:**
311
+ - `callbackfn`: Function to execute for each entry (receives the value twice, as per Set interface)
312
+ - `thisArg`: Optional value to use as `this` when executing the callback
313
+
314
+ **Example:**
315
+ ```typescript
316
+ set.forEach((value) => {
317
+ console.log(value)
318
+ })
319
+ ```
320
+
321
+ ##### `entries(): SetIterator<[K, K]>`
322
+
323
+ Returns an iterator over value-value pairs (as per Set interface).
324
+
325
+ **Returns:** An iterator that yields `[value, value]` tuples
326
+
327
+ **Example:**
328
+ ```typescript
329
+ for (const [value] of set.entries()) {
330
+ console.log(value)
331
+ }
332
+ ```
333
+
334
+ ##### `keys(): SetIterator<K>`
335
+
336
+ Returns an iterator over values (same as `values()` for sets).
337
+
338
+ **Returns:** An iterator that yields values
339
+
340
+ **Example:**
341
+ ```typescript
342
+ for (const value of set.keys()) {
343
+ console.log(value)
344
+ }
345
+ ```
346
+
347
+ ##### `values(): SetIterator<K>`
348
+
349
+ Returns an iterator over values.
350
+
351
+ **Returns:** An iterator that yields values
352
+
353
+ **Example:**
354
+ ```typescript
355
+ for (const value of set.values()) {
356
+ console.log(value)
357
+ }
358
+ ```
359
+
360
+ ##### `[Symbol.iterator](): SetIterator<K>`
361
+
362
+ Allows the set to be iterated directly using `for...of` loops.
363
+
364
+ **Example:**
365
+ ```typescript
366
+ for (const value of set) {
367
+ console.log(value)
368
+ }
369
+ ```
370
+
371
+ #### Set Operations
372
+
373
+ ##### `union<U>(other: ReadonlySetLike<U>): Set<K | U>`
374
+
375
+ Computes the union of this set with another set-like object.
376
+
377
+ **Parameters:**
378
+ - `other`: A set-like object (Set, IterableWeakSet, or any object with `has()` and `keys()` methods)
379
+
380
+ **Returns:** A new `Set` containing all values from both sets
381
+
382
+ **Example:**
383
+ ```typescript
384
+ const set1 = new IterableWeakSet([value1, value2])
385
+ const set2 = new Set([value2, value3])
386
+ const union = set1.union(set2)
387
+ // union contains value1, value2, value3
388
+ ```
389
+
390
+ ##### `intersection<U>(other: ReadonlySetLike<U>): Set<K & U>`
391
+
392
+ Computes the intersection of this set with another set-like object.
393
+
394
+ **Parameters:**
395
+ - `other`: A set-like object
396
+
397
+ **Returns:** A new `Set` containing only values present in both sets
398
+
399
+ **Example:**
400
+ ```typescript
401
+ const set1 = new IterableWeakSet([value1, value2])
402
+ const set2 = new Set([value2, value3])
403
+ const intersection = set1.intersection(set2)
404
+ // intersection contains only value2
405
+ ```
406
+
407
+ ##### `difference<U>(other: ReadonlySetLike<U>): Set<K>`
408
+
409
+ Computes the difference (this set minus the other set).
410
+
411
+ **Parameters:**
412
+ - `other`: A set-like object
413
+
414
+ **Returns:** A new `Set` containing values in this set but not in the other
415
+
416
+ **Example:**
417
+ ```typescript
418
+ const set1 = new IterableWeakSet([value1, value2])
419
+ const set2 = new Set([value2, value3])
420
+ const difference = set1.difference(set2)
421
+ // difference contains only value1
422
+ ```
423
+
424
+ ##### `symmetricDifference<U>(other: ReadonlySetLike<U>): Set<K | U>`
425
+
426
+ Computes the symmetric difference (values in either set but not in both).
427
+
428
+ **Parameters:**
429
+ - `other`: A set-like object
430
+
431
+ **Returns:** A new `Set` containing values in either set but not in both
432
+
433
+ **Example:**
434
+ ```typescript
435
+ const set1 = new IterableWeakSet([value1, value2])
436
+ const set2 = new Set([value2, value3])
437
+ const symDiff = set1.symmetricDifference(set2)
438
+ // symDiff contains value1 and value3
439
+ ```
440
+
441
+ ##### `isSubsetOf(other: ReadonlySetLike<unknown>): boolean`
442
+
443
+ Checks if this set is a subset of another set-like object.
444
+
445
+ **Parameters:**
446
+ - `other`: A set-like object
447
+
448
+ **Returns:** `true` if all values in this set are also in the other set
449
+
450
+ **Example:**
451
+ ```typescript
452
+ const set1 = new IterableWeakSet([value1, value2])
453
+ const set2 = new Set([value1, value2, value3])
454
+ console.log(set1.isSubsetOf(set2)) // true
455
+ ```
456
+
457
+ ##### `isSupersetOf(other: ReadonlySetLike<unknown>): boolean`
458
+
459
+ Checks if this set is a superset of another set-like object.
460
+
461
+ **Parameters:**
462
+ - `other`: A set-like object
463
+
464
+ **Returns:** `true` if all values in the other set are also in this set
465
+
466
+ **Example:**
467
+ ```typescript
468
+ const set1 = new IterableWeakSet([value1, value2, value3])
469
+ const set2 = new Set([value1, value2])
470
+ console.log(set1.isSupersetOf(set2)) // true
471
+ ```
472
+
473
+ ##### `isDisjointFrom(other: ReadonlySetLike<unknown>): boolean`
474
+
475
+ Checks if this set has no values in common with another set-like object.
476
+
477
+ **Parameters:**
478
+ - `other`: A set-like object
479
+
480
+ **Returns:** `true` if the sets have no common values
481
+
482
+ **Example:**
483
+ ```typescript
484
+ const set1 = new IterableWeakSet([value1, value2])
485
+ const set2 = new Set([value3, value4])
486
+ console.log(set1.isDisjointFrom(set2)) // true
487
+ ```
488
+
489
+ #### Properties
490
+
491
+ ##### `size: number`
492
+
493
+ Returns the number of entries in the set. **Note:** This property computes the size by iterating, so it may exclude garbage-collected entries.
494
+
495
+ **Example:**
496
+ ```typescript
497
+ console.log(`Set has ${set.size} entries`)
498
+ ```
499
+
500
+ ## Usage Examples
501
+
502
+ ### Basic Map Usage
503
+
504
+ ```typescript
505
+ import { IterableWeakMap } from 'mutts'
506
+
507
+ // Create a map
508
+ const cache = new IterableWeakMap<object, string>()
509
+
510
+ // Store values
511
+ const obj1 = { id: 1 }
512
+ const obj2 = { id: 2 }
513
+ cache.set(obj1, 'data1')
514
+ cache.set(obj2, 'data2')
515
+
516
+ // Retrieve values
517
+ console.log(cache.get(obj1)) // 'data1'
518
+
519
+ // Iterate over entries
520
+ for (const [key, value] of cache) {
521
+ console.log(key, value)
522
+ }
523
+
524
+ // Check existence
525
+ if (cache.has(obj1)) {
526
+ console.log('Object is cached')
527
+ }
528
+ ```
529
+
530
+ ### Basic Set Usage
531
+
532
+ ```typescript
533
+ import { IterableWeakSet } from 'mutts'
534
+
535
+ // Create a set
536
+ const tracked = new IterableWeakSet<object>()
537
+
538
+ // Add values
539
+ const obj1 = { id: 1 }
540
+ const obj2 = { id: 2 }
541
+ tracked.add(obj1)
542
+ tracked.add(obj2)
543
+
544
+ // Check membership
545
+ if (tracked.has(obj1)) {
546
+ console.log('Object is tracked')
547
+ }
548
+
549
+ // Iterate over values
550
+ for (const obj of tracked) {
551
+ console.log(obj)
552
+ }
553
+ ```
554
+
555
+ ### Set Operations
556
+
557
+ ```typescript
558
+ import { IterableWeakSet } from 'mutts'
559
+
560
+ const set1 = new IterableWeakSet<object>()
561
+ const set2 = new Set<object>()
562
+
563
+ const a = { id: 'a' }
564
+ const b = { id: 'b' }
565
+ const c = { id: 'c' }
566
+
567
+ set1.add(a)
568
+ set1.add(b)
569
+ set2.add(b)
570
+ set2.add(c)
571
+
572
+ // Union: all values from both sets
573
+ const union = set1.union(set2)
574
+ console.log(union.size) // 3
575
+
576
+ // Intersection: values in both sets
577
+ const intersection = set1.intersection(set2)
578
+ console.log(intersection.size) // 1 (only b)
579
+
580
+ // Difference: values in set1 but not in set2
581
+ const difference = set1.difference(set2)
582
+ console.log(difference.size) // 1 (only a)
583
+
584
+ // Symmetric difference: values in either set but not both
585
+ const symDiff = set1.symmetricDifference(set2)
586
+ console.log(symDiff.size) // 2 (a and c)
587
+ ```
588
+
589
+ ### Garbage Collection Behavior
590
+
591
+ ```typescript
592
+ import { IterableWeakSet } from 'mutts'
593
+
594
+ const set = new IterableWeakSet<object>()
595
+
596
+ // Create objects
597
+ let obj1: object | null = { id: 1 }
598
+ const obj2 = { id: 2 }
599
+
600
+ set.add(obj1)
601
+ set.add(obj2)
602
+
603
+ console.log(set.size) // 2
604
+
605
+ // Remove reference to obj1
606
+ obj1 = null
607
+
608
+ // Force garbage collection (Node.js with --expose-gc)
609
+ if (global.gc) {
610
+ global.gc()
611
+
612
+ // After GC, obj1 may be collected
613
+ // The size will reflect this on next iteration
614
+ console.log(set.size) // May be 1 or 2 depending on GC timing
615
+ }
616
+ ```
617
+
618
+ ## Important Notes
619
+
620
+ ### Garbage Collection
621
+
622
+ - **Non-deterministic behavior**: The garbage collector may collect entries at any time
623
+ - **Size property**: The `size` property iterates through entries, so it may exclude collected entries
624
+ - **Don't resuscitate**: If an entry is collected during iteration, don't try to recreate it
625
+ - **Iteration safety**: During iteration, collected entries are automatically cleaned up
626
+
627
+ ### Type Constraints
628
+
629
+ - Keys/values must extend `WeakKey` (objects, functions, or symbols)
630
+ - Primitive values (strings, numbers, booleans) cannot be used as keys/values
631
+ - This is a limitation of JavaScript's `WeakRef` API
632
+
633
+ ### Performance Considerations
634
+
635
+ - The `size` property requires iteration, so it's O(n) rather than O(1)
636
+ - Iteration automatically cleans up collected entries, which adds overhead
637
+ - For large collections, consider caching the size if needed frequently
638
+
639
+ ## Use Cases
640
+
641
+ - **Cache Management**: Store cached data with automatic cleanup when keys are garbage collected
642
+ - **Event Listener Tracking**: Track objects that have event listeners without preventing garbage collection
643
+ - **Observer Patterns**: Maintain weak references to observers while still being able to iterate
644
+ - **Memory-Efficient Collections**: Collections that automatically clean up when objects are no longer referenced
645
+ - **Set Operations**: Advanced set operations on weakly-referenced collections
646
+