@figliolia/galena 3.0.2 → 3.0.3
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 +43 -43
- package/dist/Galena.cjs +49 -18
- package/dist/Galena.d.cts +46 -19
- package/dist/Galena.d.cts.map +1 -1
- package/dist/Galena.d.mts +46 -19
- package/dist/Galena.d.mts.map +1 -1
- package/dist/Galena.mjs +49 -18
- package/dist/Galena.mjs.map +1 -1
- package/dist/State.cjs +13 -18
- package/dist/State.d.cts +13 -18
- package/dist/State.d.cts.map +1 -1
- package/dist/State.d.mts +13 -18
- package/dist/State.d.mts.map +1 -1
- package/dist/State.mjs +13 -18
- 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 +3 -2
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +3 -2
- package/dist/types.d.mts.map +1 -1
- package/package.json +1 -1
- package/src/Galena.ts +64 -19
- package/src/State.ts +13 -18
- package/src/types.ts +3 -1
package/src/Galena.ts
CHANGED
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
import { EventEmitter } from "@figliolia/event-emitter";
|
|
2
2
|
import type { Middleware } from "./Middleware";
|
|
3
3
|
import type { State } from "./State";
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
AppSubscriber,
|
|
6
|
+
GalenaSnapshot,
|
|
7
|
+
Setter,
|
|
8
|
+
StateType,
|
|
9
|
+
StateTypes,
|
|
10
|
+
} from "./types";
|
|
5
11
|
|
|
6
12
|
/**
|
|
7
|
-
* Galena
|
|
13
|
+
* ### Galena
|
|
8
14
|
*
|
|
9
|
-
* Galena
|
|
15
|
+
* Galena instances are designed to house one or more units of `State`
|
|
10
16
|
* and exist as a pseudo global application state.
|
|
11
17
|
*
|
|
12
18
|
* By design, each of its `State` units have isolated reactivity
|
|
13
19
|
* that prevents entire state trees from updating when a single
|
|
14
20
|
* unit changes.
|
|
15
21
|
*
|
|
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
22
|
* ```typescript
|
|
22
23
|
* import { Galena } from "@figliolia/galena";
|
|
23
24
|
*
|
|
24
25
|
* const AppState = new Galena({
|
|
26
|
+
* user: new State("<user-stuff>"),
|
|
27
|
+
* business: new State("<business-logic-stuff>")
|
|
25
28
|
* // your reactive instances
|
|
26
29
|
* }, ...middleware);
|
|
27
30
|
*
|
|
@@ -29,8 +32,9 @@ import type { AppSubscriber, GalenaSnapshot, StateTypes } from "./types";
|
|
|
29
32
|
* const myUnit = AppState.get("<key>"); // Returns State<T>
|
|
30
33
|
*
|
|
31
34
|
* // to run a callback anytime a unit of state changes
|
|
32
|
-
* const
|
|
35
|
+
* const listener = AppState.subscribe(({ state, updated }) => {
|
|
33
36
|
* // do something with the `State` instance that updated
|
|
37
|
+
* // the entirety of your state
|
|
34
38
|
* });
|
|
35
39
|
* ```
|
|
36
40
|
*/
|
|
@@ -43,10 +47,47 @@ export class Galena<T extends Record<string, State<any>>> {
|
|
|
43
47
|
this.registerMiddleware(...middleware);
|
|
44
48
|
}
|
|
45
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Get
|
|
52
|
+
*
|
|
53
|
+
* Returns a connected State instance by key
|
|
54
|
+
*/
|
|
46
55
|
public get<K extends Extract<keyof T, string>>(key: K) {
|
|
47
56
|
return this.state[key];
|
|
48
57
|
}
|
|
49
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Set
|
|
61
|
+
*
|
|
62
|
+
* Sets a connected State instance's state by key
|
|
63
|
+
*/
|
|
64
|
+
public set<K extends Extract<keyof T, string>>(
|
|
65
|
+
key: K,
|
|
66
|
+
value: StateType<T[K]>,
|
|
67
|
+
) {
|
|
68
|
+
return this.get(key).set(value);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Update
|
|
73
|
+
*
|
|
74
|
+
* Invokes a connected State instance's update method key
|
|
75
|
+
*/
|
|
76
|
+
public update<K extends Extract<keyof T, string>>(
|
|
77
|
+
key: K,
|
|
78
|
+
updater: Setter<StateType<T[K]>>,
|
|
79
|
+
) {
|
|
80
|
+
return this.get(key).update(updater);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Subscribe
|
|
85
|
+
*
|
|
86
|
+
* Listen for changes on your Galena instnace. Your provided
|
|
87
|
+
* callback will be invoked each time an attached state instance
|
|
88
|
+
* changes. To your callback will be provided the `updated` state
|
|
89
|
+
* instance, along with the entire `state` tree
|
|
90
|
+
*/
|
|
50
91
|
public subscribe = (subscriber: AppSubscriber<T>) => {
|
|
51
92
|
const ID = this.Emitter.on("change", subscriber);
|
|
52
93
|
const unsubscribers: (() => void)[] = [];
|
|
@@ -69,6 +110,12 @@ export class Galena<T extends Record<string, State<any>>> {
|
|
|
69
110
|
};
|
|
70
111
|
};
|
|
71
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Register Middleware
|
|
115
|
+
*
|
|
116
|
+
* Adds middleware instances to each of the connected
|
|
117
|
+
* `State` instances
|
|
118
|
+
*/
|
|
72
119
|
public registerMiddleware(...middlewares: Middleware<StateTypes<T>>[]) {
|
|
73
120
|
for (const key in this.state) {
|
|
74
121
|
this.state[key]?.registerMiddleware?.(...middlewares);
|
|
@@ -83,24 +130,21 @@ export class Galena<T extends Record<string, State<any>>> {
|
|
|
83
130
|
}
|
|
84
131
|
|
|
85
132
|
/**
|
|
86
|
-
*
|
|
133
|
+
* ### createGalena
|
|
87
134
|
*
|
|
88
|
-
* Galena
|
|
135
|
+
* Galena instances are designed to house one or more units of `State`
|
|
89
136
|
* and exist as a pseudo global application state.
|
|
90
137
|
*
|
|
91
138
|
* By design, each of its `State` units have isolated reactivity
|
|
92
139
|
* that prevents entire state trees from updating when a single
|
|
93
140
|
* unit changes.
|
|
94
141
|
*
|
|
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
142
|
* ```typescript
|
|
101
|
-
* import {
|
|
143
|
+
* import { Galena } from "@figliolia/galena";
|
|
102
144
|
*
|
|
103
|
-
* const AppState =
|
|
145
|
+
* const AppState = new Galena({
|
|
146
|
+
* user: new State("<user-stuff>"),
|
|
147
|
+
* business: new State("<business-logic-stuff>")
|
|
104
148
|
* // your reactive instances
|
|
105
149
|
* }, ...middleware);
|
|
106
150
|
*
|
|
@@ -108,8 +152,9 @@ export class Galena<T extends Record<string, State<any>>> {
|
|
|
108
152
|
* const myUnit = AppState.get("<key>"); // Returns State<T>
|
|
109
153
|
*
|
|
110
154
|
* // to run a callback anytime a unit of state changes
|
|
111
|
-
* const
|
|
155
|
+
* const listener = AppState.subscribe(({ state, updated }) => {
|
|
112
156
|
* // do something with the `State` instance that updated
|
|
157
|
+
* // the entirety of your state
|
|
113
158
|
* });
|
|
114
159
|
* ```
|
|
115
160
|
*/
|
package/src/State.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { Middleware } from "./Middleware";
|
|
|
3
3
|
import type { NonFunction, Setter, Subscriber } from "./types";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* State
|
|
6
|
+
* ### State
|
|
7
7
|
*
|
|
8
8
|
* The unit of reactivity for Galena. `State`'s can act
|
|
9
9
|
* as isolated instances or be part of your global app
|
|
@@ -12,7 +12,7 @@ import type { NonFunction, Setter, Subscriber } from "./types";
|
|
|
12
12
|
* There are three ways to create state instances
|
|
13
13
|
*
|
|
14
14
|
* ```typescript
|
|
15
|
-
* import { State, createState,
|
|
15
|
+
* import { State, createState, Profiler } from "@figliolia/galena";
|
|
16
16
|
* // for island states that can be shared between react components
|
|
17
17
|
* const myState = new State("<any value>", ...middleware);
|
|
18
18
|
* // or
|
|
@@ -22,17 +22,7 @@ import type { NonFunction, Setter, Subscriber } from "./types";
|
|
|
22
22
|
* myState.update(previousValue => "<new-value>");
|
|
23
23
|
* myState.subscribe(nextValue => {});
|
|
24
24
|
* myState.registerMiddleware(new Profiler());
|
|
25
|
-
*
|
|
26
|
-
* // Similarly if you wish to use your state inside a react component
|
|
27
|
-
* const MyComponent = () => {
|
|
28
|
-
* const [state, setState] = useState(myState);
|
|
29
|
-
* // or
|
|
30
|
-
* const [state, setState] = useMyState("<any-value>", ...middlware);
|
|
31
|
-
*
|
|
32
|
-
* return (
|
|
33
|
-
* // your jsx
|
|
34
|
-
* );
|
|
35
|
-
* }
|
|
25
|
+
* myState.reset(); // reset back to it's original value
|
|
36
26
|
* ```
|
|
37
27
|
*/
|
|
38
28
|
export class State<T> {
|
|
@@ -143,21 +133,26 @@ export class State<T> {
|
|
|
143
133
|
}
|
|
144
134
|
|
|
145
135
|
/**
|
|
146
|
-
*
|
|
136
|
+
* ### createState
|
|
147
137
|
*
|
|
148
|
-
*
|
|
138
|
+
* The unit of reactivity for Galena. `State`'s can act
|
|
149
139
|
* as isolated instances or be part of your global app
|
|
150
|
-
* state (via `Galena` instances)
|
|
140
|
+
* state (via `Galena` instances).
|
|
151
141
|
*
|
|
152
|
-
*
|
|
153
|
-
* import { createState, Profiler } from "@figliolia/galena";
|
|
142
|
+
* There are three ways to create state instances
|
|
154
143
|
*
|
|
144
|
+
* ```typescript
|
|
145
|
+
* import { State, createState, Profiler } from "@figliolia/galena";
|
|
146
|
+
* // for island states that can be shared between react components
|
|
147
|
+
* const myState = new State("<any value>", ...middleware);
|
|
148
|
+
* // or
|
|
155
149
|
* const myState = createState("<any value>", ...middleware);
|
|
156
150
|
*
|
|
157
151
|
* myState.set("<new-value>");
|
|
158
152
|
* myState.update(previousValue => "<new-value>");
|
|
159
153
|
* myState.subscribe(nextValue => {});
|
|
160
154
|
* myState.registerMiddleware(new Profiler());
|
|
155
|
+
* myState.reset(); // reset back to it's original value
|
|
161
156
|
* ```
|
|
162
157
|
*/
|
|
163
158
|
export function createState<T>(
|
package/src/types.ts
CHANGED
|
@@ -24,5 +24,7 @@ export type AppSubscriber<
|
|
|
24
24
|
> = ((payload: GalenaSnapshot<T, K>) => void) | (() => void);
|
|
25
25
|
|
|
26
26
|
export type StateTypes<T extends Record<string, State<any>>> = ReturnType<
|
|
27
|
-
T[keyof T]
|
|
27
|
+
StateType<T[keyof T]>
|
|
28
28
|
>;
|
|
29
|
+
|
|
30
|
+
export type StateType<T extends State<any>> = ReturnType<T["getSnapshot"]>;
|