evg_observable 3.0.0 → 3.0.1
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/package.json +1 -1
- package/BENCHMARK_BUNDLE_RESULTS.md +0 -149
- package/BENCHMARK_OBSERVABLE_FNS_RESULTS.md +0 -197
- package/BREAKING_CHANGES.md +0 -70
package/package.json
CHANGED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
# Benchmark Results: Bundle vs TypeScript vs RxJS
|
|
2
|
-
|
|
3
|
-
Date: 2026-01-10
|
|
4
|
-
|
|
5
|
-
## Methodology
|
|
6
|
-
|
|
7
|
-
Performance comparison of three variants:
|
|
8
|
-
|
|
9
|
-
1. **Bundle** - Minified JavaScript from `repo/evg_observable.js` (7.2 kB)
|
|
10
|
-
2. **TypeScript** - On-the-fly compilation via ts-node
|
|
11
|
-
3. **RxJS** - From node_modules (88 kB UMD bundle)
|
|
12
|
-
|
|
13
|
-
**Size comparison:** EVG Observable is **12.2x smaller** than RxJS (7.2 kB vs 88 kB)
|
|
14
|
-
|
|
15
|
-
## Test Results
|
|
16
|
-
|
|
17
|
-
Results averaged over 3 clean benchmark runs (no background processes):
|
|
18
|
-
|
|
19
|
-
### 1. Observable Creation
|
|
20
|
-
|
|
21
|
-
| Variant | Ops/sec | Relative Performance |
|
|
22
|
-
|---------|---------|---------------------|
|
|
23
|
-
| Bundle | 122,701,000 | **baseline** |
|
|
24
|
-
| TypeScript | 52,574,000 | 2.3x slower |
|
|
25
|
-
| RxJS | 53,639,000 | 2.3x slower |
|
|
26
|
-
|
|
27
|
-
**Winner: Bundle**
|
|
28
|
-
|
|
29
|
-
### 2. Emit 100 Values (1 subscriber)
|
|
30
|
-
|
|
31
|
-
| Variant | Ops/sec | Relative Performance |
|
|
32
|
-
|---------|---------|---------------------|
|
|
33
|
-
| Bundle | 1,662,000 | **baseline** |
|
|
34
|
-
| TypeScript | 1,079,000 | 1.5x slower |
|
|
35
|
-
| RxJS | 239,000 | 7.0x slower |
|
|
36
|
-
|
|
37
|
-
**Winner: Bundle**
|
|
38
|
-
|
|
39
|
-
### 3. Filter and Transform (pipe chain)
|
|
40
|
-
|
|
41
|
-
| Variant | Ops/sec | Relative Performance |
|
|
42
|
-
|---------|---------|---------------------|
|
|
43
|
-
| Bundle | 340,000 | **baseline** |
|
|
44
|
-
| TypeScript | 324,000 | ~equal (5% difference) |
|
|
45
|
-
| RxJS | 149,000 | 2.3x slower |
|
|
46
|
-
|
|
47
|
-
**Winner: Bundle** (marginal advantage)
|
|
48
|
-
|
|
49
|
-
### 4. Multiple Subscribers
|
|
50
|
-
|
|
51
|
-
#### 10 Subscribers
|
|
52
|
-
|
|
53
|
-
| Variant | Ops/sec | Relative Performance |
|
|
54
|
-
|---------|---------|---------------------|
|
|
55
|
-
| Bundle | 9,946,000 | **baseline** |
|
|
56
|
-
| TypeScript | 8,119,000 | 1.2x slower |
|
|
57
|
-
| RxJS | 3,500,000 | 2.8x slower |
|
|
58
|
-
|
|
59
|
-
#### 100 Subscribers
|
|
60
|
-
|
|
61
|
-
| Variant | Ops/sec | Relative Performance |
|
|
62
|
-
|---------|---------|---------------------|
|
|
63
|
-
| Bundle | 1,236,000 | **baseline** |
|
|
64
|
-
| TypeScript | 991,000 | 1.2x slower |
|
|
65
|
-
| RxJS | 432,000 | 2.9x slower |
|
|
66
|
-
|
|
67
|
-
#### 1000 Subscribers
|
|
68
|
-
|
|
69
|
-
| Variant | Ops/sec | Relative Performance |
|
|
70
|
-
|---------|---------|---------------------|
|
|
71
|
-
| Bundle | 124,000 | **baseline** |
|
|
72
|
-
| TypeScript | 98,000 | 1.3x slower |
|
|
73
|
-
| RxJS | 41,000 | 3.0x slower |
|
|
74
|
-
|
|
75
|
-
**Winner: Bundle** (all cases)
|
|
76
|
-
|
|
77
|
-
### 5. Batch Emission - of(100)
|
|
78
|
-
|
|
79
|
-
| Variant | Ops/sec | Relative Performance |
|
|
80
|
-
|---------|---------|---------------------|
|
|
81
|
-
| Bundle | 906,000 | **baseline** |
|
|
82
|
-
| TypeScript | 752,000 | 1.2x slower |
|
|
83
|
-
| RxJS | 176,000 | 5.1x slower |
|
|
84
|
-
|
|
85
|
-
**Winner: Bundle**
|
|
86
|
-
|
|
87
|
-
### 6. Five Chained Filters
|
|
88
|
-
|
|
89
|
-
| Variant | Ops/sec | Relative Performance |
|
|
90
|
-
|---------|---------|---------------------|
|
|
91
|
-
| Bundle | 18,900 | **baseline** |
|
|
92
|
-
| TypeScript | 18,200 | ~equal (4% difference) |
|
|
93
|
-
| RxJS | 9,200 | 2.1x slower |
|
|
94
|
-
|
|
95
|
-
**Winner: Bundle** (marginal advantage)
|
|
96
|
-
|
|
97
|
-
### 7. Large Payload (complex objects)
|
|
98
|
-
|
|
99
|
-
| Variant | Ops/sec | Relative Performance |
|
|
100
|
-
|---------|---------|---------------------|
|
|
101
|
-
| Bundle | 879,000 | **baseline** |
|
|
102
|
-
| TypeScript | 755,000 | 1.2x slower |
|
|
103
|
-
| RxJS | 184,000 | 4.8x slower |
|
|
104
|
-
|
|
105
|
-
**Winner: Bundle**
|
|
106
|
-
|
|
107
|
-
## Summary
|
|
108
|
-
|
|
109
|
-
### Bundle vs TypeScript
|
|
110
|
-
|
|
111
|
-
The minified bundle shows **consistent advantage** over TypeScript compilation:
|
|
112
|
-
|
|
113
|
-
- **Object creation**: 2.3x faster - significant advantage
|
|
114
|
-
- **Data emission**: 1.5x faster - noticeable advantage
|
|
115
|
-
- **Filtering/transformation**: ~equal performance (within 5%)
|
|
116
|
-
- **Multiple subscribers**: 1.2-1.3x faster - stable advantage
|
|
117
|
-
- **Batch emission**: 1.2x faster
|
|
118
|
-
- **Large objects**: 1.2x faster
|
|
119
|
-
|
|
120
|
-
**Reasons for bundle's advantage:**
|
|
121
|
-
1. Minification and dead code elimination
|
|
122
|
-
2. Better V8 JIT optimization for compiled code
|
|
123
|
-
3. Reduced module loading overhead
|
|
124
|
-
4. Inlining of small functions
|
|
125
|
-
|
|
126
|
-
### EVG Observable vs RxJS
|
|
127
|
-
|
|
128
|
-
Both variants (bundle and TypeScript) **significantly outperform RxJS**:
|
|
129
|
-
|
|
130
|
-
- **Creation**: ~2.3x faster
|
|
131
|
-
- **Simple emission**: 5-7x faster
|
|
132
|
-
- **Filtering**: 2.3x faster
|
|
133
|
-
- **Multiple subscribers**: 2.8-3.0x faster
|
|
134
|
-
- **Batch emission**: 4.5-5.1x faster
|
|
135
|
-
- **Complex filtering**: ~2.1x faster
|
|
136
|
-
- **Large objects**: 4.7-4.8x faster
|
|
137
|
-
|
|
138
|
-
### Recommendations
|
|
139
|
-
|
|
140
|
-
1. **For production**: Use minified bundle for maximum performance
|
|
141
|
-
2. **For development**: TypeScript compilation provides nearly equal performance with type safety convenience
|
|
142
|
-
3. **Migration from RxJS**: Expect 2-7x performance improvement depending on usage patterns
|
|
143
|
-
|
|
144
|
-
## Technical Details
|
|
145
|
-
|
|
146
|
-
- **Node.js**: v22.17.1
|
|
147
|
-
- **Benchmark.js**: Standard settings
|
|
148
|
-
- **Minimum runs**: 71-90 per test
|
|
149
|
-
- **Margin of Error**: ±0.71% - ±5.21%
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
# Benchmark Results: EVG Observable vs observable-fns
|
|
2
|
-
|
|
3
|
-
Date: 2026-01-10
|
|
4
|
-
|
|
5
|
-
## Methodology
|
|
6
|
-
|
|
7
|
-
Performance comparison of two lightweight Observable libraries:
|
|
8
|
-
|
|
9
|
-
1. **EVG Observable** - True hot observables with original architecture (7.2 kB minified)
|
|
10
|
-
2. **observable-fns** - Based on zen-observable, provides Subject for hot observables (10.8 kB minified)
|
|
11
|
-
|
|
12
|
-
**Size comparison:** EVG Observable is **1.5x smaller** than observable-fns (7.2 kB vs 10.8 kB)
|
|
13
|
-
|
|
14
|
-
Benchmarked on Node.js v22.17.1, results averaged over 3 clean runs (no background processes).
|
|
15
|
-
|
|
16
|
-
## Test Results
|
|
17
|
-
|
|
18
|
-
### 1. Observable Creation
|
|
19
|
-
|
|
20
|
-
| Library | Ops/sec | Relative Performance |
|
|
21
|
-
|---------|---------|---------------------|
|
|
22
|
-
| EVG Observable | 54,138,000 | **baseline** |
|
|
23
|
-
| observable-fns | 17,226,000 | 3.1x slower |
|
|
24
|
-
|
|
25
|
-
**Winner: EVG Observable** (3.1x faster)
|
|
26
|
-
|
|
27
|
-
### 2. Single Emission Performance Matrix
|
|
28
|
-
|
|
29
|
-
#### 1 Emission × Multiple Subscribers
|
|
30
|
-
|
|
31
|
-
| Subscribers | EVG Observable | observable-fns | Advantage |
|
|
32
|
-
|-------------|----------------|----------------|-----------|
|
|
33
|
-
| 1 | 53,802,000 ops/sec | 36,757,000 | **1.5x faster** |
|
|
34
|
-
| 10 | 14,318,000 ops/sec | 6,283,000 | **2.3x faster** |
|
|
35
|
-
| 100 | 1,700,000 ops/sec | 733,000 | **2.3x faster** |
|
|
36
|
-
| 1,000 | 176,000 ops/sec | 73,000 | **2.4x faster** |
|
|
37
|
-
| 10,000 | 16,100 ops/sec | 6,900 | **2.3x faster** |
|
|
38
|
-
|
|
39
|
-
**Winner: EVG Observable** (consistent 1.5-2.4x advantage)
|
|
40
|
-
|
|
41
|
-
#### 10 Emissions × Multiple Subscribers
|
|
42
|
-
|
|
43
|
-
| Subscribers | EVG Observable | observable-fns | Advantage |
|
|
44
|
-
|-------------|----------------|----------------|-----------|
|
|
45
|
-
| 1 | 9,881,000 ops/sec | 5,568,000 | **1.8x faster** |
|
|
46
|
-
| 10 | 1,651,000 ops/sec | 677,000 | **2.4x faster** |
|
|
47
|
-
| 100 | 176,000 ops/sec | 75,000 | **2.3x faster** |
|
|
48
|
-
| 1,000 | 17,800 ops/sec | 7,400 | **2.4x faster** |
|
|
49
|
-
| 10,000 | 1,600 ops/sec | 700 | **2.3x faster** |
|
|
50
|
-
|
|
51
|
-
**Winner: EVG Observable** (consistent 1.8-2.4x advantage)
|
|
52
|
-
|
|
53
|
-
#### 100 Emissions × Multiple Subscribers
|
|
54
|
-
|
|
55
|
-
| Subscribers | EVG Observable | observable-fns | Advantage |
|
|
56
|
-
|-------------|----------------|----------------|-----------|
|
|
57
|
-
| 1 | 1,022,000 ops/sec | 552,000 | **1.9x faster** |
|
|
58
|
-
| 10 | 169,000 ops/sec | 69,000 | **2.4x faster** |
|
|
59
|
-
| 100 | 17,500 ops/sec | 7,300 | **2.4x faster** |
|
|
60
|
-
| 1,000 | 1,770 ops/sec | 730 | **2.4x faster** |
|
|
61
|
-
| 10,000 | 166 ops/sec | 65 | **2.6x faster** |
|
|
62
|
-
|
|
63
|
-
**Winner: EVG Observable** (consistent 1.9-2.6x advantage)
|
|
64
|
-
|
|
65
|
-
#### 1000 Emissions × Multiple Subscribers
|
|
66
|
-
|
|
67
|
-
| Subscribers | EVG Observable | observable-fns | Advantage |
|
|
68
|
-
|-------------|----------------|----------------|-----------|
|
|
69
|
-
| 1 | 98,400 ops/sec | 54,400 | **1.8x faster** |
|
|
70
|
-
| 10 | 16,900 ops/sec | 7,000 | **2.4x faster** |
|
|
71
|
-
| 100 | 1,750 ops/sec | 730 | **2.4x faster** |
|
|
72
|
-
| 1,000 | 179 ops/sec | 75 | **2.4x faster** |
|
|
73
|
-
| 10,000 | 15.8 ops/sec | 6.1 | **2.6x faster** |
|
|
74
|
-
|
|
75
|
-
**Winner: EVG Observable** (consistent 1.8-2.6x advantage)
|
|
76
|
-
|
|
77
|
-
### 3. Filter & Transform (pipe chain with 100 emissions)
|
|
78
|
-
|
|
79
|
-
| Subscribers | EVG Observable | observable-fns | Advantage |
|
|
80
|
-
|-------------|----------------|----------------|-----------|
|
|
81
|
-
| 1 | 292,000 ops/sec | 127,000 | **2.3x faster** |
|
|
82
|
-
| 10 | 275,000 ops/sec | 18,700 | **14.7x faster** |
|
|
83
|
-
| 100 | 280,000 ops/sec | 1,880 | **149x faster** |
|
|
84
|
-
| 1,000 | 273,000 ops/sec | 143 | **1,909x faster** |
|
|
85
|
-
| 10,000 | 277,000 ops/sec | 13.7 | **20,219x faster** |
|
|
86
|
-
|
|
87
|
-
**Winner: EVG Observable** (dramatic advantage at higher subscriber counts)
|
|
88
|
-
|
|
89
|
-
**Analysis:** EVG Observable's pipe architecture is extremely efficient with multiple subscribers. observable-fns creates separate pipe chains per subscriber, causing exponential slowdown.
|
|
90
|
-
|
|
91
|
-
### 4. Five Chained Filters (100 emissions)
|
|
92
|
-
|
|
93
|
-
| Subscribers | EVG Observable | observable-fns | Advantage |
|
|
94
|
-
|-------------|----------------|----------------|-----------|
|
|
95
|
-
| 1 | 119,000 ops/sec | 71,300 | **1.7x faster** |
|
|
96
|
-
| 10 | 116,400 ops/sec | 7,280 | **16.0x faster** |
|
|
97
|
-
| 100 | 113,500 ops/sec | 709 | **160x faster** |
|
|
98
|
-
| 1,000 | 112,400 ops/sec | 57.6 | **1,951x faster** |
|
|
99
|
-
| 10,000 | 114,100 ops/sec | 2.1 | **54,333x faster** |
|
|
100
|
-
|
|
101
|
-
**Winner: EVG Observable** (exponential advantage at higher subscriber counts)
|
|
102
|
-
|
|
103
|
-
**Analysis:** Complex pipe chains show EVG Observable's architectural superiority. The advantage grows exponentially with subscriber count.
|
|
104
|
-
|
|
105
|
-
### 5. Large Payload (complex objects, 100 emissions)
|
|
106
|
-
|
|
107
|
-
| Library | Ops/sec | Relative Performance |
|
|
108
|
-
|---------|---------|---------------------|
|
|
109
|
-
| EVG Observable | 749,000 | **baseline** |
|
|
110
|
-
| observable-fns | 549,000 | 1.4x slower |
|
|
111
|
-
|
|
112
|
-
**Winner: EVG Observable** (1.4x faster)
|
|
113
|
-
|
|
114
|
-
### 6. Subscribe/Unsubscribe Churn (1000 cycles)
|
|
115
|
-
|
|
116
|
-
| Library | Ops/sec | Relative Performance |
|
|
117
|
-
|---------|---------|---------------------|
|
|
118
|
-
| EVG Observable | 4,406 | **~equal** |
|
|
119
|
-
| observable-fns | 4,537 | ~equal |
|
|
120
|
-
|
|
121
|
-
**Winner: Tie** (within margin of error)
|
|
122
|
-
|
|
123
|
-
**Analysis:** Both libraries have similar overhead for subscription management.
|
|
124
|
-
|
|
125
|
-
## Summary
|
|
126
|
-
|
|
127
|
-
### Key Findings
|
|
128
|
-
|
|
129
|
-
1. **Simple Emissions (1 subscriber)**: EVG Observable is **1.5-1.9x faster**
|
|
130
|
-
- Consistent advantage across all emission counts
|
|
131
|
-
- Both scale linearly
|
|
132
|
-
|
|
133
|
-
2. **Multiple Subscribers (10-10,000)**: EVG Observable is **2.3-2.6x faster**
|
|
134
|
-
- Advantage increases slightly with subscriber count
|
|
135
|
-
- EVG's true hot observable architecture shines
|
|
136
|
-
|
|
137
|
-
3. **Pipe Operations**: EVG Observable has **dramatic advantage**
|
|
138
|
-
- 1 subscriber: 1.7-2.3x faster
|
|
139
|
-
- 10 subscribers: 14.7-16.0x faster
|
|
140
|
-
- 100 subscribers: 149-160x faster
|
|
141
|
-
- 1,000 subscribers: 1,900-1,950x faster
|
|
142
|
-
- 10,000 subscribers: 20,000-54,000x faster
|
|
143
|
-
|
|
144
|
-
4. **Observable Creation**: EVG Observable is **3.1x faster**
|
|
145
|
-
- Lower instantiation overhead
|
|
146
|
-
|
|
147
|
-
5. **Large Payloads**: EVG Observable is **1.4x faster**
|
|
148
|
-
- Efficient data passing
|
|
149
|
-
|
|
150
|
-
### Architectural Insights
|
|
151
|
-
|
|
152
|
-
**EVG Observable's advantages:**
|
|
153
|
-
- True hot observable architecture (single pipe chain for all subscribers)
|
|
154
|
-
- Efficient subscription management for multi-subscriber scenarios
|
|
155
|
-
- Optimized pipe operations that don't duplicate work
|
|
156
|
-
- Lower memory overhead per subscriber
|
|
157
|
-
|
|
158
|
-
**observable-fns characteristics:**
|
|
159
|
-
- Based on zen-observable (cold observables)
|
|
160
|
-
- Each subscriber creates separate pipe chain
|
|
161
|
-
- Good for single-subscriber patterns
|
|
162
|
-
- Struggles with multi-subscriber pipe operations
|
|
163
|
-
|
|
164
|
-
### Recommendations
|
|
165
|
-
|
|
166
|
-
**Choose EVG Observable when:**
|
|
167
|
-
- You have multiple subscribers (most real-world scenarios)
|
|
168
|
-
- Using pipe operators (filter, map, etc.)
|
|
169
|
-
- Performance is critical
|
|
170
|
-
- Real-time broadcasting (WebSocket, SSE, event emitters)
|
|
171
|
-
- Need hot observable semantics
|
|
172
|
-
|
|
173
|
-
**Choose observable-fns when:**
|
|
174
|
-
- You need zen-observable API compatibility
|
|
175
|
-
- Single subscriber patterns
|
|
176
|
-
- Cold observable semantics required
|
|
177
|
-
|
|
178
|
-
### Performance Summary Table
|
|
179
|
-
|
|
180
|
-
| Operation Type | Typical Advantage | Best Case | Worst Case |
|
|
181
|
-
|----------------|-------------------|-----------|------------|
|
|
182
|
-
| Simple emission | 1.5-2.4x | 2.6x | 1.5x |
|
|
183
|
-
| Pipe (1 sub) | 1.7-2.3x | 2.3x | 1.7x |
|
|
184
|
-
| Pipe (10+ subs) | 15-20,000x | 54,333x | 14.7x |
|
|
185
|
-
| Creation | 3.1x | 3.1x | 3.1x |
|
|
186
|
-
| Large payloads | 1.4x | 1.4x | 1.4x |
|
|
187
|
-
| Sub/Unsub | ~equal | - | - |
|
|
188
|
-
|
|
189
|
-
## Technical Details
|
|
190
|
-
|
|
191
|
-
- **Node.js**: v22.17.1
|
|
192
|
-
- **Benchmark.js**: Standard settings
|
|
193
|
-
- **Runs**: 3 clean benchmark runs, averaged
|
|
194
|
-
- **Per-test samples**: 70-94 runs per scenario
|
|
195
|
-
- **Margin of Error**: ±1.2% - ±2.9% (typical)
|
|
196
|
-
- **Total scenarios**: 33 benchmark scenarios
|
|
197
|
-
- **Verification**: All pipe operations include result verification to ensure correct behavior
|
package/BREAKING_CHANGES.md
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# Breaking Changes - Performance Optimizations Branch
|
|
2
|
-
|
|
3
|
-
## Version 2.15.0
|
|
4
|
-
|
|
5
|
-
### Internal Field Renaming
|
|
6
|
-
|
|
7
|
-
**Affected field:** `value` renamed to `_value`
|
|
8
|
-
|
|
9
|
-
The internal field storing the current observable value has been renamed from `value` to `_value` to follow TypeScript conventions for protected/private members.
|
|
10
|
-
|
|
11
|
-
**Before:**
|
|
12
|
-
```typescript
|
|
13
|
-
export class Observable<T> {
|
|
14
|
-
constructor(private value: T) {}
|
|
15
|
-
}
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
**After:**
|
|
19
|
-
```typescript
|
|
20
|
-
export class Observable<T> {
|
|
21
|
-
protected _value: T;
|
|
22
|
-
constructor(value: T) {
|
|
23
|
-
this._value = value;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
**Migration:**
|
|
29
|
-
- If you were extending `Observable` and accessing `this.value`, change to `this._value`
|
|
30
|
-
- Use the public `getValue()` method for reading the current value (recommended)
|
|
31
|
-
|
|
32
|
-
### Visibility Changes
|
|
33
|
-
|
|
34
|
-
The following fields changed from `private` to `protected` to enable better inheritance:
|
|
35
|
-
|
|
36
|
-
| Field | Before | After |
|
|
37
|
-
|-------|--------|-------|
|
|
38
|
-
| `enabled` | private | protected |
|
|
39
|
-
| `filters` | private | protected |
|
|
40
|
-
| `_value` (formerly `value`) | private | protected |
|
|
41
|
-
|
|
42
|
-
**Impact:** This is not a breaking change for most users, but allows subclasses to access these fields.
|
|
43
|
-
|
|
44
|
-
### Recommended Migration Path
|
|
45
|
-
|
|
46
|
-
Instead of accessing internal fields directly, use the public API:
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
// Instead of:
|
|
50
|
-
// @ts-ignore
|
|
51
|
-
const val = observable._value;
|
|
52
|
-
|
|
53
|
-
// Use:
|
|
54
|
-
const val = observable.getValue();
|
|
55
|
-
|
|
56
|
-
// Instead of:
|
|
57
|
-
// @ts-ignore
|
|
58
|
-
const count = observable.subs.length;
|
|
59
|
-
|
|
60
|
-
// Use:
|
|
61
|
-
const count = observable.size();
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### New Behavior
|
|
65
|
-
|
|
66
|
-
1. **`destroy()` now uses `Promise.resolve()`** instead of `setInterval()` for async cleanup when called during emission
|
|
67
|
-
2. **`unsubscribeAll()` is now safe to call during `next()`** - uses deferred cleanup mechanism
|
|
68
|
-
3. **Early exit optimization** - `next()` returns immediately if there are no subscribers
|
|
69
|
-
|
|
70
|
-
These behavioral changes improve performance and memory management but should not require code changes.
|