solid-state-tools 1.3.0 → 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 CHANGED
@@ -1,5 +1,7 @@
1
1
  # Solid State Tools
2
2
 
3
+ Links: [GitHub Repository](https://github.com/ReedSyllas/solid-state-tools), [NPM Package](https://www.npmjs.com/package/solid-state-tools).
4
+
3
5
  Solid State Tools is a collection of simple utilities for managing [Solid JS](https://docs.solidjs.com/) state.
4
6
 
5
7
  All features are intended to compliment Solid JS's existing state system, building upon the existing foundation.
@@ -29,12 +31,15 @@ const count: Atom<Signal<number>> = atom(createSignal(0));
29
31
 
30
32
  console.log(count()); // 0
31
33
 
34
+ // Sets count to 100.
32
35
  count(100);
33
36
  console.log(count()); // 100
34
37
 
38
+ // Sets count to its current value plus one.
35
39
  count(count() + 1);
36
40
  console.log(count()); // 101
37
41
 
42
+ // Sets count to its current value plus one (alternative syntax).
38
43
  count((c) => c + 1);
39
44
  console.log(count()); // 102
40
45
  ```
@@ -56,6 +61,14 @@ const count: Asig<number> = asig(0);
56
61
  const count: Atom<Signal<number>> = atom(createSignal(0));
57
62
  ```
58
63
 
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).
65
+
66
+ ```ts
67
+ const list = asig([], { equals: false });
68
+ // is short for
69
+ const list = atom(createSignal([], { equals: false }));
70
+ ```
71
+
59
72
  ## Couples (`createCouple`)
60
73
 
61
74
  A signal can be summarized as a getter setter pair.
@@ -71,8 +84,8 @@ Why?
71
84
  ```ts
72
85
  const [ _count, setCount ] = createSignal(0);
73
86
 
74
- console.log(setCount(10)); // Prints: 10
75
- console.log(setCount(x => x + 5)); // Prints: 15
87
+ console.log(setCount(10)); // 10
88
+ console.log(setCount(x => x + 5)); // 15
76
89
  ```
77
90
 
78
91
  All of this is to say that creating custom signal pairs can be tedious.
@@ -99,26 +112,28 @@ const [ double, setDouble ] = [
99
112
  ];
100
113
  ```
101
114
 
102
- With that, all of the statements below work exactly as expected.
115
+ With that, the following statements work (as is expected of a setter):
103
116
 
104
117
  ```ts
105
118
  setDouble(10); // double: 10, count: 5
106
119
  setDouble(x => x + 1); // double: 11, count: 5.5
107
- console.log(setDouble(20)); // Prints: 20
120
+ console.log(setDouble(20)); // 20
108
121
  ```
109
122
 
110
- But, wouldn't it be convenient if we could skip the crusty boilerplate?
123
+ But, the crusty boilerplate to get it working is annoying as heck.
111
124
 
112
- **Enter the `createCouple` utility**
125
+ **Enter the `createCouple` utility.**
113
126
 
114
- It accepts a getter and a co-setter and returns a signal.
115
- A co-setter is similar to a setter, except that it doesn't take a function nor does it return a value.
116
- Basically, it's the previous example without the boilerplate. See the following example:
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.
130
+ See it in action:
117
131
 
118
132
  ```ts
119
133
  const [ count, setCount ] = createSignal(0);
120
134
 
121
135
  const [ double, setDouble ] = createCouple(
136
+ // The provided getter is automatically memoized.
122
137
  () => count() * 2,
123
138
 
124
139
  (newValue) => {
@@ -129,7 +144,7 @@ const [ double, setDouble ] = createCouple(
129
144
  },
130
145
  );
131
146
 
132
- // Yet, we can still pass a function in.
147
+ // Yet, we can still inject a function.
133
148
  setDouble(x => x + 2);
134
149
  console.log(double(), count()); // 2 1
135
150
 
@@ -137,16 +152,25 @@ console.log(double(), count()); // 2 1
137
152
  console.log(setDouble(10), count()); // 10 5
138
153
  ```
139
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
+
140
161
  Much better, right?
141
162
 
142
163
  > [!NOTE]
143
- > The getter passed to `createCouple` is always memoized.
144
- > This has the consequence that the getter is invoked immediately during creation of the couple.
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.
145
166
 
146
- By the way! A `createCouple` call, like any expression that evaluates to a signal, can be converted into an atom so that the getter and setter are merged into one.
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.
147
168
 
148
169
  ```ts
149
- const double = atom(createCouple(/* ... */));
170
+ const double = atom(createCouple(() => count() * 2, (x) => setCount(x / 2)));
171
+
172
+ double() // read
173
+ double(10) // write
150
174
  ```
151
175
 
152
176
  ## Atomic couples (`apair`)
@@ -162,6 +186,6 @@ const double = atom(createCouple(() => count() * 2, (double) => count(double / 2
162
186
  # Conclusion
163
187
 
164
188
  Perhaps you can see the power of the above primitives.
165
- Not only in what they do, but also in how they combine.
189
+ Not just what they do individually, but how they work together.
166
190
 
167
- More utilities for this library are in the works and will be coming soon.
191
+ More utilities for this library are in the works and are coming soon.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solid-state-tools",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "A collection of Solid JS state utilities",
5
5
  "author": "Reed Syllas <reedsyllas@gmail.com>",
6
6
  "license": "ISC",
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>(value: 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
@@ -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,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAmBpE;;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,75 +0,0 @@
1
- import { createMemo, createSignal, untrack } from "solid-js";
2
- import { isDev } from "solid-js/web";
3
- export function atom(value) {
4
- if (isDev) {
5
- // Assert that the input is valid.
6
- // For production, these checks are skipped for performance.
7
- if (!Array.isArray(value)) {
8
- throw new Error(`expected a getter setter pair as an array, but got ${typeof value}`);
9
- }
10
- if (typeof value[0] !== "function") {
11
- throw new Error(`expected a getter function, but got ${typeof value[0]}`);
12
- }
13
- if (typeof value[1] !== "function") {
14
- throw new Error(`expected a setter function, but got ${typeof value[1]}`);
15
- }
16
- }
17
- return (...args) => (args.length === 0) ? value[0]() : value[1](...args);
18
- }
19
- /**
20
- * Create a signal from a cosignal.
21
- *
22
- * ### Example
23
- * ```
24
- * const [ count, setCount ] = createSignal(0);
25
- * const [ double, setDouble ] = createSignalPair([
26
- * () => count() * 2,
27
- * (x) => void setCount(x / 2),
28
- * ]);
29
- *
30
- * double(x => x + 2);
31
- * console.log(double(), count()); // 2 1
32
- * ```
33
- */
34
- export function createCouple(getter, setter) {
35
- if (isDev) {
36
- // Assert that the input is valid.
37
- // For production, these checks are skipped for performance.
38
- if (typeof getter !== "function") {
39
- throw new Error(`expected getter to be a function, but got ${typeof getter}`);
40
- }
41
- if (typeof setter !== "function") {
42
- throw new Error(`expected setter to be a function, but got ${typeof setter}`);
43
- }
44
- }
45
- const get = createMemo(getter);
46
- const set = ((source) => {
47
- const value = (typeof source === "function") ? source(untrack(get)) : source;
48
- setter(value);
49
- return value;
50
- });
51
- return [get, set];
52
- }
53
- export function asig(value, options) {
54
- return atom(createSignal(value, options));
55
- }
56
- /**
57
- * Create an atomic cosignal pair.
58
- * Short for `atom(createCouple(...))`.
59
- *
60
- * ### Example
61
- * ```
62
- * const count = asig(0);
63
- * const double = apair(() => count() * 2, (double) => void count(double / 2));
64
- *
65
- * count(10);
66
- * console.log(count(), double()); // 10 20
67
- *
68
- * double(100);
69
- * console.log(count(), double()); // 50 100
70
- * ```
71
- */
72
- export function apair(getter, setter) {
73
- return atom(createCouple(getter, setter));
74
- }
75
- //# 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;AAwCrC,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,IAAe,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAE,KAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,KAAoB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACrH,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
@@ -1,2 +0,0 @@
1
- export * from "./atom.js";
2
- //# sourceMappingURL=index.d.ts.map
@@ -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
@@ -1,2 +0,0 @@
1
- export * from "./atom.js";
2
- //# sourceMappingURL=index.js.map
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"}