@ersbeth/picoflow 0.2.1 → 0.2.3
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/picoflow.from.md +55 -0
- package/api/doc/picoflow.from_1.md +55 -0
- package/api/doc/picoflow.from_2.md +55 -0
- package/api/doc/picoflow.from_3.md +55 -0
- package/api/doc/picoflow.from_4.md +55 -0
- package/api/doc/picoflow.from_5.md +55 -0
- package/api/doc/picoflow.md +121 -0
- package/api/doc/picoflow.solidderivation._constructor_.md +49 -0
- package/api/doc/picoflow.solidderivation.get.md +13 -0
- package/api/doc/picoflow.solidderivation.md +94 -0
- package/api/doc/picoflow.solidgetter.md +13 -0
- package/api/doc/picoflow.solidobservable.get.md +13 -0
- package/api/doc/picoflow.solidobservable.md +57 -0
- package/api/doc/picoflow.solidresource._constructor_.md +49 -0
- package/api/doc/picoflow.solidresource.get.md +13 -0
- package/api/doc/picoflow.solidresource.latest.md +13 -0
- package/api/doc/picoflow.solidresource.md +157 -0
- package/api/doc/picoflow.solidresource.refetch.md +13 -0
- package/api/doc/picoflow.solidresource.state.md +13 -0
- package/api/doc/picoflow.solidstate._constructor_.md +49 -0
- package/api/doc/picoflow.solidstate.get.md +13 -0
- package/api/doc/picoflow.solidstate.md +115 -0
- package/api/doc/picoflow.solidstate.set.md +13 -0
- package/api/picoflow.public.api.md +52 -0
- package/dist/picoflow.js +844 -2
- package/dist/types/basic/derivation.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -5
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/solid/converters.d.ts +64 -0
- package/dist/types/solid/converters.d.ts.map +1 -0
- package/dist/types/solid/index.d.ts +3 -0
- package/dist/types/solid/index.d.ts.map +1 -0
- package/dist/types/solid/primitives.d.ts +88 -0
- package/dist/types/solid/primitives.d.ts.map +1 -0
- package/package.json +4 -1
- package/src/basic/derivation.ts +18 -1
- package/src/index.ts +18 -12
- package/src/solid/converters.ts +159 -0
- package/src/solid/index.ts +2 -0
- package/src/solid/primitives.ts +109 -0
- package/test/derivation.test.ts +98 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derivation.d.ts","sourceRoot":"","sources":["../../../src/basic/derivation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;;;GAQG;AACH,qBAAa,cAAc,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;IACpD;;;;;OAKG;gBACS,OAAO,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,KAAK,CAAC;IAK/D;;;;;;;OAOG;IACI,GAAG,IAAI,CAAC;IASf,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,WAAW,CAAyD;IAC5E,OAAO,CAAC,aAAa,CAAoD;IACzE,OAAO,CAAC,aAAa,CAAgD;IACrE,OAAO,CAAC,eAAe,CAA4C;IACnE,OAAO,CAAC,eAAe,CAAW;IAClC,OAAO,CAAC,iBAAiB,CAAW;IAEpC,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,SAAS;
|
|
1
|
+
{"version":3,"file":"derivation.d.ts","sourceRoot":"","sources":["../../../src/basic/derivation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;;;GAQG;AACH,qBAAa,cAAc,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;IACpD;;;;;OAKG;gBACS,OAAO,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,KAAK,CAAC;IAK/D;;;;;;;OAOG;IACI,GAAG,IAAI,CAAC;IASf,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,WAAW,CAAyD;IAC5E,OAAO,CAAC,aAAa,CAAoD;IACzE,OAAO,CAAC,aAAa,CAAgD;IACrE,OAAO,CAAC,eAAe,CAA4C;IACnE,OAAO,CAAC,eAAe,CAAW;IAClC,OAAO,CAAC,iBAAiB,CAAW;IAEpC,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,SAAS;CA0CpB"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -7,9 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
*/
|
|
9
9
|
export { signal, state, constant, resource, stream, derivation, effect, map, array, streamAsync, resourceAsync, } from './creators';
|
|
10
|
-
export { isDisposable } from './basic';
|
|
11
|
-
export {
|
|
12
|
-
export
|
|
13
|
-
export { FlowResource, FlowMap, FlowResourceAsync, FlowStreamAsync, FlowStream, FlowArray, } from './advanced/';
|
|
14
|
-
export type { FlowStreamDisposer, FlowStreamSetter, FlowStreamUpdater, FlowArrayAction, } from './advanced/';
|
|
10
|
+
export { isDisposable, FlowDerivation, FlowEffect, FlowObservable, FlowSignal, FlowState, FlowConstant, type FlowGetter, type FlowWatcher, type FlowDisposable, } from './basic/';
|
|
11
|
+
export { FlowResource, FlowMap, FlowResourceAsync, FlowStreamAsync, FlowStream, FlowArray, type FlowStreamDisposer, type FlowStreamSetter, type FlowStreamUpdater, type FlowArrayAction, } from './advanced/';
|
|
12
|
+
export { from, SolidState, SolidResource, SolidDerivation, type SolidObservable, type SolidGetter, } from './solid/';
|
|
15
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACH,MAAM,EACN,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,UAAU,EACV,MAAM,EACN,GAAG,EACH,KAAK,EACL,WAAW,EACX,aAAa,GAChB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACH,MAAM,EACN,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,UAAU,EACV,MAAM,EACN,GAAG,EACH,KAAK,EACL,WAAW,EACX,aAAa,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACH,YAAY,EACZ,cAAc,EACd,UAAU,EACV,cAAc,EACd,UAAU,EACV,SAAS,EACT,YAAY,EACZ,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,cAAc,GACtB,MAAM,UAAU,CAAC;AAElB,OAAO,EACH,YAAY,EACZ,OAAO,EACP,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,SAAS,EACT,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,eAAe,GACvB,MAAM,aAAa,CAAC;AAErB,OAAO,EACH,IAAI,EACJ,UAAU,EACV,aAAa,EACb,eAAe,EACf,KAAK,eAAe,EACpB,KAAK,WAAW,GACnB,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { FlowObservable, FlowGetter } from '@ersbeth/picoflow';
|
|
2
|
+
import { SolidResource, SolidDerivation } from './primitives';
|
|
3
|
+
/**
|
|
4
|
+
* Utility type that excludes Promise types from T.
|
|
5
|
+
* Used to ensure type safety for synchronous derivations/resources.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export type NotPromise<T> = T extends Promise<unknown> ? never : T;
|
|
10
|
+
/**
|
|
11
|
+
* Converts a FlowObservable of a Promise value into a SolidResource.
|
|
12
|
+
*
|
|
13
|
+
* @param flow - The FlowObservable to convert.
|
|
14
|
+
* @returns A SolidResource wrapping the observable.
|
|
15
|
+
*
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export declare function from<T>(flow: FlowObservable<Promise<NotPromise<T>>>): SolidResource<NotPromise<T>>;
|
|
19
|
+
/**
|
|
20
|
+
* Converts a FlowObservable of a non-Promise value into a SolidDerivation.
|
|
21
|
+
*
|
|
22
|
+
* @param flow - The FlowObservable to convert.
|
|
23
|
+
* @returns A SolidDerivation wrapping the observable.
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export declare function from<T>(flow: FlowObservable<NotPromise<T>>): SolidDerivation<NotPromise<T>>;
|
|
28
|
+
/**
|
|
29
|
+
* Converts a FlowObservable into a Solid derivation or resource, depending on whether the value is synchronous or asynchronous.
|
|
30
|
+
*
|
|
31
|
+
* @param flow - The FlowObservable to convert.
|
|
32
|
+
* @returns A SolidDerivation or SolidResource, depending on the input type.
|
|
33
|
+
*
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
export declare function from<T>(flow: FlowObservable<Promise<NotPromise<T>>> | FlowObservable<NotPromise<T>>): SolidDerivation<NotPromise<T>> | SolidResource<NotPromise<T>>;
|
|
37
|
+
/**
|
|
38
|
+
* Converts a getter function returning a non-Promise value into a SolidDerivation.
|
|
39
|
+
*
|
|
40
|
+
* @param flow - The getter function to convert.
|
|
41
|
+
* @returns A SolidDerivation wrapping the getter.
|
|
42
|
+
*
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
export declare function from<T>(flow: (get: FlowGetter) => NotPromise<T>): SolidDerivation<NotPromise<T>>;
|
|
46
|
+
/**
|
|
47
|
+
* Converts a getter function returning a Promise into a SolidResource.
|
|
48
|
+
*
|
|
49
|
+
* @param flow - The getter function to convert.
|
|
50
|
+
* @returns A SolidResource wrapping the getter.
|
|
51
|
+
*
|
|
52
|
+
* @public
|
|
53
|
+
*/
|
|
54
|
+
export declare function from<T>(flow: (get: FlowGetter) => Promise<NotPromise<T>>): SolidResource<NotPromise<T>>;
|
|
55
|
+
/**
|
|
56
|
+
* Converts a getter function into a Solid derivation or resource, depending on whether the returned value is synchronous or asynchronous.
|
|
57
|
+
*
|
|
58
|
+
* @param flow - The getter function to convert.
|
|
59
|
+
* @returns A SolidDerivation or SolidResource, depending on the input type.
|
|
60
|
+
*
|
|
61
|
+
* @public
|
|
62
|
+
*/
|
|
63
|
+
export declare function from<T>(flow: ((get: FlowGetter) => NotPromise<T>) | ((get: FlowGetter) => Promise<NotPromise<T>>)): SolidDerivation<T> | SolidResource<T>;
|
|
64
|
+
//# sourceMappingURL=converters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converters.d.ts","sourceRoot":"","sources":["../../../src/solid/converters.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEhG,OAAO,EAAE,aAAa,EAAc,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAsE/E;;;;;GAKG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;AAEnE;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACpG;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7F;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAClB,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAC7E,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACjE;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAClG;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACzG;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAClB,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAC3F,eAAe,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/solid/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { ResourceFetcher } from 'solid-js';
|
|
2
|
+
/**
|
|
3
|
+
* A getter function or value for Solid state/derivation.
|
|
4
|
+
*
|
|
5
|
+
* @typeParam T - The value type.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export type SolidGetter<T> = ((previous: T) => T) | T;
|
|
9
|
+
/**
|
|
10
|
+
* Interface for a Solid-style observable value.
|
|
11
|
+
*
|
|
12
|
+
* @typeParam T - The value type.
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export interface SolidObservable<T> {
|
|
16
|
+
/**
|
|
17
|
+
* Returns the current value.
|
|
18
|
+
*/
|
|
19
|
+
get: () => T;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Solid-style state container, similar to a writable signal.
|
|
23
|
+
*
|
|
24
|
+
* @typeParam T - The value type.
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export declare class SolidState<T> implements SolidObservable<T> {
|
|
28
|
+
/**
|
|
29
|
+
* Returns the current value.
|
|
30
|
+
*/
|
|
31
|
+
readonly get: () => T;
|
|
32
|
+
/**
|
|
33
|
+
* Sets the value or updates it using a getter function.
|
|
34
|
+
*/
|
|
35
|
+
readonly set: (param: SolidGetter<T>) => void;
|
|
36
|
+
/**
|
|
37
|
+
* Creates a new SolidState with the given initial value.
|
|
38
|
+
* @param initialValue - The initial value.
|
|
39
|
+
*/
|
|
40
|
+
constructor(initialValue: T);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Solid-style derivation, similar to a computed/memoized value.
|
|
44
|
+
*
|
|
45
|
+
* @typeParam T - The value type.
|
|
46
|
+
* @public
|
|
47
|
+
*/
|
|
48
|
+
export declare class SolidDerivation<T> implements SolidObservable<T> {
|
|
49
|
+
/**
|
|
50
|
+
* Returns the current derived value.
|
|
51
|
+
*/
|
|
52
|
+
readonly get: () => T;
|
|
53
|
+
/**
|
|
54
|
+
* Creates a new SolidDerivation from a getter function or value.
|
|
55
|
+
* @param calculator - The getter function or value.
|
|
56
|
+
*/
|
|
57
|
+
constructor(calculator: SolidGetter<T>);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Solid-style resource, similar to an async resource or data loader.
|
|
61
|
+
*
|
|
62
|
+
* @typeParam T - The value type.
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
export declare class SolidResource<T> implements SolidObservable<T | undefined> {
|
|
66
|
+
/**
|
|
67
|
+
* Returns the current value (or undefined if not yet loaded).
|
|
68
|
+
*/
|
|
69
|
+
readonly get: () => T | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Returns the current resource state.
|
|
72
|
+
*/
|
|
73
|
+
readonly state: () => 'unresolved' | 'pending' | 'errored' | 'ready' | 'refreshing';
|
|
74
|
+
/**
|
|
75
|
+
* Returns the latest successfully loaded value (or undefined).
|
|
76
|
+
*/
|
|
77
|
+
readonly latest: () => T | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* Triggers a refetch of the resource.
|
|
80
|
+
*/
|
|
81
|
+
readonly refetch: () => void;
|
|
82
|
+
/**
|
|
83
|
+
* Creates a new SolidResource from a fetcher function.
|
|
84
|
+
* @param fetcher - The async fetcher function.
|
|
85
|
+
*/
|
|
86
|
+
constructor(fetcher: ResourceFetcher<true, T, unknown>);
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=primitives.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../../src/solid/primitives.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,eAAe,EAAG,MAAM,UAAU,CAAC;AAE3F;;;;;GAKG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC;IAC9B;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC,CAAC;CAChB;AAED;;;;;GAKG;AACH,qBAAa,UAAU,CAAC,CAAC,CAAE,YAAW,eAAe,CAAC,CAAC,CAAC;IACpD;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACtB;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAE9C;;;OAGG;gBACS,YAAY,EAAE,CAAC;CAK9B;AAGD;;;;;GAKG;AACH,qBAAa,eAAe,CAAC,CAAC,CAAE,YAAW,eAAe,CAAC,CAAC,CAAC;IACzD;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAEtB;;;OAGG;gBACS,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;CAIzC;AAED;;;;;GAKG;AACH,qBAAa,aAAa,CAAC,CAAC,CAAE,YAAW,eAAe,CAAC,CAAC,GAAG,SAAS,CAAC;IACnE;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAClC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,YAAY,CAAC;IACpF;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACrC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAE7B;;;OAGG;gBACS,OAAO,EAAE,eAAe,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC;CAOzD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ersbeth/picoflow",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Minimal Dataflow librairy for TypeScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -20,6 +20,9 @@
|
|
|
20
20
|
"api:clean": "rm ./api/temp/*",
|
|
21
21
|
"api": "npm run api:extract && npm run api:generate && npm run api:clean"
|
|
22
22
|
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"solid-js": "^1.9.7"
|
|
25
|
+
},
|
|
23
26
|
"devDependencies": {
|
|
24
27
|
"@biomejs/biome": "^1.9.4",
|
|
25
28
|
"@vitest/coverage-v8": "^3.0.9",
|
package/src/basic/derivation.ts
CHANGED
|
@@ -67,7 +67,24 @@ export class FlowDerivation<T> extends FlowObservable<T> {
|
|
|
67
67
|
|
|
68
68
|
/* @internal */ _compute(): void {
|
|
69
69
|
if (this._dirty) {
|
|
70
|
-
|
|
70
|
+
// we cant use untrackedCompute because it will not track dependencies
|
|
71
|
+
// that changed dynamically
|
|
72
|
+
|
|
73
|
+
// store current dependencies
|
|
74
|
+
const dependencies = [...this._dependencies];
|
|
75
|
+
|
|
76
|
+
// clear current dependencies, compute and retrack dependencies
|
|
77
|
+
this._dependencies.clear();
|
|
78
|
+
this._value = this._trackedCompute();
|
|
79
|
+
|
|
80
|
+
// unsubscribe from dependencies that are no longer needed
|
|
81
|
+
const dependenciesToRemove = dependencies.filter(
|
|
82
|
+
(dependency) => !this._dependencies.has(dependency),
|
|
83
|
+
);
|
|
84
|
+
dependenciesToRemove.forEach((dependency) =>
|
|
85
|
+
dependency._unregisterDependency(this),
|
|
86
|
+
);
|
|
87
|
+
|
|
71
88
|
this._dirty = false;
|
|
72
89
|
}
|
|
73
90
|
}
|
package/src/index.ts
CHANGED
|
@@ -19,21 +19,20 @@ export {
|
|
|
19
19
|
streamAsync,
|
|
20
20
|
resourceAsync,
|
|
21
21
|
} from "./creators";
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
export {
|
|
24
|
+
isDisposable,
|
|
24
25
|
FlowDerivation,
|
|
25
26
|
FlowEffect,
|
|
26
27
|
FlowObservable,
|
|
27
28
|
FlowSignal,
|
|
28
29
|
FlowState,
|
|
29
30
|
FlowConstant,
|
|
31
|
+
type FlowGetter,
|
|
32
|
+
type FlowWatcher,
|
|
33
|
+
type FlowDisposable,
|
|
30
34
|
} from "./basic/";
|
|
31
35
|
|
|
32
|
-
export type {
|
|
33
|
-
FlowGetter,
|
|
34
|
-
FlowWatcher,
|
|
35
|
-
FlowDisposable,
|
|
36
|
-
} from "./basic/";
|
|
37
36
|
export {
|
|
38
37
|
FlowResource,
|
|
39
38
|
FlowMap,
|
|
@@ -41,10 +40,17 @@ export {
|
|
|
41
40
|
FlowStreamAsync,
|
|
42
41
|
FlowStream,
|
|
43
42
|
FlowArray,
|
|
43
|
+
type FlowStreamDisposer,
|
|
44
|
+
type FlowStreamSetter,
|
|
45
|
+
type FlowStreamUpdater,
|
|
46
|
+
type FlowArrayAction,
|
|
44
47
|
} from "./advanced/";
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
|
|
49
|
+
export {
|
|
50
|
+
from,
|
|
51
|
+
SolidState,
|
|
52
|
+
SolidResource,
|
|
53
|
+
SolidDerivation,
|
|
54
|
+
type SolidObservable,
|
|
55
|
+
type SolidGetter,
|
|
56
|
+
} from "./solid/";
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { FlowDerivation, FlowEffect, FlowObservable, type FlowGetter } from '@ersbeth/picoflow';
|
|
2
|
+
import { onCleanup, onMount } from 'solid-js';
|
|
3
|
+
import { SolidResource, SolidState, type SolidDerivation } from './primitives';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
function fromSync<T>(state: FlowObservable<T>): SolidDerivation<T> {
|
|
7
|
+
|
|
8
|
+
const solidState = new SolidState<T>(state.get());
|
|
9
|
+
|
|
10
|
+
let fx: FlowEffect;
|
|
11
|
+
|
|
12
|
+
onMount(() => {
|
|
13
|
+
fx = new FlowEffect((get) => {
|
|
14
|
+
const value = get(state);
|
|
15
|
+
solidState.set(() => value);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
onCleanup(() => fx.dispose());
|
|
20
|
+
|
|
21
|
+
return solidState
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function fromAsync<T>(derivation: FlowObservable<Promise<T>>): SolidResource<T> {
|
|
25
|
+
|
|
26
|
+
const solidResource = new SolidResource<T>(async () => {
|
|
27
|
+
const value = await derivation.get();
|
|
28
|
+
return value;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
let fx: FlowEffect;
|
|
32
|
+
|
|
33
|
+
onMount(() => {
|
|
34
|
+
fx = new FlowEffect(async (get) => {
|
|
35
|
+
await get(derivation);
|
|
36
|
+
solidResource.refetch();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
onCleanup(() => fx.dispose());
|
|
41
|
+
|
|
42
|
+
return solidResource;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function shallowFrom<T>(flow: FlowObservable<Promise<T>>): SolidResource<T>;
|
|
46
|
+
function shallowFrom<T>(flow: FlowObservable<T>): SolidDerivation<T>;
|
|
47
|
+
function shallowFrom<T>(flow: FlowObservable<Promise<T>> | FlowObservable<T>): SolidDerivation<T> | SolidResource<T> {
|
|
48
|
+
const initialValue = flow.get();
|
|
49
|
+
const isAsync = initialValue instanceof Promise;
|
|
50
|
+
if (isAsync) {
|
|
51
|
+
return fromAsync(flow as FlowObservable<Promise<T>>);
|
|
52
|
+
}
|
|
53
|
+
return fromSync(flow as FlowObservable<T>);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function deepFrom<T>(getter: (get: FlowGetter) => T): SolidDerivation<T>;
|
|
57
|
+
function deepFrom<T>(getter: (get: FlowGetter) => Promise<T>): SolidResource<T>;
|
|
58
|
+
function deepFrom<T>(getter: (get: FlowGetter) => T | Promise<T>): SolidDerivation<T> | SolidResource<T> {
|
|
59
|
+
const derivation = new FlowDerivation((get) => {
|
|
60
|
+
return getter(get);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const initialValue = derivation.get();
|
|
64
|
+
const isAsync = initialValue instanceof Promise;
|
|
65
|
+
|
|
66
|
+
if (isAsync) {
|
|
67
|
+
return fromAsync(derivation as FlowObservable<Promise<T>>);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return fromSync(derivation as FlowObservable<T>);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Utility type that excludes Promise types from T.
|
|
75
|
+
* Used to ensure type safety for synchronous derivations/resources.
|
|
76
|
+
*
|
|
77
|
+
* @public
|
|
78
|
+
*/
|
|
79
|
+
export type NotPromise<T> = T extends Promise<unknown> ? never : T;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Converts a FlowObservable of a Promise value into a SolidResource.
|
|
83
|
+
*
|
|
84
|
+
* @param flow - The FlowObservable to convert.
|
|
85
|
+
* @returns A SolidResource wrapping the observable.
|
|
86
|
+
*
|
|
87
|
+
* @public
|
|
88
|
+
*/
|
|
89
|
+
export function from<T>(flow: FlowObservable<Promise<NotPromise<T>>>): SolidResource<NotPromise<T>>;
|
|
90
|
+
/**
|
|
91
|
+
* Converts a FlowObservable of a non-Promise value into a SolidDerivation.
|
|
92
|
+
*
|
|
93
|
+
* @param flow - The FlowObservable to convert.
|
|
94
|
+
* @returns A SolidDerivation wrapping the observable.
|
|
95
|
+
*
|
|
96
|
+
* @public
|
|
97
|
+
*/
|
|
98
|
+
export function from<T>(flow: FlowObservable<NotPromise<T>>): SolidDerivation<NotPromise<T>>;
|
|
99
|
+
/**
|
|
100
|
+
* Converts a FlowObservable into a Solid derivation or resource, depending on whether the value is synchronous or asynchronous.
|
|
101
|
+
*
|
|
102
|
+
* @param flow - The FlowObservable to convert.
|
|
103
|
+
* @returns A SolidDerivation or SolidResource, depending on the input type.
|
|
104
|
+
*
|
|
105
|
+
* @public
|
|
106
|
+
*/
|
|
107
|
+
export function from<T>(
|
|
108
|
+
flow: FlowObservable<Promise<NotPromise<T>>> | FlowObservable<NotPromise<T>>,
|
|
109
|
+
): SolidDerivation<NotPromise<T>> | SolidResource<NotPromise<T>>;
|
|
110
|
+
/**
|
|
111
|
+
* Converts a getter function returning a non-Promise value into a SolidDerivation.
|
|
112
|
+
*
|
|
113
|
+
* @param flow - The getter function to convert.
|
|
114
|
+
* @returns A SolidDerivation wrapping the getter.
|
|
115
|
+
*
|
|
116
|
+
* @public
|
|
117
|
+
*/
|
|
118
|
+
export function from<T>(flow: (get: FlowGetter) => NotPromise<T>): SolidDerivation<NotPromise<T>>;
|
|
119
|
+
/**
|
|
120
|
+
* Converts a getter function returning a Promise into a SolidResource.
|
|
121
|
+
*
|
|
122
|
+
* @param flow - The getter function to convert.
|
|
123
|
+
* @returns A SolidResource wrapping the getter.
|
|
124
|
+
*
|
|
125
|
+
* @public
|
|
126
|
+
*/
|
|
127
|
+
export function from<T>(flow: (get: FlowGetter) => Promise<NotPromise<T>>): SolidResource<NotPromise<T>>;
|
|
128
|
+
/**
|
|
129
|
+
* Converts a getter function into a Solid derivation or resource, depending on whether the returned value is synchronous or asynchronous.
|
|
130
|
+
*
|
|
131
|
+
* @param flow - The getter function to convert.
|
|
132
|
+
* @returns A SolidDerivation or SolidResource, depending on the input type.
|
|
133
|
+
*
|
|
134
|
+
* @public
|
|
135
|
+
*/
|
|
136
|
+
export function from<T>(
|
|
137
|
+
flow: ((get: FlowGetter) => NotPromise<T>) | ((get: FlowGetter) => Promise<NotPromise<T>>),
|
|
138
|
+
): SolidDerivation<T> | SolidResource<T>;
|
|
139
|
+
/**
|
|
140
|
+
* Converts a FlowObservable or getter function into a Solid derivation or resource, depending on whether the value is synchronous or asynchronous.
|
|
141
|
+
*
|
|
142
|
+
* - If passed a FlowObservable of a non-Promise value, returns a SolidDerivation.
|
|
143
|
+
* - If passed a FlowObservable of a Promise, returns a SolidResource.
|
|
144
|
+
* - If passed a getter function returning a non-Promise value, returns a SolidDerivation.
|
|
145
|
+
* - If passed a getter function returning a Promise, returns a SolidResource.
|
|
146
|
+
*
|
|
147
|
+
* @param flow - The FlowObservable or getter function to convert.
|
|
148
|
+
* @returns A SolidDerivation or SolidResource, depending on the input type.
|
|
149
|
+
* @public
|
|
150
|
+
*/
|
|
151
|
+
export function from<T>(
|
|
152
|
+
flow: FlowObservable<Promise<T>> | FlowObservable<T> | ((get: FlowGetter) => T) | ((get: FlowGetter) => Promise<T>),
|
|
153
|
+
): SolidDerivation<T> | SolidResource<T> {
|
|
154
|
+
if (flow instanceof FlowObservable) {
|
|
155
|
+
return shallowFrom(flow as FlowObservable<T | Promise<T>>) as SolidDerivation<T> | SolidResource<T>;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return deepFrom(flow as (get: FlowGetter) => T | Promise<T>) as SolidDerivation<T> | SolidResource<T>;
|
|
159
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { createMemo, createResource, createSignal, type ResourceFetcher, } from "solid-js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A getter function or value for Solid state/derivation.
|
|
5
|
+
*
|
|
6
|
+
* @typeParam T - The value type.
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export type SolidGetter<T> = ((previous: T) => T) | T;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Interface for a Solid-style observable value.
|
|
13
|
+
*
|
|
14
|
+
* @typeParam T - The value type.
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export interface SolidObservable<T> {
|
|
18
|
+
/**
|
|
19
|
+
* Returns the current value.
|
|
20
|
+
*/
|
|
21
|
+
get: () => T;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Solid-style state container, similar to a writable signal.
|
|
26
|
+
*
|
|
27
|
+
* @typeParam T - The value type.
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export class SolidState<T> implements SolidObservable<T> {
|
|
31
|
+
/**
|
|
32
|
+
* Returns the current value.
|
|
33
|
+
*/
|
|
34
|
+
readonly get: () => T;
|
|
35
|
+
/**
|
|
36
|
+
* Sets the value or updates it using a getter function.
|
|
37
|
+
*/
|
|
38
|
+
readonly set: (param: SolidGetter<T>) => void;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Creates a new SolidState with the given initial value.
|
|
42
|
+
* @param initialValue - The initial value.
|
|
43
|
+
*/
|
|
44
|
+
constructor(initialValue: T) {
|
|
45
|
+
const [get, set] = createSignal<T>(initialValue);
|
|
46
|
+
this.get = get;
|
|
47
|
+
this.set = set;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
type EffectFunction<Prev, Next extends Prev = Prev> = (v: Prev) => Next;
|
|
52
|
+
/**
|
|
53
|
+
* Solid-style derivation, similar to a computed/memoized value.
|
|
54
|
+
*
|
|
55
|
+
* @typeParam T - The value type.
|
|
56
|
+
* @public
|
|
57
|
+
*/
|
|
58
|
+
export class SolidDerivation<T> implements SolidObservable<T> {
|
|
59
|
+
/**
|
|
60
|
+
* Returns the current derived value.
|
|
61
|
+
*/
|
|
62
|
+
readonly get: () => T;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Creates a new SolidDerivation from a getter function or value.
|
|
66
|
+
* @param calculator - The getter function or value.
|
|
67
|
+
*/
|
|
68
|
+
constructor(calculator: SolidGetter<T>) {
|
|
69
|
+
const get = createMemo<T>(calculator as EffectFunction<T | undefined, T>);
|
|
70
|
+
this.get = get;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Solid-style resource, similar to an async resource or data loader.
|
|
76
|
+
*
|
|
77
|
+
* @typeParam T - The value type.
|
|
78
|
+
* @public
|
|
79
|
+
*/
|
|
80
|
+
export class SolidResource<T> implements SolidObservable<T | undefined> {
|
|
81
|
+
/**
|
|
82
|
+
* Returns the current value (or undefined if not yet loaded).
|
|
83
|
+
*/
|
|
84
|
+
readonly get: () => T | undefined;
|
|
85
|
+
/**
|
|
86
|
+
* Returns the current resource state.
|
|
87
|
+
*/
|
|
88
|
+
readonly state: () => 'unresolved' | 'pending' | 'errored' | 'ready' | 'refreshing';
|
|
89
|
+
/**
|
|
90
|
+
* Returns the latest successfully loaded value (or undefined).
|
|
91
|
+
*/
|
|
92
|
+
readonly latest: () => T | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Triggers a refetch of the resource.
|
|
95
|
+
*/
|
|
96
|
+
readonly refetch: () => void;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Creates a new SolidResource from a fetcher function.
|
|
100
|
+
* @param fetcher - The async fetcher function.
|
|
101
|
+
*/
|
|
102
|
+
constructor(fetcher: ResourceFetcher<true, T, unknown>) {
|
|
103
|
+
const [get, set] = createResource<T>(fetcher);
|
|
104
|
+
this.get = get;
|
|
105
|
+
this.state = () => get.state;
|
|
106
|
+
this.latest = () => get.latest;
|
|
107
|
+
this.refetch = () => set.refetch();
|
|
108
|
+
}
|
|
109
|
+
}
|
package/test/derivation.test.ts
CHANGED
|
@@ -443,4 +443,102 @@ describe("effect", () => {
|
|
|
443
443
|
expect(effectFn).toHaveBeenLastCalledWith(4);
|
|
444
444
|
});
|
|
445
445
|
});
|
|
446
|
+
|
|
447
|
+
describe("complex test", () => {
|
|
448
|
+
test("test", () => {
|
|
449
|
+
const obj1 = {
|
|
450
|
+
cond: state(false),
|
|
451
|
+
num: state(2),
|
|
452
|
+
dispose: (options: { self: boolean }) => {
|
|
453
|
+
obj1.cond.dispose(options);
|
|
454
|
+
obj1.num.dispose(options);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
const obj2 = {
|
|
458
|
+
cond: state(false),
|
|
459
|
+
num: state(4),
|
|
460
|
+
dispose: (options: { self: boolean }) => {
|
|
461
|
+
obj2.cond.dispose(options);
|
|
462
|
+
obj2.num.dispose(options);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
const $state = state(obj1);
|
|
466
|
+
const $derivationCond = derivation((get) => get(get($state).cond));
|
|
467
|
+
const $derivationNum = derivation((get) => get(get($state).num) * 2);
|
|
468
|
+
const effectCondFn = vi.fn();
|
|
469
|
+
const effectNumFn = vi.fn();
|
|
470
|
+
effect((get) => effectCondFn(get($derivationCond)));
|
|
471
|
+
effect((get) => effectNumFn(get($derivationNum)));
|
|
472
|
+
|
|
473
|
+
expect(effectCondFn).toHaveBeenCalledTimes(1);
|
|
474
|
+
expect(effectCondFn).toHaveBeenLastCalledWith(false);
|
|
475
|
+
expect(effectNumFn).toHaveBeenCalledTimes(1);
|
|
476
|
+
expect(effectNumFn).toHaveBeenLastCalledWith(4);
|
|
477
|
+
|
|
478
|
+
$state.get().num.set(3);
|
|
479
|
+
expect(effectCondFn).toHaveBeenCalledTimes(1);
|
|
480
|
+
expect(effectCondFn).toHaveBeenLastCalledWith(false);
|
|
481
|
+
expect(effectNumFn).toHaveBeenCalledTimes(2);
|
|
482
|
+
expect(effectNumFn).toHaveBeenLastCalledWith(6);
|
|
483
|
+
|
|
484
|
+
$state.get().cond.set(true);
|
|
485
|
+
expect(effectCondFn).toHaveBeenCalledTimes(2);
|
|
486
|
+
expect(effectCondFn).toHaveBeenLastCalledWith(true);
|
|
487
|
+
expect(effectNumFn).toHaveBeenCalledTimes(2);
|
|
488
|
+
expect(effectNumFn).toHaveBeenLastCalledWith(6);
|
|
489
|
+
|
|
490
|
+
$state.set(obj2)
|
|
491
|
+
expect(effectCondFn).toHaveBeenCalledTimes(3);
|
|
492
|
+
expect(effectCondFn).toHaveBeenLastCalledWith(false);
|
|
493
|
+
expect(effectNumFn).toHaveBeenCalledTimes(3);
|
|
494
|
+
expect(effectNumFn).toHaveBeenLastCalledWith(8);
|
|
495
|
+
|
|
496
|
+
$state.get().cond.set(true);
|
|
497
|
+
expect(effectCondFn).toHaveBeenCalledTimes(4); // fails -> called 3 times
|
|
498
|
+
expect(effectCondFn).toHaveBeenLastCalledWith(true);
|
|
499
|
+
expect(effectNumFn).toHaveBeenCalledTimes(3);
|
|
500
|
+
expect(effectNumFn).toHaveBeenLastCalledWith(8);
|
|
501
|
+
|
|
502
|
+
$state.get().num.set(5);
|
|
503
|
+
expect(effectCondFn).toHaveBeenCalledTimes(4);
|
|
504
|
+
expect(effectCondFn).toHaveBeenLastCalledWith(true);
|
|
505
|
+
expect(effectNumFn).toHaveBeenCalledTimes(4);
|
|
506
|
+
expect(effectNumFn).toHaveBeenLastCalledWith(10);
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
test("test", () => {
|
|
510
|
+
const obj = {
|
|
511
|
+
cond: state(false),
|
|
512
|
+
b: state(2)
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
const $state = state(obj);
|
|
516
|
+
const $derivation = derivation((get) => {
|
|
517
|
+
const cond = get(get($state).cond);
|
|
518
|
+
if (cond) {
|
|
519
|
+
return get(get($state).b) * 2;
|
|
520
|
+
}
|
|
521
|
+
return 0;
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
const effectFn = vi.fn();
|
|
526
|
+
effect((get) => effectFn(get($derivation)));
|
|
527
|
+
|
|
528
|
+
expect(effectFn).toHaveBeenCalledTimes(1);
|
|
529
|
+
expect(effectFn).toHaveBeenLastCalledWith(0);
|
|
530
|
+
|
|
531
|
+
$state.get().cond.set(true);
|
|
532
|
+
expect(effectFn).toHaveBeenCalledTimes(2);
|
|
533
|
+
expect(effectFn).toHaveBeenLastCalledWith(4);
|
|
534
|
+
|
|
535
|
+
$state.set({ cond: state(false), b: state(3) })
|
|
536
|
+
expect(effectFn).toHaveBeenCalledTimes(3);
|
|
537
|
+
expect(effectFn).toHaveBeenLastCalledWith(0);
|
|
538
|
+
|
|
539
|
+
$state.get().cond.set(true);
|
|
540
|
+
expect(effectFn).toHaveBeenCalledTimes(4);
|
|
541
|
+
expect(effectFn).toHaveBeenLastCalledWith(6);
|
|
542
|
+
});
|
|
543
|
+
});
|
|
446
544
|
});
|