solid-state-tools 1.3.1 → 1.4.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/README.md +27 -14
- package/package.json +1 -1
- package/dist/atom.d.ts +0 -95
- package/dist/atom.d.ts.map +0 -1
- package/dist/atom.js +0 -97
- package/dist/atom.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -31,12 +31,15 @@ const count: Atom<Signal<number>> = atom(createSignal(0));
|
|
|
31
31
|
|
|
32
32
|
console.log(count()); // 0
|
|
33
33
|
|
|
34
|
+
// Sets count to 100.
|
|
34
35
|
count(100);
|
|
35
36
|
console.log(count()); // 100
|
|
36
37
|
|
|
38
|
+
// Sets count to its current value plus one.
|
|
37
39
|
count(count() + 1);
|
|
38
40
|
console.log(count()); // 101
|
|
39
41
|
|
|
42
|
+
// Sets count to its current value plus one (alternative syntax).
|
|
40
43
|
count((c) => c + 1);
|
|
41
44
|
console.log(count()); // 102
|
|
42
45
|
```
|
|
@@ -58,7 +61,7 @@ const count: Asig<number> = asig(0);
|
|
|
58
61
|
const count: Atom<Signal<number>> = atom(createSignal(0));
|
|
59
62
|
```
|
|
60
63
|
|
|
61
|
-
The second parameter (optional) is the config object, which is simply forwarded to
|
|
64
|
+
The second parameter (optional) is the config object, which is simply forwarded to [createSignal's options](https://docs.solidjs.com/reference/basic-reactivity/create-signal#options).
|
|
62
65
|
|
|
63
66
|
```ts
|
|
64
67
|
const list = asig([], { equals: false });
|
|
@@ -81,8 +84,8 @@ Why?
|
|
|
81
84
|
```ts
|
|
82
85
|
const [ _count, setCount ] = createSignal(0);
|
|
83
86
|
|
|
84
|
-
console.log(setCount(10)); //
|
|
85
|
-
console.log(setCount(x => x + 5)); //
|
|
87
|
+
console.log(setCount(10)); // 10
|
|
88
|
+
console.log(setCount(x => x + 5)); // 15
|
|
86
89
|
```
|
|
87
90
|
|
|
88
91
|
All of this is to say that creating custom signal pairs can be tedious.
|
|
@@ -114,22 +117,23 @@ With that, the following statements work (as is expected of a setter):
|
|
|
114
117
|
```ts
|
|
115
118
|
setDouble(10); // double: 10, count: 5
|
|
116
119
|
setDouble(x => x + 1); // double: 11, count: 5.5
|
|
117
|
-
console.log(setDouble(20)); //
|
|
120
|
+
console.log(setDouble(20)); // 20
|
|
118
121
|
```
|
|
119
122
|
|
|
120
123
|
But, the crusty boilerplate to get it working is annoying as heck.
|
|
121
124
|
|
|
122
125
|
**Enter the `createCouple` utility.**
|
|
123
126
|
|
|
124
|
-
It accepts a getter and a
|
|
125
|
-
A
|
|
126
|
-
Basically, it's the previous example without the boilerplate.
|
|
127
|
+
It accepts a getter and a writer and returns a signal.
|
|
128
|
+
A writer is similar to a setter, except that it doesn't accept a function as input nor does it return a value.
|
|
129
|
+
Basically, it's the setter of the previous example without all the boilerplate.
|
|
127
130
|
See it in action:
|
|
128
131
|
|
|
129
132
|
```ts
|
|
130
133
|
const [ count, setCount ] = createSignal(0);
|
|
131
134
|
|
|
132
135
|
const [ double, setDouble ] = createCouple(
|
|
136
|
+
// The provided getter is automatically memoized.
|
|
133
137
|
() => count() * 2,
|
|
134
138
|
|
|
135
139
|
(newValue) => {
|
|
@@ -140,7 +144,7 @@ const [ double, setDouble ] = createCouple(
|
|
|
140
144
|
},
|
|
141
145
|
);
|
|
142
146
|
|
|
143
|
-
// Yet, we can still
|
|
147
|
+
// Yet, we can still inject a function.
|
|
144
148
|
setDouble(x => x + 2);
|
|
145
149
|
console.log(double(), count()); // 2 1
|
|
146
150
|
|
|
@@ -148,16 +152,25 @@ console.log(double(), count()); // 2 1
|
|
|
148
152
|
console.log(setDouble(10), count()); // 10 5
|
|
149
153
|
```
|
|
150
154
|
|
|
155
|
+
It can be succinctly rewritten into this:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
const [ double, setDouble ] = createCouple(() => count() * 2, (x) => setCount(x / 2));
|
|
159
|
+
```
|
|
160
|
+
|
|
151
161
|
Much better, right?
|
|
152
162
|
|
|
153
163
|
> [!NOTE]
|
|
154
|
-
> The getter passed to `createCouple` is
|
|
155
|
-
>
|
|
164
|
+
> The getter passed to `createCouple` is [memoized](https://docs.solidjs.com/concepts/derived-values/memos) unless otherwise set in the `options`.
|
|
165
|
+
> Memoization immediately invokes the getter, so keep that in mind because it can cause undesirable side-effects.
|
|
156
166
|
|
|
157
|
-
By the way!
|
|
167
|
+
By the way! The `createCouple` output, like any signal, can be converted into an atom so that the getter and setter are merged together. See [atom](#atoms-atom) for details.
|
|
158
168
|
|
|
159
169
|
```ts
|
|
160
|
-
const double = atom(createCouple(
|
|
170
|
+
const double = atom(createCouple(() => count() * 2, (x) => setCount(x / 2)));
|
|
171
|
+
|
|
172
|
+
double() // read
|
|
173
|
+
double(10) // write
|
|
161
174
|
```
|
|
162
175
|
|
|
163
176
|
## Atomic couples (`apair`)
|
|
@@ -173,6 +186,6 @@ const double = atom(createCouple(() => count() * 2, (double) => count(double / 2
|
|
|
173
186
|
# Conclusion
|
|
174
187
|
|
|
175
188
|
Perhaps you can see the power of the above primitives.
|
|
176
|
-
Not
|
|
189
|
+
Not just what they do individually, but how they work together.
|
|
177
190
|
|
|
178
|
-
More utilities for this library are in the works and
|
|
191
|
+
More utilities for this library are in the works and are coming soon.
|
package/package.json
CHANGED
package/dist/atom.d.ts
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { type Accessor, type Signal, type SignalOptions } from "solid-js";
|
|
2
|
-
/**
|
|
3
|
-
* Any tuple of two functions where the first accepts no arguments and the second accepts any amount.
|
|
4
|
-
*/
|
|
5
|
-
export type SignalLike = readonly [() => any, (...args: any) => any];
|
|
6
|
-
/**
|
|
7
|
-
* An atom is a polymorphic function that calls one of two
|
|
8
|
-
* functions depending on the number of arguments it has.
|
|
9
|
-
*
|
|
10
|
-
* If called with zero arguments, the first function is called.
|
|
11
|
-
* Otherwise, the second function is called and all of the arguments are forwarded to it.
|
|
12
|
-
*/
|
|
13
|
-
export type Atom<T extends SignalLike = SignalLike> = T[0] & T[1];
|
|
14
|
-
/**
|
|
15
|
-
* Combine a getter and setter function pair into one.
|
|
16
|
-
*
|
|
17
|
-
* Accepts a tuple of two functions.
|
|
18
|
-
* The first is the getter, the second is the setter.
|
|
19
|
-
* A new function is returned that, when called with zero arguments, calls the getter.
|
|
20
|
-
* Otherwise, it calls the setter and forwards all of the arguments.
|
|
21
|
-
*
|
|
22
|
-
* ### Example
|
|
23
|
-
* ```
|
|
24
|
-
* const count = atom(createSignal(0));
|
|
25
|
-
*
|
|
26
|
-
* // Read
|
|
27
|
-
* count();
|
|
28
|
-
*
|
|
29
|
-
* // Write
|
|
30
|
-
* count(100);
|
|
31
|
-
* count(x => x + 1);
|
|
32
|
-
* count(count() + 1);
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
export declare function atom<const T extends SignalLike>(signal: T): Atom<T>;
|
|
36
|
-
/**
|
|
37
|
-
* Similar to a signal setter, except it doesn't accept a mapping function nor return a result.
|
|
38
|
-
*/
|
|
39
|
-
export type Cosetter<T> = (value: T) => void;
|
|
40
|
-
/**
|
|
41
|
-
* Create a signal from a cosignal.
|
|
42
|
-
*
|
|
43
|
-
* ### Example
|
|
44
|
-
* ```
|
|
45
|
-
* const [ count, setCount ] = createSignal(0);
|
|
46
|
-
* const [ double, setDouble ] = createSignalPair([
|
|
47
|
-
* () => count() * 2,
|
|
48
|
-
* (x) => void setCount(x / 2),
|
|
49
|
-
* ]);
|
|
50
|
-
*
|
|
51
|
-
* double(x => x + 2);
|
|
52
|
-
* console.log(double(), count()); // 2 1
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
|
-
export declare function createCouple<T>(getter: Accessor<T>, setter: Cosetter<T>): Signal<T>;
|
|
56
|
-
/**
|
|
57
|
-
* An atomic signal.
|
|
58
|
-
* A signal where the getter and setter are combined into one function.
|
|
59
|
-
*/
|
|
60
|
-
export type Asig<T> = Atom<Signal<T>>;
|
|
61
|
-
/**
|
|
62
|
-
* Create an atomic signal.
|
|
63
|
-
* Short for `atom(createSignal(...))`.
|
|
64
|
-
*
|
|
65
|
-
* ### Example
|
|
66
|
-
* ```
|
|
67
|
-
* const count = asig(0);
|
|
68
|
-
*
|
|
69
|
-
* count(10);
|
|
70
|
-
* console.log(count()); // 10
|
|
71
|
-
*
|
|
72
|
-
* count(x => x + 10);
|
|
73
|
-
* console.log(count()); // 20
|
|
74
|
-
* ```
|
|
75
|
-
*/
|
|
76
|
-
export declare function asig<T>(): Asig<T | undefined>;
|
|
77
|
-
export declare function asig<T>(value: T, options?: SignalOptions<T>): Asig<T>;
|
|
78
|
-
/**
|
|
79
|
-
* Create an atomic cosignal pair.
|
|
80
|
-
* Short for `atom(createCouple(...))`.
|
|
81
|
-
*
|
|
82
|
-
* ### Example
|
|
83
|
-
* ```
|
|
84
|
-
* const count = asig(0);
|
|
85
|
-
* const double = apair(() => count() * 2, (double) => void count(double / 2));
|
|
86
|
-
*
|
|
87
|
-
* count(10);
|
|
88
|
-
* console.log(count(), double()); // 10 20
|
|
89
|
-
*
|
|
90
|
-
* double(100);
|
|
91
|
-
* console.log(count(), double()); // 50 100
|
|
92
|
-
* ```
|
|
93
|
-
*/
|
|
94
|
-
export declare function apair<T>(getter: Accessor<T>, setter: Cosetter<T>): Asig<T>;
|
|
95
|
-
//# sourceMappingURL=atom.d.ts.map
|
package/dist/atom.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"atom.d.ts","sourceRoot":"","sources":["../src/atom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqC,KAAK,QAAQ,EAAe,KAAK,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAK1H;;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,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAiBnE;AAED;;GAEG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;AAE7C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAmBnF;AAID;;;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,CAAC,GAAG,SAAS,CAAC,CAAC;AAC/C,wBAAgB,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAKvE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAE1E"}
|
package/dist/atom.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { createMemo, createSignal, untrack } from "solid-js";
|
|
2
|
-
import { isDev } from "solid-js/web";
|
|
3
|
-
/**
|
|
4
|
-
* Combine a getter and setter function pair into one.
|
|
5
|
-
*
|
|
6
|
-
* Accepts a tuple of two functions.
|
|
7
|
-
* The first is the getter, the second is the setter.
|
|
8
|
-
* A new function is returned that, when called with zero arguments, calls the getter.
|
|
9
|
-
* Otherwise, it calls the setter and forwards all of the arguments.
|
|
10
|
-
*
|
|
11
|
-
* ### Example
|
|
12
|
-
* ```
|
|
13
|
-
* const count = atom(createSignal(0));
|
|
14
|
-
*
|
|
15
|
-
* // Read
|
|
16
|
-
* count();
|
|
17
|
-
*
|
|
18
|
-
* // Write
|
|
19
|
-
* count(100);
|
|
20
|
-
* count(x => x + 1);
|
|
21
|
-
* count(count() + 1);
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
export function atom(signal) {
|
|
25
|
-
if (isDev) {
|
|
26
|
-
// Assert that the input is valid.
|
|
27
|
-
// For production, these checks are skipped for performance.
|
|
28
|
-
if (!Array.isArray(signal)) {
|
|
29
|
-
throw new Error(`expected a getter setter pair as an array, but got ${typeof signal}`);
|
|
30
|
-
}
|
|
31
|
-
if (typeof signal[0] !== "function") {
|
|
32
|
-
throw new Error(`expected a getter function, but got ${typeof signal[0]}`);
|
|
33
|
-
}
|
|
34
|
-
if (typeof signal[1] !== "function") {
|
|
35
|
-
throw new Error(`expected a setter function, but got ${typeof signal[1]}`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
const [getter, setter] = signal;
|
|
39
|
-
return (...args) => (args.length === 0) ? getter() : setter(...args);
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Create a signal from a cosignal.
|
|
43
|
-
*
|
|
44
|
-
* ### Example
|
|
45
|
-
* ```
|
|
46
|
-
* const [ count, setCount ] = createSignal(0);
|
|
47
|
-
* const [ double, setDouble ] = createSignalPair([
|
|
48
|
-
* () => count() * 2,
|
|
49
|
-
* (x) => void setCount(x / 2),
|
|
50
|
-
* ]);
|
|
51
|
-
*
|
|
52
|
-
* double(x => x + 2);
|
|
53
|
-
* console.log(double(), count()); // 2 1
|
|
54
|
-
* ```
|
|
55
|
-
*/
|
|
56
|
-
export function createCouple(getter, setter) {
|
|
57
|
-
if (isDev) {
|
|
58
|
-
// Assert that the input is valid.
|
|
59
|
-
// For production, these checks are skipped for performance.
|
|
60
|
-
if (typeof getter !== "function") {
|
|
61
|
-
throw new Error(`expected getter to be a function, but got ${typeof getter}`);
|
|
62
|
-
}
|
|
63
|
-
if (typeof setter !== "function") {
|
|
64
|
-
throw new Error(`expected setter to be a function, but got ${typeof setter}`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
const get = createMemo(getter);
|
|
68
|
-
const set = ((source) => {
|
|
69
|
-
const value = (typeof source === "function") ? source(untrack(get)) : source;
|
|
70
|
-
setter(value);
|
|
71
|
-
return value;
|
|
72
|
-
});
|
|
73
|
-
return [get, set];
|
|
74
|
-
}
|
|
75
|
-
export function asig(value, options) {
|
|
76
|
-
return atom(createSignal(value, options));
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Create an atomic cosignal pair.
|
|
80
|
-
* Short for `atom(createCouple(...))`.
|
|
81
|
-
*
|
|
82
|
-
* ### Example
|
|
83
|
-
* ```
|
|
84
|
-
* const count = asig(0);
|
|
85
|
-
* const double = apair(() => count() * 2, (double) => void count(double / 2));
|
|
86
|
-
*
|
|
87
|
-
* count(10);
|
|
88
|
-
* console.log(count(), double()); // 10 20
|
|
89
|
-
*
|
|
90
|
-
* double(100);
|
|
91
|
-
* console.log(count(), double()); // 50 100
|
|
92
|
-
* ```
|
|
93
|
-
*/
|
|
94
|
-
export function apair(getter, setter) {
|
|
95
|
-
return atom(createCouple(getter, setter));
|
|
96
|
-
}
|
|
97
|
-
//# sourceMappingURL=atom.js.map
|
package/dist/atom.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"atom.js","sourceRoot":"","sources":["../src/atom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAA+D,MAAM,UAAU,CAAC;AAC1H,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAkBrC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,IAAI,CAA6B,MAAS;IACzD,IAAI,KAAK,EAAE,CAAC;QACX,kCAAkC;QAClC,4DAA4D;QAE5D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,sDAAsD,OAAO,MAAM,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,IAAI,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,uCAAuC,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,uCAAuC,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5E,CAAC;IACF,CAAC;IACD,MAAM,CAAE,MAAM,EAAE,MAAM,CAAE,GAAG,MAAM,CAAC;IAClC,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;AACjF,CAAC;AAOD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,YAAY,CAAI,MAAmB,EAAE,MAAmB;IACvE,IAAI,KAAK,EAAE,CAAC;QACX,kCAAkC;QAClC,4DAA4D;QAE5D,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,6CAA6C,OAAO,MAAM,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,6CAA6C,OAAO,MAAM,EAAE,CAAC,CAAC;QAC/E,CAAC;IACF,CAAC;IACD,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACvB,MAAM,KAAK,GAAG,CAAC,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,CAAE,MAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC3F,MAAM,CAAC,KAAK,CAAC,CAAC;QACd,OAAO,KAAK,CAAC;IACd,CAAC,CAAc,CAAC;IAChB,OAAO,CAAE,GAAG,EAAE,GAAG,CAAW,CAAC;AAC9B,CAAC;AA2BD,MAAM,UAAU,IAAI,CAAI,KAAqB,EAAE,OAAsC;IACpF,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,KAAK,CAAI,MAAmB,EAAE,MAAmB;IAChE,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAC3C,CAAC"}
|
package/dist/index.d.ts
DELETED
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
|
package/dist/index.js
DELETED
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
|