@guanghechen/observable 6.0.2 → 6.1.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/CHANGELOG.md +31 -0
- package/lib/cjs/index.cjs +8 -64
- package/lib/esm/index.mjs +7 -56
- package/lib/types/index.d.ts +81 -22
- package/package.json +6 -7
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,37 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See
|
|
4
4
|
[Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [6.1.0](https://github.com/guanghechen/sora/compare/@guanghechen/observable@6.0.3...@guanghechen/observable@6.1.0) (2024-03-10)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- ✨ add @guanghechen/subscriber
|
|
11
|
+
([ba57528](https://github.com/guanghechen/sora/commit/ba575283cd159e21896dfab062eff0b5da216757))
|
|
12
|
+
|
|
13
|
+
### Performance Improvements
|
|
14
|
+
|
|
15
|
+
- 🎨 refaactor observable with subscriber & remove observable.types
|
|
16
|
+
([bac2118](https://github.com/guanghechen/sora/commit/bac211888713cac920154efb593dbbcf903ab33e))
|
|
17
|
+
|
|
18
|
+
# Change Log
|
|
19
|
+
|
|
20
|
+
All notable changes to this project will be documented in this file. See
|
|
21
|
+
[Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
22
|
+
|
|
23
|
+
## [6.0.3](https://github.com/guanghechen/sora/compare/@guanghechen/observable@6.0.2...@guanghechen/observable@6.0.3) (2024-03-10)
|
|
24
|
+
|
|
25
|
+
### Performance Improvements
|
|
26
|
+
|
|
27
|
+
- 🎨 add @guanghechen/monitor back
|
|
28
|
+
([4c75f05](https://github.com/guanghechen/sora/commit/4c75f05441f57eb2428c086aea20c733f4a730c5))
|
|
29
|
+
- 🎨 format codes
|
|
30
|
+
([a953c67](https://github.com/guanghechen/sora/commit/a953c67ba19389b6b14bc829361d9ca406c24059))
|
|
31
|
+
|
|
32
|
+
# Change Log
|
|
33
|
+
|
|
34
|
+
All notable changes to this project will be documented in this file. See
|
|
35
|
+
[Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
36
|
+
|
|
6
37
|
## [6.0.2](https://github.com/guanghechen/sora/compare/@guanghechen/observable@6.0.1...@guanghechen/observable@6.0.2) (2024-03-09)
|
|
7
38
|
|
|
8
39
|
### Bug Fixes
|
package/lib/cjs/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var disposable = require('@guanghechen/disposable');
|
|
4
|
-
var
|
|
4
|
+
var subscriber = require('@guanghechen/subscriber');
|
|
5
5
|
|
|
6
6
|
const noop = (..._args) => { };
|
|
7
7
|
const noopUnsubscribable = { unsubscribe: noop };
|
|
@@ -31,7 +31,7 @@ class Observable extends disposable.BatchDisposable {
|
|
|
31
31
|
super();
|
|
32
32
|
const { equals = defaultEquals } = options;
|
|
33
33
|
this._delay = Math.max(0, Number(options.delay) || 0);
|
|
34
|
-
this._subscribers =
|
|
34
|
+
this._subscribers = new subscriber.Subscribers();
|
|
35
35
|
this._value = defaultValue;
|
|
36
36
|
this._updateTick = 0;
|
|
37
37
|
this._notifyTick = 0;
|
|
@@ -44,16 +44,7 @@ class Observable extends disposable.BatchDisposable {
|
|
|
44
44
|
return;
|
|
45
45
|
super.dispose();
|
|
46
46
|
this._flush();
|
|
47
|
-
|
|
48
|
-
const size = this._subscribers.length;
|
|
49
|
-
for (let i = 0; i < size; ++i) {
|
|
50
|
-
const item = this._subscribers[i];
|
|
51
|
-
if (item.inactive || item.subscriber.disposed)
|
|
52
|
-
continue;
|
|
53
|
-
batcher.run(() => item.subscriber.dispose());
|
|
54
|
-
}
|
|
55
|
-
this._subscribers.length = 0;
|
|
56
|
-
batcher.summary();
|
|
47
|
+
this._subscribers.dispose();
|
|
57
48
|
}
|
|
58
49
|
getSnapshot() {
|
|
59
50
|
return this._value;
|
|
@@ -84,14 +75,8 @@ class Observable extends disposable.BatchDisposable {
|
|
|
84
75
|
return noopUnsubscribable;
|
|
85
76
|
}
|
|
86
77
|
this._flush();
|
|
87
|
-
const item = { subscriber, inactive: false };
|
|
88
|
-
this._subscribers.push(item);
|
|
89
78
|
subscriber.next(value, prevValue);
|
|
90
|
-
return
|
|
91
|
-
unsubscribe: () => {
|
|
92
|
-
item.inactive = true;
|
|
93
|
-
},
|
|
94
|
-
};
|
|
79
|
+
return this._subscribers.subscribe(subscriber);
|
|
95
80
|
}
|
|
96
81
|
_flush() {
|
|
97
82
|
if (this._notifyTick < this._updateTick) {
|
|
@@ -126,41 +111,7 @@ class Observable extends disposable.BatchDisposable {
|
|
|
126
111
|
const value = this._value;
|
|
127
112
|
this._lastNotifiedValue = value;
|
|
128
113
|
this._notifyTick = this._updateTick;
|
|
129
|
-
|
|
130
|
-
const subscribers = this._subscribers;
|
|
131
|
-
const size = subscribers.length;
|
|
132
|
-
for (let i = 0; i < size; ++i) {
|
|
133
|
-
const subscriber = subscribers[i];
|
|
134
|
-
if (subscriber.inactive || subscriber.subscriber.disposed)
|
|
135
|
-
continue;
|
|
136
|
-
batcher.run(() => subscriber.subscriber.next(value, prevValue));
|
|
137
|
-
}
|
|
138
|
-
batcher.summary();
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
class Subscriber {
|
|
143
|
-
_onDispose;
|
|
144
|
-
_onNext;
|
|
145
|
-
_disposed;
|
|
146
|
-
constructor(options) {
|
|
147
|
-
this._onDispose = options?.onDispose ?? noop;
|
|
148
|
-
this._onNext = options.onNext;
|
|
149
|
-
this._disposed = false;
|
|
150
|
-
}
|
|
151
|
-
get disposed() {
|
|
152
|
-
return this._disposed;
|
|
153
|
-
}
|
|
154
|
-
dispose() {
|
|
155
|
-
if (this._disposed)
|
|
156
|
-
return;
|
|
157
|
-
this._disposed = true;
|
|
158
|
-
this._onDispose();
|
|
159
|
-
}
|
|
160
|
-
next(value, prevValue) {
|
|
161
|
-
if (this._disposed)
|
|
162
|
-
return;
|
|
163
|
-
this._onNext(value, prevValue);
|
|
114
|
+
this._subscribers.notify(value, prevValue);
|
|
164
115
|
}
|
|
165
116
|
}
|
|
166
117
|
|
|
@@ -182,25 +133,18 @@ class Ticker extends Observable {
|
|
|
182
133
|
}
|
|
183
134
|
if (observable.disposed)
|
|
184
135
|
return noopUnobservable;
|
|
185
|
-
const subscriber = new Subscriber({ onNext: () => this.tick() });
|
|
186
|
-
const unsubscribable = observable.subscribe(subscriber);
|
|
136
|
+
const subscriber$1 = new subscriber.Subscriber({ onNext: () => this.tick() });
|
|
137
|
+
const unsubscribable = observable.subscribe(subscriber$1);
|
|
187
138
|
const disposable$1 = new disposable.Disposable(() => unsubscribable.unsubscribe());
|
|
188
|
-
this.registerDisposable(subscriber);
|
|
139
|
+
this.registerDisposable(subscriber$1);
|
|
189
140
|
this.registerDisposable(disposable$1);
|
|
190
141
|
return { unobserve: () => disposable$1.dispose() };
|
|
191
142
|
}
|
|
192
143
|
}
|
|
193
144
|
|
|
194
145
|
exports.Observable = Observable;
|
|
195
|
-
exports.Subscriber = Subscriber;
|
|
196
146
|
exports.Ticker = Ticker;
|
|
197
147
|
exports.isObservable = isObservable;
|
|
198
148
|
exports.noop = noop;
|
|
199
149
|
exports.noopUnobservable = noopUnobservable;
|
|
200
150
|
exports.noopUnsubscribable = noopUnsubscribable;
|
|
201
|
-
Object.keys(observable_types).forEach(function (k) {
|
|
202
|
-
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
203
|
-
enumerable: true,
|
|
204
|
-
get: function () { return observable_types[k]; }
|
|
205
|
-
});
|
|
206
|
-
});
|
package/lib/esm/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BatchDisposable,
|
|
2
|
-
|
|
1
|
+
import { BatchDisposable, Disposable } from '@guanghechen/disposable';
|
|
2
|
+
import { Subscribers, Subscriber } from '@guanghechen/subscriber';
|
|
3
3
|
|
|
4
4
|
const noop = (..._args) => { };
|
|
5
5
|
const noopUnsubscribable = { unsubscribe: noop };
|
|
@@ -29,7 +29,7 @@ class Observable extends BatchDisposable {
|
|
|
29
29
|
super();
|
|
30
30
|
const { equals = defaultEquals } = options;
|
|
31
31
|
this._delay = Math.max(0, Number(options.delay) || 0);
|
|
32
|
-
this._subscribers =
|
|
32
|
+
this._subscribers = new Subscribers();
|
|
33
33
|
this._value = defaultValue;
|
|
34
34
|
this._updateTick = 0;
|
|
35
35
|
this._notifyTick = 0;
|
|
@@ -42,16 +42,7 @@ class Observable extends BatchDisposable {
|
|
|
42
42
|
return;
|
|
43
43
|
super.dispose();
|
|
44
44
|
this._flush();
|
|
45
|
-
|
|
46
|
-
const size = this._subscribers.length;
|
|
47
|
-
for (let i = 0; i < size; ++i) {
|
|
48
|
-
const item = this._subscribers[i];
|
|
49
|
-
if (item.inactive || item.subscriber.disposed)
|
|
50
|
-
continue;
|
|
51
|
-
batcher.run(() => item.subscriber.dispose());
|
|
52
|
-
}
|
|
53
|
-
this._subscribers.length = 0;
|
|
54
|
-
batcher.summary();
|
|
45
|
+
this._subscribers.dispose();
|
|
55
46
|
}
|
|
56
47
|
getSnapshot() {
|
|
57
48
|
return this._value;
|
|
@@ -82,14 +73,8 @@ class Observable extends BatchDisposable {
|
|
|
82
73
|
return noopUnsubscribable;
|
|
83
74
|
}
|
|
84
75
|
this._flush();
|
|
85
|
-
const item = { subscriber, inactive: false };
|
|
86
|
-
this._subscribers.push(item);
|
|
87
76
|
subscriber.next(value, prevValue);
|
|
88
|
-
return
|
|
89
|
-
unsubscribe: () => {
|
|
90
|
-
item.inactive = true;
|
|
91
|
-
},
|
|
92
|
-
};
|
|
77
|
+
return this._subscribers.subscribe(subscriber);
|
|
93
78
|
}
|
|
94
79
|
_flush() {
|
|
95
80
|
if (this._notifyTick < this._updateTick) {
|
|
@@ -124,41 +109,7 @@ class Observable extends BatchDisposable {
|
|
|
124
109
|
const value = this._value;
|
|
125
110
|
this._lastNotifiedValue = value;
|
|
126
111
|
this._notifyTick = this._updateTick;
|
|
127
|
-
|
|
128
|
-
const subscribers = this._subscribers;
|
|
129
|
-
const size = subscribers.length;
|
|
130
|
-
for (let i = 0; i < size; ++i) {
|
|
131
|
-
const subscriber = subscribers[i];
|
|
132
|
-
if (subscriber.inactive || subscriber.subscriber.disposed)
|
|
133
|
-
continue;
|
|
134
|
-
batcher.run(() => subscriber.subscriber.next(value, prevValue));
|
|
135
|
-
}
|
|
136
|
-
batcher.summary();
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
class Subscriber {
|
|
141
|
-
_onDispose;
|
|
142
|
-
_onNext;
|
|
143
|
-
_disposed;
|
|
144
|
-
constructor(options) {
|
|
145
|
-
this._onDispose = options?.onDispose ?? noop;
|
|
146
|
-
this._onNext = options.onNext;
|
|
147
|
-
this._disposed = false;
|
|
148
|
-
}
|
|
149
|
-
get disposed() {
|
|
150
|
-
return this._disposed;
|
|
151
|
-
}
|
|
152
|
-
dispose() {
|
|
153
|
-
if (this._disposed)
|
|
154
|
-
return;
|
|
155
|
-
this._disposed = true;
|
|
156
|
-
this._onDispose();
|
|
157
|
-
}
|
|
158
|
-
next(value, prevValue) {
|
|
159
|
-
if (this._disposed)
|
|
160
|
-
return;
|
|
161
|
-
this._onNext(value, prevValue);
|
|
112
|
+
this._subscribers.notify(value, prevValue);
|
|
162
113
|
}
|
|
163
114
|
}
|
|
164
115
|
|
|
@@ -189,4 +140,4 @@ class Ticker extends Observable {
|
|
|
189
140
|
}
|
|
190
141
|
}
|
|
191
142
|
|
|
192
|
-
export { Observable,
|
|
143
|
+
export { Observable, Ticker, isObservable, noop, noopUnobservable, noopUnsubscribable };
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,15 +1,51 @@
|
|
|
1
|
-
import { BatchDisposable } from '@guanghechen/disposable';
|
|
2
|
-
import {
|
|
3
|
-
export * from '@guanghechen/observable.types';
|
|
1
|
+
import { IBatchDisposable, BatchDisposable } from '@guanghechen/disposable';
|
|
2
|
+
import { ISubscribable, ISubscribers, ISubscriber, IUnsubscribable } from '@guanghechen/subscriber';
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
type IEquals<T> = (x: T, y: T) => boolean;
|
|
5
|
+
interface IObservableOptions<T> {
|
|
6
|
+
/**
|
|
7
|
+
* Delay before notifying subscribers. (milliseconds)
|
|
8
|
+
*/
|
|
9
|
+
readonly delay?: number;
|
|
10
|
+
/**
|
|
11
|
+
* Determine whether the two values are equal.
|
|
12
|
+
*/
|
|
13
|
+
readonly equals?: IEquals<T>;
|
|
8
14
|
}
|
|
15
|
+
interface IObservableNextOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Whether to throw an error if the observable disposed.
|
|
18
|
+
* @default true
|
|
19
|
+
*/
|
|
20
|
+
readonly strict?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Force trigger the notification of subscribers even the next value is equals to the current value.
|
|
23
|
+
* @default false
|
|
24
|
+
*/
|
|
25
|
+
readonly force?: boolean;
|
|
26
|
+
}
|
|
27
|
+
interface IObservable<T> extends IBatchDisposable, ISubscribable<T> {
|
|
28
|
+
readonly equals: IEquals<T>;
|
|
29
|
+
getSnapshot(): T;
|
|
30
|
+
next(value: T, options?: IObservableNextOptions): void;
|
|
31
|
+
}
|
|
32
|
+
type IValueList<T extends Array<IObservable<any>>> = {
|
|
33
|
+
[K in keyof T]: T[K] extends IObservable<infer U> ? U : never;
|
|
34
|
+
};
|
|
35
|
+
type IValueMap<T extends object> = {
|
|
36
|
+
[key in keyof T]: T[key] extends IObservable<infer U> ? U : never;
|
|
37
|
+
};
|
|
38
|
+
type IObservableRecord<T extends object> = {
|
|
39
|
+
[key in keyof T]: T[key] extends IObservable<any> ? T[key] : never;
|
|
40
|
+
};
|
|
41
|
+
type IObservableKey<T extends object> = keyof {
|
|
42
|
+
[key in keyof T]: T[key] extends IObservable<any> ? key : never;
|
|
43
|
+
};
|
|
44
|
+
|
|
9
45
|
declare class Observable<T> extends BatchDisposable implements IObservable<T> {
|
|
10
46
|
readonly equals: IEquals<T>;
|
|
11
47
|
protected readonly _delay: number;
|
|
12
|
-
protected readonly _subscribers:
|
|
48
|
+
protected readonly _subscribers: ISubscribers<T>;
|
|
13
49
|
protected _value: T;
|
|
14
50
|
protected _updateTick: number;
|
|
15
51
|
protected _notifyTick: number;
|
|
@@ -25,20 +61,43 @@ declare class Observable<T> extends BatchDisposable implements IObservable<T> {
|
|
|
25
61
|
protected _notifyImmediate(): void;
|
|
26
62
|
}
|
|
27
63
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
64
|
+
/**
|
|
65
|
+
* A unobservable can be unobserved.
|
|
66
|
+
*/
|
|
67
|
+
interface IUnobservable {
|
|
68
|
+
/**
|
|
69
|
+
* Won't get notified from the observable after unobserved, but it could still not be completed.
|
|
70
|
+
*/
|
|
71
|
+
unobserve(): void;
|
|
72
|
+
}
|
|
73
|
+
interface ITickerOptions {
|
|
74
|
+
/**
|
|
75
|
+
* The initial value of the ticker.
|
|
76
|
+
*/
|
|
77
|
+
readonly start?: number;
|
|
78
|
+
/**
|
|
79
|
+
* Delay before notifying subscribers. (milliseconds)
|
|
80
|
+
*/
|
|
81
|
+
readonly delay?: number;
|
|
82
|
+
}
|
|
83
|
+
interface ITickerObserveOptions {
|
|
84
|
+
/**
|
|
85
|
+
* Whether to throw an error if the observable disposed.
|
|
86
|
+
* @default true
|
|
87
|
+
*/
|
|
88
|
+
readonly strict?: boolean;
|
|
89
|
+
}
|
|
90
|
+
interface ITicker extends IObservable<number> {
|
|
91
|
+
/**
|
|
92
|
+
* Trigger the ticker to update the value.
|
|
93
|
+
*/
|
|
94
|
+
tick(options?: IObservableNextOptions): void;
|
|
95
|
+
/**
|
|
96
|
+
* Subscribe the change of an observable.
|
|
97
|
+
* @param observable
|
|
98
|
+
* @param options
|
|
99
|
+
*/
|
|
100
|
+
observe(observable: IObservable<any>, options?: ITickerObserveOptions): void;
|
|
42
101
|
}
|
|
43
102
|
|
|
44
103
|
declare class Ticker extends Observable<number> implements ITicker {
|
|
@@ -52,4 +111,4 @@ declare const noopUnsubscribable: IUnsubscribable;
|
|
|
52
111
|
declare const noopUnobservable: IUnobservable;
|
|
53
112
|
declare const isObservable: (obj: unknown) => obj is IObservable<unknown>;
|
|
54
113
|
|
|
55
|
-
export { type
|
|
114
|
+
export { type IEquals, type IObservable, type IObservableKey, type IObservableNextOptions, type IObservableOptions, type IObservableRecord, type ITicker, type ITickerObserveOptions, type ITickerOptions, type IUnobservable, type IValueList, type IValueMap, Observable, Ticker, isObservable, noop, noopUnobservable, noopUnsubscribable };
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guanghechen/observable",
|
|
3
|
-
"version": "6.0
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "guanghechen",
|
|
6
6
|
"url": "https://github.com/guanghechen/"
|
|
7
7
|
},
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/guanghechen/sora/tree/@guanghechen/observable@6.0.
|
|
10
|
+
"url": "https://github.com/guanghechen/sora/tree/@guanghechen/observable@6.0.3",
|
|
11
11
|
"directory": "packages/observable"
|
|
12
12
|
},
|
|
13
|
-
"homepage": "https://github.com/guanghechen/sora/tree/@guanghechen/observable@6.0.
|
|
13
|
+
"homepage": "https://github.com/guanghechen/sora/tree/@guanghechen/observable@6.0.3/packages/observable#readme",
|
|
14
14
|
"keywords": [
|
|
15
15
|
"observable"
|
|
16
16
|
],
|
|
@@ -34,9 +34,8 @@
|
|
|
34
34
|
"README.md"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@guanghechen/disposable": "^1.0.0-alpha.
|
|
38
|
-
"@guanghechen/
|
|
39
|
-
"@guanghechen/observable.types": "^6.0.1"
|
|
37
|
+
"@guanghechen/disposable": "^1.0.0-alpha.4",
|
|
38
|
+
"@guanghechen/subscriber": "^1.0.0-alpha.1"
|
|
40
39
|
},
|
|
41
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "497dbbfba4b26ad22cdc2e9500ceca625d3ffac3"
|
|
42
41
|
}
|