recursive-set 2.2.1 → 3.0.0
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 +87 -73
- package/dist/cjs/index.js +109 -104
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.d.ts +23 -10
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +107 -103
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# RecursiveSet
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> High-performance, mutable set implementation for TypeScript – modeled after ZFC set theory.
|
|
4
4
|
|
|
5
|
-
Supports
|
|
5
|
+
Supports recursive nesting, strict structural equality, and includes all classic set operations (union, intersection, difference, powerset, cartesian product). **Designed for Theoretical Computer Science, Graphs, and FSMs.**
|
|
6
6
|
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
[](https://www.npmjs.com/package/recursive-set)
|
|
@@ -11,50 +11,56 @@ Supports arbitrary nesting, detects cycles (Foundation axiom), and includes all
|
|
|
11
11
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
|
-
**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
**
|
|
18
|
-
**
|
|
19
|
-
**
|
|
20
|
-
**TypeScript generics**: works with strings, numbers, objects, states, even sets of sets
|
|
21
|
-
**Ready for FSM**, mathematical, symbolic and practical use cases
|
|
14
|
+
* **Strict Value Equality:** Mathematical sets behave mathematically. `{a, b}` is equal to `{b, a}`.
|
|
15
|
+
* **Tuples First:** Includes a strongly typed `Tuple` class for ordered pairs (e.g., edges, transitions), solving JS Array reference pitfalls.
|
|
16
|
+
* **Homogeneous by Default:** Generic typing (`RecursiveSet<T>`) enforces clean data structures.
|
|
17
|
+
* **Recursive:** Sets can contain sets (of sets...). Ideal for Power Sets and Von Neumann Ordinals.
|
|
18
|
+
* **Copy-on-Write:** **O(1) cloning** via structural sharing (powered by persistent Red-Black Trees).
|
|
19
|
+
* **Lean \& Mean:** No implicit overhead. Cycle checking is left to the user to allow maximum performance.
|
|
22
20
|
|
|
23
21
|
---
|
|
24
22
|
|
|
25
23
|
## Implementation Details
|
|
26
24
|
|
|
27
|
-
This library enforces
|
|
25
|
+
This library enforces **Strict ZFC Semantics**, differing from native JavaScript `Set`:
|
|
28
26
|
|
|
29
|
-
- **Extensionality:** Two sets are
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
- **Performance:**
|
|
35
|
-
-
|
|
36
|
-
-
|
|
27
|
+
- **Extensionality:** Two sets are equal if they contain the same elements.
|
|
28
|
+
- `new RecursiveSet(new RecursiveSet(1)).equals(new RecursiveSet(new RecursiveSet(1)))` is `true`.
|
|
29
|
+
- **No Hidden References:** Plain JavaScript Arrays and Objects are **rejected** to prevent reference-equality confusion.
|
|
30
|
+
- Use `Tuple` for ordered sequences.
|
|
31
|
+
- Use `RecursiveSet` for collections.
|
|
32
|
+
- **Performance:** Powered by **Functional Red-Black Trees**.
|
|
33
|
+
- Insertion/Lookup: **O(log n)**.
|
|
34
|
+
- Cloning: **O(1)**.
|
|
37
35
|
|
|
38
36
|
---
|
|
39
37
|
|
|
40
38
|
## Installation
|
|
41
39
|
|
|
42
|
-
```
|
|
40
|
+
```bash
|
|
43
41
|
npm install recursive-set
|
|
44
42
|
```
|
|
45
43
|
|
|
46
44
|
---
|
|
47
45
|
## Quickstart
|
|
48
|
-
```
|
|
49
|
-
import { RecursiveSet } from "recursive-set";
|
|
46
|
+
```typescript
|
|
47
|
+
import { RecursiveSet, Tuple } from "recursive-set";
|
|
50
48
|
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
49
|
+
// 1. Sets of primitives
|
|
50
|
+
const states = new RecursiveSet<string>();
|
|
51
|
+
states.add("q0").add("q1");
|
|
54
52
|
|
|
55
|
-
|
|
53
|
+
// 2. Sets of Sets (Partitioning)
|
|
54
|
+
const partition = new RecursiveSet<RecursiveSet<string>>();
|
|
55
|
+
partition.add(states); // {{q0, q1}}
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
// 3. Tuples (Ordered Pairs / Edges)
|
|
58
|
+
const edge = new Tuple("q0", "q1"); // (q0, q1)
|
|
59
|
+
const transitions = new RecursiveSet<Tuple<[string, string]>>();
|
|
60
|
+
transitions.add(edge);
|
|
61
|
+
|
|
62
|
+
console.log(partition.toString()); // {{q0, q1}}
|
|
63
|
+
console.log(transitions.toString()); // {(q0, q1)}
|
|
58
64
|
```
|
|
59
65
|
|
|
60
66
|
---
|
|
@@ -63,16 +69,17 @@ console.log(classes.toString()); // {{q0, q1}, {q2, q3}}
|
|
|
63
69
|
|
|
64
70
|
### Constructor
|
|
65
71
|
|
|
66
|
-
```
|
|
72
|
+
```typescript
|
|
73
|
+
// T must be explicit or inferred. No default 'unknown'.
|
|
67
74
|
new RecursiveSet<T>(...elements: Array<T | RecursiveSet<T>>)
|
|
68
75
|
```
|
|
69
76
|
|
|
70
77
|
### Methods
|
|
71
78
|
|
|
72
79
|
**Mutation:**
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
80
|
+
* `add(element: T | RecursiveSet<T>): this` – Add element. **Throws on NaN or plain Object/Array.**
|
|
81
|
+
* `remove(element: T | RecursiveSet<T>): this` – Remove element.
|
|
82
|
+
* `clear(): this` – Remove all elements.
|
|
76
83
|
|
|
77
84
|
**Snapshot:**
|
|
78
85
|
- `clone(): RecursiveSet<T>` – Creates a shallow copy in **O(1)** time (Copy-on-Write).
|
|
@@ -85,7 +92,7 @@ new RecursiveSet<T>(...elements: Array<T | RecursiveSet<T>>)
|
|
|
85
92
|
|
|
86
93
|
**Advanced Operations:**
|
|
87
94
|
- `powerset(): RecursiveSet<RecursiveSet<T>>` – 𝒫(A)
|
|
88
|
-
- `cartesianProduct<U>(other: RecursiveSet<U>): RecursiveSet<
|
|
95
|
+
- `cartesianProduct<U>(other: RecursiveSet<U>): RecursiveSet<Tuple<[T, U]>>` – A × B (Returns Tuples!)
|
|
89
96
|
|
|
90
97
|
**Predicates:**
|
|
91
98
|
- `has(element: T | RecursiveSet<T>): boolean` – Check membership
|
|
@@ -98,13 +105,23 @@ new RecursiveSet<T>(...elements: Array<T | RecursiveSet<T>>)
|
|
|
98
105
|
- `size: number` – Cardinality |A|
|
|
99
106
|
- `toString(): string` – Pretty print with ∅ and {}
|
|
100
107
|
|
|
108
|
+
### Tuple Class
|
|
109
|
+
|
|
110
|
+
Helper for structural value equality of sequences.
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
const t1 = new Tuple(1, 2);
|
|
114
|
+
const t2 = new Tuple(1, 2);
|
|
115
|
+
// In JS: [1,2] !== [1,2]
|
|
116
|
+
// In RecursiveSet: t1 equals t2 (Structural Equality)
|
|
117
|
+
```
|
|
101
118
|
---
|
|
102
119
|
|
|
103
120
|
## Examples
|
|
104
121
|
|
|
105
122
|
### Basic Usage
|
|
106
123
|
|
|
107
|
-
```
|
|
124
|
+
```typescript
|
|
108
125
|
const s1 = new RecursiveSet(1, 2, 3);
|
|
109
126
|
const s2 = new RecursiveSet(2, 3, 4);
|
|
110
127
|
|
|
@@ -115,7 +132,7 @@ console.log(s1.difference(s2)); // {1}
|
|
|
115
132
|
|
|
116
133
|
### Backtracking with O(1) Clone
|
|
117
134
|
|
|
118
|
-
```
|
|
135
|
+
```typescript
|
|
119
136
|
const state = new RecursiveSet("init");
|
|
120
137
|
// ... perform some operations ...
|
|
121
138
|
|
|
@@ -129,67 +146,65 @@ state.add("newState");
|
|
|
129
146
|
|
|
130
147
|
### Power Set
|
|
131
148
|
|
|
132
|
-
```
|
|
149
|
+
```typescript
|
|
133
150
|
const set = new RecursiveSet(1, 2);
|
|
134
151
|
const power = set.powerset();
|
|
135
152
|
|
|
136
153
|
console.log(power.toString()); // {∅, {1}, {2}, {1, 2}}
|
|
137
154
|
```
|
|
138
155
|
|
|
139
|
-
###
|
|
156
|
+
### Cartesian Product \& Tuples
|
|
140
157
|
|
|
141
|
-
```
|
|
142
|
-
const
|
|
158
|
+
```typescript
|
|
159
|
+
const A = new RecursiveSet(1, 2);
|
|
160
|
+
const B = new RecursiveSet("x", "y");
|
|
143
161
|
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
s.add(s);
|
|
147
|
-
} catch (e) {
|
|
148
|
-
console.error(e.message); // "Foundation axiom violated..."
|
|
149
|
-
}
|
|
162
|
+
// A × B = {(1, x), (1, y), (2, x), (2, y)}
|
|
163
|
+
const product = A.cartesianProduct(B);
|
|
150
164
|
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
} catch (e) {
|
|
155
|
-
console.error(e.message); // "NaN is not supported..."
|
|
165
|
+
// Result contains strongly typed Tuples
|
|
166
|
+
for (const tuple of product) {
|
|
167
|
+
console.log(tuple.get(0), tuple.get(1)); // 1 "x"
|
|
156
168
|
}
|
|
157
169
|
```
|
|
158
170
|
|
|
159
|
-
---
|
|
160
171
|
|
|
161
|
-
|
|
172
|
+
### Strictness (Breaking Changes in V3)
|
|
162
173
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
- **Graph algorithms**: Represent node sets and partitions
|
|
166
|
-
- **Compiler design**: Symbol tables, scope analysis
|
|
167
|
-
- **Type systems**: Type inference and unification
|
|
174
|
+
```typescript
|
|
175
|
+
const s = new RecursiveSet<number>();
|
|
168
176
|
|
|
169
|
-
|
|
177
|
+
// ❌ Error: Plain Arrays not supported (Reference Ambiguity)
|
|
178
|
+
// s.add([1, 2]);
|
|
170
179
|
|
|
171
|
-
|
|
180
|
+
// ✅ Correct: Use Tuple
|
|
181
|
+
s.add(new Tuple(1, 2));
|
|
172
182
|
|
|
183
|
+
// ❌ Error: NaN is not supported
|
|
184
|
+
// s.add(NaN);
|
|
173
185
|
```
|
|
174
|
-
# Clone repository
|
|
175
|
-
git clone https://github.com/cstrerath/recursive-set.git
|
|
176
|
-
cd recursive-set
|
|
177
186
|
|
|
178
|
-
# Install dependencies
|
|
179
|
-
npm install
|
|
180
187
|
|
|
181
|
-
|
|
182
|
-
npm run build
|
|
188
|
+
---
|
|
183
189
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
190
|
+
## Use Cases
|
|
191
|
+
|
|
192
|
+
* **Finite State Machine (FSM):** States as Sets, Transitions as Tuples.
|
|
193
|
+
* **Graph Theory:** Edges as Tuples `(u, v)`, Nodes as Sets.
|
|
194
|
+
* **Formal Languages:** Alphabets, Grammars, Power Sets.
|
|
187
195
|
|
|
188
196
|
---
|
|
189
197
|
|
|
190
198
|
## Contributing
|
|
191
199
|
|
|
192
|
-
Contributions are welcome!
|
|
200
|
+
Contributions are welcome!
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
git clone https://github.com/cstrerath/recursive-set.git
|
|
204
|
+
npm install
|
|
205
|
+
npm run build
|
|
206
|
+
npx tsx test.ts
|
|
207
|
+
```
|
|
193
208
|
|
|
194
209
|
---
|
|
195
210
|
|
|
@@ -205,7 +220,6 @@ See [LICENSE](LICENSE) for details.
|
|
|
205
220
|
## Acknowledgments
|
|
206
221
|
|
|
207
222
|
Inspired by:
|
|
208
|
-
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
- Powered by [functional-red-black-tree](https://github.com/mikolalysenko/functional-red-black-tree) for O(log n) persistence
|
|
223
|
+
* Zermelo-Fraenkel set theory (ZFC)
|
|
224
|
+
* Formal Language Theory requirements
|
|
225
|
+
* Powered by [functional-red-black-tree](https://github.com/mikolalysenko/functional-red-black-tree)
|
package/dist/cjs/index.js
CHANGED
|
@@ -3,62 +3,111 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.RecursiveSet = void 0;
|
|
6
|
+
exports.RecursiveSet = exports.Tuple = void 0;
|
|
7
7
|
exports.emptySet = emptySet;
|
|
8
8
|
exports.singleton = singleton;
|
|
9
9
|
exports.fromIterable = fromIterable;
|
|
10
10
|
const functional_red_black_tree_1 = __importDefault(require("functional-red-black-tree"));
|
|
11
11
|
/**
|
|
12
12
|
* @module recursive-set
|
|
13
|
-
* A mutable recursive set implementation
|
|
13
|
+
* A mutable recursive set implementation.
|
|
14
14
|
* Powered by functional Red-Black Trees for O(log n) operations and O(1) cloning.
|
|
15
15
|
*/
|
|
16
|
+
/**
|
|
17
|
+
* A lightweight wrapper for Tuples to enable Value-Equality in RecursiveSet.
|
|
18
|
+
* Immutable by design.
|
|
19
|
+
*/
|
|
20
|
+
class Tuple {
|
|
21
|
+
values;
|
|
22
|
+
constructor(...values) {
|
|
23
|
+
this.values = values;
|
|
24
|
+
}
|
|
25
|
+
get length() {
|
|
26
|
+
return this.values.length;
|
|
27
|
+
}
|
|
28
|
+
get(index) {
|
|
29
|
+
return this.values[index];
|
|
30
|
+
}
|
|
31
|
+
*[Symbol.iterator]() {
|
|
32
|
+
for (const val of this.values) {
|
|
33
|
+
yield val;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
toString() {
|
|
37
|
+
return `(${this.values.map(v => String(v)).join(', ')})`;
|
|
38
|
+
}
|
|
39
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
40
|
+
return this.toString();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.Tuple = Tuple;
|
|
16
44
|
class RecursiveSet {
|
|
17
|
-
// Underlying persistent data structure
|
|
18
45
|
_tree;
|
|
19
|
-
// Internal XOR-based hash for O(1) inequality checks
|
|
20
|
-
_hash = 0;
|
|
21
46
|
/**
|
|
22
47
|
* Static comparator for Red-Black Tree ordering.
|
|
23
|
-
*
|
|
48
|
+
* Supports Primitives, RecursiveSets and Tuples.
|
|
49
|
+
* REJECTS plain JS Objects and Arrays to enforce strict semantics.
|
|
24
50
|
*/
|
|
25
51
|
static compare(a, b) {
|
|
26
|
-
// 1. Identity optimization
|
|
27
52
|
if (a === b)
|
|
28
53
|
return 0;
|
|
29
|
-
// 2. Type separation
|
|
30
54
|
const isSetA = a instanceof RecursiveSet;
|
|
31
55
|
const isSetB = b instanceof RecursiveSet;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
if (
|
|
37
|
-
return
|
|
38
|
-
if (
|
|
39
|
-
return -1;
|
|
40
|
-
if (a > b)
|
|
56
|
+
const isTupA = a instanceof Tuple;
|
|
57
|
+
const isTupB = b instanceof Tuple;
|
|
58
|
+
// Sort Order: Primitives (0) < Tuples (1) < Sets (2)
|
|
59
|
+
const getTypeScore = (isSet, isTup) => {
|
|
60
|
+
if (isSet)
|
|
61
|
+
return 2;
|
|
62
|
+
if (isTup)
|
|
41
63
|
return 1;
|
|
42
64
|
return 0;
|
|
65
|
+
};
|
|
66
|
+
const scoreA = getTypeScore(isSetA, isTupA);
|
|
67
|
+
const scoreB = getTypeScore(isSetB, isTupB);
|
|
68
|
+
if (scoreA !== scoreB)
|
|
69
|
+
return scoreA < scoreB ? -1 : 1;
|
|
70
|
+
// 1. Sets
|
|
71
|
+
if (isSetA && isSetB) {
|
|
72
|
+
const setA = a;
|
|
73
|
+
const setB = b;
|
|
74
|
+
if (setA.size !== setB.size)
|
|
75
|
+
return setA.size < setB.size ? -1 : 1;
|
|
76
|
+
let iterA = setA._tree.begin;
|
|
77
|
+
let iterB = setB._tree.begin;
|
|
78
|
+
while (iterA.valid && iterB.valid) {
|
|
79
|
+
const cmp = RecursiveSet.compare(iterA.key, iterB.key);
|
|
80
|
+
if (cmp !== 0)
|
|
81
|
+
return cmp;
|
|
82
|
+
iterA.next();
|
|
83
|
+
iterB.next();
|
|
84
|
+
}
|
|
85
|
+
return 0;
|
|
43
86
|
}
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const cmp = RecursiveSet.compare(iterA.key, iterB.key);
|
|
57
|
-
if (cmp !== 0)
|
|
58
|
-
return cmp;
|
|
59
|
-
iterA.next();
|
|
60
|
-
iterB.next();
|
|
87
|
+
// 2. Tuples
|
|
88
|
+
if (isTupA && isTupB) {
|
|
89
|
+
const tupA = a;
|
|
90
|
+
const tupB = b;
|
|
91
|
+
if (tupA.length !== tupB.length)
|
|
92
|
+
return tupA.length < tupB.length ? -1 : 1;
|
|
93
|
+
for (let i = 0; i < tupA.length; i++) {
|
|
94
|
+
const cmp = RecursiveSet.compare(tupA.get(i), tupB.get(i));
|
|
95
|
+
if (cmp !== 0)
|
|
96
|
+
return cmp;
|
|
97
|
+
}
|
|
98
|
+
return 0;
|
|
61
99
|
}
|
|
100
|
+
// 3. Primitives (guaranteed by add() validation)
|
|
101
|
+
const tA = typeof a;
|
|
102
|
+
const tB = typeof b;
|
|
103
|
+
if (tA !== tB)
|
|
104
|
+
return tA > tB ? 1 : -1;
|
|
105
|
+
// @ts-ignore
|
|
106
|
+
if (a < b)
|
|
107
|
+
return -1;
|
|
108
|
+
// @ts-ignore
|
|
109
|
+
if (a > b)
|
|
110
|
+
return 1;
|
|
62
111
|
return 0;
|
|
63
112
|
}
|
|
64
113
|
constructor(...elements) {
|
|
@@ -70,72 +119,48 @@ class RecursiveSet {
|
|
|
70
119
|
// === Copy-on-Write Support ===
|
|
71
120
|
/**
|
|
72
121
|
* Creates a shallow copy of the set in O(1) time.
|
|
73
|
-
* Leveraging the persistent nature of the underlying tree.
|
|
74
122
|
*/
|
|
75
123
|
clone() {
|
|
76
124
|
const clone = new RecursiveSet();
|
|
77
125
|
clone._tree = this._tree;
|
|
78
|
-
clone._hash = this._hash;
|
|
79
126
|
return clone;
|
|
80
127
|
}
|
|
81
128
|
// === Mutable Operations ===
|
|
82
129
|
add(element) {
|
|
130
|
+
// Validation
|
|
83
131
|
if (typeof element === "number" && Number.isNaN(element)) {
|
|
84
|
-
throw new Error("NaN is not supported
|
|
132
|
+
throw new Error("NaN is not supported");
|
|
85
133
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (this._wouldCreateCycle(element)) {
|
|
93
|
-
throw new Error("Foundation axiom violated: membership cycle detected");
|
|
94
|
-
}
|
|
134
|
+
const isSet = element instanceof RecursiveSet;
|
|
135
|
+
const isTup = element instanceof Tuple;
|
|
136
|
+
const isObject = element !== null && typeof element === 'object' && !isSet && !isTup;
|
|
137
|
+
if (isObject) {
|
|
138
|
+
throw new Error("Plain Objects and Arrays are not supported. " +
|
|
139
|
+
"Use Tuple for sequences or RecursiveSet for nested structures.");
|
|
95
140
|
}
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
|
|
141
|
+
// Idempotency
|
|
142
|
+
if (this.has(element))
|
|
143
|
+
return this;
|
|
99
144
|
this._tree = this._tree.insert(element, true);
|
|
100
145
|
return this;
|
|
101
146
|
}
|
|
102
147
|
remove(element) {
|
|
103
|
-
if (!this.has(element)) {
|
|
104
|
-
return this;
|
|
105
|
-
}
|
|
106
|
-
// Update Hash (XOR removes the element from hash)
|
|
107
|
-
this._hash = (this._hash ^ this._computeHash(element)) | 0;
|
|
108
148
|
this._tree = this._tree.remove(element);
|
|
109
149
|
return this;
|
|
110
150
|
}
|
|
111
151
|
clear() {
|
|
112
152
|
this._tree = (0, functional_red_black_tree_1.default)(RecursiveSet.compare);
|
|
113
|
-
this._hash = 0;
|
|
114
153
|
return this;
|
|
115
154
|
}
|
|
116
|
-
|
|
117
|
-
if (element instanceof RecursiveSet)
|
|
118
|
-
return element._hash;
|
|
119
|
-
if (typeof element === 'number')
|
|
120
|
-
return element | 0;
|
|
121
|
-
if (typeof element === 'string') {
|
|
122
|
-
let h = 0;
|
|
123
|
-
for (let i = 0; i < element.length; i++)
|
|
124
|
-
h = Math.imul(31, h) + element.charCodeAt(i) | 0;
|
|
125
|
-
return h;
|
|
126
|
-
}
|
|
127
|
-
return 0;
|
|
128
|
-
}
|
|
129
|
-
// === Immutable Operations ===
|
|
155
|
+
// === Set Operations ===
|
|
130
156
|
union(other) {
|
|
131
|
-
const result = this.clone();
|
|
157
|
+
const result = this.clone();
|
|
132
158
|
for (const el of other)
|
|
133
159
|
result.add(el);
|
|
134
160
|
return result;
|
|
135
161
|
}
|
|
136
162
|
intersection(other) {
|
|
137
163
|
const result = new RecursiveSet();
|
|
138
|
-
// Iterate over smaller set for performance optimization
|
|
139
164
|
const [smaller, larger] = this.size < other.size ? [this, other] : [other, this];
|
|
140
165
|
for (const el of smaller) {
|
|
141
166
|
if (larger.has(el)) {
|
|
@@ -154,7 +179,6 @@ class RecursiveSet {
|
|
|
154
179
|
return result;
|
|
155
180
|
}
|
|
156
181
|
symmetricDifference(other) {
|
|
157
|
-
// (A \ B) U (B \ A)
|
|
158
182
|
return this.difference(other).union(other.difference(this));
|
|
159
183
|
}
|
|
160
184
|
powerset() {
|
|
@@ -162,7 +186,7 @@ class RecursiveSet {
|
|
|
162
186
|
if (n > 30)
|
|
163
187
|
throw new Error("Powerset size exceeds 32-bit integer limit");
|
|
164
188
|
const elements = [];
|
|
165
|
-
this._tree.forEach((key) => { elements.push(key);
|
|
189
|
+
this._tree.forEach((key) => { elements.push(key); });
|
|
166
190
|
const subsets = [];
|
|
167
191
|
for (let i = 0; i < (1 << n); i++) {
|
|
168
192
|
const subset = new RecursiveSet();
|
|
@@ -175,18 +199,18 @@ class RecursiveSet {
|
|
|
175
199
|
}
|
|
176
200
|
return new RecursiveSet(...subsets);
|
|
177
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Returns the Cartesian product as a set of Tuples.
|
|
204
|
+
* Uses the Tuple class to ensure structural equality.
|
|
205
|
+
*/
|
|
178
206
|
cartesianProduct(other) {
|
|
179
|
-
const
|
|
207
|
+
const result = new RecursiveSet();
|
|
180
208
|
for (const x of this) {
|
|
181
209
|
for (const y of other) {
|
|
182
|
-
|
|
183
|
-
const valY = y;
|
|
184
|
-
// Kuratowski pair: (x, y) = {{x}, {x, y}}
|
|
185
|
-
const pair = new RecursiveSet(new RecursiveSet(valX), new RecursiveSet(valX, valY));
|
|
186
|
-
pairs.push(pair);
|
|
210
|
+
result.add(new Tuple(x, y));
|
|
187
211
|
}
|
|
188
212
|
}
|
|
189
|
-
return
|
|
213
|
+
return result;
|
|
190
214
|
}
|
|
191
215
|
// === Predicates ===
|
|
192
216
|
has(element) {
|
|
@@ -213,37 +237,16 @@ class RecursiveSet {
|
|
|
213
237
|
equals(other) {
|
|
214
238
|
return RecursiveSet.compare(this, other) === 0;
|
|
215
239
|
}
|
|
216
|
-
// === Internals ===
|
|
217
|
-
_wouldCreateCycle(element) {
|
|
218
|
-
const visited = new Set();
|
|
219
|
-
const stack = [element];
|
|
220
|
-
while (stack.length > 0) {
|
|
221
|
-
const current = stack.pop();
|
|
222
|
-
if (current === this)
|
|
223
|
-
return true;
|
|
224
|
-
if (visited.has(current))
|
|
225
|
-
continue;
|
|
226
|
-
visited.add(current);
|
|
227
|
-
// Optimization: Direct internal tree traversal avoids iterator overhead
|
|
228
|
-
current._tree.forEach((key) => {
|
|
229
|
-
if (key instanceof RecursiveSet) {
|
|
230
|
-
stack.push(key);
|
|
231
|
-
}
|
|
232
|
-
return undefined;
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
return false;
|
|
236
|
-
}
|
|
237
240
|
// === Utility ===
|
|
238
241
|
get size() {
|
|
239
242
|
return this._tree.length;
|
|
240
243
|
}
|
|
241
244
|
toSet() {
|
|
242
245
|
const result = new Set();
|
|
243
|
-
this._tree.forEach((key) => { result.add(key);
|
|
246
|
+
this._tree.forEach((key) => { result.add(key); });
|
|
244
247
|
return result;
|
|
245
248
|
}
|
|
246
|
-
// Lazy Iterator
|
|
249
|
+
// Lazy Iterator
|
|
247
250
|
*[Symbol.iterator]() {
|
|
248
251
|
let iter = this._tree.begin;
|
|
249
252
|
while (iter.valid) {
|
|
@@ -259,10 +262,12 @@ class RecursiveSet {
|
|
|
259
262
|
if (key instanceof RecursiveSet) {
|
|
260
263
|
elements.push(key.toString());
|
|
261
264
|
}
|
|
265
|
+
else if (key instanceof Tuple) {
|
|
266
|
+
elements.push(key.toString());
|
|
267
|
+
}
|
|
262
268
|
else {
|
|
263
269
|
elements.push(String(key));
|
|
264
270
|
}
|
|
265
|
-
return undefined;
|
|
266
271
|
});
|
|
267
272
|
return `{${elements.join(", ")}}`;
|
|
268
273
|
}
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,45 +1,58 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module recursive-set
|
|
3
|
-
* A mutable recursive set implementation
|
|
3
|
+
* A mutable recursive set implementation.
|
|
4
4
|
* Powered by functional Red-Black Trees for O(log n) operations and O(1) cloning.
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* A lightweight wrapper for Tuples to enable Value-Equality in RecursiveSet.
|
|
8
|
+
* Immutable by design.
|
|
9
|
+
*/
|
|
10
|
+
export declare class Tuple<T extends unknown[]> {
|
|
11
|
+
readonly values: T;
|
|
12
|
+
constructor(...values: T);
|
|
13
|
+
get length(): number;
|
|
14
|
+
get<K extends keyof T>(index: K): T[K];
|
|
15
|
+
[Symbol.iterator](): Iterator<T[number]>;
|
|
16
|
+
toString(): string;
|
|
17
|
+
}
|
|
18
|
+
export declare class RecursiveSet<T> {
|
|
7
19
|
private _tree;
|
|
8
|
-
private _hash;
|
|
9
20
|
/**
|
|
10
21
|
* Static comparator for Red-Black Tree ordering.
|
|
11
|
-
*
|
|
22
|
+
* Supports Primitives, RecursiveSets and Tuples.
|
|
23
|
+
* REJECTS plain JS Objects and Arrays to enforce strict semantics.
|
|
12
24
|
*/
|
|
13
|
-
static compare(a:
|
|
25
|
+
static compare(a: unknown, b: unknown): number;
|
|
14
26
|
constructor(...elements: Array<T | RecursiveSet<T>>);
|
|
15
27
|
/**
|
|
16
28
|
* Creates a shallow copy of the set in O(1) time.
|
|
17
|
-
* Leveraging the persistent nature of the underlying tree.
|
|
18
29
|
*/
|
|
19
30
|
clone(): RecursiveSet<T>;
|
|
20
31
|
add(element: T | RecursiveSet<T>): this;
|
|
21
32
|
remove(element: T | RecursiveSet<T>): this;
|
|
22
33
|
clear(): this;
|
|
23
|
-
private _computeHash;
|
|
24
34
|
union(other: RecursiveSet<T>): RecursiveSet<T>;
|
|
25
35
|
intersection(other: RecursiveSet<T>): RecursiveSet<T>;
|
|
26
36
|
difference(other: RecursiveSet<T>): RecursiveSet<T>;
|
|
27
37
|
symmetricDifference(other: RecursiveSet<T>): RecursiveSet<T>;
|
|
28
38
|
powerset(): RecursiveSet<RecursiveSet<T>>;
|
|
29
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Returns the Cartesian product as a set of Tuples.
|
|
41
|
+
* Uses the Tuple class to ensure structural equality.
|
|
42
|
+
*/
|
|
43
|
+
cartesianProduct<U>(other: RecursiveSet<U>): RecursiveSet<Tuple<[T | RecursiveSet<T>, U | RecursiveSet<U>]>>;
|
|
30
44
|
has(element: T | RecursiveSet<T>): boolean;
|
|
31
45
|
isSubset(other: RecursiveSet<T>): boolean;
|
|
32
46
|
isSuperset(other: RecursiveSet<T>): boolean;
|
|
33
47
|
isProperSubset(other: RecursiveSet<T>): boolean;
|
|
34
48
|
isEmpty(): boolean;
|
|
35
49
|
equals(other: RecursiveSet<T>): boolean;
|
|
36
|
-
private _wouldCreateCycle;
|
|
37
50
|
get size(): number;
|
|
38
51
|
toSet(): Set<T | RecursiveSet<T>>;
|
|
39
52
|
[Symbol.iterator](): Iterator<T | RecursiveSet<T>>;
|
|
40
53
|
toString(): string;
|
|
41
54
|
}
|
|
42
|
-
export declare function emptySet<T
|
|
55
|
+
export declare function emptySet<T>(): RecursiveSet<T>;
|
|
43
56
|
export declare function singleton<T>(element: T): RecursiveSet<T>;
|
|
44
57
|
export declare function fromIterable<T>(iterable: Iterable<T>): RecursiveSet<T>;
|
|
45
58
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,qBAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,55 +1,103 @@
|
|
|
1
1
|
import createTree from 'functional-red-black-tree';
|
|
2
2
|
/**
|
|
3
3
|
* @module recursive-set
|
|
4
|
-
* A mutable recursive set implementation
|
|
4
|
+
* A mutable recursive set implementation.
|
|
5
5
|
* Powered by functional Red-Black Trees for O(log n) operations and O(1) cloning.
|
|
6
6
|
*/
|
|
7
|
+
/**
|
|
8
|
+
* A lightweight wrapper for Tuples to enable Value-Equality in RecursiveSet.
|
|
9
|
+
* Immutable by design.
|
|
10
|
+
*/
|
|
11
|
+
export class Tuple {
|
|
12
|
+
values;
|
|
13
|
+
constructor(...values) {
|
|
14
|
+
this.values = values;
|
|
15
|
+
}
|
|
16
|
+
get length() {
|
|
17
|
+
return this.values.length;
|
|
18
|
+
}
|
|
19
|
+
get(index) {
|
|
20
|
+
return this.values[index];
|
|
21
|
+
}
|
|
22
|
+
*[Symbol.iterator]() {
|
|
23
|
+
for (const val of this.values) {
|
|
24
|
+
yield val;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
toString() {
|
|
28
|
+
return `(${this.values.map(v => String(v)).join(', ')})`;
|
|
29
|
+
}
|
|
30
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
31
|
+
return this.toString();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
7
34
|
export class RecursiveSet {
|
|
8
|
-
// Underlying persistent data structure
|
|
9
35
|
_tree;
|
|
10
|
-
// Internal XOR-based hash for O(1) inequality checks
|
|
11
|
-
_hash = 0;
|
|
12
36
|
/**
|
|
13
37
|
* Static comparator for Red-Black Tree ordering.
|
|
14
|
-
*
|
|
38
|
+
* Supports Primitives, RecursiveSets and Tuples.
|
|
39
|
+
* REJECTS plain JS Objects and Arrays to enforce strict semantics.
|
|
15
40
|
*/
|
|
16
41
|
static compare(a, b) {
|
|
17
|
-
// 1. Identity optimization
|
|
18
42
|
if (a === b)
|
|
19
43
|
return 0;
|
|
20
|
-
// 2. Type separation
|
|
21
44
|
const isSetA = a instanceof RecursiveSet;
|
|
22
45
|
const isSetB = b instanceof RecursiveSet;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
if (
|
|
28
|
-
return
|
|
29
|
-
if (
|
|
30
|
-
return -1;
|
|
31
|
-
if (a > b)
|
|
46
|
+
const isTupA = a instanceof Tuple;
|
|
47
|
+
const isTupB = b instanceof Tuple;
|
|
48
|
+
// Sort Order: Primitives (0) < Tuples (1) < Sets (2)
|
|
49
|
+
const getTypeScore = (isSet, isTup) => {
|
|
50
|
+
if (isSet)
|
|
51
|
+
return 2;
|
|
52
|
+
if (isTup)
|
|
32
53
|
return 1;
|
|
33
54
|
return 0;
|
|
55
|
+
};
|
|
56
|
+
const scoreA = getTypeScore(isSetA, isTupA);
|
|
57
|
+
const scoreB = getTypeScore(isSetB, isTupB);
|
|
58
|
+
if (scoreA !== scoreB)
|
|
59
|
+
return scoreA < scoreB ? -1 : 1;
|
|
60
|
+
// 1. Sets
|
|
61
|
+
if (isSetA && isSetB) {
|
|
62
|
+
const setA = a;
|
|
63
|
+
const setB = b;
|
|
64
|
+
if (setA.size !== setB.size)
|
|
65
|
+
return setA.size < setB.size ? -1 : 1;
|
|
66
|
+
let iterA = setA._tree.begin;
|
|
67
|
+
let iterB = setB._tree.begin;
|
|
68
|
+
while (iterA.valid && iterB.valid) {
|
|
69
|
+
const cmp = RecursiveSet.compare(iterA.key, iterB.key);
|
|
70
|
+
if (cmp !== 0)
|
|
71
|
+
return cmp;
|
|
72
|
+
iterA.next();
|
|
73
|
+
iterB.next();
|
|
74
|
+
}
|
|
75
|
+
return 0;
|
|
34
76
|
}
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const cmp = RecursiveSet.compare(iterA.key, iterB.key);
|
|
48
|
-
if (cmp !== 0)
|
|
49
|
-
return cmp;
|
|
50
|
-
iterA.next();
|
|
51
|
-
iterB.next();
|
|
77
|
+
// 2. Tuples
|
|
78
|
+
if (isTupA && isTupB) {
|
|
79
|
+
const tupA = a;
|
|
80
|
+
const tupB = b;
|
|
81
|
+
if (tupA.length !== tupB.length)
|
|
82
|
+
return tupA.length < tupB.length ? -1 : 1;
|
|
83
|
+
for (let i = 0; i < tupA.length; i++) {
|
|
84
|
+
const cmp = RecursiveSet.compare(tupA.get(i), tupB.get(i));
|
|
85
|
+
if (cmp !== 0)
|
|
86
|
+
return cmp;
|
|
87
|
+
}
|
|
88
|
+
return 0;
|
|
52
89
|
}
|
|
90
|
+
// 3. Primitives (guaranteed by add() validation)
|
|
91
|
+
const tA = typeof a;
|
|
92
|
+
const tB = typeof b;
|
|
93
|
+
if (tA !== tB)
|
|
94
|
+
return tA > tB ? 1 : -1;
|
|
95
|
+
// @ts-ignore
|
|
96
|
+
if (a < b)
|
|
97
|
+
return -1;
|
|
98
|
+
// @ts-ignore
|
|
99
|
+
if (a > b)
|
|
100
|
+
return 1;
|
|
53
101
|
return 0;
|
|
54
102
|
}
|
|
55
103
|
constructor(...elements) {
|
|
@@ -61,72 +109,48 @@ export class RecursiveSet {
|
|
|
61
109
|
// === Copy-on-Write Support ===
|
|
62
110
|
/**
|
|
63
111
|
* Creates a shallow copy of the set in O(1) time.
|
|
64
|
-
* Leveraging the persistent nature of the underlying tree.
|
|
65
112
|
*/
|
|
66
113
|
clone() {
|
|
67
114
|
const clone = new RecursiveSet();
|
|
68
115
|
clone._tree = this._tree;
|
|
69
|
-
clone._hash = this._hash;
|
|
70
116
|
return clone;
|
|
71
117
|
}
|
|
72
118
|
// === Mutable Operations ===
|
|
73
119
|
add(element) {
|
|
120
|
+
// Validation
|
|
74
121
|
if (typeof element === "number" && Number.isNaN(element)) {
|
|
75
|
-
throw new Error("NaN is not supported
|
|
122
|
+
throw new Error("NaN is not supported");
|
|
76
123
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (this._wouldCreateCycle(element)) {
|
|
84
|
-
throw new Error("Foundation axiom violated: membership cycle detected");
|
|
85
|
-
}
|
|
124
|
+
const isSet = element instanceof RecursiveSet;
|
|
125
|
+
const isTup = element instanceof Tuple;
|
|
126
|
+
const isObject = element !== null && typeof element === 'object' && !isSet && !isTup;
|
|
127
|
+
if (isObject) {
|
|
128
|
+
throw new Error("Plain Objects and Arrays are not supported. " +
|
|
129
|
+
"Use Tuple for sequences or RecursiveSet for nested structures.");
|
|
86
130
|
}
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
|
|
131
|
+
// Idempotency
|
|
132
|
+
if (this.has(element))
|
|
133
|
+
return this;
|
|
90
134
|
this._tree = this._tree.insert(element, true);
|
|
91
135
|
return this;
|
|
92
136
|
}
|
|
93
137
|
remove(element) {
|
|
94
|
-
if (!this.has(element)) {
|
|
95
|
-
return this;
|
|
96
|
-
}
|
|
97
|
-
// Update Hash (XOR removes the element from hash)
|
|
98
|
-
this._hash = (this._hash ^ this._computeHash(element)) | 0;
|
|
99
138
|
this._tree = this._tree.remove(element);
|
|
100
139
|
return this;
|
|
101
140
|
}
|
|
102
141
|
clear() {
|
|
103
142
|
this._tree = createTree(RecursiveSet.compare);
|
|
104
|
-
this._hash = 0;
|
|
105
143
|
return this;
|
|
106
144
|
}
|
|
107
|
-
|
|
108
|
-
if (element instanceof RecursiveSet)
|
|
109
|
-
return element._hash;
|
|
110
|
-
if (typeof element === 'number')
|
|
111
|
-
return element | 0;
|
|
112
|
-
if (typeof element === 'string') {
|
|
113
|
-
let h = 0;
|
|
114
|
-
for (let i = 0; i < element.length; i++)
|
|
115
|
-
h = Math.imul(31, h) + element.charCodeAt(i) | 0;
|
|
116
|
-
return h;
|
|
117
|
-
}
|
|
118
|
-
return 0;
|
|
119
|
-
}
|
|
120
|
-
// === Immutable Operations ===
|
|
145
|
+
// === Set Operations ===
|
|
121
146
|
union(other) {
|
|
122
|
-
const result = this.clone();
|
|
147
|
+
const result = this.clone();
|
|
123
148
|
for (const el of other)
|
|
124
149
|
result.add(el);
|
|
125
150
|
return result;
|
|
126
151
|
}
|
|
127
152
|
intersection(other) {
|
|
128
153
|
const result = new RecursiveSet();
|
|
129
|
-
// Iterate over smaller set for performance optimization
|
|
130
154
|
const [smaller, larger] = this.size < other.size ? [this, other] : [other, this];
|
|
131
155
|
for (const el of smaller) {
|
|
132
156
|
if (larger.has(el)) {
|
|
@@ -145,7 +169,6 @@ export class RecursiveSet {
|
|
|
145
169
|
return result;
|
|
146
170
|
}
|
|
147
171
|
symmetricDifference(other) {
|
|
148
|
-
// (A \ B) U (B \ A)
|
|
149
172
|
return this.difference(other).union(other.difference(this));
|
|
150
173
|
}
|
|
151
174
|
powerset() {
|
|
@@ -153,7 +176,7 @@ export class RecursiveSet {
|
|
|
153
176
|
if (n > 30)
|
|
154
177
|
throw new Error("Powerset size exceeds 32-bit integer limit");
|
|
155
178
|
const elements = [];
|
|
156
|
-
this._tree.forEach((key) => { elements.push(key);
|
|
179
|
+
this._tree.forEach((key) => { elements.push(key); });
|
|
157
180
|
const subsets = [];
|
|
158
181
|
for (let i = 0; i < (1 << n); i++) {
|
|
159
182
|
const subset = new RecursiveSet();
|
|
@@ -166,18 +189,18 @@ export class RecursiveSet {
|
|
|
166
189
|
}
|
|
167
190
|
return new RecursiveSet(...subsets);
|
|
168
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Returns the Cartesian product as a set of Tuples.
|
|
194
|
+
* Uses the Tuple class to ensure structural equality.
|
|
195
|
+
*/
|
|
169
196
|
cartesianProduct(other) {
|
|
170
|
-
const
|
|
197
|
+
const result = new RecursiveSet();
|
|
171
198
|
for (const x of this) {
|
|
172
199
|
for (const y of other) {
|
|
173
|
-
|
|
174
|
-
const valY = y;
|
|
175
|
-
// Kuratowski pair: (x, y) = {{x}, {x, y}}
|
|
176
|
-
const pair = new RecursiveSet(new RecursiveSet(valX), new RecursiveSet(valX, valY));
|
|
177
|
-
pairs.push(pair);
|
|
200
|
+
result.add(new Tuple(x, y));
|
|
178
201
|
}
|
|
179
202
|
}
|
|
180
|
-
return
|
|
203
|
+
return result;
|
|
181
204
|
}
|
|
182
205
|
// === Predicates ===
|
|
183
206
|
has(element) {
|
|
@@ -204,37 +227,16 @@ export class RecursiveSet {
|
|
|
204
227
|
equals(other) {
|
|
205
228
|
return RecursiveSet.compare(this, other) === 0;
|
|
206
229
|
}
|
|
207
|
-
// === Internals ===
|
|
208
|
-
_wouldCreateCycle(element) {
|
|
209
|
-
const visited = new Set();
|
|
210
|
-
const stack = [element];
|
|
211
|
-
while (stack.length > 0) {
|
|
212
|
-
const current = stack.pop();
|
|
213
|
-
if (current === this)
|
|
214
|
-
return true;
|
|
215
|
-
if (visited.has(current))
|
|
216
|
-
continue;
|
|
217
|
-
visited.add(current);
|
|
218
|
-
// Optimization: Direct internal tree traversal avoids iterator overhead
|
|
219
|
-
current._tree.forEach((key) => {
|
|
220
|
-
if (key instanceof RecursiveSet) {
|
|
221
|
-
stack.push(key);
|
|
222
|
-
}
|
|
223
|
-
return undefined;
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
return false;
|
|
227
|
-
}
|
|
228
230
|
// === Utility ===
|
|
229
231
|
get size() {
|
|
230
232
|
return this._tree.length;
|
|
231
233
|
}
|
|
232
234
|
toSet() {
|
|
233
235
|
const result = new Set();
|
|
234
|
-
this._tree.forEach((key) => { result.add(key);
|
|
236
|
+
this._tree.forEach((key) => { result.add(key); });
|
|
235
237
|
return result;
|
|
236
238
|
}
|
|
237
|
-
// Lazy Iterator
|
|
239
|
+
// Lazy Iterator
|
|
238
240
|
*[Symbol.iterator]() {
|
|
239
241
|
let iter = this._tree.begin;
|
|
240
242
|
while (iter.valid) {
|
|
@@ -250,10 +252,12 @@ export class RecursiveSet {
|
|
|
250
252
|
if (key instanceof RecursiveSet) {
|
|
251
253
|
elements.push(key.toString());
|
|
252
254
|
}
|
|
255
|
+
else if (key instanceof Tuple) {
|
|
256
|
+
elements.push(key.toString());
|
|
257
|
+
}
|
|
253
258
|
else {
|
|
254
259
|
elements.push(String(key));
|
|
255
260
|
}
|
|
256
|
-
return undefined;
|
|
257
261
|
});
|
|
258
262
|
return `{${elements.join(", ")}}`;
|
|
259
263
|
}
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|