@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/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Lightning fast, framework agnostic state, that doesn't glue your state operations to your UI components!
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
[State](#the-state-model)
|
|
6
|
+
[Galena](#the-galena-model)
|
|
7
|
+
[For use with react](#frameworks)
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
@@ -18,30 +18,34 @@ npm i @figliolia/react-galena
|
|
|
18
18
|
|
|
19
19
|
### The State Model
|
|
20
20
|
|
|
21
|
-
The instancable `State` object in Galena is
|
|
21
|
+
The instancable `State` object in Galena is a reactive wrapper around any value. You can use it to apply reactivity to large objects or simple values
|
|
22
22
|
|
|
23
23
|
```typescript
|
|
24
|
-
import { State } from "@figliolia/galena";
|
|
24
|
+
import { State, createState } from "@figliolia/galena";
|
|
25
25
|
|
|
26
|
-
const
|
|
26
|
+
const myState = new State(/* any value */, /* middleware */);
|
|
27
|
+
// or
|
|
28
|
+
const myState = createState(/* any value */, /* middleware */);
|
|
27
29
|
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
const currentValue = myState.getState();
|
|
31
|
+
const subscriber = myState.subscribe(nextValue => {});
|
|
32
|
+
myState.set(/* new value */);
|
|
33
|
+
myState.update(previousValue => /* new value */);
|
|
31
34
|
|
|
32
|
-
// to
|
|
33
|
-
|
|
35
|
+
// to reset state back to its original value
|
|
36
|
+
myState.reset();
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
MyState.reset(); // reset state back to the initial value
|
|
38
|
+
// to unregister the subscription
|
|
39
|
+
subscriber();
|
|
38
40
|
```
|
|
39
41
|
|
|
40
42
|
Instances of `State` are ultimately what compose all reactivity in Galena. They can exist as islands compose larger stateful model.
|
|
41
43
|
|
|
42
44
|
### The Galena Model
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
`Galena` objects are designed to "link" multiple instances of `State` together to create a "global" application state.
|
|
47
|
+
|
|
48
|
+
To use it simply define your `State`'s and pass them to a `Galena` instance
|
|
45
49
|
|
|
46
50
|
```typescript
|
|
47
51
|
import { Galena, State } from "@figliolia/galena";
|
|
@@ -55,16 +59,14 @@ const AppState = new Galena(
|
|
|
55
59
|
user: new State({
|
|
56
60
|
userID: "<id>",
|
|
57
61
|
membershipTier: "free",
|
|
58
|
-
friends: ["<
|
|
62
|
+
friends: ["<id-1>", "<id-2>"],
|
|
59
63
|
}),
|
|
60
64
|
// ...and so on
|
|
61
65
|
} /* middleware */,
|
|
62
66
|
);
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
From here, operations on any slice of state are type-aware and operable via a single construct:
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
// From here, operations on any slice of state are type-aware
|
|
69
|
+
// and operable via a single construct:
|
|
68
70
|
const subscriber = AppState.subscribe(
|
|
69
71
|
({
|
|
70
72
|
state, // The entire state object at the time of change
|
|
@@ -75,23 +77,22 @@ const subscriber = AppState.subscribe(
|
|
|
75
77
|
);
|
|
76
78
|
|
|
77
79
|
// to unsubscribe
|
|
78
|
-
|
|
80
|
+
subscriber();
|
|
79
81
|
|
|
82
|
+
// to access an instance of state
|
|
83
|
+
const UserState = AppState.get("user");
|
|
80
84
|
// to operate
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
AppState.
|
|
87
|
-
...state,
|
|
88
|
-
navigationMenuOpen: true,
|
|
89
|
-
}));
|
|
85
|
+
UserState.update(state => /* next state */);
|
|
86
|
+
// or
|
|
87
|
+
AppState.update("user", state => /* next state */);
|
|
88
|
+
|
|
89
|
+
// to get the current value of the state tree
|
|
90
|
+
const state = AppState.getState();
|
|
90
91
|
```
|
|
91
92
|
|
|
92
93
|
### Beyond the Basics
|
|
93
94
|
|
|
94
|
-
####
|
|
95
|
+
#### Modeling Data with Mutations
|
|
95
96
|
|
|
96
97
|
`State` in Galena is designed for extension and instancing - a need that ultimately motivated the library's development.
|
|
97
98
|
|
|
@@ -136,42 +137,29 @@ export class MyGameState extends State<IMyGameState> {
|
|
|
136
137
|
}
|
|
137
138
|
```
|
|
138
139
|
|
|
139
|
-
|
|
140
|
+
These more "robust" state models assist in standardizing a developer API along with your data models. The models you create are also compatible with your your `Galena` instances:
|
|
140
141
|
|
|
141
142
|
```typescript
|
|
142
|
-
import {
|
|
143
|
-
|
|
144
|
-
const player1 = new MyGameState("<playerID>");
|
|
145
|
-
const player2 = new MyGameState("<playerID>");
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
Each instance has a shared API and defined set of state operations that make for predictable operability
|
|
149
|
-
|
|
150
|
-
This instances or robust models can also be used on your `Galena` instances
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
import { Galena, State } from "@figliolia/galena";
|
|
143
|
+
import { Galena } from "@figliolia/galena";
|
|
154
144
|
import { MyGameState } from "./MyGameState";
|
|
155
145
|
|
|
156
146
|
const MyAppState = new Galena({
|
|
157
|
-
navigation: new State({
|
|
158
|
-
currentScreen: "/",
|
|
159
|
-
navigationMenuOpen: false,
|
|
160
|
-
}),
|
|
161
147
|
player1: new MyGameState(),
|
|
162
148
|
player2: new MyGameState(),
|
|
163
149
|
});
|
|
164
150
|
|
|
165
151
|
// Operate
|
|
166
152
|
MyAppState.get("player1").incrementScore(100);
|
|
167
|
-
MyAppState.get("
|
|
153
|
+
MyAppState.get("player2").raiseLevel();
|
|
168
154
|
```
|
|
169
155
|
|
|
170
156
|
### Middleware
|
|
171
157
|
|
|
172
|
-
Middleware provides a developer API for building out
|
|
158
|
+
Middleware provides a developer API for building out custom tooling for your state.
|
|
159
|
+
|
|
160
|
+
Building middleware is as simple as extending `Galena`'s `Middleware` class and registering on your state.
|
|
173
161
|
|
|
174
|
-
|
|
162
|
+
Here's a quick example using the redux-like logger provided by this package:
|
|
175
163
|
|
|
176
164
|
```typescript
|
|
177
165
|
import { Middleware, type State } from "@figliolia/galena";
|
|
@@ -181,7 +169,7 @@ export class Logger<T = any> extends Middleware<T> {
|
|
|
181
169
|
|
|
182
170
|
override onBeforeUpdate(state: State<T>) {
|
|
183
171
|
// capture the previous state before an update takes place
|
|
184
|
-
this.previousState = state.
|
|
172
|
+
this.previousState = state.getState();
|
|
185
173
|
}
|
|
186
174
|
|
|
187
175
|
override onUpdate(state: State<T>) {
|
|
@@ -202,7 +190,7 @@ export class Logger<T = any> extends Middleware<T> {
|
|
|
202
190
|
console.log(
|
|
203
191
|
" %cNext State ",
|
|
204
192
|
"color: rgb(17, 118, 249); font-weight: bold",
|
|
205
|
-
state.
|
|
193
|
+
state.getState(),
|
|
206
194
|
);
|
|
207
195
|
}
|
|
208
196
|
|
|
@@ -232,7 +220,7 @@ const MyAppState = new Galena({
|
|
|
232
220
|
// state
|
|
233
221
|
}, new Logger(), new Profiler());
|
|
234
222
|
|
|
235
|
-
// To apply middleware to a single of `State`
|
|
223
|
+
// To apply middleware to a single piece of `State`
|
|
236
224
|
const MyState = new State(
|
|
237
225
|
/* reactive value */,
|
|
238
226
|
new Logger(),
|
package/dist/API.cjs
ADDED
package/dist/API.d.cts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Middleware } from "./Middleware.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/API.d.ts
|
|
4
|
+
declare abstract class API<T, E, M = T> {
|
|
5
|
+
readonly middleware: Middleware<M>[];
|
|
6
|
+
constructor(...middleware: Middleware<M>[]);
|
|
7
|
+
abstract getState(): T;
|
|
8
|
+
abstract subscribe(subscriber: (payload: E) => void): () => void;
|
|
9
|
+
abstract registerMiddleware(...middlewares: Middleware<M>[]): void;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { API };
|
|
13
|
+
//# sourceMappingURL=API.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"API.d.cts","names":[],"sources":["../src/API.ts"],"mappings":";;;uBAEsB,GAAA,WAAc,CAAA;EAAA,SAClB,UAAA,EAAY,UAAA,CAAW,CAAA;iBACxB,UAAA,EAAY,UAAA,CAAW,CAAA;EAAA,SAItB,QAAA,CAAA,GAAY,CAAA;EAAA,SACZ,SAAA,CAAU,UAAA,GAAa,OAAA,EAAS,CAAA;EAAA,SAChC,kBAAA,CAAA,GAAsB,WAAA,EAAa,UAAA,CAAW,CAAA;AAAA"}
|
package/dist/API.d.mts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Middleware } from "./Middleware.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/API.d.ts
|
|
4
|
+
declare abstract class API<T, E, M = T> {
|
|
5
|
+
readonly middleware: Middleware<M>[];
|
|
6
|
+
constructor(...middleware: Middleware<M>[]);
|
|
7
|
+
abstract getState(): T;
|
|
8
|
+
abstract subscribe(subscriber: (payload: E) => void): () => void;
|
|
9
|
+
abstract registerMiddleware(...middlewares: Middleware<M>[]): void;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { API };
|
|
13
|
+
//# sourceMappingURL=API.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"API.d.mts","names":[],"sources":["../src/API.ts"],"mappings":";;;uBAEsB,GAAA,WAAc,CAAA;EAAA,SAClB,UAAA,EAAY,UAAA,CAAW,CAAA;iBACxB,UAAA,EAAY,UAAA,CAAW,CAAA;EAAA,SAItB,QAAA,CAAA,GAAY,CAAA;EAAA,SACZ,SAAA,CAAU,UAAA,GAAa,OAAA,EAAS,CAAA;EAAA,SAChC,kBAAA,CAAA,GAAsB,WAAA,EAAa,UAAA,CAAW,CAAA;AAAA"}
|
package/dist/API.mjs
ADDED
package/dist/API.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"API.mjs","names":[],"sources":["../src/API.ts"],"sourcesContent":["import type { Middleware } from \"./Middleware\";\n\nexport abstract class API<T, E, M = T> {\n public readonly middleware: Middleware<M>[] = [];\n constructor(...middleware: Middleware<M>[]) {\n this.registerMiddleware(...middleware);\n }\n\n public abstract getState(): T;\n public abstract subscribe(subscriber: (payload: E) => void): () => void;\n public abstract registerMiddleware(...middlewares: Middleware<M>[]): void;\n}\n"],"mappings":";AAEA,IAAsB,MAAtB,MAAuC;CACrC,aAA8C,EAAE;CAChD,YAAY,GAAG,YAA6B;AAC1C,OAAK,mBAAmB,GAAG,WAAW"}
|
package/dist/Galena.cjs
CHANGED
|
@@ -1,45 +1,90 @@
|
|
|
1
|
+
const require_API = require("./API.cjs");
|
|
1
2
|
let _figliolia_event_emitter = require("@figliolia/event-emitter");
|
|
2
3
|
//#region src/Galena.ts
|
|
3
4
|
/**
|
|
4
|
-
* Galena
|
|
5
|
+
* ### Galena
|
|
5
6
|
*
|
|
6
|
-
* Galena
|
|
7
|
+
* Galena instances are designed to house one or more units of `State`
|
|
7
8
|
* and exist as a pseudo global application state.
|
|
8
9
|
*
|
|
9
10
|
* By design, each of its `State` units have isolated reactivity
|
|
10
11
|
* that prevents entire state trees from updating when a single
|
|
11
12
|
* unit changes.
|
|
12
13
|
*
|
|
13
|
-
* This is dissimilar to redux-like models where downstream reconciliations
|
|
14
|
-
* will propagate everwhere a given store is read from. In galena, downstream
|
|
15
|
-
* reconciliations occur only for consumers of the slice of state that
|
|
16
|
-
* changed - making it safer to use with more frequent state changes.
|
|
17
|
-
*
|
|
18
14
|
* ```typescript
|
|
19
15
|
* import { Galena } from "@figliolia/galena";
|
|
20
16
|
*
|
|
21
17
|
* const AppState = new Galena({
|
|
18
|
+
* user: new State("<user-stuff>"),
|
|
19
|
+
* business: new State("<business-logic-stuff>")
|
|
22
20
|
* // your reactive instances
|
|
23
21
|
* }, ...middleware);
|
|
24
22
|
*
|
|
25
23
|
* // to retreive and work with an individual unit
|
|
26
|
-
* const
|
|
24
|
+
* const userState = AppState.get("user"); // Returns State<T>
|
|
27
25
|
*
|
|
28
26
|
* // to run a callback anytime a unit of state changes
|
|
29
|
-
* const
|
|
27
|
+
* const listener = AppState.subscribe(({ state, updated }) => {
|
|
30
28
|
* // do something with the `State` instance that updated
|
|
29
|
+
* // the entirety of your state
|
|
31
30
|
* });
|
|
31
|
+
*
|
|
32
|
+
* // get the current application state
|
|
33
|
+
* const currentState = AppState.getState();
|
|
34
|
+
*
|
|
35
|
+
* // operate on an instance of state
|
|
36
|
+
* AppState.update("user", userState => ({
|
|
37
|
+
* ...userState,
|
|
38
|
+
* // your updates
|
|
39
|
+
* }));
|
|
32
40
|
* ```
|
|
33
41
|
*/
|
|
34
|
-
var Galena = class {
|
|
42
|
+
var Galena = class extends require_API.API {
|
|
35
43
|
Emitter = new _figliolia_event_emitter.EventEmitter();
|
|
36
44
|
constructor(state, ...middleware) {
|
|
45
|
+
super(...middleware);
|
|
37
46
|
this.state = state;
|
|
38
|
-
this.registerMiddleware(...middleware);
|
|
39
47
|
}
|
|
48
|
+
getState() {
|
|
49
|
+
const result = {};
|
|
50
|
+
for (const key in this.state) {
|
|
51
|
+
const state = key;
|
|
52
|
+
result[state] = this.state[key].getState();
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get
|
|
58
|
+
*
|
|
59
|
+
* Returns a connected State instance by key
|
|
60
|
+
*/
|
|
40
61
|
get(key) {
|
|
41
62
|
return this.state[key];
|
|
42
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Set
|
|
66
|
+
*
|
|
67
|
+
* Sets a connected State instance's state by key
|
|
68
|
+
*/
|
|
69
|
+
set(key, value) {
|
|
70
|
+
return this.get(key).set(value);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Update
|
|
74
|
+
*
|
|
75
|
+
* Invokes a connected State instance's update method key
|
|
76
|
+
*/
|
|
77
|
+
update(key, updater) {
|
|
78
|
+
return this.get(key).update(updater);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Subscribe
|
|
82
|
+
*
|
|
83
|
+
* Listen for changes on your Galena instnace. Your provided
|
|
84
|
+
* callback will be invoked each time an attached state instance
|
|
85
|
+
* changes. To your callback will be provided the `updated` state
|
|
86
|
+
* instance, along with the entire `state` tree
|
|
87
|
+
*/
|
|
43
88
|
subscribe = (subscriber) => {
|
|
44
89
|
const ID = this.Emitter.on("change", subscriber);
|
|
45
90
|
const unsubscribers = [];
|
|
@@ -56,6 +101,12 @@ var Galena = class {
|
|
|
56
101
|
while (unsubscribers.length) unsubscribers.pop?.()?.();
|
|
57
102
|
};
|
|
58
103
|
};
|
|
104
|
+
/**
|
|
105
|
+
* Register Middleware
|
|
106
|
+
*
|
|
107
|
+
* Adds middleware instances to each of the connected
|
|
108
|
+
* `State` instances
|
|
109
|
+
*/
|
|
59
110
|
registerMiddleware(...middlewares) {
|
|
60
111
|
for (const key in this.state) this.state[key]?.registerMiddleware?.(...middlewares);
|
|
61
112
|
}
|
|
@@ -64,34 +115,41 @@ var Galena = class {
|
|
|
64
115
|
}
|
|
65
116
|
};
|
|
66
117
|
/**
|
|
67
|
-
*
|
|
118
|
+
* ### createGalena
|
|
68
119
|
*
|
|
69
|
-
* Galena
|
|
120
|
+
* Galena instances are designed to house one or more units of `State`
|
|
70
121
|
* and exist as a pseudo global application state.
|
|
71
122
|
*
|
|
72
123
|
* By design, each of its `State` units have isolated reactivity
|
|
73
124
|
* that prevents entire state trees from updating when a single
|
|
74
125
|
* unit changes.
|
|
75
126
|
*
|
|
76
|
-
* This is dissimilar to redux-like models where downstream reconciliations
|
|
77
|
-
* will propagate everwhere a given store is read from. In galena, downstream
|
|
78
|
-
* reconciliations occur only for consumers of the slice of state that
|
|
79
|
-
* changed - making it safer to use with more frequent state changes.
|
|
80
|
-
*
|
|
81
127
|
* ```typescript
|
|
82
|
-
* import {
|
|
128
|
+
* import { Galena } from "@figliolia/galena";
|
|
83
129
|
*
|
|
84
|
-
* const AppState =
|
|
130
|
+
* const AppState = new Galena({
|
|
131
|
+
* user: new State("<user-stuff>"),
|
|
132
|
+
* business: new State("<business-logic-stuff>")
|
|
85
133
|
* // your reactive instances
|
|
86
134
|
* }, ...middleware);
|
|
87
135
|
*
|
|
88
136
|
* // to retreive and work with an individual unit
|
|
89
|
-
* const
|
|
137
|
+
* const userState = AppState.get("user"); // Returns State<T>
|
|
90
138
|
*
|
|
91
139
|
* // to run a callback anytime a unit of state changes
|
|
92
|
-
* const
|
|
140
|
+
* const listener = AppState.subscribe(({ state, updated }) => {
|
|
93
141
|
* // do something with the `State` instance that updated
|
|
142
|
+
* // the entirety of your state
|
|
94
143
|
* });
|
|
144
|
+
*
|
|
145
|
+
* // get the current application state
|
|
146
|
+
* const currentState = AppState.getState();
|
|
147
|
+
*
|
|
148
|
+
* // operate on an instance of state
|
|
149
|
+
* AppState.update("user", userState => ({
|
|
150
|
+
* ...userState,
|
|
151
|
+
* // your updates
|
|
152
|
+
* }));
|
|
95
153
|
* ```
|
|
96
154
|
*/
|
|
97
155
|
const createGalena = (...args) => {
|
package/dist/Galena.d.cts
CHANGED
|
@@ -1,77 +1,124 @@
|
|
|
1
|
-
import { AppSubscriber, StateTypes } from "./types.cjs";
|
|
1
|
+
import { AppSubscriber, GalenaSnapshot, GalenaState, Setter, StateType, StateTypes } from "./types.cjs";
|
|
2
2
|
import { State } from "./State.cjs";
|
|
3
3
|
import { Middleware } from "./Middleware.cjs";
|
|
4
|
+
import { API } from "./API.cjs";
|
|
4
5
|
|
|
5
6
|
//#region src/Galena.d.ts
|
|
6
7
|
/**
|
|
7
|
-
* Galena
|
|
8
|
+
* ### Galena
|
|
8
9
|
*
|
|
9
|
-
* Galena
|
|
10
|
+
* Galena instances are designed to house one or more units of `State`
|
|
10
11
|
* and exist as a pseudo global application state.
|
|
11
12
|
*
|
|
12
13
|
* By design, each of its `State` units have isolated reactivity
|
|
13
14
|
* that prevents entire state trees from updating when a single
|
|
14
15
|
* unit changes.
|
|
15
16
|
*
|
|
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
17
|
* ```typescript
|
|
22
18
|
* import { Galena } from "@figliolia/galena";
|
|
23
19
|
*
|
|
24
20
|
* const AppState = new Galena({
|
|
21
|
+
* user: new State("<user-stuff>"),
|
|
22
|
+
* business: new State("<business-logic-stuff>")
|
|
25
23
|
* // your reactive instances
|
|
26
24
|
* }, ...middleware);
|
|
27
25
|
*
|
|
28
26
|
* // to retreive and work with an individual unit
|
|
29
|
-
* const
|
|
27
|
+
* const userState = AppState.get("user"); // Returns State<T>
|
|
30
28
|
*
|
|
31
29
|
* // to run a callback anytime a unit of state changes
|
|
32
|
-
* const
|
|
30
|
+
* const listener = AppState.subscribe(({ state, updated }) => {
|
|
33
31
|
* // do something with the `State` instance that updated
|
|
32
|
+
* // the entirety of your state
|
|
34
33
|
* });
|
|
34
|
+
*
|
|
35
|
+
* // get the current application state
|
|
36
|
+
* const currentState = AppState.getState();
|
|
37
|
+
*
|
|
38
|
+
* // operate on an instance of state
|
|
39
|
+
* AppState.update("user", userState => ({
|
|
40
|
+
* ...userState,
|
|
41
|
+
* // your updates
|
|
42
|
+
* }));
|
|
35
43
|
* ```
|
|
36
44
|
*/
|
|
37
|
-
declare class Galena<T extends Record<string, State<any>>> {
|
|
45
|
+
declare class Galena<T extends Record<string, State<any>>> extends API<GalenaState<T>, GalenaSnapshot<T>, StateTypes<T>> {
|
|
38
46
|
readonly state: T;
|
|
39
47
|
private Emitter;
|
|
40
48
|
constructor(state: T, ...middleware: Middleware<StateTypes<T>>[]);
|
|
49
|
+
getState(): GalenaState<T>;
|
|
50
|
+
/**
|
|
51
|
+
* Get
|
|
52
|
+
*
|
|
53
|
+
* Returns a connected State instance by key
|
|
54
|
+
*/
|
|
41
55
|
get<K extends Extract<keyof T, string>>(key: K): T[K];
|
|
56
|
+
/**
|
|
57
|
+
* Set
|
|
58
|
+
*
|
|
59
|
+
* Sets a connected State instance's state by key
|
|
60
|
+
*/
|
|
61
|
+
set<K extends Extract<keyof T, string>>(key: K, value: StateType<T[K]>): void;
|
|
62
|
+
/**
|
|
63
|
+
* Update
|
|
64
|
+
*
|
|
65
|
+
* Invokes a connected State instance's update method key
|
|
66
|
+
*/
|
|
67
|
+
update<K extends Extract<keyof T, string>>(key: K, updater: Setter<StateType<T[K]>>): void;
|
|
68
|
+
/**
|
|
69
|
+
* Subscribe
|
|
70
|
+
*
|
|
71
|
+
* Listen for changes on your Galena instnace. Your provided
|
|
72
|
+
* callback will be invoked each time an attached state instance
|
|
73
|
+
* changes. To your callback will be provided the `updated` state
|
|
74
|
+
* instance, along with the entire `state` tree
|
|
75
|
+
*/
|
|
42
76
|
subscribe: (subscriber: AppSubscriber<T>) => () => void;
|
|
77
|
+
/**
|
|
78
|
+
* Register Middleware
|
|
79
|
+
*
|
|
80
|
+
* Adds middleware instances to each of the connected
|
|
81
|
+
* `State` instances
|
|
82
|
+
*/
|
|
43
83
|
registerMiddleware(...middlewares: Middleware<StateTypes<T>>[]): void;
|
|
44
84
|
private emit;
|
|
45
85
|
}
|
|
46
86
|
/**
|
|
47
|
-
*
|
|
87
|
+
* ### createGalena
|
|
48
88
|
*
|
|
49
|
-
* Galena
|
|
89
|
+
* Galena instances are designed to house one or more units of `State`
|
|
50
90
|
* and exist as a pseudo global application state.
|
|
51
91
|
*
|
|
52
92
|
* By design, each of its `State` units have isolated reactivity
|
|
53
93
|
* that prevents entire state trees from updating when a single
|
|
54
94
|
* unit changes.
|
|
55
95
|
*
|
|
56
|
-
* This is dissimilar to redux-like models where downstream reconciliations
|
|
57
|
-
* will propagate everwhere a given store is read from. In galena, downstream
|
|
58
|
-
* reconciliations occur only for consumers of the slice of state that
|
|
59
|
-
* changed - making it safer to use with more frequent state changes.
|
|
60
|
-
*
|
|
61
96
|
* ```typescript
|
|
62
|
-
* import {
|
|
97
|
+
* import { Galena } from "@figliolia/galena";
|
|
63
98
|
*
|
|
64
|
-
* const AppState =
|
|
99
|
+
* const AppState = new Galena({
|
|
100
|
+
* user: new State("<user-stuff>"),
|
|
101
|
+
* business: new State("<business-logic-stuff>")
|
|
65
102
|
* // your reactive instances
|
|
66
103
|
* }, ...middleware);
|
|
67
104
|
*
|
|
68
105
|
* // to retreive and work with an individual unit
|
|
69
|
-
* const
|
|
106
|
+
* const userState = AppState.get("user"); // Returns State<T>
|
|
70
107
|
*
|
|
71
108
|
* // to run a callback anytime a unit of state changes
|
|
72
|
-
* const
|
|
109
|
+
* const listener = AppState.subscribe(({ state, updated }) => {
|
|
73
110
|
* // do something with the `State` instance that updated
|
|
111
|
+
* // the entirety of your state
|
|
74
112
|
* });
|
|
113
|
+
*
|
|
114
|
+
* // get the current application state
|
|
115
|
+
* const currentState = AppState.getState();
|
|
116
|
+
*
|
|
117
|
+
* // operate on an instance of state
|
|
118
|
+
* AppState.update("user", userState => ({
|
|
119
|
+
* ...userState,
|
|
120
|
+
* // your updates
|
|
121
|
+
* }));
|
|
75
122
|
* ```
|
|
76
123
|
*/
|
|
77
124
|
declare const createGalena: <T extends Record<string, State<any>>>(...args: ConstructorParameters<typeof Galena<T>>) => Galena<T>;
|
package/dist/Galena.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Galena.d.cts","names":[],"sources":["../src/Galena.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Galena.d.cts","names":[],"sources":["../src/Galena.ts"],"mappings":";;;;;;;;AAmDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAAa,MAAA,WAAiB,MAAA,SAAe,KAAA,gBAAqB,GAAA,CAChE,WAAA,CAAY,CAAA,GACZ,cAAA,CAAe,CAAA,GACf,UAAA,CAAW,CAAA;EAAA,SAIO,KAAA,EAAO,CAAA;EAAA,QAFjB,OAAA;cAEU,KAAA,EAAO,CAAA,KACpB,UAAA,EAAY,UAAA,CAAW,UAAA,CAAW,CAAA;EAKhC,QAAA,CAAA,GAAQ,WAAA,CAAA,CAAA;EAbiD;;;;;EA2BzD,GAAA,WAAc,OAAA,OAAc,CAAA,UAAA,CAAY,GAAA,EAAK,CAAA,GAAC,CAAA,CAAA,CAAA;EA3BW;;;;;EAoCzD,GAAA,WAAc,OAAA,OAAc,CAAA,UAAA,CACjC,GAAA,EAAK,CAAA,EACL,KAAA,EAAO,SAAA,CAAU,CAAA,CAAE,CAAA;EAnCV;;;;;EA6CJ,MAAA,WAAiB,OAAA,OAAc,CAAA,UAAA,CACpC,GAAA,EAAK,CAAA,EACL,OAAA,EAAS,MAAA,CAAO,SAAA,CAAU,CAAA,CAAE,CAAA;EA3CZ;;;;;;;;EAwDX,SAAA,GAAa,UAAA,EAAY,aAAA,CAAc,CAAA;EApCnC;;;;;;EAgEJ,kBAAA,CAAA,GAAsB,WAAA,EAAa,UAAA,CAAW,UAAA,CAAW,CAAA;EAAA,QAMxD,IAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CV;;;;;;;cAAa,YAAA,aAA0B,MAAA,SAAe,KAAA,WACjD,IAAA,EAAM,qBAAA,QAA6B,MAAA,CAAO,CAAA,OAAG,MAAA,CAAA,CAAA"}
|