@figliolia/galena 3.0.2 → 4.0.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 +42 -54
- package/dist/API.cjs +9 -0
- package/dist/API.d.cts +13 -0
- package/dist/API.d.cts.map +1 -0
- package/dist/API.d.mts +13 -0
- package/dist/API.d.mts.map +1 -0
- package/dist/API.mjs +11 -0
- package/dist/API.mjs.map +1 -0
- package/dist/Galena.cjs +80 -22
- package/dist/Galena.d.cts +69 -22
- package/dist/Galena.d.cts.map +1 -1
- package/dist/Galena.d.mts +69 -22
- package/dist/Galena.d.mts.map +1 -1
- package/dist/Galena.mjs +80 -22
- package/dist/Galena.mjs.map +1 -1
- package/dist/Logger.cjs +2 -2
- package/dist/Logger.mjs +2 -2
- package/dist/Logger.mjs.map +1 -1
- package/dist/Middleware.cjs +2 -2
- package/dist/Middleware.d.cts +2 -2
- package/dist/Middleware.d.mts +2 -2
- package/dist/Middleware.mjs +2 -2
- package/dist/Middleware.mjs.map +1 -1
- package/dist/Profiler.cjs +2 -2
- package/dist/Profiler.mjs +2 -2
- package/dist/Profiler.mjs.map +1 -1
- package/dist/State.cjs +23 -24
- package/dist/State.d.cts +22 -23
- package/dist/State.d.cts.map +1 -1
- package/dist/State.d.mts +22 -23
- package/dist/State.d.mts.map +1 -1
- package/dist/State.mjs +23 -24
- package/dist/State.mjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/types.d.cts +4 -2
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +4 -2
- package/dist/types.d.mts.map +1 -1
- package/package.json +8 -8
- package/src/API.ts +12 -0
- package/src/Galena.ts +101 -23
- package/src/Logger.ts +2 -2
- package/src/Middleware.ts +2 -2
- package/src/Profiler.ts +2 -2
- package/src/State.ts +23 -24
- package/src/types.ts +7 -1
package/dist/State.d.cts
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { NonFunction, Setter, Subscriber } from "./types.cjs";
|
|
2
2
|
import { Middleware } from "./Middleware.cjs";
|
|
3
|
+
import { API } from "./API.cjs";
|
|
3
4
|
|
|
4
5
|
//#region src/State.d.ts
|
|
5
6
|
/**
|
|
6
|
-
* State
|
|
7
|
+
* ### State
|
|
7
8
|
*
|
|
8
9
|
* The unit of reactivity for Galena. `State`'s can act
|
|
9
10
|
* as isolated instances or be part of your global app
|
|
10
11
|
* state (via `Galena` instances).
|
|
11
12
|
*
|
|
12
|
-
* There are
|
|
13
|
+
* There are two ways to create state instances
|
|
13
14
|
*
|
|
14
15
|
* ```typescript
|
|
15
|
-
* import { State, createState,
|
|
16
|
-
|
|
16
|
+
* import { State, createState, Profiler } from "@figliolia/galena";
|
|
17
|
+
|
|
17
18
|
* const myState = new State("<any value>", ...middleware);
|
|
18
19
|
* // or
|
|
19
20
|
* const myState = createState("<any value>", ...middleware);
|
|
@@ -22,23 +23,14 @@ import { Middleware } from "./Middleware.cjs";
|
|
|
22
23
|
* myState.update(previousValue => "<new-value>");
|
|
23
24
|
* myState.subscribe(nextValue => {});
|
|
24
25
|
* myState.registerMiddleware(new Profiler());
|
|
25
|
-
*
|
|
26
|
-
* //
|
|
27
|
-
* const
|
|
28
|
-
* const [state, setState] = useState(myState);
|
|
29
|
-
* // or
|
|
30
|
-
* const [state, setState] = useMyState("<any-value>", ...middlware);
|
|
31
|
-
*
|
|
32
|
-
* return (
|
|
33
|
-
* // your jsx
|
|
34
|
-
* );
|
|
35
|
-
* }
|
|
26
|
+
* myState.reset(); // reset back to it's original value
|
|
27
|
+
* // to get the current value at any point in time
|
|
28
|
+
* const currentValue = myState.getState();
|
|
36
29
|
* ```
|
|
37
30
|
*/
|
|
38
|
-
declare class State<T> {
|
|
31
|
+
declare class State<T> extends API<T, NonFunction<T>> {
|
|
39
32
|
readonly initialState: NonFunction<T>;
|
|
40
33
|
private state;
|
|
41
|
-
readonly middleware: Middleware<T>[];
|
|
42
34
|
private readonly Emitter;
|
|
43
35
|
constructor(initialState: NonFunction<T>, ...middleware: Middleware<T>[]);
|
|
44
36
|
/**
|
|
@@ -69,7 +61,7 @@ declare class State<T> {
|
|
|
69
61
|
* Returns the current state. Designed for compatibility with
|
|
70
62
|
* `useSyncExternalStore`
|
|
71
63
|
*/
|
|
72
|
-
readonly
|
|
64
|
+
readonly getState: () => NonFunction<T>;
|
|
73
65
|
/**
|
|
74
66
|
* Subscribe
|
|
75
67
|
*
|
|
@@ -91,21 +83,28 @@ declare class State<T> {
|
|
|
91
83
|
private invokeMiddleware;
|
|
92
84
|
}
|
|
93
85
|
/**
|
|
94
|
-
*
|
|
86
|
+
* ### createState
|
|
95
87
|
*
|
|
96
|
-
*
|
|
88
|
+
* The unit of reactivity for Galena. `State`'s can act
|
|
97
89
|
* as isolated instances or be part of your global app
|
|
98
|
-
* state (via `Galena` instances)
|
|
90
|
+
* state (via `Galena` instances).
|
|
99
91
|
*
|
|
100
|
-
*
|
|
101
|
-
* import { createState, Profiler } from "@figliolia/galena";
|
|
92
|
+
* There are two ways to create state instances
|
|
102
93
|
*
|
|
94
|
+
* ```typescript
|
|
95
|
+
* import { State, createState, Profiler } from "@figliolia/galena";
|
|
96
|
+
|
|
97
|
+
* const myState = new State("<any value>", ...middleware);
|
|
98
|
+
* // or
|
|
103
99
|
* const myState = createState("<any value>", ...middleware);
|
|
104
100
|
*
|
|
105
101
|
* myState.set("<new-value>");
|
|
106
102
|
* myState.update(previousValue => "<new-value>");
|
|
107
103
|
* myState.subscribe(nextValue => {});
|
|
108
104
|
* myState.registerMiddleware(new Profiler());
|
|
105
|
+
* myState.reset(); // reset back to it's original value
|
|
106
|
+
* // to get the current value at any point in time
|
|
107
|
+
* const currentValue = myState.getState();
|
|
109
108
|
* ```
|
|
110
109
|
*/
|
|
111
110
|
declare function createState<T>(...args: ConstructorParameters<typeof State<T>>): State<T>;
|
package/dist/State.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"State.d.cts","names":[],"sources":["../src/State.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"State.d.cts","names":[],"sources":["../src/State.ts"],"mappings":";;;;;;;AA8BA;;;;;;;;;;;;;;;;;;;;;;;cAAa,KAAA,YAAiB,GAAA,CAAI,CAAA,EAAG,WAAA,CAAY,CAAA;EAAA,SAI7B,YAAA,EAAc,WAAA,CAAY,CAAA;EAAA,QAHpC,KAAA;EAAA,iBACS,OAAA;cAEC,YAAA,EAAc,WAAA,CAAY,CAAA,MACvC,UAAA,EAAY,UAAA,CAAW,CAAA;EALG;;;;;;EAAA,SAiBf,GAAA,GAAG,KAAA,EAAA,WAAA,CAAA,CAAA;EAba;;;;;;;EAAA,SAsBhB,MAAA,GAAM,MAAA,EAAA,MAAA,CAAA,CAAA;EArBjB;;;;;;EAAA,SAkCW,KAAA;EAbA;;;;;;EAAA,SAqBA,QAAA,QAAQ,WAAA,CAAA,CAAA;EAAA;;;;;;EAAA,SAUR,SAAA,GAAa,EAAA,EAAI,UAAA,CAAW,CAAA;EAcH;;;;;;;EAAlC,kBAAA,CAAA,GAAsB,UAAA,EAAY,UAAA,CAAW,CAAA;EAAA,QAI5C,YAAA;EAAA,QAaA,IAAA;EAAA,UAOE,UAAA,CAAW,MAAA,EAAQ,MAAA,CAAO,CAAA,IAAK,MAAA,IAAU,WAAA,CAAY,CAAA;EAAA,QAIvD,gBAAA;AAAA;;AAgCV;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,WAAA,GAAA,CAAA,GACX,IAAA,EAAM,qBAAA,QAA6B,KAAA,CAAM,CAAA,KAAG,KAAA,CAAA,CAAA"}
|
package/dist/State.d.mts
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { NonFunction, Setter, Subscriber } from "./types.mjs";
|
|
2
2
|
import { Middleware } from "./Middleware.mjs";
|
|
3
|
+
import { API } from "./API.mjs";
|
|
3
4
|
|
|
4
5
|
//#region src/State.d.ts
|
|
5
6
|
/**
|
|
6
|
-
* State
|
|
7
|
+
* ### State
|
|
7
8
|
*
|
|
8
9
|
* The unit of reactivity for Galena. `State`'s can act
|
|
9
10
|
* as isolated instances or be part of your global app
|
|
10
11
|
* state (via `Galena` instances).
|
|
11
12
|
*
|
|
12
|
-
* There are
|
|
13
|
+
* There are two ways to create state instances
|
|
13
14
|
*
|
|
14
15
|
* ```typescript
|
|
15
|
-
* import { State, createState,
|
|
16
|
-
|
|
16
|
+
* import { State, createState, Profiler } from "@figliolia/galena";
|
|
17
|
+
|
|
17
18
|
* const myState = new State("<any value>", ...middleware);
|
|
18
19
|
* // or
|
|
19
20
|
* const myState = createState("<any value>", ...middleware);
|
|
@@ -22,23 +23,14 @@ import { Middleware } from "./Middleware.mjs";
|
|
|
22
23
|
* myState.update(previousValue => "<new-value>");
|
|
23
24
|
* myState.subscribe(nextValue => {});
|
|
24
25
|
* myState.registerMiddleware(new Profiler());
|
|
25
|
-
*
|
|
26
|
-
* //
|
|
27
|
-
* const
|
|
28
|
-
* const [state, setState] = useState(myState);
|
|
29
|
-
* // or
|
|
30
|
-
* const [state, setState] = useMyState("<any-value>", ...middlware);
|
|
31
|
-
*
|
|
32
|
-
* return (
|
|
33
|
-
* // your jsx
|
|
34
|
-
* );
|
|
35
|
-
* }
|
|
26
|
+
* myState.reset(); // reset back to it's original value
|
|
27
|
+
* // to get the current value at any point in time
|
|
28
|
+
* const currentValue = myState.getState();
|
|
36
29
|
* ```
|
|
37
30
|
*/
|
|
38
|
-
declare class State<T> {
|
|
31
|
+
declare class State<T> extends API<T, NonFunction<T>> {
|
|
39
32
|
readonly initialState: NonFunction<T>;
|
|
40
33
|
private state;
|
|
41
|
-
readonly middleware: Middleware<T>[];
|
|
42
34
|
private readonly Emitter;
|
|
43
35
|
constructor(initialState: NonFunction<T>, ...middleware: Middleware<T>[]);
|
|
44
36
|
/**
|
|
@@ -69,7 +61,7 @@ declare class State<T> {
|
|
|
69
61
|
* Returns the current state. Designed for compatibility with
|
|
70
62
|
* `useSyncExternalStore`
|
|
71
63
|
*/
|
|
72
|
-
readonly
|
|
64
|
+
readonly getState: () => NonFunction<T>;
|
|
73
65
|
/**
|
|
74
66
|
* Subscribe
|
|
75
67
|
*
|
|
@@ -91,21 +83,28 @@ declare class State<T> {
|
|
|
91
83
|
private invokeMiddleware;
|
|
92
84
|
}
|
|
93
85
|
/**
|
|
94
|
-
*
|
|
86
|
+
* ### createState
|
|
95
87
|
*
|
|
96
|
-
*
|
|
88
|
+
* The unit of reactivity for Galena. `State`'s can act
|
|
97
89
|
* as isolated instances or be part of your global app
|
|
98
|
-
* state (via `Galena` instances)
|
|
90
|
+
* state (via `Galena` instances).
|
|
99
91
|
*
|
|
100
|
-
*
|
|
101
|
-
* import { createState, Profiler } from "@figliolia/galena";
|
|
92
|
+
* There are two ways to create state instances
|
|
102
93
|
*
|
|
94
|
+
* ```typescript
|
|
95
|
+
* import { State, createState, Profiler } from "@figliolia/galena";
|
|
96
|
+
|
|
97
|
+
* const myState = new State("<any value>", ...middleware);
|
|
98
|
+
* // or
|
|
103
99
|
* const myState = createState("<any value>", ...middleware);
|
|
104
100
|
*
|
|
105
101
|
* myState.set("<new-value>");
|
|
106
102
|
* myState.update(previousValue => "<new-value>");
|
|
107
103
|
* myState.subscribe(nextValue => {});
|
|
108
104
|
* myState.registerMiddleware(new Profiler());
|
|
105
|
+
* myState.reset(); // reset back to it's original value
|
|
106
|
+
* // to get the current value at any point in time
|
|
107
|
+
* const currentValue = myState.getState();
|
|
109
108
|
* ```
|
|
110
109
|
*/
|
|
111
110
|
declare function createState<T>(...args: ConstructorParameters<typeof State<T>>): State<T>;
|
package/dist/State.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"State.d.mts","names":[],"sources":["../src/State.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"State.d.mts","names":[],"sources":["../src/State.ts"],"mappings":";;;;;;;AA8BA;;;;;;;;;;;;;;;;;;;;;;;cAAa,KAAA,YAAiB,GAAA,CAAI,CAAA,EAAG,WAAA,CAAY,CAAA;EAAA,SAI7B,YAAA,EAAc,WAAA,CAAY,CAAA;EAAA,QAHpC,KAAA;EAAA,iBACS,OAAA;cAEC,YAAA,EAAc,WAAA,CAAY,CAAA,MACvC,UAAA,EAAY,UAAA,CAAW,CAAA;EALG;;;;;;EAAA,SAiBf,GAAA,GAAG,KAAA,EAAA,WAAA,CAAA,CAAA;EAba;;;;;;;EAAA,SAsBhB,MAAA,GAAM,MAAA,EAAA,MAAA,CAAA,CAAA;EArBjB;;;;;;EAAA,SAkCW,KAAA;EAbA;;;;;;EAAA,SAqBA,QAAA,QAAQ,WAAA,CAAA,CAAA;EAAA;;;;;;EAAA,SAUR,SAAA,GAAa,EAAA,EAAI,UAAA,CAAW,CAAA;EAcH;;;;;;;EAAlC,kBAAA,CAAA,GAAsB,UAAA,EAAY,UAAA,CAAW,CAAA;EAAA,QAI5C,YAAA;EAAA,QAaA,IAAA;EAAA,UAOE,UAAA,CAAW,MAAA,EAAQ,MAAA,CAAO,CAAA,IAAK,MAAA,IAAU,WAAA,CAAY,CAAA;EAAA,QAIvD,gBAAA;AAAA;;AAgCV;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,WAAA,GAAA,CAAA,GACX,IAAA,EAAM,qBAAA,QAA6B,KAAA,CAAM,CAAA,KAAG,KAAA,CAAA,CAAA"}
|
package/dist/State.mjs
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
+
import { API } from "./API.mjs";
|
|
1
2
|
import { EventEmitter } from "@figliolia/event-emitter";
|
|
2
3
|
//#region src/State.ts
|
|
3
4
|
/**
|
|
4
|
-
* State
|
|
5
|
+
* ### State
|
|
5
6
|
*
|
|
6
7
|
* The unit of reactivity for Galena. `State`'s can act
|
|
7
8
|
* as isolated instances or be part of your global app
|
|
8
9
|
* state (via `Galena` instances).
|
|
9
10
|
*
|
|
10
|
-
* There are
|
|
11
|
+
* There are two ways to create state instances
|
|
11
12
|
*
|
|
12
13
|
* ```typescript
|
|
13
|
-
* import { State, createState,
|
|
14
|
-
|
|
14
|
+
* import { State, createState, Profiler } from "@figliolia/galena";
|
|
15
|
+
|
|
15
16
|
* const myState = new State("<any value>", ...middleware);
|
|
16
17
|
* // or
|
|
17
18
|
* const myState = createState("<any value>", ...middleware);
|
|
@@ -20,27 +21,18 @@ import { EventEmitter } from "@figliolia/event-emitter";
|
|
|
20
21
|
* myState.update(previousValue => "<new-value>");
|
|
21
22
|
* myState.subscribe(nextValue => {});
|
|
22
23
|
* myState.registerMiddleware(new Profiler());
|
|
23
|
-
*
|
|
24
|
-
* //
|
|
25
|
-
* const
|
|
26
|
-
* const [state, setState] = useState(myState);
|
|
27
|
-
* // or
|
|
28
|
-
* const [state, setState] = useMyState("<any-value>", ...middlware);
|
|
29
|
-
*
|
|
30
|
-
* return (
|
|
31
|
-
* // your jsx
|
|
32
|
-
* );
|
|
33
|
-
* }
|
|
24
|
+
* myState.reset(); // reset back to it's original value
|
|
25
|
+
* // to get the current value at any point in time
|
|
26
|
+
* const currentValue = myState.getState();
|
|
34
27
|
* ```
|
|
35
28
|
*/
|
|
36
|
-
var State = class {
|
|
29
|
+
var State = class extends API {
|
|
37
30
|
state;
|
|
38
|
-
middleware = [];
|
|
39
31
|
Emitter = new EventEmitter();
|
|
40
32
|
constructor(initialState, ...middleware) {
|
|
33
|
+
super(...middleware);
|
|
41
34
|
this.initialState = initialState;
|
|
42
35
|
this.state = initialState;
|
|
43
|
-
this.registerMiddleware(...middleware);
|
|
44
36
|
}
|
|
45
37
|
/**
|
|
46
38
|
* Set
|
|
@@ -73,7 +65,7 @@ var State = class {
|
|
|
73
65
|
* Returns the current state. Designed for compatibility with
|
|
74
66
|
* `useSyncExternalStore`
|
|
75
67
|
*/
|
|
76
|
-
|
|
68
|
+
getState = () => {
|
|
77
69
|
return this.state;
|
|
78
70
|
};
|
|
79
71
|
/**
|
|
@@ -122,21 +114,28 @@ var State = class {
|
|
|
122
114
|
}
|
|
123
115
|
};
|
|
124
116
|
/**
|
|
125
|
-
*
|
|
117
|
+
* ### createState
|
|
126
118
|
*
|
|
127
|
-
*
|
|
119
|
+
* The unit of reactivity for Galena. `State`'s can act
|
|
128
120
|
* as isolated instances or be part of your global app
|
|
129
|
-
* state (via `Galena` instances)
|
|
121
|
+
* state (via `Galena` instances).
|
|
130
122
|
*
|
|
131
|
-
*
|
|
132
|
-
* import { createState, Profiler } from "@figliolia/galena";
|
|
123
|
+
* There are two ways to create state instances
|
|
133
124
|
*
|
|
125
|
+
* ```typescript
|
|
126
|
+
* import { State, createState, Profiler } from "@figliolia/galena";
|
|
127
|
+
|
|
128
|
+
* const myState = new State("<any value>", ...middleware);
|
|
129
|
+
* // or
|
|
134
130
|
* const myState = createState("<any value>", ...middleware);
|
|
135
131
|
*
|
|
136
132
|
* myState.set("<new-value>");
|
|
137
133
|
* myState.update(previousValue => "<new-value>");
|
|
138
134
|
* myState.subscribe(nextValue => {});
|
|
139
135
|
* myState.registerMiddleware(new Profiler());
|
|
136
|
+
* myState.reset(); // reset back to it's original value
|
|
137
|
+
* // to get the current value at any point in time
|
|
138
|
+
* const currentValue = myState.getState();
|
|
140
139
|
* ```
|
|
141
140
|
*/
|
|
142
141
|
function createState(...args) {
|
package/dist/State.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"State.mjs","names":[],"sources":["../src/State.ts"],"sourcesContent":["import { EventEmitter } from \"@figliolia/event-emitter\";\nimport type { Middleware } from \"./Middleware\";\nimport type { NonFunction, Setter, Subscriber } from \"./types\";\n\n/**\n * State\n *\n * The unit of reactivity for Galena. `State`'s can act\n * as isolated instances or be part of your global app\n * state (via `Galena` instances).\n *\n * There are
|
|
1
|
+
{"version":3,"file":"State.mjs","names":[],"sources":["../src/State.ts"],"sourcesContent":["import { EventEmitter } from \"@figliolia/event-emitter\";\nimport { API } from \"./API\";\nimport type { Middleware } from \"./Middleware\";\nimport type { NonFunction, Setter, Subscriber } from \"./types\";\n\n/**\n * ### State\n *\n * The unit of reactivity for Galena. `State`'s can act\n * as isolated instances or be part of your global app\n * state (via `Galena` instances).\n *\n * There are two ways to create state instances\n *\n * ```typescript\n * import { State, createState, Profiler } from \"@figliolia/galena\";\n \n * const myState = new State(\"<any value>\", ...middleware);\n * // or\n * const myState = createState(\"<any value>\", ...middleware);\n *\n * myState.set(\"<new-value>\");\n * myState.update(previousValue => \"<new-value>\");\n * myState.subscribe(nextValue => {});\n * myState.registerMiddleware(new Profiler());\n * myState.reset(); // reset back to it's original value\n * // to get the current value at any point in time\n * const currentValue = myState.getState();\n * ```\n */\nexport class State<T> extends API<T, NonFunction<T>> {\n private state: NonFunction<T>;\n private readonly Emitter = new EventEmitter<{ change: NonFunction<T> }>();\n constructor(\n public readonly initialState: NonFunction<T>,\n ...middleware: Middleware<T>[]\n ) {\n super(...middleware);\n this.state = initialState;\n }\n\n /**\n * Set\n *\n * Updates the current value of state notifying\n * all interested parties\n */\n public readonly set = this.withEmission((state: NonFunction<T>) => state);\n\n /**\n * Update\n *\n * Updates the current value of state using a setter function\n * receiving the previous state as a parameter. Notifies all\n * interested parties\n */\n public readonly update = this.withEmission((setter: Setter<T>) => {\n if (this.diffSetter(setter)) {\n return setter;\n }\n return setter(this.state);\n });\n\n /**\n * Reset\n *\n * Resets the current state back to the state which the instance\n * was initialized with. Notifies all interested parties\n */\n public readonly reset = this.withEmission(() => this.initialState);\n\n /**\n * Get Snapshot\n *\n * Returns the current state. Designed for compatibility with\n * `useSyncExternalStore`\n */\n public readonly getState = () => {\n return this.state;\n };\n\n /**\n * Subscribe\n *\n * Registers a callback to be executed each time state\n * changes. Returns an `unsubscribe` function\n */\n public readonly subscribe = (fn: Subscriber<T>) => {\n const ID = this.Emitter.on(\"change\", fn);\n return () => {\n this.Emitter.off(\"change\", ID);\n };\n };\n\n /**\n * Register Middleware\n *\n * Registers any number of `Middleware` instances on the\n * current instance of `State`. Your middleware will begin\n * executing at the next state transition\n */\n public registerMiddleware(...middleware: Middleware<T>[]) {\n this.middleware.push(...middleware);\n }\n\n private withEmission<\n F extends (...args: any[]) => NonFunction<T> | Promise<NonFunction<T>>,\n >(fn: F) {\n return (...args: Parameters<F>) => {\n const result = fn(...args);\n if (result instanceof Promise) {\n void result.then(resolved => this.emit(resolved));\n return;\n }\n return this.emit(result);\n };\n }\n\n private emit(nextState: NonFunction<T>) {\n this.invokeMiddleware(\"onBeforeUpdate\");\n this.state = nextState;\n this.Emitter.emit(\"change\", this.state);\n this.invokeMiddleware(\"onUpdate\");\n }\n\n protected diffSetter(setter: Setter<T>): setter is NonFunction<T> {\n return typeof setter !== \"function\";\n }\n\n private invokeMiddleware<K extends keyof Middleware<T>>(fn: K) {\n for (const middleware of this.middleware) {\n middleware[fn](this);\n }\n }\n}\n\n/**\n * ### createState\n *\n * The unit of reactivity for Galena. `State`'s can act\n * as isolated instances or be part of your global app\n * state (via `Galena` instances).\n *\n * There are two ways to create state instances\n *\n * ```typescript\n * import { State, createState, Profiler } from \"@figliolia/galena\";\n \n * const myState = new State(\"<any value>\", ...middleware);\n * // or\n * const myState = createState(\"<any value>\", ...middleware);\n *\n * myState.set(\"<new-value>\");\n * myState.update(previousValue => \"<new-value>\");\n * myState.subscribe(nextValue => {});\n * myState.registerMiddleware(new Profiler());\n * myState.reset(); // reset back to it's original value\n * // to get the current value at any point in time\n * const currentValue = myState.getState();\n * ```\n */\nexport function createState<T>(\n ...args: ConstructorParameters<typeof State<T>>\n) {\n return new State<T>(...args);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,IAAa,QAAb,cAA8B,IAAuB;CACnD;CACA,UAA2B,IAAI,cAA0C;CACzE,YACE,cACA,GAAG,YACH;AACA,QAAM,GAAG,WAAW;AAHJ,OAAA,eAAA;AAIhB,OAAK,QAAQ;;;;;;;;CASf,MAAsB,KAAK,cAAc,UAA0B,MAAM;;;;;;;;CASzE,SAAyB,KAAK,cAAc,WAAsB;AAChE,MAAI,KAAK,WAAW,OAAO,CACzB,QAAO;AAET,SAAO,OAAO,KAAK,MAAM;GACzB;;;;;;;CAQF,QAAwB,KAAK,mBAAmB,KAAK,aAAa;;;;;;;CAQlE,iBAAiC;AAC/B,SAAO,KAAK;;;;;;;;CASd,aAA6B,OAAsB;EACjD,MAAM,KAAK,KAAK,QAAQ,GAAG,UAAU,GAAG;AACxC,eAAa;AACX,QAAK,QAAQ,IAAI,UAAU,GAAG;;;;;;;;;;CAWlC,mBAA0B,GAAG,YAA6B;AACxD,OAAK,WAAW,KAAK,GAAG,WAAW;;CAGrC,aAEE,IAAO;AACP,UAAQ,GAAG,SAAwB;GACjC,MAAM,SAAS,GAAG,GAAG,KAAK;AAC1B,OAAI,kBAAkB,SAAS;AACxB,WAAO,MAAK,aAAY,KAAK,KAAK,SAAS,CAAC;AACjD;;AAEF,UAAO,KAAK,KAAK,OAAO;;;CAI5B,KAAa,WAA2B;AACtC,OAAK,iBAAiB,iBAAiB;AACvC,OAAK,QAAQ;AACb,OAAK,QAAQ,KAAK,UAAU,KAAK,MAAM;AACvC,OAAK,iBAAiB,WAAW;;CAGnC,WAAqB,QAA6C;AAChE,SAAO,OAAO,WAAW;;CAG3B,iBAAwD,IAAO;AAC7D,OAAK,MAAM,cAAc,KAAK,WAC5B,YAAW,IAAI,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8B1B,SAAgB,YACd,GAAG,MACH;AACA,QAAO,IAAI,MAAS,GAAG,KAAK"}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { AppSubscriber, GalenaSnapshot, NonFunction, PartialSupport, Setter, StateTypes, Subscriber } from "./types.cjs";
|
|
1
|
+
import { AppSubscriber, GalenaSnapshot, GalenaState, NonFunction, PartialSupport, Setter, StateType, StateTypes, Subscriber } from "./types.cjs";
|
|
2
2
|
import { State, createState } from "./State.cjs";
|
|
3
3
|
import { Middleware } from "./Middleware.cjs";
|
|
4
4
|
import { Galena, createGalena } from "./Galena.cjs";
|
|
5
5
|
import { Logger } from "./Logger.cjs";
|
|
6
6
|
import { Profiler } from "./Profiler.cjs";
|
|
7
|
-
export { AppSubscriber, Galena, GalenaSnapshot, Logger, Middleware, NonFunction, PartialSupport, Profiler, Setter, State, StateTypes, Subscriber, createGalena, createState };
|
|
7
|
+
export { AppSubscriber, Galena, GalenaSnapshot, GalenaState, Logger, Middleware, NonFunction, PartialSupport, Profiler, Setter, State, StateType, StateTypes, Subscriber, createGalena, createState };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { AppSubscriber, GalenaSnapshot, NonFunction, PartialSupport, Setter, StateTypes, Subscriber } from "./types.mjs";
|
|
1
|
+
import { AppSubscriber, GalenaSnapshot, GalenaState, NonFunction, PartialSupport, Setter, StateType, StateTypes, Subscriber } from "./types.mjs";
|
|
2
2
|
import { State, createState } from "./State.mjs";
|
|
3
3
|
import { Middleware } from "./Middleware.mjs";
|
|
4
4
|
import { Galena, createGalena } from "./Galena.mjs";
|
|
5
5
|
import { Logger } from "./Logger.mjs";
|
|
6
6
|
import { Profiler } from "./Profiler.mjs";
|
|
7
|
-
export { AppSubscriber, Galena, GalenaSnapshot, Logger, Middleware, NonFunction, PartialSupport, Profiler, Setter, State, StateTypes, Subscriber, createGalena, createState };
|
|
7
|
+
export { AppSubscriber, Galena, GalenaSnapshot, GalenaState, Logger, Middleware, NonFunction, PartialSupport, Profiler, Setter, State, StateType, StateTypes, Subscriber, createGalena, createState };
|
package/dist/types.d.cts
CHANGED
|
@@ -10,7 +10,9 @@ interface GalenaSnapshot<T extends Record<string, State<any>>, K extends Extract
|
|
|
10
10
|
state: T;
|
|
11
11
|
}
|
|
12
12
|
type AppSubscriber<T extends Record<string, State<any>>, K extends Extract<keyof T, string> = Extract<keyof T, string>> = ((payload: GalenaSnapshot<T, K>) => void) | (() => void);
|
|
13
|
-
type StateTypes<T extends Record<string, State<any>>> = ReturnType<T[keyof T]
|
|
13
|
+
type StateTypes<T extends Record<string, State<any>>> = ReturnType<StateType<T[keyof T]>>;
|
|
14
|
+
type StateType<T extends State<any>> = ReturnType<T["getState"]>;
|
|
15
|
+
type GalenaState<T extends Record<string, State<any>>> = { [K in keyof T]: StateType<T[K]> };
|
|
14
16
|
//#endregion
|
|
15
|
-
export { AppSubscriber, GalenaSnapshot, NonFunction, PartialSupport, Setter, StateTypes, Subscriber };
|
|
17
|
+
export { AppSubscriber, GalenaSnapshot, GalenaState, NonFunction, PartialSupport, Setter, StateType, StateTypes, Subscriber };
|
|
16
18
|
//# sourceMappingURL=types.d.cts.map
|
package/dist/types.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"mappings":";;;KAEY,WAAA,MAAiB,CAAA,cAAc,IAAA,2BAA8B,CAAA;AAAA,KAE7D,cAAA,MAAoB,CAAA,SAAU,MAAA,gBAAsB,OAAA,CAAQ,CAAA,IAAK,CAAA;AAAA,KAEjE,MAAA,MACR,WAAA,CAAY,CAAA,MACV,SAAA,EAAW,WAAA,CAAY,CAAA,MAAO,WAAA,CAAY,CAAA,IAAK,OAAA,CAAQ,WAAA,CAAY,CAAA;AAAA,KAE7D,UAAA,QAAkB,KAAA,EAAO,WAAA,CAAY,CAAA;AAAA,UAEhC,cAAA,WACL,MAAA,SAAe,KAAA,kBACf,OAAA,OAAc,CAAA,YAAa,OAAA,OAAc,CAAA;EAEnD,OAAA,EAAS,CAAA,CAAE,CAAA;EACX,KAAA,EAAO,CAAA;AAAA;AAAA,KAGG,aAAA,WACA,MAAA,SAAe,KAAA,kBACf,OAAA,OAAc,CAAA,YAAa,OAAA,OAAc,CAAA,eAC/C,OAAA,EAAS,cAAA,CAAe,CAAA,EAAG,CAAA;AAAA,KAErB,UAAA,WAAqB,MAAA,SAAe,KAAA,UAAe,UAAA,CAC7D,CAAA,OAAQ,CAAA"}
|
|
1
|
+
{"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"mappings":";;;KAEY,WAAA,MAAiB,CAAA,cAAc,IAAA,2BAA8B,CAAA;AAAA,KAE7D,cAAA,MAAoB,CAAA,SAAU,MAAA,gBAAsB,OAAA,CAAQ,CAAA,IAAK,CAAA;AAAA,KAEjE,MAAA,MACR,WAAA,CAAY,CAAA,MACV,SAAA,EAAW,WAAA,CAAY,CAAA,MAAO,WAAA,CAAY,CAAA,IAAK,OAAA,CAAQ,WAAA,CAAY,CAAA;AAAA,KAE7D,UAAA,QAAkB,KAAA,EAAO,WAAA,CAAY,CAAA;AAAA,UAEhC,cAAA,WACL,MAAA,SAAe,KAAA,kBACf,OAAA,OAAc,CAAA,YAAa,OAAA,OAAc,CAAA;EAEnD,OAAA,EAAS,CAAA,CAAE,CAAA;EACX,KAAA,EAAO,CAAA;AAAA;AAAA,KAGG,aAAA,WACA,MAAA,SAAe,KAAA,kBACf,OAAA,OAAc,CAAA,YAAa,OAAA,OAAc,CAAA,eAC/C,OAAA,EAAS,cAAA,CAAe,CAAA,EAAG,CAAA;AAAA,KAErB,UAAA,WAAqB,MAAA,SAAe,KAAA,UAAe,UAAA,CAC7D,SAAA,CAAU,CAAA,OAAQ,CAAA;AAAA,KAGR,SAAA,WAAoB,KAAA,SAAc,UAAA,CAAW,CAAA;AAAA,KAE7C,WAAA,WAAsB,MAAA,SAAe,KAAA,wBACnC,CAAA,GAAI,SAAA,CAAU,CAAA,CAAE,CAAA"}
|
package/dist/types.d.mts
CHANGED
|
@@ -10,7 +10,9 @@ interface GalenaSnapshot<T extends Record<string, State<any>>, K extends Extract
|
|
|
10
10
|
state: T;
|
|
11
11
|
}
|
|
12
12
|
type AppSubscriber<T extends Record<string, State<any>>, K extends Extract<keyof T, string> = Extract<keyof T, string>> = ((payload: GalenaSnapshot<T, K>) => void) | (() => void);
|
|
13
|
-
type StateTypes<T extends Record<string, State<any>>> = ReturnType<T[keyof T]
|
|
13
|
+
type StateTypes<T extends Record<string, State<any>>> = ReturnType<StateType<T[keyof T]>>;
|
|
14
|
+
type StateType<T extends State<any>> = ReturnType<T["getState"]>;
|
|
15
|
+
type GalenaState<T extends Record<string, State<any>>> = { [K in keyof T]: StateType<T[K]> };
|
|
14
16
|
//#endregion
|
|
15
|
-
export { AppSubscriber, GalenaSnapshot, NonFunction, PartialSupport, Setter, StateTypes, Subscriber };
|
|
17
|
+
export { AppSubscriber, GalenaSnapshot, GalenaState, NonFunction, PartialSupport, Setter, StateType, StateTypes, Subscriber };
|
|
16
18
|
//# sourceMappingURL=types.d.mts.map
|
package/dist/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;;KAEY,WAAA,MAAiB,CAAA,cAAc,IAAA,2BAA8B,CAAA;AAAA,KAE7D,cAAA,MAAoB,CAAA,SAAU,MAAA,gBAAsB,OAAA,CAAQ,CAAA,IAAK,CAAA;AAAA,KAEjE,MAAA,MACR,WAAA,CAAY,CAAA,MACV,SAAA,EAAW,WAAA,CAAY,CAAA,MAAO,WAAA,CAAY,CAAA,IAAK,OAAA,CAAQ,WAAA,CAAY,CAAA;AAAA,KAE7D,UAAA,QAAkB,KAAA,EAAO,WAAA,CAAY,CAAA;AAAA,UAEhC,cAAA,WACL,MAAA,SAAe,KAAA,kBACf,OAAA,OAAc,CAAA,YAAa,OAAA,OAAc,CAAA;EAEnD,OAAA,EAAS,CAAA,CAAE,CAAA;EACX,KAAA,EAAO,CAAA;AAAA;AAAA,KAGG,aAAA,WACA,MAAA,SAAe,KAAA,kBACf,OAAA,OAAc,CAAA,YAAa,OAAA,OAAc,CAAA,eAC/C,OAAA,EAAS,cAAA,CAAe,CAAA,EAAG,CAAA;AAAA,KAErB,UAAA,WAAqB,MAAA,SAAe,KAAA,UAAe,UAAA,CAC7D,CAAA,OAAQ,CAAA"}
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;;KAEY,WAAA,MAAiB,CAAA,cAAc,IAAA,2BAA8B,CAAA;AAAA,KAE7D,cAAA,MAAoB,CAAA,SAAU,MAAA,gBAAsB,OAAA,CAAQ,CAAA,IAAK,CAAA;AAAA,KAEjE,MAAA,MACR,WAAA,CAAY,CAAA,MACV,SAAA,EAAW,WAAA,CAAY,CAAA,MAAO,WAAA,CAAY,CAAA,IAAK,OAAA,CAAQ,WAAA,CAAY,CAAA;AAAA,KAE7D,UAAA,QAAkB,KAAA,EAAO,WAAA,CAAY,CAAA;AAAA,UAEhC,cAAA,WACL,MAAA,SAAe,KAAA,kBACf,OAAA,OAAc,CAAA,YAAa,OAAA,OAAc,CAAA;EAEnD,OAAA,EAAS,CAAA,CAAE,CAAA;EACX,KAAA,EAAO,CAAA;AAAA;AAAA,KAGG,aAAA,WACA,MAAA,SAAe,KAAA,kBACf,OAAA,OAAc,CAAA,YAAa,OAAA,OAAc,CAAA,eAC/C,OAAA,EAAS,cAAA,CAAe,CAAA,EAAG,CAAA;AAAA,KAErB,UAAA,WAAqB,MAAA,SAAe,KAAA,UAAe,UAAA,CAC7D,SAAA,CAAU,CAAA,OAAQ,CAAA;AAAA,KAGR,SAAA,WAAoB,KAAA,SAAc,UAAA,CAAW,CAAA;AAAA,KAE7C,WAAA,WAAsB,MAAA,SAAe,KAAA,wBACnC,CAAA,GAAI,SAAA,CAAU,CAAA,CAAE,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@figliolia/galena",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "A performant state management library supporting middleware and a rich developer API",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"flux",
|
|
7
|
+
"react",
|
|
8
|
+
"state",
|
|
9
|
+
"state management"
|
|
10
|
+
],
|
|
5
11
|
"homepage": "https://github.com/alexfigliolia/galena#readme",
|
|
6
12
|
"license": "MIT",
|
|
7
13
|
"author": "Alex Figliolia",
|
|
@@ -48,11 +54,5 @@
|
|
|
48
54
|
},
|
|
49
55
|
"peerDependencies": {
|
|
50
56
|
"@figliolia/event-emitter": ">=1.2.0"
|
|
51
|
-
}
|
|
52
|
-
"keywords": [
|
|
53
|
-
"state",
|
|
54
|
-
"state management",
|
|
55
|
-
"flux",
|
|
56
|
-
"react"
|
|
57
|
-
]
|
|
57
|
+
}
|
|
58
58
|
}
|
package/src/API.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Middleware } from "./Middleware";
|
|
2
|
+
|
|
3
|
+
export abstract class API<T, E, M = T> {
|
|
4
|
+
public readonly middleware: Middleware<M>[] = [];
|
|
5
|
+
constructor(...middleware: Middleware<M>[]) {
|
|
6
|
+
this.registerMiddleware(...middleware);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
public abstract getState(): T;
|
|
10
|
+
public abstract subscribe(subscriber: (payload: E) => void): () => void;
|
|
11
|
+
public abstract registerMiddleware(...middlewares: Middleware<M>[]): void;
|
|
12
|
+
}
|
package/src/Galena.ts
CHANGED
|
@@ -1,52 +1,117 @@
|
|
|
1
1
|
import { EventEmitter } from "@figliolia/event-emitter";
|
|
2
|
+
import { API } from "./API";
|
|
2
3
|
import type { Middleware } from "./Middleware";
|
|
3
4
|
import type { State } from "./State";
|
|
4
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
AppSubscriber,
|
|
7
|
+
GalenaSnapshot,
|
|
8
|
+
GalenaState,
|
|
9
|
+
Setter,
|
|
10
|
+
StateType,
|
|
11
|
+
StateTypes,
|
|
12
|
+
} from "./types";
|
|
5
13
|
|
|
6
14
|
/**
|
|
7
|
-
* Galena
|
|
15
|
+
* ### Galena
|
|
8
16
|
*
|
|
9
|
-
* Galena
|
|
17
|
+
* Galena instances are designed to house one or more units of `State`
|
|
10
18
|
* and exist as a pseudo global application state.
|
|
11
19
|
*
|
|
12
20
|
* By design, each of its `State` units have isolated reactivity
|
|
13
21
|
* that prevents entire state trees from updating when a single
|
|
14
22
|
* unit changes.
|
|
15
23
|
*
|
|
16
|
-
* This is dissimilar to redux-like models where downstream reconciliations
|
|
17
|
-
* will propagate everwhere a given store is read from. In galena, downstream
|
|
18
|
-
* reconciliations occur only for consumers of the slice of state that
|
|
19
|
-
* changed - making it safer to use with more frequent state changes.
|
|
20
|
-
*
|
|
21
24
|
* ```typescript
|
|
22
25
|
* import { Galena } from "@figliolia/galena";
|
|
23
26
|
*
|
|
24
27
|
* const AppState = new Galena({
|
|
28
|
+
* user: new State("<user-stuff>"),
|
|
29
|
+
* business: new State("<business-logic-stuff>")
|
|
25
30
|
* // your reactive instances
|
|
26
31
|
* }, ...middleware);
|
|
27
32
|
*
|
|
28
33
|
* // to retreive and work with an individual unit
|
|
29
|
-
* const
|
|
34
|
+
* const userState = AppState.get("user"); // Returns State<T>
|
|
30
35
|
*
|
|
31
36
|
* // to run a callback anytime a unit of state changes
|
|
32
|
-
* const
|
|
37
|
+
* const listener = AppState.subscribe(({ state, updated }) => {
|
|
33
38
|
* // do something with the `State` instance that updated
|
|
39
|
+
* // the entirety of your state
|
|
34
40
|
* });
|
|
41
|
+
*
|
|
42
|
+
* // get the current application state
|
|
43
|
+
* const currentState = AppState.getState();
|
|
44
|
+
*
|
|
45
|
+
* // operate on an instance of state
|
|
46
|
+
* AppState.update("user", userState => ({
|
|
47
|
+
* ...userState,
|
|
48
|
+
* // your updates
|
|
49
|
+
* }));
|
|
35
50
|
* ```
|
|
36
51
|
*/
|
|
37
|
-
export class Galena<T extends Record<string, State<any>>>
|
|
52
|
+
export class Galena<T extends Record<string, State<any>>> extends API<
|
|
53
|
+
GalenaState<T>,
|
|
54
|
+
GalenaSnapshot<T>,
|
|
55
|
+
StateTypes<T>
|
|
56
|
+
> {
|
|
38
57
|
private Emitter = new EventEmitter<{ change: GalenaSnapshot<T> }>();
|
|
39
58
|
constructor(
|
|
40
59
|
public readonly state: T,
|
|
41
60
|
...middleware: Middleware<StateTypes<T>>[]
|
|
42
61
|
) {
|
|
43
|
-
|
|
62
|
+
super(...middleware);
|
|
44
63
|
}
|
|
45
64
|
|
|
65
|
+
public getState() {
|
|
66
|
+
const result = {} as GalenaState<T>;
|
|
67
|
+
for (const key in this.state) {
|
|
68
|
+
const state = key as keyof T;
|
|
69
|
+
result[state] = this.state[key].getState();
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get
|
|
76
|
+
*
|
|
77
|
+
* Returns a connected State instance by key
|
|
78
|
+
*/
|
|
46
79
|
public get<K extends Extract<keyof T, string>>(key: K) {
|
|
47
80
|
return this.state[key];
|
|
48
81
|
}
|
|
49
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Set
|
|
85
|
+
*
|
|
86
|
+
* Sets a connected State instance's state by key
|
|
87
|
+
*/
|
|
88
|
+
public set<K extends Extract<keyof T, string>>(
|
|
89
|
+
key: K,
|
|
90
|
+
value: StateType<T[K]>,
|
|
91
|
+
) {
|
|
92
|
+
return this.get(key).set(value);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Update
|
|
97
|
+
*
|
|
98
|
+
* Invokes a connected State instance's update method key
|
|
99
|
+
*/
|
|
100
|
+
public update<K extends Extract<keyof T, string>>(
|
|
101
|
+
key: K,
|
|
102
|
+
updater: Setter<StateType<T[K]>>,
|
|
103
|
+
) {
|
|
104
|
+
return this.get(key).update(updater);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Subscribe
|
|
109
|
+
*
|
|
110
|
+
* Listen for changes on your Galena instnace. Your provided
|
|
111
|
+
* callback will be invoked each time an attached state instance
|
|
112
|
+
* changes. To your callback will be provided the `updated` state
|
|
113
|
+
* instance, along with the entire `state` tree
|
|
114
|
+
*/
|
|
50
115
|
public subscribe = (subscriber: AppSubscriber<T>) => {
|
|
51
116
|
const ID = this.Emitter.on("change", subscriber);
|
|
52
117
|
const unsubscribers: (() => void)[] = [];
|
|
@@ -69,6 +134,12 @@ export class Galena<T extends Record<string, State<any>>> {
|
|
|
69
134
|
};
|
|
70
135
|
};
|
|
71
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Register Middleware
|
|
139
|
+
*
|
|
140
|
+
* Adds middleware instances to each of the connected
|
|
141
|
+
* `State` instances
|
|
142
|
+
*/
|
|
72
143
|
public registerMiddleware(...middlewares: Middleware<StateTypes<T>>[]) {
|
|
73
144
|
for (const key in this.state) {
|
|
74
145
|
this.state[key]?.registerMiddleware?.(...middlewares);
|
|
@@ -83,34 +154,41 @@ export class Galena<T extends Record<string, State<any>>> {
|
|
|
83
154
|
}
|
|
84
155
|
|
|
85
156
|
/**
|
|
86
|
-
*
|
|
157
|
+
* ### createGalena
|
|
87
158
|
*
|
|
88
|
-
* Galena
|
|
159
|
+
* Galena instances are designed to house one or more units of `State`
|
|
89
160
|
* and exist as a pseudo global application state.
|
|
90
161
|
*
|
|
91
162
|
* By design, each of its `State` units have isolated reactivity
|
|
92
163
|
* that prevents entire state trees from updating when a single
|
|
93
164
|
* unit changes.
|
|
94
165
|
*
|
|
95
|
-
* This is dissimilar to redux-like models where downstream reconciliations
|
|
96
|
-
* will propagate everwhere a given store is read from. In galena, downstream
|
|
97
|
-
* reconciliations occur only for consumers of the slice of state that
|
|
98
|
-
* changed - making it safer to use with more frequent state changes.
|
|
99
|
-
*
|
|
100
166
|
* ```typescript
|
|
101
|
-
* import {
|
|
167
|
+
* import { Galena } from "@figliolia/galena";
|
|
102
168
|
*
|
|
103
|
-
* const AppState =
|
|
169
|
+
* const AppState = new Galena({
|
|
170
|
+
* user: new State("<user-stuff>"),
|
|
171
|
+
* business: new State("<business-logic-stuff>")
|
|
104
172
|
* // your reactive instances
|
|
105
173
|
* }, ...middleware);
|
|
106
174
|
*
|
|
107
175
|
* // to retreive and work with an individual unit
|
|
108
|
-
* const
|
|
176
|
+
* const userState = AppState.get("user"); // Returns State<T>
|
|
109
177
|
*
|
|
110
178
|
* // to run a callback anytime a unit of state changes
|
|
111
|
-
* const
|
|
179
|
+
* const listener = AppState.subscribe(({ state, updated }) => {
|
|
112
180
|
* // do something with the `State` instance that updated
|
|
181
|
+
* // the entirety of your state
|
|
113
182
|
* });
|
|
183
|
+
*
|
|
184
|
+
* // get the current application state
|
|
185
|
+
* const currentState = AppState.getState();
|
|
186
|
+
*
|
|
187
|
+
* // operate on an instance of state
|
|
188
|
+
* AppState.update("user", userState => ({
|
|
189
|
+
* ...userState,
|
|
190
|
+
* // your updates
|
|
191
|
+
* }));
|
|
114
192
|
* ```
|
|
115
193
|
*/
|
|
116
194
|
export const createGalena = <T extends Record<string, State<any>>>(
|
package/src/Logger.ts
CHANGED
|
@@ -22,7 +22,7 @@ export class Logger<T = any> extends Middleware {
|
|
|
22
22
|
private previousState: T | null = null;
|
|
23
23
|
|
|
24
24
|
override onBeforeUpdate(state: State<T>) {
|
|
25
|
-
this.previousState = state.
|
|
25
|
+
this.previousState = state.getState();
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
override onUpdate(state: State<T>) {
|
|
@@ -40,7 +40,7 @@ export class Logger<T = any> extends Middleware {
|
|
|
40
40
|
console.log(
|
|
41
41
|
" %cNext State ",
|
|
42
42
|
"color: rgb(17, 118, 249); font-weight: bold",
|
|
43
|
-
state.
|
|
43
|
+
state.getState(),
|
|
44
44
|
);
|
|
45
45
|
}
|
|
46
46
|
|