solid-state-tools 1.1.0 → 1.1.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/README.md +60 -24
- package/dist/atom.d.ts +13 -6
- package/dist/atom.d.ts.map +1 -1
- package/dist/atom.js +15 -14
- package/dist/atom.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# Solid JS State Tools
|
|
2
2
|
|
|
3
|
-
This
|
|
3
|
+
This is a collection of simple utilities for managing [Solid JS](https://docs.solidjs.com/) state.
|
|
4
|
+
It is intended to compliment Solid JS's existing state system, not replace it.
|
|
5
|
+
|
|
6
|
+
This package is tiny and only has a peer dependency of Solid JS.
|
|
4
7
|
|
|
5
8
|
## Atoms (`atom`)
|
|
6
9
|
|
|
@@ -35,44 +38,77 @@ const count = asig(0);
|
|
|
35
38
|
const count = atom(createSignal(0));
|
|
36
39
|
```
|
|
37
40
|
|
|
38
|
-
## Co-signals (`
|
|
41
|
+
## Co-signals (`createCouple`)
|
|
42
|
+
|
|
43
|
+
A signal can be summarized as a getter setter pair. However, Solid JS's setters are more complex than just a function that accepts the new value. They can also accept a function which acts like a map predicate from the old value to the new one.
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
setCount(x => x + 1);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
All of this is to say that creating signal pairs can be tedious because the setter has to handle this edge case. Take a look at the below example.
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
const [ count, setCount ] = createSignal(0);
|
|
53
|
+
|
|
54
|
+
const [ double, setDouble ] = [
|
|
55
|
+
// The getter
|
|
56
|
+
createMemo(() => count() * 2),
|
|
57
|
+
|
|
58
|
+
// The setter
|
|
59
|
+
(value: number | ((prev: number) => number)) => {
|
|
60
|
+
|
|
61
|
+
// Possibility of a function must be explicitly handled.
|
|
62
|
+
const newValue = (typeof value === "function") ? value(double()) : value;
|
|
63
|
+
|
|
64
|
+
setCount(newValue / 2);
|
|
65
|
+
|
|
66
|
+
// And the result must be returned.
|
|
67
|
+
return newValue;
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
// Both of the below work, as a signal should.
|
|
72
|
+
setDouble(10); // double: 10, count: 5
|
|
73
|
+
setDouble(x => x + 1); // double: 11, count: 5.5
|
|
74
|
+
```
|
|
39
75
|
|
|
40
|
-
|
|
76
|
+
Wouldn't it be convenient if we didn't have to handle all of that extra fluff though?
|
|
41
77
|
|
|
42
|
-
|
|
78
|
+
Enter co-signals. `Cosignal` is a getter setter pair like `Signal`, except that the setter doesn't accept a mapping function nor return a value. The `createCouple` function accepts a co-signal as input.
|
|
43
79
|
|
|
44
80
|
```ts
|
|
45
81
|
const [ count, setCount ] = createSignal(0);
|
|
46
|
-
|
|
82
|
+
|
|
83
|
+
const [ double, setDouble ] = createCouple([
|
|
47
84
|
() => count() * 2,
|
|
48
85
|
|
|
49
|
-
|
|
50
|
-
|
|
86
|
+
(x) => {
|
|
87
|
+
// Notice how we don't need to handle `x` being a function here.
|
|
88
|
+
setCount(x / 2);
|
|
89
|
+
|
|
90
|
+
// Nor do we need to return the result.
|
|
91
|
+
},
|
|
51
92
|
]);
|
|
52
93
|
|
|
53
|
-
// Yet, we can still pass a
|
|
94
|
+
// Yet, we can still pass a function in.
|
|
54
95
|
setDouble(x => x + 2);
|
|
55
|
-
console.log(double(), count()); //
|
|
96
|
+
console.log(double(), count()); // 2 1
|
|
56
97
|
|
|
57
|
-
// Or
|
|
58
|
-
setDouble(10);
|
|
59
|
-
console.log(double(), count()); // 10 5
|
|
98
|
+
// Or use its return value.
|
|
99
|
+
console.log(setDouble(10), count()); // 10 5
|
|
60
100
|
```
|
|
61
101
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const [ double, setDouble ] = createCosignal([
|
|
66
|
-
// Memoize to reduce extra computation.
|
|
67
|
-
createMemo(() => count() * 2),
|
|
68
|
-
/* ... */
|
|
69
|
-
]);
|
|
70
|
-
```
|
|
102
|
+
The `createCouple` function transforms a co-signal into a signal. In what way?
|
|
103
|
+
1. The getter is memoized for you.
|
|
104
|
+
2. The setter is wrapped so that if a function is passed in, it is evaluated with the current value and then forwarded to the cosignal's setter, returning the latest result.
|
|
71
105
|
|
|
72
|
-
|
|
106
|
+
The signal returned by `createCouple` can also be wrapped with `atom` to combine the getter and setter into one.
|
|
73
107
|
|
|
74
108
|
```ts
|
|
75
|
-
const double = atom(
|
|
109
|
+
const double = atom(createCouple(/* ... */));
|
|
76
110
|
```
|
|
77
111
|
|
|
78
|
-
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
Perhaps you can see the power of the above primitives. Not only in what they can do on their own, but also in what they can do when combined.
|
package/dist/atom.d.ts
CHANGED
|
@@ -45,6 +45,12 @@ export type Asig<T> = Atom<Signal<T>>;
|
|
|
45
45
|
* ### Example
|
|
46
46
|
* ```
|
|
47
47
|
* const count = asig(0);
|
|
48
|
+
*
|
|
49
|
+
* count(10);
|
|
50
|
+
* console.log(count()); // 10
|
|
51
|
+
*
|
|
52
|
+
* count(x => x + 10);
|
|
53
|
+
* console.log(count()); // 20
|
|
48
54
|
* ```
|
|
49
55
|
*/
|
|
50
56
|
export declare function asig<T>(): Atom<Signal<T | undefined>>;
|
|
@@ -52,26 +58,27 @@ export declare function asig<T>(value: T, options?: SignalOptions<T>): Atom<Sign
|
|
|
52
58
|
/**
|
|
53
59
|
* A getter setter pair.
|
|
54
60
|
* While similar to `Signal`, the setter of
|
|
55
|
-
* `Cosignal` does not accept a mapping function
|
|
61
|
+
* `Cosignal` does not accept a mapping function;
|
|
62
|
+
* nor does it return a result.
|
|
56
63
|
*/
|
|
57
64
|
export type Cosignal<T> = [
|
|
58
65
|
() => T,
|
|
59
|
-
(value: T) =>
|
|
66
|
+
(value: T) => void
|
|
60
67
|
];
|
|
61
68
|
/**
|
|
62
|
-
* Create signal from a
|
|
69
|
+
* Create a signal from a cosignal.
|
|
63
70
|
*
|
|
64
71
|
* ### Example
|
|
65
72
|
* ```
|
|
66
73
|
* const [ count, setCount ] = createSignal(0);
|
|
67
|
-
* const [ double, setDouble ] =
|
|
74
|
+
* const [ double, setDouble ] = createSignalPair([
|
|
68
75
|
* () => count() * 2,
|
|
69
76
|
* (x) => void setCount(x / 2),
|
|
70
77
|
* ]);
|
|
71
78
|
*
|
|
72
79
|
* double(x => x + 2);
|
|
73
|
-
* console.log(double(), count()); //
|
|
80
|
+
* console.log(double(), count()); // 2 1
|
|
74
81
|
* ```
|
|
75
82
|
*/
|
|
76
|
-
export declare function
|
|
83
|
+
export declare function createCouple<T>(cosignal: Cosignal<T>): Signal<T>;
|
|
77
84
|
//# sourceMappingURL=atom.d.ts.map
|
package/dist/atom.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"atom.d.ts","sourceRoot":"","sources":["../src/atom.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"atom.d.ts","sourceRoot":"","sources":["../src/atom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkD,KAAK,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAG3G;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,CAAE,MAAM,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,CAAE,CAAC;AAEvE;;;;;;GAMG;AACH,MAAM,MAAM,IAAI,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,UAAU,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAmBpE;;;GAGG;AACH,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;AACvD,wBAAgB,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAK/E;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;IACzB,MAAM,CAAC;IACP,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI;CAClB,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAqBhE"}
|
package/dist/atom.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { createSignal, untrack } from "solid-js";
|
|
1
|
+
import { createMemo, createSignal, untrack } from "solid-js";
|
|
2
2
|
import { isDev } from "solid-js/web";
|
|
3
3
|
export function atom(value) {
|
|
4
4
|
if (isDev) {
|
|
5
5
|
// Assert that the input is valid.
|
|
6
|
-
// For production,
|
|
6
|
+
// For production, these checks are skipped for performance.
|
|
7
7
|
if (!Array.isArray(value)) {
|
|
8
8
|
throw new Error(`expected a getter setter pair as an array, but got ${typeof value}`);
|
|
9
9
|
}
|
|
@@ -16,28 +16,28 @@ export function atom(value) {
|
|
|
16
16
|
}
|
|
17
17
|
return (...args) => (args.length === 0) ? value[0]() : value[1](...args);
|
|
18
18
|
}
|
|
19
|
-
export function asig(
|
|
20
|
-
return atom(
|
|
19
|
+
export function asig(value, options) {
|
|
20
|
+
return atom(createSignal(value, options));
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
|
-
* Create signal from a
|
|
23
|
+
* Create a signal from a cosignal.
|
|
24
24
|
*
|
|
25
25
|
* ### Example
|
|
26
26
|
* ```
|
|
27
27
|
* const [ count, setCount ] = createSignal(0);
|
|
28
|
-
* const [ double, setDouble ] =
|
|
28
|
+
* const [ double, setDouble ] = createSignalPair([
|
|
29
29
|
* () => count() * 2,
|
|
30
30
|
* (x) => void setCount(x / 2),
|
|
31
31
|
* ]);
|
|
32
32
|
*
|
|
33
33
|
* double(x => x + 2);
|
|
34
|
-
* console.log(double(), count()); //
|
|
34
|
+
* console.log(double(), count()); // 2 1
|
|
35
35
|
* ```
|
|
36
36
|
*/
|
|
37
|
-
export function
|
|
37
|
+
export function createCouple(cosignal) {
|
|
38
38
|
if (isDev) {
|
|
39
39
|
// Assert that the input is valid.
|
|
40
|
-
// For production,
|
|
40
|
+
// For production, these checks are skipped for performance.
|
|
41
41
|
if (!Array.isArray(cosignal)) {
|
|
42
42
|
throw new Error(`expected a getter setter pair as an array, but got ${typeof cosignal}`);
|
|
43
43
|
}
|
|
@@ -48,10 +48,11 @@ export function createCosignal(cosignal) {
|
|
|
48
48
|
throw new Error(`expected a setter function, but got ${typeof cosignal[1]}`);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
get
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
const get = createMemo(cosignal[0]);
|
|
52
|
+
const set = ((value) => {
|
|
53
|
+
cosignal[1]((typeof value === "function") ? value(untrack(get)) : value);
|
|
54
|
+
return get();
|
|
55
|
+
});
|
|
56
|
+
return [get, set];
|
|
56
57
|
}
|
|
57
58
|
//# sourceMappingURL=atom.js.map
|
package/dist/atom.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"atom.js","sourceRoot":"","sources":["../src/atom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"atom.js","sourceRoot":"","sources":["../src/atom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAAgD,MAAM,UAAU,CAAC;AAC3G,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAsCrC,MAAM,UAAU,IAAI,CAAC,KAAc;IAClC,IAAI,KAAK,EAAE,CAAC;QACX,kCAAkC;QAClC,4DAA4D;QAE5D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,sDAAsD,OAAO,KAAK,EAAE,CAAC,CAAC;QACvF,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,uCAAuC,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,uCAAuC,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3E,CAAC;IACF,CAAC;IACD,OAAO,CAAC,GAAG,IAAS,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAE,KAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,KAAa,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACjG,CAAC;AAyBD,MAAM,UAAU,IAAI,CAAI,KAAqB,EAAE,OAAsC;IACpF,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AAC3C,CAAC;AAaD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,YAAY,CAAI,QAAqB;IACpD,IAAI,KAAK,EAAE,CAAC;QACX,kCAAkC;QAClC,4DAA4D;QAE5D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,sDAAsD,OAAO,QAAQ,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,IAAI,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,uCAAuC,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9E,CAAC;QACD,IAAI,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,uCAAuC,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9E,CAAC;IACF,CAAC;IACD,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACtB,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,CAAE,KAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAClF,OAAO,GAAG,EAAE,CAAC;IACd,CAAC,CAAc,CAAC;IAChB,OAAO,CAAE,GAAG,EAAE,GAAG,CAAW,CAAC;AAC9B,CAAC"}
|