react-state-monad 1.0.14 → 1.0.16

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,13 +1,13 @@
1
- import {StateObject} from "../stateObject";
2
- import {EmptyState} from "../implementations/emptyState";
3
-
4
- /**
5
- * Hook that initializes a StateObject with an empty state.
6
- * This is useful as a fallback when no valid state is available.
7
- *
8
- * @template T - The type of the value that could be held by the state.
9
- * @returns A StateObject representing an empty state.
10
- */
11
- export function useEmptyState<T>(): StateObject<T> {
12
- return new EmptyState<T>(); // Returns a new EmptyState object.
1
+ import {StateObject} from "../stateObject";
2
+ import {EmptyState} from "../implementations/emptyState";
3
+
4
+ /**
5
+ * Hook that initializes a StateObject with an empty state.
6
+ * This is useful as a fallback when no valid state is available.
7
+ *
8
+ * @template T - The type of the value that could be held by the state.
9
+ * @returns A StateObject representing an empty state.
10
+ */
11
+ export function useEmptyState<T>(): StateObject<T> {
12
+ return new EmptyState<T>(); // Returns a new EmptyState object.
13
13
  }
@@ -1,21 +1,21 @@
1
- import {StateObject} from "../stateObject";
2
- import {ValidFieldFrom} from "./types";
3
-
4
- /**
5
- * Hook that derives a field from the state object and creates a new StateObject for the field's value.
6
- *
7
- * @template TOriginal - The type of the original state object.
8
- * @template TField - The type of the field value to be derived.
9
- * @param state - The StateObject containing the original state.
10
- * @param field - The field name to be derived from the state.
11
- * @returns A new StateObject for the derived field.
12
- */
13
- export function useFieldState<TOriginal, TField>(
14
- state: StateObject<TOriginal>,
15
- field: ValidFieldFrom<TOriginal, TField>
16
- ): StateObject<TField> {
17
- return state.map(
18
- (original) => original[field] as TField, // Extracts the field value.
19
- (newField, original) => ({...original, [field]: newField} as TOriginal) // Updates the field with the new value.
20
- );
1
+ import {StateObject} from "../stateObject";
2
+ import {ValidFieldFrom} from "./types";
3
+
4
+ /**
5
+ * Hook that derives a field from the state object and creates a new StateObject for the field's value.
6
+ *
7
+ * @template TOriginal - The type of the original state object.
8
+ * @template TField - The type of the field value to be derived.
9
+ * @param state - The StateObject containing the original state.
10
+ * @param field - The field name to be derived from the state.
11
+ * @returns A new StateObject for the derived field.
12
+ */
13
+ export function useFieldState<TOriginal, TField>(
14
+ state: StateObject<TOriginal>,
15
+ field: ValidFieldFrom<TOriginal, TField>
16
+ ): StateObject<TField> {
17
+ return state.map(
18
+ (original) => original[field] as TField, // Extracts the field value.
19
+ (newField, original) => ({...original, [field]: newField} as TOriginal) // Updates the field with the new value.
20
+ );
21
21
  }
@@ -1,50 +1,50 @@
1
- import {StateObject} from "../stateObject";
2
- import {ValidState} from "../implementations/validState";
3
- import {useState} from "react";
4
- import {useStateObject} from "./useStateObject";
5
-
6
- /**
7
- * Hook that maps each element in an array within a StateObject to a new StateObject,
8
- * allowing for independent updates of each element while keeping the overall array state synchronized.
9
- *
10
- * @template T - The type of the array elements.
11
- * @param state - The StateObject containing an array.
12
- * @returns An array of new StateObjects, each representing an element in the original array,
13
- * allowing individual updates while keeping the array state synchronized.
14
- */
15
- export function useRemapArray<T>(state: StateObject<T[]>): StateObject<T>[] {
16
- if (!state.hasValue) return [] // Returns an empty array if the state has no value.
17
-
18
- const count = state.value.length
19
- const result: StateObject<T>[] = []
20
-
21
- for (let i = 0; i < count; i++) {
22
- result.push(
23
- new ValidState<T>(
24
- state.value[i], // The current value of the element at index i.
25
- (newElement) => { // Setter to update the element at index i in the array.
26
- const arrayCopy = [...state.value]; // Create a copy of the original array.
27
- arrayCopy[i] = newElement; // Replace the element at index i with the new element.
28
- state.value = arrayCopy; // Update the state with the new array, triggering a re-render.
29
- }
30
- )
31
- )
32
- }
33
-
34
- return result // Return the array of StateObjects representing each element.
35
- }
36
-
37
-
38
- /**
39
- * Hook that takes an array of StateObjects and returns a new StateObject containing that array,
40
- * allowing for updates to the entire array while keeping it synchronized within a single StateObject.
41
- *
42
- * @template T - The type of the elements in the array.
43
- * @param states - The array of StateObjects.
44
- * @returns A new StateObject containing the array of StateObjects, allowing for updates to the whole array.
45
- */
46
- export function useArrayState<T>(states: StateObject<T>[]): StateObject<T[]> {
47
-
48
- return useStateObject(states.filter(state => state.hasValue).map(state => state.value));
49
-
50
- }
1
+ import {StateObject} from "../stateObject";
2
+ import {ValidState} from "../implementations/validState";
3
+ import {useState} from "react";
4
+ import {useStateObject} from "./useStateObject";
5
+
6
+ /**
7
+ * Hook that maps each element in an array within a StateObject to a new StateObject,
8
+ * allowing for independent updates of each element while keeping the overall array state synchronized.
9
+ *
10
+ * @template T - The type of the array elements.
11
+ * @param state - The StateObject containing an array.
12
+ * @returns An array of new StateObjects, each representing an element in the original array,
13
+ * allowing individual updates while keeping the array state synchronized.
14
+ */
15
+ export function useRemapArray<T>(state: StateObject<T[]>): StateObject<T>[] {
16
+ if (!state.hasValue) return [] // Returns an empty array if the state has no value.
17
+
18
+ const count = state.value.length
19
+ const result: StateObject<T>[] = []
20
+
21
+ for (let i = 0; i < count; i++) {
22
+ result.push(
23
+ new ValidState<T>(
24
+ state.value[i], // The current value of the element at index i.
25
+ (newElement) => { // Setter to update the element at index i in the array.
26
+ const arrayCopy = [...state.value]; // Create a copy of the original array.
27
+ arrayCopy[i] = newElement; // Replace the element at index i with the new element.
28
+ state.value = arrayCopy; // Update the state with the new array, triggering a re-render.
29
+ }
30
+ )
31
+ )
32
+ }
33
+
34
+ return result // Return the array of StateObjects representing each element.
35
+ }
36
+
37
+
38
+ /**
39
+ * Hook that takes an array of StateObjects and returns a new StateObject containing that array,
40
+ * allowing for updates to the entire array while keeping it synchronized within a single StateObject.
41
+ *
42
+ * @template T - The type of the elements in the array.
43
+ * @param states - The array of StateObjects.
44
+ * @returns A new StateObject containing the array of StateObjects, allowing for updates to the whole array.
45
+ */
46
+ export function useArrayState<T>(states: StateObject<T>[]): StateObject<T[]> {
47
+
48
+ return useStateObject(states.filter(state => state.hasValue).map(state => state.value));
49
+
50
+ }
@@ -0,0 +1,24 @@
1
+ import {StateObject} from "../stateObject";
2
+ import {ValidState} from "../implementations/validState";
3
+ import {EmptyState} from "../implementations/emptyState";
4
+
5
+ /**
6
+ * Hook that ensures a StateObject contains a defined, non-null value.
7
+ * If the StateObject's value is `undefined` or `null`, it returns an EmptyState.
8
+ * Otherwise, it returns a ValidState with the value and a setter to update the value.
9
+ *
10
+ * @template TOrigin - The type of the value contained in the StateObject.
11
+ * @param state - The StateObject which may contain a value, `undefined`, or `null`.
12
+ * @returns A new StateObject containing the value if it is defined and non-null,
13
+ * otherwise an EmptyState.
14
+ */
15
+ export function useNullSafety<TOrigin>(state: StateObject<TOrigin | undefined | null>): StateObject<TOrigin> {
16
+
17
+ if (!state.hasValue) return new EmptyState<TOrigin>();
18
+
19
+ if (state.value === undefined) return new EmptyState<TOrigin>();
20
+
21
+ if (state.value === null) return new EmptyState<TOrigin>();
22
+
23
+ return new ValidState<TOrigin>(state.value, (value: TOrigin) => state.value = value);
24
+ }
@@ -1,15 +1,15 @@
1
- import {StateObject} from "../stateObject";
2
- import {useState} from "react";
3
- import {ValidState} from "../implementations/validState";
4
-
5
- /**
6
- * Hook that initializes a StateObject with the given initial value.
7
- *
8
- * @template T - The type of the value to be stored in the state.
9
- * @param initialState - The initial value of the state.
10
- * @returns A StateObject representing the initialized state.
11
- */
12
- export function useStateObject<T>(initialState: T): StateObject<T> {
13
- const [state, setState] = useState<T>(initialState);
14
- return new ValidState<T>(state, setState); // Returns a new ValidState object with the initial state value.
1
+ import {StateObject} from "../stateObject";
2
+ import {useState} from "react";
3
+ import {ValidState} from "../implementations/validState";
4
+
5
+ /**
6
+ * Hook that initializes a StateObject with the given initial value.
7
+ *
8
+ * @template T - The type of the value to be stored in the state.
9
+ * @param initialState - The initial value of the state.
10
+ * @returns A StateObject representing the initialized state.
11
+ */
12
+ export function useStateObject<T>(initialState: T): StateObject<T> {
13
+ const [state, setState] = useState<T>(initialState);
14
+ return new ValidState<T>(state, setState); // Returns a new ValidState object with the initial state value.
15
15
  }
@@ -1,43 +1,43 @@
1
- import {StateObject} from "../stateObject";
2
-
3
- /**
4
- * Represents a state that holds no value and is considered "empty".
5
- * This is used as a fallback or default when there is no valid state.
6
- * you should NEVER use this class directly, use the `StateObject` interface instead.
7
- * and create instances by using the hooks
8
- * @template T - The type of the value that could be held by the state.
9
- */
10
- export class EmptyState<T> implements StateObject<T> {
11
- // No value stored, returns an error when accessed.
12
- get value(): T {
13
- throw new Error("Not implemented");
14
- }
15
-
16
- get hasValue(): boolean {
17
- return false;
18
- }
19
-
20
- orElse(orElse: T): T {
21
- return orElse; // Returns the fallback value when the state is empty.
22
- }
23
-
24
- do() {
25
- // No operation for empty state.
26
- }
27
-
28
- filter(): StateObject<T> {
29
- return this; // The empty state remains unchanged when filtered.
30
- }
31
-
32
- set value(_: T) {
33
- // No operation for setting a value in the empty state.
34
- }
35
-
36
- flatMap<U>(): StateObject<U> {
37
- return new EmptyState<U>(); // Returns an empty state when flatMapped.
38
- }
39
-
40
- map<U>(): StateObject<U> {
41
- return new EmptyState<U>(); // Returns an empty state when mapped.
42
- }
1
+ import {StateObject} from "../stateObject";
2
+
3
+ /**
4
+ * Represents a state that holds no value and is considered "empty".
5
+ * This is used as a fallback or default when there is no valid state.
6
+ * you should NEVER use this class directly, use the `StateObject` interface instead.
7
+ * and create instances by using the hooks
8
+ * @template T - The type of the value that could be held by the state.
9
+ */
10
+ export class EmptyState<T> implements StateObject<T> {
11
+ // No value stored, returns an error when accessed.
12
+ get value(): T {
13
+ throw new Error("Not implemented");
14
+ }
15
+
16
+ get hasValue(): boolean {
17
+ return false;
18
+ }
19
+
20
+ orElse(orElse: T): T {
21
+ return orElse; // Returns the fallback value when the state is empty.
22
+ }
23
+
24
+ do() {
25
+ // No operation for empty state.
26
+ }
27
+
28
+ filter(): StateObject<T> {
29
+ return this; // The empty state remains unchanged when filtered.
30
+ }
31
+
32
+ set value(_: T) {
33
+ // No operation for setting a value in the empty state.
34
+ }
35
+
36
+ flatMap<U>(): StateObject<U> {
37
+ return new EmptyState<U>(); // Returns an empty state when flatMapped.
38
+ }
39
+
40
+ map<U>(): StateObject<U> {
41
+ return new EmptyState<U>(); // Returns an empty state when mapped.
42
+ }
43
43
  }
@@ -1,60 +1,60 @@
1
- import {EmptyState} from "./emptyState";
2
- import {StateObject} from "../stateObject";
3
-
4
- /**
5
- * Represents a state that holds a valid value of type T.
6
- * you should NEVER use this class directly, use the `StateObject` interface instead.
7
- * and create instances by using the hooks
8
- * @template T - The type of the value stored in the state.
9
- */
10
- export class ValidState<T> implements StateObject<T> {
11
- private readonly state: T;
12
- private readonly setter: (state: T) => void;
13
-
14
- constructor(state: T, setter: (state: T) => void) {
15
- this.state = state;
16
- this.setter = setter;
17
- }
18
-
19
- get value(): T {
20
- return this.state;
21
- }
22
-
23
- do(action: (t: T) => void) {
24
- action(this.state); // Performs the given action on the state value.
25
- }
26
-
27
- orElse() {
28
- return this.state; // Returns the state value as it is valid.
29
- }
30
-
31
- set value(newState: T) {
32
- this.setter(newState); // Sets a new value for the state.
33
- }
34
-
35
- map<U>(
36
- mappingFunction: (t: T) => U,
37
- inverseMappingFunction: (u: U, t: T) => T
38
- ): StateObject<U> {
39
- const derivedState = mappingFunction(this.state);
40
- const derivedSetter = (newState: U) => {
41
- this.setter(inverseMappingFunction(newState, this.state)); // Updates the state with the inverse mapping.
42
- };
43
-
44
- return new ValidState<U>(derivedState, derivedSetter); // Returns a new state object with the transformed value.
45
- }
46
-
47
- flatMap<U>(
48
- mappingFunction: (t: T) => StateObject<U>
49
- ): StateObject<U> {
50
- return mappingFunction(this.state); // Applies the mapping function and returns the result.
51
- }
52
-
53
- get hasValue(): boolean {
54
- return true;
55
- }
56
-
57
- filter(predicate: (t: T) => boolean): StateObject<T> {
58
- return predicate(this.state) ? (this as StateObject<T>) : new EmptyState<T>(); // Filters the state based on the predicate.
59
- }
1
+ import {EmptyState} from "./emptyState";
2
+ import {StateObject} from "../stateObject";
3
+
4
+ /**
5
+ * Represents a state that holds a valid value of type T.
6
+ * you should NEVER use this class directly, use the `StateObject` interface instead.
7
+ * and create instances by using the hooks
8
+ * @template T - The type of the value stored in the state.
9
+ */
10
+ export class ValidState<T> implements StateObject<T> {
11
+ private readonly state: T;
12
+ private readonly setter: (state: T) => void;
13
+
14
+ constructor(state: T, setter: (state: T) => void) {
15
+ this.state = state;
16
+ this.setter = setter;
17
+ }
18
+
19
+ get value(): T {
20
+ return this.state;
21
+ }
22
+
23
+ do(action: (t: T) => void) {
24
+ action(this.state); // Performs the given action on the state value.
25
+ }
26
+
27
+ orElse() {
28
+ return this.state; // Returns the state value as it is valid.
29
+ }
30
+
31
+ set value(newState: T) {
32
+ this.setter(newState); // Sets a new value for the state.
33
+ }
34
+
35
+ map<U>(
36
+ mappingFunction: (t: T) => U,
37
+ inverseMappingFunction: (u: U, t: T) => T
38
+ ): StateObject<U> {
39
+ const derivedState = mappingFunction(this.state);
40
+ const derivedSetter = (newState: U) => {
41
+ this.setter(inverseMappingFunction(newState, this.state)); // Updates the state with the inverse mapping.
42
+ };
43
+
44
+ return new ValidState<U>(derivedState, derivedSetter); // Returns a new state object with the transformed value.
45
+ }
46
+
47
+ flatMap<U>(
48
+ mappingFunction: (t: T) => StateObject<U>
49
+ ): StateObject<U> {
50
+ return mappingFunction(this.state); // Applies the mapping function and returns the result.
51
+ }
52
+
53
+ get hasValue(): boolean {
54
+ return true;
55
+ }
56
+
57
+ filter(predicate: (t: T) => boolean): StateObject<T> {
58
+ return predicate(this.state) ? (this as StateObject<T>) : new EmptyState<T>(); // Filters the state based on the predicate.
59
+ }
60
60
  }
package/src/index.ts CHANGED
@@ -1,9 +1,9 @@
1
- export * from "./hooks/useFieldState";
2
- export * from "./hooks/useElementState";
3
- export * from "./hooks/useEmptyState";
4
- export * from "./hooks/useFieldState";
5
- export * from "./hooks/useRemapArray";
6
- export * from "./hooks/useStateObject";
7
- export * from "./stateObject";
8
-
9
- export default this;
1
+ export * from "./hooks/useFieldState";
2
+ export * from "./hooks/useElementState";
3
+ export * from "./hooks/useEmptyState";
4
+ export * from "./hooks/useFieldState";
5
+ export * from "./hooks/useRemapArray";
6
+ export * from "./hooks/useStateObject";
7
+ export * from "./stateObject";
8
+
9
+ export default this;
@@ -1,71 +1,71 @@
1
- /**
2
- * Represents a state object that holds a value of type T, allowing various state operations.
3
- * This is the main interface for managing state, with operations like `map`, `filter`, and `flatMap`.
4
- * initialize with useStateObject<T>(initialState: T) hook
5
- * @template T - The type of the value stored in the state object.
6
- */
7
- export type StateObject<T> = {
8
- /**
9
- * The current value of the state.
10
- */
11
- get value(): T;
12
-
13
- /**
14
- * Returns true if the state has a valid value, false otherwise.
15
- */
16
- get hasValue(): boolean;
17
-
18
- /**
19
- * Performs an action on the current state value.
20
- *
21
- * @param action - A function that accepts the current state value and performs some operation.
22
- */
23
- do(action: (t: T) => void): void;
24
-
25
- /**
26
- * Sets a new value for the state.
27
- *
28
- * @param newState - The new state value to set.
29
- */
30
- set value(newState: T);
31
-
32
- /**
33
- * Transforms the current state into another state object by applying a mapping function.
34
- *
35
- * @template U - The type of the new state value.
36
- * @param mappingFunction - A function that transforms the current state value into a new value.
37
- * @param inverseMappingFunction - A function that transforms a new value back to the original state type.
38
- * @returns A new StateObject with the transformed value.
39
- */
40
- map<U>(
41
- mappingFunction: (t: T) => U,
42
- inverseMappingFunction: (u: U, t: T) => T
43
- ): StateObject<U>;
44
-
45
- /**
46
- * Filters the state based on a predicate, returning an empty state if the predicate is not satisfied.
47
- *
48
- * @param predicate - A function that tests the current state value.
49
- * @returns A new StateObject with the original value or an empty state.
50
- */
51
- filter(predicate: (t: T) => boolean): StateObject<T>;
52
-
53
- /**
54
- * Returns the current state value if it exists; otherwise, returns the provided alternative value.
55
- *
56
- * @param orElse - The value to return if the state does not have a valid value.
57
- * @returns The current state value or the provided fallback value.
58
- */
59
- orElse(orElse: T): T;
60
-
61
- /**
62
- * Transforms the current state into another state object by applying a mapping function that returns a new state.
63
- *
64
- * @template U - The type of the new state value.
65
- * @param mappingFunction - A function that transforms the current state value into another state object.
66
- * @returns A new StateObject based on the result of the mapping function.
67
- */
68
- flatMap<U>(
69
- mappingFunction: (t: T) => StateObject<U>
70
- ): StateObject<U>;
1
+ /**
2
+ * Represents a state object that holds a value of type T, allowing various state operations.
3
+ * This is the main interface for managing state, with operations like `map`, `filter`, and `flatMap`.
4
+ * initialize with useStateObject<T>(initialState: T) hook
5
+ * @template T - The type of the value stored in the state object.
6
+ */
7
+ export type StateObject<T> = {
8
+ /**
9
+ * The current value of the state.
10
+ */
11
+ get value(): T;
12
+
13
+ /**
14
+ * Returns true if the state has a valid value, false otherwise.
15
+ */
16
+ get hasValue(): boolean;
17
+
18
+ /**
19
+ * Performs an action on the current state value.
20
+ *
21
+ * @param action - A function that accepts the current state value and performs some operation.
22
+ */
23
+ do(action: (t: T) => void): void;
24
+
25
+ /**
26
+ * Sets a new value for the state.
27
+ *
28
+ * @param newState - The new state value to set.
29
+ */
30
+ set value(newState: T);
31
+
32
+ /**
33
+ * Transforms the current state into another state object by applying a mapping function.
34
+ *
35
+ * @template U - The type of the new state value.
36
+ * @param mappingFunction - A function that transforms the current state value into a new value.
37
+ * @param inverseMappingFunction - A function that transforms a new value back to the original state type.
38
+ * @returns A new StateObject with the transformed value.
39
+ */
40
+ map<U>(
41
+ mappingFunction: (t: T) => U,
42
+ inverseMappingFunction: (u: U, t: T) => T
43
+ ): StateObject<U>;
44
+
45
+ /**
46
+ * Filters the state based on a predicate, returning an empty state if the predicate is not satisfied.
47
+ *
48
+ * @param predicate - A function that tests the current state value.
49
+ * @returns A new StateObject with the original value or an empty state.
50
+ */
51
+ filter(predicate: (t: T) => boolean): StateObject<T>;
52
+
53
+ /**
54
+ * Returns the current state value if it exists; otherwise, returns the provided alternative value.
55
+ *
56
+ * @param orElse - The value to return if the state does not have a valid value.
57
+ * @returns The current state value or the provided fallback value.
58
+ */
59
+ orElse(orElse: T): T;
60
+
61
+ /**
62
+ * Transforms the current state into another state object by applying a mapping function that returns a new state.
63
+ *
64
+ * @template U - The type of the new state value.
65
+ * @param mappingFunction - A function that transforms the current state value into another state object.
66
+ * @returns A new StateObject based on the result of the mapping function.
67
+ */
68
+ flatMap<U>(
69
+ mappingFunction: (t: T) => StateObject<U>
70
+ ): StateObject<U>;
71
71
  }
package/tsconfig.json CHANGED
@@ -1,16 +1,16 @@
1
- {
2
- "compilerOptions": {
3
- "module": "ESNext",
4
- "target": "ESNext",
5
- "declaration": true,
6
- "declarationDir": "./",
7
- "outDir": "dist",
8
- "moduleResolution": "Node",
9
- "esModuleInterop": true,
10
- "strict": true
11
- },
12
- "include": [
13
- "src/**/*",
14
- "index.ts"
15
- ]
1
+ {
2
+ "compilerOptions": {
3
+ "module": "ESNext",
4
+ "target": "ESNext",
5
+ "declaration": true,
6
+ "declarationDir": "./",
7
+ "outDir": "dist",
8
+ "moduleResolution": "Node",
9
+ "esModuleInterop": true,
10
+ "strict": true
11
+ },
12
+ "include": [
13
+ "src/**/*",
14
+ "index.ts"
15
+ ]
16
16
  }