react-state-monad 1.0.8 → 1.0.10

Sign up to get free protection for your applications and to get access to all the features.
package/index.d.cts ADDED
@@ -0,0 +1,132 @@
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
+ type StateObject<T> = {
8
+ /**
9
+ * The current value of the state.
10
+ */
11
+ get value(): T;
12
+ /**
13
+ * Returns true if the state has a valid value, false otherwise.
14
+ */
15
+ get hasValue(): boolean;
16
+ /**
17
+ * Performs an action on the current state value.
18
+ *
19
+ * @param action - A function that accepts the current state value and performs some operation.
20
+ */
21
+ do(action: (t: T) => void): void;
22
+ /**
23
+ * Sets a new value for the state.
24
+ *
25
+ * @param newState - The new state value to set.
26
+ */
27
+ set value(newState: T);
28
+ /**
29
+ * Transforms the current state into another state object by applying a mapping function.
30
+ *
31
+ * @template U - The type of the new state value.
32
+ * @param mappingFunction - A function that transforms the current state value into a new value.
33
+ * @param inverseMappingFunction - A function that transforms a new value back to the original state type.
34
+ * @returns A new StateObject with the transformed value.
35
+ */
36
+ map<U>(mappingFunction: (t: T) => U, inverseMappingFunction: (u: U, t: T) => T): StateObject<U>;
37
+ /**
38
+ * Filters the state based on a predicate, returning an empty state if the predicate is not satisfied.
39
+ *
40
+ * @param predicate - A function that tests the current state value.
41
+ * @returns A new StateObject with the original value or an empty state.
42
+ */
43
+ filter(predicate: (t: T) => boolean): StateObject<T>;
44
+ /**
45
+ * Returns the current state value if it exists; otherwise, returns the provided alternative value.
46
+ *
47
+ * @param orElse - The value to return if the state does not have a valid value.
48
+ * @returns The current state value or the provided fallback value.
49
+ */
50
+ orElse(orElse: T): T;
51
+ /**
52
+ * Transforms the current state into another state object by applying a mapping function that returns a new state.
53
+ *
54
+ * @template U - The type of the new state value.
55
+ * @param mappingFunction - A function that transforms the current state value into another state object.
56
+ * @returns A new StateObject based on the result of the mapping function.
57
+ */
58
+ flatMap<U>(mappingFunction: (t: T) => StateObject<U>): StateObject<U>;
59
+ };
60
+
61
+ /**
62
+ * Helper type that ensures a field is a valid key of an object and that the field's type matches the expected type.
63
+ *
64
+ * @template TObject - The object type.
65
+ * @template TField - The expected type of the field.
66
+ */
67
+ type ValidFieldFrom<TObject, TField> = {
68
+ [Key in keyof TObject]: TObject[Key] extends TField ? Key : never;
69
+ }[keyof TObject];
70
+
71
+ /**
72
+ * Hook that derives a field from the state object and creates a new StateObject for the field's value.
73
+ *
74
+ * @template TOriginal - The type of the original state object.
75
+ * @template TField - The type of the field value to be derived.
76
+ * @param state - The StateObject containing the original state.
77
+ * @param field - The field name to be derived from the state.
78
+ * @returns A new StateObject for the derived field.
79
+ */
80
+ declare function useFieldState<TOriginal, TField>(state: StateObject<TOriginal>, field: ValidFieldFrom<TOriginal, TField>): StateObject<TField>;
81
+
82
+ /**
83
+ * Hook that allows you to derive and update a specific element in an array within a StateObject.
84
+ *
85
+ * @template T - The type of the array elements.
86
+ * @param state - The StateObject containing an array.
87
+ * @param index - The index of the element to be derived.
88
+ * @returns A new StateObject representing the element at the given index.
89
+ */
90
+ declare function useElementState<T>(state: StateObject<T[]>, index: number): StateObject<T>;
91
+
92
+ /**
93
+ * Hook that initializes a StateObject with an empty state.
94
+ * This is useful as a fallback when no valid state is available.
95
+ *
96
+ * @template T - The type of the value that could be held by the state.
97
+ * @returns A StateObject representing an empty state.
98
+ */
99
+ declare function useEmptyState<T>(): StateObject<T>;
100
+
101
+ /**
102
+ * Hook that maps each element in an array within a StateObject to a new StateObject,
103
+ * allowing for independent updates of each element while keeping the overall array state synchronized.
104
+ *
105
+ * @template T - The type of the array elements.
106
+ * @param state - The StateObject containing an array.
107
+ * @returns An array of new StateObjects, each representing an element in the original array,
108
+ * allowing individual updates while keeping the array state synchronized.
109
+ */
110
+ declare function useRemapArray<T>(state: StateObject<T[]>): StateObject<T>[];
111
+ /**
112
+ * Hook that takes an array of StateObjects and returns a new StateObject containing that array,
113
+ * allowing for updates to the entire array while keeping it synchronized within a single StateObject.
114
+ *
115
+ * @template T - The type of the elements in the array.
116
+ * @param states - The array of StateObjects.
117
+ * @returns A new StateObject containing the array of StateObjects, allowing for updates to the whole array.
118
+ */
119
+ declare function useArrayState<T>(states: StateObject<T>[]): StateObject<T[]>;
120
+
121
+ /**
122
+ * Hook that initializes a StateObject with the given initial value.
123
+ *
124
+ * @template T - The type of the value to be stored in the state.
125
+ * @param initialState - The initial value of the state.
126
+ * @returns A StateObject representing the initialized state.
127
+ */
128
+ declare function useStateObject<T>(initialState: T): StateObject<T>;
129
+
130
+ declare const _default: undefined;
131
+
132
+ export { type StateObject, _default as default, useArrayState, useElementState, useEmptyState, useFieldState, useRemapArray, useStateObject };
package/index.d.ts ADDED
@@ -0,0 +1,132 @@
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
+ type StateObject<T> = {
8
+ /**
9
+ * The current value of the state.
10
+ */
11
+ get value(): T;
12
+ /**
13
+ * Returns true if the state has a valid value, false otherwise.
14
+ */
15
+ get hasValue(): boolean;
16
+ /**
17
+ * Performs an action on the current state value.
18
+ *
19
+ * @param action - A function that accepts the current state value and performs some operation.
20
+ */
21
+ do(action: (t: T) => void): void;
22
+ /**
23
+ * Sets a new value for the state.
24
+ *
25
+ * @param newState - The new state value to set.
26
+ */
27
+ set value(newState: T);
28
+ /**
29
+ * Transforms the current state into another state object by applying a mapping function.
30
+ *
31
+ * @template U - The type of the new state value.
32
+ * @param mappingFunction - A function that transforms the current state value into a new value.
33
+ * @param inverseMappingFunction - A function that transforms a new value back to the original state type.
34
+ * @returns A new StateObject with the transformed value.
35
+ */
36
+ map<U>(mappingFunction: (t: T) => U, inverseMappingFunction: (u: U, t: T) => T): StateObject<U>;
37
+ /**
38
+ * Filters the state based on a predicate, returning an empty state if the predicate is not satisfied.
39
+ *
40
+ * @param predicate - A function that tests the current state value.
41
+ * @returns A new StateObject with the original value or an empty state.
42
+ */
43
+ filter(predicate: (t: T) => boolean): StateObject<T>;
44
+ /**
45
+ * Returns the current state value if it exists; otherwise, returns the provided alternative value.
46
+ *
47
+ * @param orElse - The value to return if the state does not have a valid value.
48
+ * @returns The current state value or the provided fallback value.
49
+ */
50
+ orElse(orElse: T): T;
51
+ /**
52
+ * Transforms the current state into another state object by applying a mapping function that returns a new state.
53
+ *
54
+ * @template U - The type of the new state value.
55
+ * @param mappingFunction - A function that transforms the current state value into another state object.
56
+ * @returns A new StateObject based on the result of the mapping function.
57
+ */
58
+ flatMap<U>(mappingFunction: (t: T) => StateObject<U>): StateObject<U>;
59
+ };
60
+
61
+ /**
62
+ * Helper type that ensures a field is a valid key of an object and that the field's type matches the expected type.
63
+ *
64
+ * @template TObject - The object type.
65
+ * @template TField - The expected type of the field.
66
+ */
67
+ type ValidFieldFrom<TObject, TField> = {
68
+ [Key in keyof TObject]: TObject[Key] extends TField ? Key : never;
69
+ }[keyof TObject];
70
+
71
+ /**
72
+ * Hook that derives a field from the state object and creates a new StateObject for the field's value.
73
+ *
74
+ * @template TOriginal - The type of the original state object.
75
+ * @template TField - The type of the field value to be derived.
76
+ * @param state - The StateObject containing the original state.
77
+ * @param field - The field name to be derived from the state.
78
+ * @returns A new StateObject for the derived field.
79
+ */
80
+ declare function useFieldState<TOriginal, TField>(state: StateObject<TOriginal>, field: ValidFieldFrom<TOriginal, TField>): StateObject<TField>;
81
+
82
+ /**
83
+ * Hook that allows you to derive and update a specific element in an array within a StateObject.
84
+ *
85
+ * @template T - The type of the array elements.
86
+ * @param state - The StateObject containing an array.
87
+ * @param index - The index of the element to be derived.
88
+ * @returns A new StateObject representing the element at the given index.
89
+ */
90
+ declare function useElementState<T>(state: StateObject<T[]>, index: number): StateObject<T>;
91
+
92
+ /**
93
+ * Hook that initializes a StateObject with an empty state.
94
+ * This is useful as a fallback when no valid state is available.
95
+ *
96
+ * @template T - The type of the value that could be held by the state.
97
+ * @returns A StateObject representing an empty state.
98
+ */
99
+ declare function useEmptyState<T>(): StateObject<T>;
100
+
101
+ /**
102
+ * Hook that maps each element in an array within a StateObject to a new StateObject,
103
+ * allowing for independent updates of each element while keeping the overall array state synchronized.
104
+ *
105
+ * @template T - The type of the array elements.
106
+ * @param state - The StateObject containing an array.
107
+ * @returns An array of new StateObjects, each representing an element in the original array,
108
+ * allowing individual updates while keeping the array state synchronized.
109
+ */
110
+ declare function useRemapArray<T>(state: StateObject<T[]>): StateObject<T>[];
111
+ /**
112
+ * Hook that takes an array of StateObjects and returns a new StateObject containing that array,
113
+ * allowing for updates to the entire array while keeping it synchronized within a single StateObject.
114
+ *
115
+ * @template T - The type of the elements in the array.
116
+ * @param states - The array of StateObjects.
117
+ * @returns A new StateObject containing the array of StateObjects, allowing for updates to the whole array.
118
+ */
119
+ declare function useArrayState<T>(states: StateObject<T>[]): StateObject<T[]>;
120
+
121
+ /**
122
+ * Hook that initializes a StateObject with the given initial value.
123
+ *
124
+ * @template T - The type of the value to be stored in the state.
125
+ * @param initialState - The initial value of the state.
126
+ * @returns A StateObject representing the initialized state.
127
+ */
128
+ declare function useStateObject<T>(initialState: T): StateObject<T>;
129
+
130
+ declare const _default: undefined;
131
+
132
+ export { type StateObject, _default as default, useArrayState, useElementState, useEmptyState, useFieldState, useRemapArray, useStateObject };
package/index.js ADDED
@@ -0,0 +1,137 @@
1
+ // src/hooks/useFieldState.ts
2
+ function useFieldState(state, field) {
3
+ return state.map(
4
+ (original) => original[field],
5
+ // Extracts the field value.
6
+ (newField, original) => ({ ...original, [field]: newField })
7
+ // Updates the field with the new value.
8
+ );
9
+ }
10
+
11
+ // src/implementations/emptyState.ts
12
+ var EmptyState = class _EmptyState {
13
+ // No value stored, returns an error when accessed.
14
+ get value() {
15
+ throw new Error("Not implemented");
16
+ }
17
+ get hasValue() {
18
+ return false;
19
+ }
20
+ orElse(orElse) {
21
+ return orElse;
22
+ }
23
+ do() {
24
+ }
25
+ filter() {
26
+ return this;
27
+ }
28
+ set value(_) {
29
+ }
30
+ flatMap() {
31
+ return new _EmptyState();
32
+ }
33
+ map() {
34
+ return new _EmptyState();
35
+ }
36
+ };
37
+
38
+ // src/implementations/validState.ts
39
+ var ValidState = class _ValidState {
40
+ state;
41
+ setter;
42
+ constructor(state, setter) {
43
+ this.state = state;
44
+ this.setter = setter;
45
+ }
46
+ get value() {
47
+ return this.state;
48
+ }
49
+ do(action) {
50
+ action(this.state);
51
+ }
52
+ orElse() {
53
+ return this.state;
54
+ }
55
+ set value(newState) {
56
+ this.setter(newState);
57
+ }
58
+ map(mappingFunction, inverseMappingFunction) {
59
+ const derivedState = mappingFunction(this.state);
60
+ const derivedSetter = (newState) => {
61
+ this.setter(inverseMappingFunction(newState, this.state));
62
+ };
63
+ return new _ValidState(derivedState, derivedSetter);
64
+ }
65
+ flatMap(mappingFunction) {
66
+ return mappingFunction(this.state);
67
+ }
68
+ get hasValue() {
69
+ return true;
70
+ }
71
+ filter(predicate) {
72
+ return predicate(this.state) ? this : new EmptyState();
73
+ }
74
+ };
75
+
76
+ // src/hooks/useElementState.ts
77
+ function useElementState(state, index) {
78
+ if (!state.hasValue || index < 0 || index >= state.value.length) {
79
+ return new EmptyState();
80
+ }
81
+ return new ValidState(
82
+ state.value[index],
83
+ (newElement) => {
84
+ const arrayCopy = [...state.value];
85
+ arrayCopy[index] = newElement;
86
+ state.value = arrayCopy;
87
+ }
88
+ );
89
+ }
90
+
91
+ // src/hooks/useEmptyState.ts
92
+ function useEmptyState() {
93
+ return new EmptyState();
94
+ }
95
+
96
+ // src/hooks/useStateObject.ts
97
+ import { useState } from "react";
98
+ function useStateObject(initialState) {
99
+ const [state, setState] = useState(initialState);
100
+ return new ValidState(state, setState);
101
+ }
102
+
103
+ // src/hooks/useRemapArray.ts
104
+ function useRemapArray(state) {
105
+ if (!state.hasValue) return [];
106
+ const count = state.value.length;
107
+ const result = [];
108
+ for (let i = 0; i < count; i++) {
109
+ result.push(
110
+ new ValidState(
111
+ state.value[i],
112
+ // The current value of the element at index i.
113
+ (newElement) => {
114
+ const arrayCopy = [...state.value];
115
+ arrayCopy[i] = newElement;
116
+ state.value = arrayCopy;
117
+ }
118
+ )
119
+ );
120
+ }
121
+ return result;
122
+ }
123
+ function useArrayState(states) {
124
+ return useStateObject(states.filter((state) => state.hasValue).map((state) => state.value));
125
+ }
126
+
127
+ // index.ts
128
+ var index_default = void 0;
129
+ export {
130
+ index_default as default,
131
+ useArrayState,
132
+ useElementState,
133
+ useEmptyState,
134
+ useFieldState,
135
+ useRemapArray,
136
+ useStateObject
137
+ };
package/index.ts CHANGED
@@ -1,9 +1,9 @@
1
- export * from "./src/hooks/useFieldState";
2
- export * from "./src/hooks/useElementState";
3
- export * from "./src/hooks/useEmptyState";
4
- export * from "./src/hooks/useFieldState";
5
- export * from "./src/hooks/useRemapArray";
6
- export * from "./src/hooks/useStateObject";
7
- export * from "./src/stateObject";
8
-
9
- export default this;
1
+ export * from "./src/hooks/useFieldState";
2
+ export * from "./src/hooks/useElementState";
3
+ export * from "./src/hooks/useEmptyState";
4
+ export * from "./src/hooks/useFieldState";
5
+ export * from "./src/hooks/useRemapArray";
6
+ export * from "./src/hooks/useStateObject";
7
+ export * from "./src/stateObject";
8
+
9
+ export default this;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-state-monad",
3
3
  "type": "module",
4
- "version": "1.0.8",
4
+ "version": "1.0.10",
5
5
  "description": "A set of hooks to manage/transform/filter states with monads in React",
6
6
  "keywords": [
7
7
  "maybe",
@@ -14,7 +14,7 @@
14
14
  ],
15
15
  "scripts": {
16
16
  "validateTypes": "tsc --noEmit",
17
- "build": "tsup index.ts --format cjs,esm --dts",
17
+ "build": "tsup index.ts --format cjs,esm --dts --dts-resolve",
18
18
  "cleanBuild": "rm -rf dist"
19
19
  },
20
20
  "dependencies": {
@@ -33,8 +33,5 @@
33
33
  "license": "GPL-3.0",
34
34
  "main": "dist/index.js",
35
35
  "module": "dist/index.mjs",
36
- "types": "dist/types/index.d.ts"
37
-
38
-
39
-
40
- }
36
+ "types": "index.d.ts"
37
+ }
@@ -1,12 +1,12 @@
1
- /**
2
- * Helper type that ensures a field is a valid key of an object and that the field's type matches the expected type.
3
- *
4
- * @template TObject - The object type.
5
- * @template TField - The expected type of the field.
6
- */
7
- export type ValidFieldFrom<TObject, TField> = {
8
- [Key in keyof TObject]: TObject[Key] extends TField ? Key : never;
9
- }[keyof TObject];
10
-
11
-
12
-
1
+ /**
2
+ * Helper type that ensures a field is a valid key of an object and that the field's type matches the expected type.
3
+ *
4
+ * @template TObject - The object type.
5
+ * @template TField - The expected type of the field.
6
+ */
7
+ export type ValidFieldFrom<TObject, TField> = {
8
+ [Key in keyof TObject]: TObject[Key] extends TField ? Key : never;
9
+ }[keyof TObject];
10
+
11
+
12
+
@@ -1,26 +1,26 @@
1
- import {StateObject} from "../stateObject";
2
- import {EmptyState} from "../implementations/emptyState";
3
- import {ValidState} from "../implementations/validState";
4
-
5
- /**
6
- * Hook that allows you to derive and update a specific element in an array within a StateObject.
7
- *
8
- * @template T - The type of the array elements.
9
- * @param state - The StateObject containing an array.
10
- * @param index - The index of the element to be derived.
11
- * @returns A new StateObject representing the element at the given index.
12
- */
13
- export function useElementState<T>(state: StateObject<T[]>, index: number): StateObject<T> {
14
- if (!state.hasValue || index < 0 || index >= state.value.length) {
15
- return new EmptyState<T>(); // Returns an empty state if the index is out of bounds or state is empty.
16
- }
17
-
18
- return new ValidState<T>(
19
- state.value[index],
20
- (newElement) => {
21
- const arrayCopy = [...state.value];
22
- arrayCopy[index] = newElement;
23
- state.value = arrayCopy;
24
- }
25
- );
1
+ import {StateObject} from "../stateObject";
2
+ import {EmptyState} from "../implementations/emptyState";
3
+ import {ValidState} from "../implementations/validState";
4
+
5
+ /**
6
+ * Hook that allows you to derive and update a specific element in an array within a StateObject.
7
+ *
8
+ * @template T - The type of the array elements.
9
+ * @param state - The StateObject containing an array.
10
+ * @param index - The index of the element to be derived.
11
+ * @returns A new StateObject representing the element at the given index.
12
+ */
13
+ export function useElementState<T>(state: StateObject<T[]>, index: number): StateObject<T> {
14
+ if (!state.hasValue || index < 0 || index >= state.value.length) {
15
+ return new EmptyState<T>(); // Returns an empty state if the index is out of bounds or state is empty.
16
+ }
17
+
18
+ return new ValidState<T>(
19
+ state.value[index],
20
+ (newElement) => {
21
+ const arrayCopy = [...state.value];
22
+ arrayCopy[index] = newElement;
23
+ state.value = arrayCopy;
24
+ }
25
+ );
26
26
  }
@@ -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
  }