@ersbeth/picoflow 0.0.1 → 0.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/api/doc/index.md +1 -1
- package/api/doc/picoflow.constant.md +55 -0
- package/api/doc/picoflow.derivation.md +1 -1
- package/api/doc/picoflow.effect.md +1 -1
- package/api/doc/picoflow.flowconstant._constructor_.md +49 -0
- package/api/doc/picoflow.flowconstant.get.md +25 -0
- package/api/doc/picoflow.flowconstant.md +88 -0
- package/api/doc/picoflow.flowderivation._constructor_.md +2 -2
- package/api/doc/picoflow.flowderivation.get.md +2 -2
- package/api/doc/picoflow.flowderivation.md +2 -2
- package/api/doc/picoflow.floweffect._constructor_.md +7 -2
- package/api/doc/picoflow.floweffect.dispose.md +3 -3
- package/api/doc/picoflow.floweffect.disposed.md +1 -1
- package/api/doc/picoflow.floweffect.md +4 -4
- package/api/doc/picoflow.flowgetter.md +2 -2
- package/api/doc/picoflow.flowmap._lastdeleted.md +1 -1
- package/api/doc/picoflow.flowmap._lastset.md +1 -1
- package/api/doc/picoflow.flowmap.delete.md +6 -2
- package/api/doc/picoflow.flowmap.md +5 -7
- package/api/doc/picoflow.flowmap.setat.md +6 -2
- package/api/doc/picoflow.flowobservable.get.md +3 -3
- package/api/doc/picoflow.flowobservable.md +18 -4
- package/api/doc/picoflow.flowobservable.subscribe.md +55 -0
- package/api/doc/picoflow.flowresource._constructor_.md +2 -18
- package/api/doc/picoflow.flowresource.fetch.md +1 -1
- package/api/doc/picoflow.flowresource.get.md +4 -4
- package/api/doc/picoflow.flowresource.md +4 -4
- package/api/doc/picoflow.flowresourceasync._constructor_.md +49 -0
- package/api/doc/picoflow.flowresourceasync.fetch.md +27 -0
- package/api/doc/picoflow.flowresourceasync.get.md +23 -0
- package/api/doc/picoflow.flowresourceasync.md +100 -0
- package/api/doc/picoflow.flowsignal.dispose.md +3 -7
- package/api/doc/picoflow.flowsignal.disposed.md +2 -2
- package/api/doc/picoflow.flowsignal.md +5 -5
- package/api/doc/picoflow.flowsignal.trigger.md +3 -7
- package/api/doc/picoflow.flowstate.md +4 -52
- package/api/doc/picoflow.flowstate.set.md +5 -5
- package/api/doc/picoflow.flowstream._constructor_.md +3 -19
- package/api/doc/picoflow.flowstream.dispose.md +1 -1
- package/api/doc/picoflow.flowstream.get.md +4 -4
- package/api/doc/picoflow.flowstream.md +5 -5
- package/api/doc/picoflow.flowstreamasync._constructor_.md +54 -0
- package/api/doc/picoflow.flowstreamasync.dispose.md +21 -0
- package/api/doc/picoflow.flowstreamasync.get.md +23 -0
- package/api/doc/picoflow.flowstreamasync.md +100 -0
- package/api/doc/picoflow.flowstreamdisposer.md +13 -0
- package/api/doc/picoflow.flowstreamsetter.md +13 -0
- package/api/doc/picoflow.flowstreamupdater.md +19 -0
- package/api/doc/picoflow.flowwatcher.md +1 -1
- package/api/doc/picoflow.map.md +1 -1
- package/api/doc/picoflow.md +80 -14
- package/api/doc/picoflow.resource.md +2 -18
- package/api/doc/picoflow.resourceasync.md +55 -0
- package/api/doc/picoflow.signal.md +1 -1
- package/api/doc/picoflow.state.md +3 -3
- package/api/doc/picoflow.stream.md +2 -18
- package/api/doc/picoflow.streamasync.md +55 -0
- package/api/picoflow.public.api.md +131 -0
- package/api-extractor.json +2 -1
- package/dist/picoflow.js +326 -302
- package/dist/types/advanced/index.d.ts +7 -0
- package/dist/types/advanced/index.d.ts.map +1 -0
- package/dist/types/{map.d.ts → advanced/map.d.ts} +12 -12
- package/dist/types/advanced/map.d.ts.map +1 -0
- package/dist/types/advanced/resource.d.ts +39 -0
- package/dist/types/advanced/resource.d.ts.map +1 -0
- package/dist/types/{resource.d.ts → advanced/resourceAsync.d.ts} +6 -11
- package/dist/types/advanced/resourceAsync.d.ts.map +1 -0
- package/dist/types/advanced/stream.d.ts +59 -0
- package/dist/types/advanced/stream.d.ts.map +1 -0
- package/dist/types/advanced/streamAsync.d.ts +43 -0
- package/dist/types/advanced/streamAsync.d.ts.map +1 -0
- package/dist/types/basic/constant.d.ts +32 -0
- package/dist/types/basic/constant.d.ts.map +1 -0
- package/dist/types/basic/derivation.d.ts +40 -0
- package/dist/types/basic/derivation.d.ts.map +1 -0
- package/dist/types/basic/effect.d.ts +56 -0
- package/dist/types/basic/effect.d.ts.map +1 -0
- package/dist/types/basic/index.d.ts +9 -0
- package/dist/types/basic/index.d.ts.map +1 -0
- package/dist/types/basic/observable.d.ts +34 -0
- package/dist/types/basic/observable.d.ts.map +1 -0
- package/dist/types/basic/signal.d.ts +37 -0
- package/dist/types/basic/signal.d.ts.map +1 -0
- package/dist/types/basic/state.d.ts +26 -0
- package/dist/types/basic/state.d.ts.map +1 -0
- package/dist/types/creators.d.ts +29 -13
- package/dist/types/creators.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -9
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/advanced/index.ts +10 -0
- package/src/{map.ts → advanced/map.ts} +14 -14
- package/src/advanced/resource.ts +56 -0
- package/src/{resource.ts → advanced/resourceAsync.ts} +9 -16
- package/src/advanced/stream.ts +87 -0
- package/src/advanced/streamAsync.ts +82 -0
- package/src/basic/constant.ts +64 -0
- package/src/basic/derivation.ts +86 -0
- package/src/basic/effect.ts +96 -0
- package/src/basic/index.ts +8 -0
- package/src/basic/observable.ts +51 -0
- package/src/basic/signal.ts +105 -0
- package/src/basic/state.ts +39 -0
- package/src/creators.ts +54 -15
- package/src/index.ts +21 -11
- package/test/constant.test.ts +46 -0
- package/test/derivation.test.ts +30 -6
- package/test/effect.test.ts +29 -0
- package/test/map.test.ts +38 -0
- package/test/resource.test.ts +18 -16
- package/test/resourceAsync.test.ts +108 -0
- package/test/signal.test.ts +18 -1
- package/test/state.test.ts +107 -2
- package/test/stream.test.ts +38 -13
- package/test/streamAsync.test.ts +194 -0
- package/tsconfig.json +3 -1
- package/api/doc/picoflow.flowdisposer.md +0 -13
- package/api/doc/picoflow.flowsetter.md +0 -13
- package/api/doc/picoflow.flowstate._constructor_.md +0 -49
- package/api/doc/picoflow.flowstate.get.md +0 -23
- package/api/doc/picoflow.flowupdater.md +0 -19
- package/api/picoflow.api.md +0 -145
- package/dist/types/derivation.d.ts +0 -58
- package/dist/types/derivation.d.ts.map +0 -1
- package/dist/types/effect.d.ts +0 -108
- package/dist/types/effect.d.ts.map +0 -1
- package/dist/types/map.d.ts.map +0 -1
- package/dist/types/observable.d.ts +0 -40
- package/dist/types/observable.d.ts.map +0 -1
- package/dist/types/resource.d.ts.map +0 -1
- package/dist/types/signal.d.ts +0 -111
- package/dist/types/signal.d.ts.map +0 -1
- package/dist/types/state.d.ts +0 -39
- package/dist/types/state.d.ts.map +0 -1
- package/dist/types/stream.d.ts +0 -71
- package/dist/types/stream.d.ts.map +0 -1
- package/src/derivation.ts +0 -96
- package/src/effect.ts +0 -152
- package/src/observable.ts +0 -50
- package/src/signal.ts +0 -166
- package/src/state.ts +0 -52
- package/src/stream.ts +0 -99
package/src/derivation.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { type FlowGetter, FlowObservable } from "./observable";
|
|
2
|
-
import type { FlowWatcher } from "./signal";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Represents a reactive derivation whose value is computed based on other reactive signals.
|
|
6
|
-
* @remarks
|
|
7
|
-
* A FlowDerivation automatically tracks its dependencies and recomputes its value when needed.
|
|
8
|
-
* @typeparam T - The type of the computed value.
|
|
9
|
-
* @public
|
|
10
|
-
*/
|
|
11
|
-
export class FlowDerivation<T> extends FlowObservable<T> {
|
|
12
|
-
/**
|
|
13
|
-
* Creates a new FlowDerivation.
|
|
14
|
-
* @param compute - A function that computes the derived value. It is provided with a getter
|
|
15
|
-
* and a watcher function to access observables and signals dependencies.
|
|
16
|
-
* @public
|
|
17
|
-
*/
|
|
18
|
-
constructor(compute: (get: FlowGetter, watch: FlowWatcher) => T) {
|
|
19
|
-
super();
|
|
20
|
-
this._trackedExec = () => compute(this._trackedGet, this._trackedWatch);
|
|
21
|
-
this._untrackedExec = () =>
|
|
22
|
-
compute(this._untrackedGet, this._untrackedWatch);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Gets the current derived value.
|
|
27
|
-
* @returns The current computed value.
|
|
28
|
-
* @remarks
|
|
29
|
-
* This method ensures that the derivation is up-to-date before returning the value.
|
|
30
|
-
* @public
|
|
31
|
-
*/
|
|
32
|
-
public get(): T {
|
|
33
|
-
this._exec();
|
|
34
|
-
return this._value;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/* INTERNAL MEMBERS AND METHODS */
|
|
38
|
-
|
|
39
|
-
/** @internal */
|
|
40
|
-
private _initialized = false;
|
|
41
|
-
|
|
42
|
-
/** @internal */
|
|
43
|
-
private _dirty = true;
|
|
44
|
-
|
|
45
|
-
/** @internal */
|
|
46
|
-
private _trackedGet: FlowGetter = (observable) => observable._getFrom(this);
|
|
47
|
-
|
|
48
|
-
/** @internal */
|
|
49
|
-
private _trackedWatch: FlowWatcher = (signal) => signal._watchFrom(this);
|
|
50
|
-
|
|
51
|
-
/** @internal */
|
|
52
|
-
private _untrackedGet: FlowGetter = (observable) => observable.get();
|
|
53
|
-
|
|
54
|
-
/** @internal */
|
|
55
|
-
private _untrackedWatch: FlowWatcher = (signal) => signal._watch();
|
|
56
|
-
|
|
57
|
-
/** @internal */
|
|
58
|
-
private _trackedExec: () => T;
|
|
59
|
-
|
|
60
|
-
/** @internal */
|
|
61
|
-
private _untrackedExec: () => T;
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* @internal
|
|
65
|
-
* Executes the compute function if necessary to update the derived value.
|
|
66
|
-
*/
|
|
67
|
-
_exec(): void {
|
|
68
|
-
if (this._disposed) throw new Error("Effect is disposed");
|
|
69
|
-
|
|
70
|
-
if (this._dirty) {
|
|
71
|
-
if (this._initialized) this._value = this._untrackedExec();
|
|
72
|
-
else {
|
|
73
|
-
this._value = this._trackedExec();
|
|
74
|
-
this._initialized = true;
|
|
75
|
-
}
|
|
76
|
-
this._dirty = false;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* @internal
|
|
82
|
-
* Marks the derivation as dirty and notifies downstream dependencies.
|
|
83
|
-
*/
|
|
84
|
-
override _notify(): void {
|
|
85
|
-
this._dirty = true;
|
|
86
|
-
super._notify();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* @internal
|
|
91
|
-
* Ensures that the derivation is up-to-date when it is watched.
|
|
92
|
-
*/
|
|
93
|
-
override _watch(): void {
|
|
94
|
-
this._exec();
|
|
95
|
-
}
|
|
96
|
-
}
|
package/src/effect.ts
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import type { FlowGetter } from "./observable";
|
|
2
|
-
import type { FlowSignal, FlowWatcher } from "./signal";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Represents a reactive effect that executes a side‐effect function
|
|
6
|
-
* based on its tracked dependencies.
|
|
7
|
-
*
|
|
8
|
-
* @remarks
|
|
9
|
-
* A FlowEffect runs an apply function to perform side effects. The apply function
|
|
10
|
-
* is executed in two modes:
|
|
11
|
-
* Initially, in a tracked mode to register dependencies.
|
|
12
|
-
* Subsequently, in an untracked mode to only re-execute the effect .
|
|
13
|
-
*
|
|
14
|
-
* @public
|
|
15
|
-
*/
|
|
16
|
-
export class FlowEffect {
|
|
17
|
-
/* API --------------------------------------------------- */
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Creates a new FlowEffect.
|
|
21
|
-
*
|
|
22
|
-
* @param apply - A function that performs the side effect. It receives a getter and a watcher
|
|
23
|
-
* function to access and register dependencies on reactive observables and signals.
|
|
24
|
-
*
|
|
25
|
-
* @public
|
|
26
|
-
*/
|
|
27
|
-
constructor(apply: (get: FlowGetter, watch: FlowWatcher) => void) {
|
|
28
|
-
this._trackedExec = () => apply(this._trackedGet, this._trackedWatch);
|
|
29
|
-
this._untrackedExec = () =>
|
|
30
|
-
apply(this._untrackedGet, this._untrackedWatch);
|
|
31
|
-
this._exec();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Disposes the effect, unregistering all its dependencies.
|
|
36
|
-
*
|
|
37
|
-
* @remarks
|
|
38
|
-
* After disposal, the effect should no longer be used. Calling this method on an already
|
|
39
|
-
* disposed effect will throw an error.
|
|
40
|
-
*
|
|
41
|
-
* @public
|
|
42
|
-
*/
|
|
43
|
-
public dispose(): void {
|
|
44
|
-
if (this._disposed) throw new Error("Effect is disposed");
|
|
45
|
-
Array.from(this._dependencies).forEach((dependency) => {
|
|
46
|
-
this._unregisterDependency(dependency);
|
|
47
|
-
});
|
|
48
|
-
this._disposed = true;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Indicates whether this effect has been disposed.
|
|
53
|
-
*
|
|
54
|
-
* @returns A boolean value indicating if the effect is disposed.
|
|
55
|
-
*
|
|
56
|
-
* @public
|
|
57
|
-
*/
|
|
58
|
-
public get disposed(): boolean {
|
|
59
|
-
return this._disposed;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/* INTERNAL ------------------------------------------------------------ */
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* @internal
|
|
66
|
-
*/
|
|
67
|
-
private _disposed = false;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* @internal
|
|
71
|
-
*/
|
|
72
|
-
private _initialized = false;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* @internal
|
|
76
|
-
*/
|
|
77
|
-
private _dependencies = new Set<FlowSignal>();
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* @internal
|
|
81
|
-
* A tracked getter that registers a dependency when accessing an observable.
|
|
82
|
-
*/
|
|
83
|
-
private _trackedGet: FlowGetter = (observable) => observable._getFrom(this);
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* @internal
|
|
87
|
-
* A tracked watcher that registers a dependency when watching a signal.
|
|
88
|
-
*/
|
|
89
|
-
private _trackedWatch: FlowWatcher = (signal) => signal._watchFrom(this);
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* @internal
|
|
93
|
-
* An untracked getter that simply retrieves the current value from an observable.
|
|
94
|
-
*/
|
|
95
|
-
private _untrackedGet: FlowGetter = (observable) => observable.get();
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* @internal
|
|
99
|
-
* An untracked watcher that calls the default watch on a signal.
|
|
100
|
-
*/
|
|
101
|
-
private _untrackedWatch: FlowWatcher = (signal) => signal._watch();
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* @internal
|
|
105
|
-
* Execution function used during initialization (tracked mode).
|
|
106
|
-
*/
|
|
107
|
-
private _trackedExec: () => void;
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* @internal
|
|
111
|
-
* Execution function used after initialization (untracked mode).
|
|
112
|
-
*/
|
|
113
|
-
private _untrackedExec: () => void;
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* @internal
|
|
117
|
-
* Executes the effect. If the effect has not been initialized, it runs in tracked mode;
|
|
118
|
-
* otherwise, it runs in untracked mode.
|
|
119
|
-
*
|
|
120
|
-
* @throws Error if the effect has been disposed.
|
|
121
|
-
*/
|
|
122
|
-
_exec(): void {
|
|
123
|
-
if (this._disposed) throw new Error("Effect is disposed");
|
|
124
|
-
if (this._initialized) this._untrackedExec();
|
|
125
|
-
else {
|
|
126
|
-
this._trackedExec();
|
|
127
|
-
this._initialized = true;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* @internal
|
|
133
|
-
* Registers a dependency on the given signal.
|
|
134
|
-
*
|
|
135
|
-
* @param dependency - The FlowSignal to register as a dependency.
|
|
136
|
-
*/
|
|
137
|
-
_registerDependency(dependency: FlowSignal): void {
|
|
138
|
-
this._dependencies.add(dependency);
|
|
139
|
-
dependency._registerEffect(this);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* @internal
|
|
144
|
-
* Unregisters the given dependency.
|
|
145
|
-
*
|
|
146
|
-
* @param dependency - The FlowSignal to unregister.
|
|
147
|
-
*/
|
|
148
|
-
_unregisterDependency(dependency: FlowSignal): void {
|
|
149
|
-
this._dependencies.delete(dependency);
|
|
150
|
-
dependency._unregisterEffect(this);
|
|
151
|
-
}
|
|
152
|
-
}
|
package/src/observable.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type { FlowEffect } from "./effect";
|
|
2
|
-
import { FlowSignal } from "./signal";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* A function for retrieving the current value from a FlowObservable.
|
|
6
|
-
* @typeparam T - The type of the value held by the observable.
|
|
7
|
-
* @param atom - The FlowObservable from which to get the value.
|
|
8
|
-
* @returns The current value of the observable.
|
|
9
|
-
* @public
|
|
10
|
-
*/
|
|
11
|
-
export type FlowGetter = <T>(observable: FlowObservable<T>) => T;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Represents a reactive observable that carries a value.
|
|
15
|
-
* @typeparam T - The type of the value held by the observable.
|
|
16
|
-
* @remarks
|
|
17
|
-
* A FlowObservable extends the basic FlowSignal to store a value. Subclasses must
|
|
18
|
-
* implement the abstract {@link FlowObservable.get} method to return the current value.
|
|
19
|
-
* @public
|
|
20
|
-
*/
|
|
21
|
-
export abstract class FlowObservable<T> extends FlowSignal {
|
|
22
|
-
/* API ----------------------------------------------- */
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Retrieves the current value of the observable.
|
|
26
|
-
* @returns The current value.
|
|
27
|
-
* @public
|
|
28
|
-
*/
|
|
29
|
-
abstract get(): T;
|
|
30
|
-
|
|
31
|
-
/* INTERNAL -------------------------------------------*/
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* @internal
|
|
35
|
-
* Internal storage for the observable's value.
|
|
36
|
-
*/
|
|
37
|
-
protected _value!: T;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @internal
|
|
41
|
-
* Retrieves the current value from the observable and registers a dependency
|
|
42
|
-
* from the provided listener.
|
|
43
|
-
* @param listener - The FlowObservable or FlowEffect that is accessing this observable.
|
|
44
|
-
* @returns The current value, as returned by {@link FlowObservable.get}.
|
|
45
|
-
*/
|
|
46
|
-
_getFrom(listener: FlowObservable<unknown> | FlowEffect): T {
|
|
47
|
-
listener._registerDependency(this);
|
|
48
|
-
return this.get();
|
|
49
|
-
}
|
|
50
|
-
}
|
package/src/signal.ts
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import type { FlowEffect } from "./effect";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* A function for watching a FlowSignal.
|
|
5
|
-
* @param signal - The FlowSignal that is being observed.
|
|
6
|
-
* @public
|
|
7
|
-
*/
|
|
8
|
-
export type FlowWatcher = (signal: FlowSignal) => void;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Represents a reactive signal.
|
|
12
|
-
* @remarks
|
|
13
|
-
* A FlowSignal allows you to trigger notifications via {@link FlowSignal.trigger}
|
|
14
|
-
* and to dispose the signal and all its registered dependencies, listeners, and effects via {@link FlowSignal.dispose}.
|
|
15
|
-
* @public
|
|
16
|
-
*/
|
|
17
|
-
export class FlowSignal {
|
|
18
|
-
/* API ---------------------------------------------------------------------- */
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Triggers the signal.
|
|
22
|
-
* @remarks
|
|
23
|
-
* This method notifies all registered listeners and causes associated effects to execute.
|
|
24
|
-
* @throws Error if the signal is disposed.
|
|
25
|
-
* @public
|
|
26
|
-
*/
|
|
27
|
-
public trigger(): void {
|
|
28
|
-
if (this._disposed) throw new Error("Signal is disposed");
|
|
29
|
-
this._notify();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Disposes the signal.
|
|
34
|
-
* @remarks
|
|
35
|
-
* Disposing a signal will dispose all registered effects and listeners,
|
|
36
|
-
* and unregister all dependencies. Once disposed, any further calls to the signal
|
|
37
|
-
* will throw an error.
|
|
38
|
-
* @throws Error if the signal is already disposed.
|
|
39
|
-
* @public
|
|
40
|
-
*/
|
|
41
|
-
public dispose(): void {
|
|
42
|
-
if (this._disposed) throw new Error("Signal is disposed");
|
|
43
|
-
Array.from(this._effects).forEach((effect) => effect.dispose());
|
|
44
|
-
Array.from(this._listeners).forEach((listener) => listener.dispose());
|
|
45
|
-
Array.from(this._dependencies).forEach((dependency) => {
|
|
46
|
-
this._unregisterDependency(dependency);
|
|
47
|
-
});
|
|
48
|
-
this._disposed = true;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Indicates whether the signal has been disposed.
|
|
53
|
-
* @remarks
|
|
54
|
-
* Once disposed, the signal should not be used.
|
|
55
|
-
* @public
|
|
56
|
-
*/
|
|
57
|
-
public get disposed(): boolean {
|
|
58
|
-
return this._disposed;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/* INTERNAL ------------------------------------------------------------- */
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* @internal
|
|
65
|
-
*/
|
|
66
|
-
protected _disposed = false;
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* @internal
|
|
70
|
-
*/
|
|
71
|
-
protected _dependencies = new Set<FlowSignal>();
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* @internal
|
|
75
|
-
*/
|
|
76
|
-
protected _listeners = new Set<FlowSignal>();
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* @internal
|
|
80
|
-
*/
|
|
81
|
-
protected _effects = new Set<FlowEffect>();
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* @internal
|
|
85
|
-
* Internal method to watch the signal.
|
|
86
|
-
* @throws Error if the signal is disposed.
|
|
87
|
-
*/
|
|
88
|
-
_watch(): void {
|
|
89
|
-
if (this._disposed) throw new Error("Signal is disposed");
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* @internal
|
|
94
|
-
* Notifies all listeners and executes all registered effects.
|
|
95
|
-
*/
|
|
96
|
-
_notify(): void {
|
|
97
|
-
this._listeners.forEach((listener) => listener._notify());
|
|
98
|
-
this._effects.forEach((effect) => effect._exec());
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* @internal
|
|
103
|
-
* Registers a dependency from the given listener and watches the signal.
|
|
104
|
-
* @param listener - A FlowSignal or FlowEffect that will depend on this signal.
|
|
105
|
-
*/
|
|
106
|
-
_watchFrom(listener: FlowSignal | FlowEffect): void {
|
|
107
|
-
listener._registerDependency(this);
|
|
108
|
-
this._watch();
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* @internal
|
|
113
|
-
* Registers a dependency with the given FlowSignal.
|
|
114
|
-
* @param dependency - The FlowSignal to register as a dependency.
|
|
115
|
-
*/
|
|
116
|
-
_registerDependency(dependency: FlowSignal): void {
|
|
117
|
-
this._dependencies.add(dependency);
|
|
118
|
-
dependency._registerListener(this);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* @internal
|
|
123
|
-
* Unregisters the given dependency.
|
|
124
|
-
* @param dependency - The FlowSignal to unregister.
|
|
125
|
-
*/
|
|
126
|
-
_unregisterDependency(dependency: FlowSignal): void {
|
|
127
|
-
this._dependencies.delete(dependency);
|
|
128
|
-
dependency._unregisterListener(this);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* @internal
|
|
133
|
-
* Registers a listener (another FlowSignal) to this signal.
|
|
134
|
-
* @param signal - The FlowSignal to register as a listener.
|
|
135
|
-
*/
|
|
136
|
-
_registerListener(signal: FlowSignal): void {
|
|
137
|
-
this._listeners.add(signal);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* @internal
|
|
142
|
-
* Unregisters the given listener.
|
|
143
|
-
* @param signal - The FlowSignal to unregister.
|
|
144
|
-
*/
|
|
145
|
-
_unregisterListener(signal: FlowSignal): void {
|
|
146
|
-
this._listeners.delete(signal);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* @internal
|
|
151
|
-
* Registers a FlowEffect to this signal.
|
|
152
|
-
* @param effect - The FlowEffect to register.
|
|
153
|
-
*/
|
|
154
|
-
_registerEffect(effect: FlowEffect): void {
|
|
155
|
-
this._effects.add(effect);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* @internal
|
|
160
|
-
* Unregisters the given FlowEffect.
|
|
161
|
-
* @param effect - The FlowEffect to unregister.
|
|
162
|
-
*/
|
|
163
|
-
_unregisterEffect(effect: FlowEffect): void {
|
|
164
|
-
this._effects.delete(effect);
|
|
165
|
-
}
|
|
166
|
-
}
|
package/src/state.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { FlowObservable } from "./observable";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Represents a reactive state that holds a mutable value.
|
|
5
|
-
*
|
|
6
|
-
* @typeparam T - The type of the state value.
|
|
7
|
-
*
|
|
8
|
-
* @remarks
|
|
9
|
-
* FlowState extends FlowObservable to provide a simple reactive state primitive.
|
|
10
|
-
* Use the {@link FlowState.get} method to read the current state and {@link FlowState.set} to update it.
|
|
11
|
-
* When the state is updated, subscribers are notified automatically.
|
|
12
|
-
*
|
|
13
|
-
* @public
|
|
14
|
-
*/
|
|
15
|
-
export class FlowState<T> extends FlowObservable<T> {
|
|
16
|
-
/**
|
|
17
|
-
* Creates a new FlowState with the given initial value.
|
|
18
|
-
* @param value - The initial value for the state.
|
|
19
|
-
* @public
|
|
20
|
-
*/
|
|
21
|
-
constructor(value: T) {
|
|
22
|
-
super();
|
|
23
|
-
this._value = value;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Retrieves the current state value.
|
|
28
|
-
* @returns The current value of the state.
|
|
29
|
-
* @throws Error if the state has been disposed.
|
|
30
|
-
* @public
|
|
31
|
-
*/
|
|
32
|
-
get(): T {
|
|
33
|
-
if (this._disposed) throw new Error("State is disposed");
|
|
34
|
-
return this._value;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Updates the state with a new value.
|
|
39
|
-
* @param value - The new value to set.
|
|
40
|
-
* @remarks
|
|
41
|
-
* If the new value is identical to the current value, no update or notification occurs.
|
|
42
|
-
* Otherwise, the state is updated and all subscribers are notified.
|
|
43
|
-
* @throws Error if the state has been disposed.
|
|
44
|
-
* @public
|
|
45
|
-
*/
|
|
46
|
-
set(value: T): void {
|
|
47
|
-
if (this._disposed) throw new Error("State is disposed");
|
|
48
|
-
if (value === this._value) return;
|
|
49
|
-
this._value = value;
|
|
50
|
-
this._notify();
|
|
51
|
-
}
|
|
52
|
-
}
|
package/src/stream.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { FlowObservable } from "./observable";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* A function that sets a new value.
|
|
5
|
-
* @typeparam T - The type of the value.
|
|
6
|
-
* @public
|
|
7
|
-
*/
|
|
8
|
-
export type FlowSetter<T> = (value: T) => void;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* A function that disposes of a resource.
|
|
12
|
-
* @public
|
|
13
|
-
*/
|
|
14
|
-
export type FlowDisposer = () => void;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* A function that performs updates on a stream.
|
|
18
|
-
* @remarks
|
|
19
|
-
* The updater receives a setter function that can be used to update the stream's value.
|
|
20
|
-
* It should return a disposer function to clean up any resources or subscriptions.
|
|
21
|
-
* @typeparam T - The type of the stream value.
|
|
22
|
-
* @public
|
|
23
|
-
*/
|
|
24
|
-
export type FlowUpdater<T> = (set: FlowSetter<T>) => FlowDisposer;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Represents a reactive stream that updates its value based on an updater function.
|
|
28
|
-
*
|
|
29
|
-
* @remarks
|
|
30
|
-
* A FlowStream extends FlowObservable and encapsulates a mechanism for updating its value
|
|
31
|
-
* via an external updater function. The updater is invoked during construction with a setter,
|
|
32
|
-
* and it returns a disposer to be called when the stream is disposed.
|
|
33
|
-
*
|
|
34
|
-
* @typeparam T - The type of the stream's value.
|
|
35
|
-
*
|
|
36
|
-
* @public
|
|
37
|
-
*/
|
|
38
|
-
export class FlowStream<T> extends FlowObservable<T> {
|
|
39
|
-
/* API -------------------------------------------------------- */
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Creates a new FlowStream.
|
|
43
|
-
* @param updater - A function that receives a setter to update the stream's value.
|
|
44
|
-
* It should return a disposer function that will be called upon disposal.
|
|
45
|
-
* @param initial - The initial value of the stream.
|
|
46
|
-
* @public
|
|
47
|
-
*/
|
|
48
|
-
constructor(updater: FlowUpdater<T>, initial: T) {
|
|
49
|
-
super();
|
|
50
|
-
this._value = initial;
|
|
51
|
-
this._disposer = updater((value: T) => {
|
|
52
|
-
this._set(value);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Retrieves the current value of the stream.
|
|
58
|
-
* @returns The current value.
|
|
59
|
-
* @throws Error if the stream is disposed.
|
|
60
|
-
* @public
|
|
61
|
-
*/
|
|
62
|
-
public get(): T {
|
|
63
|
-
if (this._disposed) throw new Error("Stream is disposed");
|
|
64
|
-
return this._value;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Disposes the stream, releasing all resources.
|
|
69
|
-
* @remarks
|
|
70
|
-
* In addition to disposing the underlying observable, this method calls the disposer
|
|
71
|
-
* returned by the updater.
|
|
72
|
-
* @public
|
|
73
|
-
*/
|
|
74
|
-
public override dispose(): void {
|
|
75
|
-
super.dispose();
|
|
76
|
-
this._disposer();
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/* INTERNAL ------------------------------------------------------ */
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* @internal
|
|
83
|
-
* The disposer function returned by the updater.
|
|
84
|
-
*/
|
|
85
|
-
private _disposer: FlowDisposer;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* @internal
|
|
89
|
-
* Updates the stream's value and notifies subscribers if the value changes.
|
|
90
|
-
* @param value - The new value to set.
|
|
91
|
-
* @internal
|
|
92
|
-
*/
|
|
93
|
-
private _set(value: T): void {
|
|
94
|
-
if (this._disposed) throw new Error("Stream is disposed");
|
|
95
|
-
if (value === this._value) return;
|
|
96
|
-
this._value = value;
|
|
97
|
-
this._notify();
|
|
98
|
-
}
|
|
99
|
-
}
|