mutts 1.0.1 → 1.0.3
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.
- package/README.md +36 -6
- package/dist/chunks/_tslib-BgjropY9.js +81 -0
- package/dist/chunks/_tslib-BgjropY9.js.map +1 -0
- package/dist/chunks/_tslib-Mzh1rNsX.esm.js +75 -0
- package/dist/chunks/_tslib-Mzh1rNsX.esm.js.map +1 -0
- package/dist/chunks/{decorator-8qjFb7dw.js → decorator-DLvrD0UF.js} +103 -14
- package/dist/chunks/decorator-DLvrD0UF.js.map +1 -0
- package/dist/chunks/{decorator-AbRkXM5O.esm.js → decorator-DqiszP7i.esm.js} +100 -15
- package/dist/chunks/decorator-DqiszP7i.esm.js.map +1 -0
- package/dist/chunks/index-DzUDtFc7.esm.js +4841 -0
- package/dist/chunks/index-DzUDtFc7.esm.js.map +1 -0
- package/dist/chunks/index-HNVqPzjz.js +4891 -0
- package/dist/chunks/index-HNVqPzjz.js.map +1 -0
- package/dist/decorator.d.ts +57 -0
- package/dist/decorator.esm.js +1 -1
- package/dist/decorator.js +1 -1
- package/dist/destroyable.d.ts +43 -1
- package/dist/destroyable.esm.js +19 -1
- package/dist/destroyable.esm.js.map +1 -1
- package/dist/destroyable.js +19 -1
- package/dist/destroyable.js.map +1 -1
- package/dist/devtools/devtools.html +9 -0
- package/dist/devtools/devtools.js +5 -0
- package/dist/devtools/devtools.js.map +1 -0
- package/dist/devtools/manifest.json +8 -0
- package/dist/devtools/panel.css +72 -0
- package/dist/devtools/panel.html +31 -0
- package/dist/devtools/panel.js +13048 -0
- package/dist/devtools/panel.js.map +1 -0
- package/dist/eventful.d.ts +10 -1
- package/dist/eventful.esm.js +5 -27
- package/dist/eventful.esm.js.map +1 -1
- package/dist/eventful.js +15 -37
- package/dist/eventful.js.map +1 -1
- package/dist/index.d.ts +18 -14
- package/dist/index.esm.js +4 -3
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +44 -5
- package/dist/index.js.map +1 -1
- package/dist/indexable.d.ts +213 -1
- package/dist/indexable.esm.js +203 -3
- package/dist/indexable.esm.js.map +1 -1
- package/dist/indexable.js +204 -2
- package/dist/indexable.js.map +1 -1
- package/dist/mutts.umd.js +1 -1
- package/dist/mutts.umd.js.map +1 -1
- package/dist/mutts.umd.min.js +1 -1
- package/dist/mutts.umd.min.js.map +1 -1
- package/dist/promiseChain.d.ts +10 -0
- package/dist/promiseChain.esm.js +6 -0
- package/dist/promiseChain.esm.js.map +1 -1
- package/dist/promiseChain.js +6 -0
- package/dist/promiseChain.js.map +1 -1
- package/dist/reactive.d.ts +774 -33
- package/dist/reactive.esm.js +4 -1458
- package/dist/reactive.esm.js.map +1 -1
- package/dist/reactive.js +53 -1474
- package/dist/reactive.js.map +1 -1
- package/dist/std-decorators.d.ts +35 -0
- package/dist/std-decorators.esm.js +36 -1
- package/dist/std-decorators.esm.js.map +1 -1
- package/dist/std-decorators.js +36 -1
- package/dist/std-decorators.js.map +1 -1
- package/docs/ai/api-reference.md +133 -0
- package/docs/ai/manual.md +105 -0
- package/docs/iterableWeak.md +646 -0
- package/docs/mixin.md +229 -0
- package/docs/reactive/advanced.md +1280 -0
- package/docs/reactive/collections.md +767 -0
- package/docs/reactive/core.md +973 -0
- package/docs/reactive.md +21 -2688
- package/package.json +18 -5
- package/src/decorator.ts +266 -0
- package/src/destroyable.ts +199 -0
- package/src/eventful.ts +77 -0
- package/src/index.d.ts +9 -0
- package/src/index.ts +9 -0
- package/src/indexable.ts +484 -0
- package/src/introspection.ts +59 -0
- package/src/iterableWeak.ts +233 -0
- package/src/mixins.ts +123 -0
- package/src/promiseChain.ts +110 -0
- package/src/reactive/array.ts +414 -0
- package/src/reactive/change.ts +134 -0
- package/src/reactive/debug.ts +517 -0
- package/src/reactive/deep-touch.ts +268 -0
- package/src/reactive/deep-watch-state.ts +82 -0
- package/src/reactive/deep-watch.ts +168 -0
- package/src/reactive/effect-context.ts +94 -0
- package/src/reactive/effects.ts +1333 -0
- package/src/reactive/index.ts +75 -0
- package/src/reactive/interface.ts +223 -0
- package/src/reactive/map.ts +171 -0
- package/src/reactive/mapped.ts +130 -0
- package/src/reactive/memoize.ts +107 -0
- package/src/reactive/non-reactive-state.ts +49 -0
- package/src/reactive/non-reactive.ts +43 -0
- package/src/reactive/project.project.md +93 -0
- package/src/reactive/project.ts +335 -0
- package/src/reactive/proxy-state.ts +27 -0
- package/src/reactive/proxy.ts +285 -0
- package/src/reactive/record.ts +196 -0
- package/src/reactive/register.ts +421 -0
- package/src/reactive/set.ts +144 -0
- package/src/reactive/tracking.ts +101 -0
- package/src/reactive/types.ts +358 -0
- package/src/reactive/zone.ts +208 -0
- package/src/std-decorators.ts +217 -0
- package/src/utils.ts +117 -0
- package/dist/chunks/decorator-8qjFb7dw.js.map +0 -1
- package/dist/chunks/decorator-AbRkXM5O.esm.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
|
+
|