solid-state-tools 1.4.0 → 1.5.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
@@ -10,15 +10,12 @@ The package is small and only has a peer dependency of Solid JS.
10
10
 
11
11
  # Usage
12
12
 
13
- This library introduces some new primitives:
14
-
15
- 1. [atom](#atoms-atom)
16
- 2. [createCouple](#couples-createcouple)
17
-
18
- And, a few shorthand functions that combine these primitives and those from Solid JS together.
19
-
20
- 1. [asig](#atomic-signals-asig)
21
- 2. [apair](#atomic-couples-apair)
13
+ | Utility | Summary |
14
+ | ------------------------------- | ------------------------------------------------ |
15
+ | [atom](#atoms-atom) | Combines a getter setter pair into one function. |
16
+ | [createPair](#pairs-createpair) | Creates a signal from a getter setter pair. |
17
+ | [asig](#atomic-signals-asig) | Shorthand for `atom(createSignal(...))` |
18
+ | [apair](#atomic-pairs-apair) | Shorthand for `atom(createCouple(...))` |
22
19
 
23
20
  Read the sections below for a breakdown of each utility.
24
21
 
@@ -69,7 +66,7 @@ const list = asig([], { equals: false });
69
66
  const list = atom(createSignal([], { equals: false }));
70
67
  ```
71
68
 
72
- ## Couples (`createCouple`)
69
+ ## Pairs (`createPair`)
73
70
 
74
71
  A signal can be summarized as a getter setter pair.
75
72
  However, the setter of a Solid JS signal is more complex than it appears at first glance.
@@ -122,7 +119,7 @@ console.log(setDouble(20)); // 20
122
119
 
123
120
  But, the crusty boilerplate to get it working is annoying as heck.
124
121
 
125
- **Enter the `createCouple` utility.**
122
+ **Enter the `createPair` utility.**
126
123
 
127
124
  It accepts a getter and a writer and returns a signal.
128
125
  A writer is similar to a setter, except that it doesn't accept a function as input nor does it return a value.
@@ -132,7 +129,7 @@ See it in action:
132
129
  ```ts
133
130
  const [ count, setCount ] = createSignal(0);
134
131
 
135
- const [ double, setDouble ] = createCouple(
132
+ const [ double, setDouble ] = createPair(
136
133
  // The provided getter is automatically memoized.
137
134
  () => count() * 2,
138
135
 
@@ -155,32 +152,32 @@ console.log(setDouble(10), count()); // 10 5
155
152
  It can be succinctly rewritten into this:
156
153
 
157
154
  ```ts
158
- const [ double, setDouble ] = createCouple(() => count() * 2, (x) => setCount(x / 2));
155
+ const [ double, setDouble ] = createPair(() => count() * 2, (x) => setCount(x / 2));
159
156
  ```
160
157
 
161
158
  Much better, right?
162
159
 
163
160
  > [!NOTE]
164
- > The getter passed to `createCouple` is [memoized](https://docs.solidjs.com/concepts/derived-values/memos) unless otherwise set in the `options`.
161
+ > The getter passed to `createPair` is [memoized](https://docs.solidjs.com/concepts/derived-values/memos) unless otherwise set in the `options`.
165
162
  > Memoization immediately invokes the getter, so keep that in mind because it can cause undesirable side-effects.
166
163
 
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.
164
+ By the way! The `createPair` 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.
168
165
 
169
166
  ```ts
170
- const double = atom(createCouple(() => count() * 2, (x) => setCount(x / 2)));
167
+ const double = atom(createPair(() => count() * 2, (x) => setCount(x / 2)));
171
168
 
172
169
  double() // read
173
170
  double(10) // write
174
171
  ```
175
172
 
176
- ## Atomic couples (`apair`)
173
+ ## Atomic pairs (`apair`)
177
174
 
178
- Similar to [atomic signals](#atomic-signals-asig), wrapping a `createCouple` call with `atom` is a common enough pattern to warrant a shorthand: `apair`.
175
+ Similar to [atomic signals](#atomic-signals-asig), wrapping a `createPair` call with `atom` is a common enough pattern to warrant a shorthand: `apair`.
179
176
 
180
177
  ```ts
181
178
  const double = apair(() => count() * 2, (double) => count(double / 2));
182
179
  // is short for
183
- const double = atom(createCouple(() => count() * 2, (double) => count(double / 2)));
180
+ const double = atom(createPair(() => count() * 2, (double) => count(double / 2)));
184
181
  ```
185
182
 
186
183
  # Conclusion
@@ -0,0 +1,127 @@
1
+ import { type Accessor, type Signal, type SignalOptions } from "solid-js";
2
+ /**
3
+ * @description
4
+ * Any tuple of two functions where the first accepts no arguments and the second accepts any amount.
5
+ *
6
+ * Used as the source of an {@link Atom}.
7
+ *
8
+ * @see {@link Atom}, {@link atom}
9
+ */
10
+ export type SignalLike = readonly [() => any, (...args: any) => any];
11
+ /**
12
+ * @description
13
+ * An {@link Atom} is a polymorphic function that calls one of two
14
+ * functions depending on the number of arguments it has.
15
+ *
16
+ * If called with zero arguments, the first function is called.
17
+ * Otherwise, the second function is called with all arguments forwarded to it.
18
+ *
19
+ * @see {@link SignalLike}, {@link atom} (constructor)
20
+ */
21
+ export type Atom<T extends SignalLike = SignalLike> = T[0] & T[1];
22
+ /**
23
+ * @description
24
+ * Combine a getter and setter function pair into one.
25
+ * [See documentation.](https://github.com/ReedSyllas/solid-state-tools#atoms-atom)
26
+ *
27
+ * Accepts a tuple of two functions.
28
+ * The first is the getter, the second is the setter.
29
+ * A new function is returned that, when called with zero arguments, calls the getter.
30
+ * Otherwise, it calls the setter and forwards all of the arguments.
31
+ *
32
+ * @see {@link SignalLike} (input), {@link Atom} (output)
33
+ *
34
+ * @example
35
+ * ```
36
+ * const count: Atom<Signal<T>> = atom(createSignal(0));
37
+ *
38
+ * // Read
39
+ * count();
40
+ *
41
+ * // Write
42
+ * count(100);
43
+ * count(x => x + 1);
44
+ * count(count() + 1);
45
+ * ```
46
+ */
47
+ export declare function atom<const T extends SignalLike>(signal: T): Atom<T>;
48
+ /**
49
+ * @description
50
+ * Similar to a signal setter, except it doesn't accept a mapping function nor return a result.
51
+ *
52
+ * @see {@link createPair} (for example usage)
53
+ */
54
+ export type Writer<T> = (value: T) => void;
55
+ export interface PairOptions {
56
+ /**
57
+ * @default true
58
+ */
59
+ memoized: boolean;
60
+ }
61
+ /**
62
+ * @description
63
+ * Create a signal from a getter setter pair.
64
+ * [See documentation.](https://github.com/ReedSyllas/solid-state-tools#pairs-createpair)
65
+ *
66
+ * **The getter is immediately invoked for memoization.**
67
+ *
68
+ * @see {@link Accessor} (input), {@link Writer} (input), {@link PairOptions} (input), {@link Signal} (output)
69
+ *
70
+ * @example
71
+ * ```
72
+ * const [ count, setCount ] = createSignal(0);
73
+ * const [ double, setDouble ] = createPair(() => count() * 2, (x) => setCount(x / 2));
74
+ *
75
+ * setDouble(x => x + 2);
76
+ * console.log(double(), count()); // 2 1
77
+ * ```
78
+ */
79
+ export declare function createPair<T>(getter: Accessor<T>, setter: Writer<T>, options?: PairOptions): Signal<T>;
80
+ /**
81
+ * @description
82
+ * An atomic signal. A signal where the getter and setter are combined into one function.
83
+ *
84
+ * @see {@link Atom}, {@link asig} (constructor)
85
+ */
86
+ export type Asig<T> = Atom<Signal<T>>;
87
+ /**
88
+ * @description
89
+ * Create an atomic signal. Short for `atom(createSignal(...))`.
90
+ * [See documentation.](https://github.com/ReedSyllas/solid-state-tools#atomic-signals-asig)
91
+ *
92
+ * @see {@link Asig} (output), {@link Atom}, {@link atom}
93
+ *
94
+ * @example
95
+ * ```
96
+ * const count = asig(0);
97
+ *
98
+ * count(10);
99
+ * console.log(count()); // 10
100
+ *
101
+ * count(x => x + 10);
102
+ * console.log(count()); // 20
103
+ * ```
104
+ */
105
+ export declare function asig<T>(value: T, options?: SignalOptions<T>): Asig<T>;
106
+ export declare function asig<T>(): Asig<T | undefined>;
107
+ /**
108
+ * @description
109
+ * Create an atomic getter setter pair. Short for `atom(createPair(...))`.
110
+ * [See documentation.](https://github.com/ReedSyllas/solid-state-tools#atomic-pairs-apair)
111
+ *
112
+ * @see {@link Accessor} (input), {@link Writer} (input), {@link PairOptions} (input), {@link Asig} (output)
113
+ *
114
+ * @example
115
+ * ```
116
+ * const count = asig(0);
117
+ * const double = apair(() => count() * 2, (x) => count(x / 2));
118
+ *
119
+ * count(10);
120
+ * console.log(count(), double()); // 10 20
121
+ *
122
+ * double(100);
123
+ * console.log(count(), double()); // 50 100
124
+ * ```
125
+ */
126
+ export declare function apair<T>(getter: Accessor<T>, setter: Writer<T>, options?: PairOptions): Asig<T>;
127
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqC,KAAK,QAAQ,EAAe,KAAK,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAK1H;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,CAAE,MAAM,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,CAAE,CAAC;AAEvE;;;;;;;;;GASG;AACH,MAAM,MAAM,IAAI,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAiBnE;AAED;;;;;GAKG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;AAE3C,MAAM,WAAW,WAAW;IAC3B;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,CAmBtG;AAID;;;;;GAKG;AACH,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AACvE,wBAAgB,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;AAK/C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,CAE/F"}
package/dist/index.js ADDED
@@ -0,0 +1,107 @@
1
+ import { createMemo, createSignal, untrack } from "solid-js";
2
+ import { isDev } from "solid-js/web";
3
+ /**
4
+ * @description
5
+ * Combine a getter and setter function pair into one.
6
+ * [See documentation.](https://github.com/ReedSyllas/solid-state-tools#atoms-atom)
7
+ *
8
+ * Accepts a tuple of two functions.
9
+ * The first is the getter, the second is the setter.
10
+ * A new function is returned that, when called with zero arguments, calls the getter.
11
+ * Otherwise, it calls the setter and forwards all of the arguments.
12
+ *
13
+ * @see {@link SignalLike} (input), {@link Atom} (output)
14
+ *
15
+ * @example
16
+ * ```
17
+ * const count: Atom<Signal<T>> = atom(createSignal(0));
18
+ *
19
+ * // Read
20
+ * count();
21
+ *
22
+ * // Write
23
+ * count(100);
24
+ * count(x => x + 1);
25
+ * count(count() + 1);
26
+ * ```
27
+ */
28
+ export function atom(signal) {
29
+ if (isDev) {
30
+ // Assert that the input is valid.
31
+ // For production, these checks are skipped for performance.
32
+ if (!Array.isArray(signal)) {
33
+ throw new Error(`expected a getter setter pair as an array, but got ${typeof signal}`);
34
+ }
35
+ if (typeof signal[0] !== "function") {
36
+ throw new Error(`expected a getter function, but got ${typeof signal[0]}`);
37
+ }
38
+ if (typeof signal[1] !== "function") {
39
+ throw new Error(`expected a setter function, but got ${typeof signal[1]}`);
40
+ }
41
+ }
42
+ const [getter, setter] = signal;
43
+ return (...args) => (args.length === 0) ? getter() : setter(...args);
44
+ }
45
+ /**
46
+ * @description
47
+ * Create a signal from a getter setter pair.
48
+ * [See documentation.](https://github.com/ReedSyllas/solid-state-tools#pairs-createpair)
49
+ *
50
+ * **The getter is immediately invoked for memoization.**
51
+ *
52
+ * @see {@link Accessor} (input), {@link Writer} (input), {@link PairOptions} (input), {@link Signal} (output)
53
+ *
54
+ * @example
55
+ * ```
56
+ * const [ count, setCount ] = createSignal(0);
57
+ * const [ double, setDouble ] = createPair(() => count() * 2, (x) => setCount(x / 2));
58
+ *
59
+ * setDouble(x => x + 2);
60
+ * console.log(double(), count()); // 2 1
61
+ * ```
62
+ */
63
+ export function createPair(getter, setter, options) {
64
+ if (isDev) {
65
+ // Assert that the input is valid.
66
+ // For production, these checks are skipped for performance.
67
+ if (typeof getter !== "function") {
68
+ throw new Error(`expected getter to be a function, but got ${typeof getter}`);
69
+ }
70
+ if (typeof setter !== "function") {
71
+ throw new Error(`expected setter to be a function, but got ${typeof setter}`);
72
+ }
73
+ }
74
+ const get = options?.memoized === false ? getter : createMemo(getter);
75
+ const set = ((source) => {
76
+ const value = (typeof source === "function") ? source(untrack(get)) : source;
77
+ setter(value);
78
+ return value;
79
+ });
80
+ return [get, set];
81
+ }
82
+ export function asig(value, options) {
83
+ return atom(createSignal(value, options));
84
+ }
85
+ /**
86
+ * @description
87
+ * Create an atomic getter setter pair. Short for `atom(createPair(...))`.
88
+ * [See documentation.](https://github.com/ReedSyllas/solid-state-tools#atomic-pairs-apair)
89
+ *
90
+ * @see {@link Accessor} (input), {@link Writer} (input), {@link PairOptions} (input), {@link Asig} (output)
91
+ *
92
+ * @example
93
+ * ```
94
+ * const count = asig(0);
95
+ * const double = apair(() => count() * 2, (x) => count(x / 2));
96
+ *
97
+ * count(10);
98
+ * console.log(count(), double()); // 10 20
99
+ *
100
+ * double(100);
101
+ * console.log(count(), double()); // 50 100
102
+ * ```
103
+ */
104
+ export function apair(getter, setter, options) {
105
+ return atom(createPair(getter, setter, options));
106
+ }
107
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAA+D,MAAM,UAAU,CAAC;AAC1H,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AA0BrC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;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;AAiBD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,UAAU,CAAI,MAAmB,EAAE,MAAiB,EAAE,OAAqB;IAC1F,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,OAAO,EAAE,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACtE,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;AAgCD,MAAM,UAAU,IAAI,CAAI,KAAqB,EAAE,OAAsC;IACpF,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,KAAK,CAAI,MAAmB,EAAE,MAAiB,EAAE,OAAqB;IACrF,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAClD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solid-state-tools",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "A collection of Solid JS state utilities",
5
5
  "author": "Reed Syllas <reedsyllas@gmail.com>",
6
6
  "license": "ISC",