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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evg_observable",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Alternative fast and light library version - observable.",
5
5
  "main": "src/outLib/index.js",
6
6
  "types": "src/outLib/index.d.ts",
@@ -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
@@ -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.