@figliolia/galena 3.0.3 → 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.
Files changed (47) hide show
  1. package/README.md +21 -33
  2. package/dist/API.cjs +9 -0
  3. package/dist/API.d.cts +13 -0
  4. package/dist/API.d.cts.map +1 -0
  5. package/dist/API.d.mts +13 -0
  6. package/dist/API.d.mts.map +1 -0
  7. package/dist/API.mjs +11 -0
  8. package/dist/API.mjs.map +1 -0
  9. package/dist/Galena.cjs +31 -4
  10. package/dist/Galena.d.cts +24 -4
  11. package/dist/Galena.d.cts.map +1 -1
  12. package/dist/Galena.d.mts +24 -4
  13. package/dist/Galena.d.mts.map +1 -1
  14. package/dist/Galena.mjs +31 -4
  15. package/dist/Galena.mjs.map +1 -1
  16. package/dist/Logger.cjs +2 -2
  17. package/dist/Logger.mjs +2 -2
  18. package/dist/Logger.mjs.map +1 -1
  19. package/dist/Middleware.cjs +2 -2
  20. package/dist/Middleware.d.cts +2 -2
  21. package/dist/Middleware.d.mts +2 -2
  22. package/dist/Middleware.mjs +2 -2
  23. package/dist/Middleware.mjs.map +1 -1
  24. package/dist/Profiler.cjs +2 -2
  25. package/dist/Profiler.mjs +2 -2
  26. package/dist/Profiler.mjs.map +1 -1
  27. package/dist/State.cjs +12 -8
  28. package/dist/State.d.cts +11 -7
  29. package/dist/State.d.cts.map +1 -1
  30. package/dist/State.d.mts +11 -7
  31. package/dist/State.d.mts.map +1 -1
  32. package/dist/State.mjs +12 -8
  33. package/dist/State.mjs.map +1 -1
  34. package/dist/index.d.cts +2 -2
  35. package/dist/index.d.mts +2 -2
  36. package/dist/types.d.cts +3 -2
  37. package/dist/types.d.cts.map +1 -1
  38. package/dist/types.d.mts +3 -2
  39. package/dist/types.d.mts.map +1 -1
  40. package/package.json +8 -8
  41. package/src/API.ts +12 -0
  42. package/src/Galena.ts +37 -4
  43. package/src/Logger.ts +2 -2
  44. package/src/Middleware.ts +2 -2
  45. package/src/Profiler.ts +2 -2
  46. package/src/State.ts +12 -8
  47. package/src/types.ts +5 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Profiler.mjs","names":[],"sources":["../src/Profiler.ts"],"sourcesContent":["import { Middleware } from \"./Middleware\";\nimport type { State } from \"./State\";\n\n/**\n * Profiler\n *\n * A logger for state transitions exceeding a given\n * millisecond threshold\n *\n * ```typescript\n * const AppState = new Galena({}, new Profiler());\n * // or\n * AppState.registerMiddlerware(new Profiler());\n * // or\n * const MyState = new State(4, new Profiler());\n * // or\n * MyState.registerMiddleware(new Profiler());\n * ```\n */\nexport class Profiler<T = any> extends Middleware<T> {\n private previousState: T | null = null;\n private startTime: null | number = null;\n constructor(public readonly threshold = 16) {\n super();\n }\n\n public override onBeforeUpdate(state: State<T>) {\n this.startTime = performance.now();\n this.previousState = state.getSnapshot();\n }\n\n public override onUpdate(state: State<T>) {\n if (this.startTime === null) {\n return;\n }\n const diff = performance.now() - this.startTime;\n if (diff >= this.threshold) {\n console.warn(\n `A slow state transition of ${diff.toFixed(1)}ms was detected when transitioning the following piece of state`,\n );\n console.log(\n \" %cPrevious State\",\n \"color: #26ad65; font-weight: bold\",\n this.previousState,\n );\n console.log(\n \" %cCurrent State \",\n \"color: rgb(17, 118, 249); font-weight: bold\",\n state.getSnapshot(),\n );\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAmBA,IAAa,WAAb,cAAuC,WAAc;CACnD,gBAAkC;CAClC,YAAmC;CACnC,YAAY,YAA4B,IAAI;AAC1C,SAAO;AADmB,OAAA,YAAA;;CAI5B,eAA+B,OAAiB;AAC9C,OAAK,YAAY,YAAY,KAAK;AAClC,OAAK,gBAAgB,MAAM,aAAa;;CAG1C,SAAyB,OAAiB;AACxC,MAAI,KAAK,cAAc,KACrB;EAEF,MAAM,OAAO,YAAY,KAAK,GAAG,KAAK;AACtC,MAAI,QAAQ,KAAK,WAAW;AAC1B,WAAQ,KACN,8BAA8B,KAAK,QAAQ,EAAE,CAAC,iEAC/C;AACD,WAAQ,IACN,uBACA,qCACA,KAAK,cACN;AACD,WAAQ,IACN,0BACA,+CACA,MAAM,aAAa,CACpB"}
1
+ {"version":3,"file":"Profiler.mjs","names":[],"sources":["../src/Profiler.ts"],"sourcesContent":["import { Middleware } from \"./Middleware\";\nimport type { State } from \"./State\";\n\n/**\n * Profiler\n *\n * A logger for state transitions exceeding a given\n * millisecond threshold\n *\n * ```typescript\n * const AppState = new Galena({}, new Profiler());\n * // or\n * AppState.registerMiddlerware(new Profiler());\n * // or\n * const MyState = new State(4, new Profiler());\n * // or\n * MyState.registerMiddleware(new Profiler());\n * ```\n */\nexport class Profiler<T = any> extends Middleware<T> {\n private previousState: T | null = null;\n private startTime: null | number = null;\n constructor(public readonly threshold = 16) {\n super();\n }\n\n public override onBeforeUpdate(state: State<T>) {\n this.startTime = performance.now();\n this.previousState = state.getState();\n }\n\n public override onUpdate(state: State<T>) {\n if (this.startTime === null) {\n return;\n }\n const diff = performance.now() - this.startTime;\n if (diff >= this.threshold) {\n console.warn(\n `A slow state transition of ${diff.toFixed(1)}ms was detected when transitioning the following piece of state`,\n );\n console.log(\n \" %cPrevious State\",\n \"color: #26ad65; font-weight: bold\",\n this.previousState,\n );\n console.log(\n \" %cCurrent State \",\n \"color: rgb(17, 118, 249); font-weight: bold\",\n state.getState(),\n );\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAmBA,IAAa,WAAb,cAAuC,WAAc;CACnD,gBAAkC;CAClC,YAAmC;CACnC,YAAY,YAA4B,IAAI;AAC1C,SAAO;AADmB,OAAA,YAAA;;CAI5B,eAA+B,OAAiB;AAC9C,OAAK,YAAY,YAAY,KAAK;AAClC,OAAK,gBAAgB,MAAM,UAAU;;CAGvC,SAAyB,OAAiB;AACxC,MAAI,KAAK,cAAc,KACrB;EAEF,MAAM,OAAO,YAAY,KAAK,GAAG,KAAK;AACtC,MAAI,QAAQ,KAAK,WAAW;AAC1B,WAAQ,KACN,8BAA8B,KAAK,QAAQ,EAAE,CAAC,iEAC/C;AACD,WAAQ,IACN,uBACA,qCACA,KAAK,cACN;AACD,WAAQ,IACN,0BACA,+CACA,MAAM,UAAU,CACjB"}
package/dist/State.cjs CHANGED
@@ -1,3 +1,4 @@
1
+ const require_API = require("./API.cjs");
1
2
  let _figliolia_event_emitter = require("@figliolia/event-emitter");
2
3
  //#region src/State.ts
3
4
  /**
@@ -7,11 +8,11 @@ let _figliolia_event_emitter = require("@figliolia/event-emitter");
7
8
  * as isolated instances or be part of your global app
8
9
  * state (via `Galena` instances).
9
10
  *
10
- * There are three ways to create state instances
11
+ * There are two ways to create state instances
11
12
  *
12
13
  * ```typescript
13
14
  * import { State, createState, Profiler } from "@figliolia/galena";
14
- * // for island states that can be shared between react components
15
+
15
16
  * const myState = new State("<any value>", ...middleware);
16
17
  * // or
17
18
  * const myState = createState("<any value>", ...middleware);
@@ -21,16 +22,17 @@ let _figliolia_event_emitter = require("@figliolia/event-emitter");
21
22
  * myState.subscribe(nextValue => {});
22
23
  * myState.registerMiddleware(new Profiler());
23
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();
24
27
  * ```
25
28
  */
26
- var State = class {
29
+ var State = class extends require_API.API {
27
30
  state;
28
- middleware = [];
29
31
  Emitter = new _figliolia_event_emitter.EventEmitter();
30
32
  constructor(initialState, ...middleware) {
33
+ super(...middleware);
31
34
  this.initialState = initialState;
32
35
  this.state = initialState;
33
- this.registerMiddleware(...middleware);
34
36
  }
35
37
  /**
36
38
  * Set
@@ -63,7 +65,7 @@ var State = class {
63
65
  * Returns the current state. Designed for compatibility with
64
66
  * `useSyncExternalStore`
65
67
  */
66
- getSnapshot = () => {
68
+ getState = () => {
67
69
  return this.state;
68
70
  };
69
71
  /**
@@ -118,11 +120,11 @@ var State = class {
118
120
  * as isolated instances or be part of your global app
119
121
  * state (via `Galena` instances).
120
122
  *
121
- * There are three ways to create state instances
123
+ * There are two ways to create state instances
122
124
  *
123
125
  * ```typescript
124
126
  * import { State, createState, Profiler } from "@figliolia/galena";
125
- * // for island states that can be shared between react components
127
+
126
128
  * const myState = new State("<any value>", ...middleware);
127
129
  * // or
128
130
  * const myState = createState("<any value>", ...middleware);
@@ -132,6 +134,8 @@ var State = class {
132
134
  * myState.subscribe(nextValue => {});
133
135
  * myState.registerMiddleware(new Profiler());
134
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();
135
139
  * ```
136
140
  */
137
141
  function createState(...args) {
package/dist/State.d.cts CHANGED
@@ -1,5 +1,6 @@
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
  /**
@@ -9,11 +10,11 @@ import { Middleware } from "./Middleware.cjs";
9
10
  * as isolated instances or be part of your global app
10
11
  * state (via `Galena` instances).
11
12
  *
12
- * There are three ways to create state instances
13
+ * There are two ways to create state instances
13
14
  *
14
15
  * ```typescript
15
16
  * import { State, createState, Profiler } from "@figliolia/galena";
16
- * // for island states that can be shared between react components
17
+
17
18
  * const myState = new State("<any value>", ...middleware);
18
19
  * // or
19
20
  * const myState = createState("<any value>", ...middleware);
@@ -23,12 +24,13 @@ import { Middleware } from "./Middleware.cjs";
23
24
  * myState.subscribe(nextValue => {});
24
25
  * myState.registerMiddleware(new Profiler());
25
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();
26
29
  * ```
27
30
  */
28
- declare class State<T> {
31
+ declare class State<T> extends API<T, NonFunction<T>> {
29
32
  readonly initialState: NonFunction<T>;
30
33
  private state;
31
- readonly middleware: Middleware<T>[];
32
34
  private readonly Emitter;
33
35
  constructor(initialState: NonFunction<T>, ...middleware: Middleware<T>[]);
34
36
  /**
@@ -59,7 +61,7 @@ declare class State<T> {
59
61
  * Returns the current state. Designed for compatibility with
60
62
  * `useSyncExternalStore`
61
63
  */
62
- readonly getSnapshot: () => NonFunction<T>;
64
+ readonly getState: () => NonFunction<T>;
63
65
  /**
64
66
  * Subscribe
65
67
  *
@@ -87,11 +89,11 @@ declare class State<T> {
87
89
  * as isolated instances or be part of your global app
88
90
  * state (via `Galena` instances).
89
91
  *
90
- * There are three ways to create state instances
92
+ * There are two ways to create state instances
91
93
  *
92
94
  * ```typescript
93
95
  * import { State, createState, Profiler } from "@figliolia/galena";
94
- * // for island states that can be shared between react components
96
+
95
97
  * const myState = new State("<any value>", ...middleware);
96
98
  * // or
97
99
  * const myState = createState("<any value>", ...middleware);
@@ -101,6 +103,8 @@ declare class State<T> {
101
103
  * myState.subscribe(nextValue => {});
102
104
  * myState.registerMiddleware(new Profiler());
103
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();
104
108
  * ```
105
109
  */
106
110
  declare function createState<T>(...args: ConstructorParameters<typeof State<T>>): State<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"State.d.cts","names":[],"sources":["../src/State.ts"],"mappings":";;;;;;AA2BA;;;;;;;;;;;;;;;;;;;;;cAAa,KAAA;EAAA,SAKO,YAAA,EAAc,WAAA,CAAY,CAAA;EAAA,QAJpC,KAAA;EAAA,SACQ,UAAA,EAAY,UAAA,CAAW,CAAA;EAAA,iBACtB,OAAA;cAEC,YAAA,EAAc,WAAA,CAAY,CAAA,MACvC,UAAA,EAAY,UAAA,CAAW,CAAA;EANX;;;;;;EAAA,SAkBD,GAAA,GAAG,KAAA,EAAA,WAAA,CAAA,CAAA;EAhBoB;;;;;;;EAAA,SAyBvB,MAAA,GAAM,MAAA,EAAA,MAAA,CAAA,CAAA;EArBM;;;;;;EAAA,SAkCZ,KAAA;EAbM;;;;;;EAAA,SAqBN,WAAA,QAAW,WAAA,CAAA,CAAA;EAUM;;;;;;EAAA,SAAjB,SAAA,GAAa,EAAA,EAAI,UAAA,CAAW,CAAA;EAkBpC;;;;;;;EAJD,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;;;;;;;;;;;;;;;;;;;;;;;;iBA8BM,WAAA,GAAA,CAAA,GACX,IAAA,EAAM,qBAAA,QAA6B,KAAA,CAAM,CAAA,KAAG,KAAA,CAAA,CAAA"}
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,5 +1,6 @@
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
  /**
@@ -9,11 +10,11 @@ import { Middleware } from "./Middleware.mjs";
9
10
  * as isolated instances or be part of your global app
10
11
  * state (via `Galena` instances).
11
12
  *
12
- * There are three ways to create state instances
13
+ * There are two ways to create state instances
13
14
  *
14
15
  * ```typescript
15
16
  * import { State, createState, Profiler } from "@figliolia/galena";
16
- * // for island states that can be shared between react components
17
+
17
18
  * const myState = new State("<any value>", ...middleware);
18
19
  * // or
19
20
  * const myState = createState("<any value>", ...middleware);
@@ -23,12 +24,13 @@ import { Middleware } from "./Middleware.mjs";
23
24
  * myState.subscribe(nextValue => {});
24
25
  * myState.registerMiddleware(new Profiler());
25
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();
26
29
  * ```
27
30
  */
28
- declare class State<T> {
31
+ declare class State<T> extends API<T, NonFunction<T>> {
29
32
  readonly initialState: NonFunction<T>;
30
33
  private state;
31
- readonly middleware: Middleware<T>[];
32
34
  private readonly Emitter;
33
35
  constructor(initialState: NonFunction<T>, ...middleware: Middleware<T>[]);
34
36
  /**
@@ -59,7 +61,7 @@ declare class State<T> {
59
61
  * Returns the current state. Designed for compatibility with
60
62
  * `useSyncExternalStore`
61
63
  */
62
- readonly getSnapshot: () => NonFunction<T>;
64
+ readonly getState: () => NonFunction<T>;
63
65
  /**
64
66
  * Subscribe
65
67
  *
@@ -87,11 +89,11 @@ declare class State<T> {
87
89
  * as isolated instances or be part of your global app
88
90
  * state (via `Galena` instances).
89
91
  *
90
- * There are three ways to create state instances
92
+ * There are two ways to create state instances
91
93
  *
92
94
  * ```typescript
93
95
  * import { State, createState, Profiler } from "@figliolia/galena";
94
- * // for island states that can be shared between react components
96
+
95
97
  * const myState = new State("<any value>", ...middleware);
96
98
  * // or
97
99
  * const myState = createState("<any value>", ...middleware);
@@ -101,6 +103,8 @@ declare class State<T> {
101
103
  * myState.subscribe(nextValue => {});
102
104
  * myState.registerMiddleware(new Profiler());
103
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();
104
108
  * ```
105
109
  */
106
110
  declare function createState<T>(...args: ConstructorParameters<typeof State<T>>): State<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"State.d.mts","names":[],"sources":["../src/State.ts"],"mappings":";;;;;;AA2BA;;;;;;;;;;;;;;;;;;;;;cAAa,KAAA;EAAA,SAKO,YAAA,EAAc,WAAA,CAAY,CAAA;EAAA,QAJpC,KAAA;EAAA,SACQ,UAAA,EAAY,UAAA,CAAW,CAAA;EAAA,iBACtB,OAAA;cAEC,YAAA,EAAc,WAAA,CAAY,CAAA,MACvC,UAAA,EAAY,UAAA,CAAW,CAAA;EANX;;;;;;EAAA,SAkBD,GAAA,GAAG,KAAA,EAAA,WAAA,CAAA,CAAA;EAhBoB;;;;;;;EAAA,SAyBvB,MAAA,GAAM,MAAA,EAAA,MAAA,CAAA,CAAA;EArBM;;;;;;EAAA,SAkCZ,KAAA;EAbM;;;;;;EAAA,SAqBN,WAAA,QAAW,WAAA,CAAA,CAAA;EAUM;;;;;;EAAA,SAAjB,SAAA,GAAa,EAAA,EAAI,UAAA,CAAW,CAAA;EAkBpC;;;;;;;EAJD,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;;;;;;;;;;;;;;;;;;;;;;;;iBA8BM,WAAA,GAAA,CAAA,GACX,IAAA,EAAM,qBAAA,QAA6B,KAAA,CAAM,CAAA,KAAG,KAAA,CAAA,CAAA"}
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,3 +1,4 @@
1
+ import { API } from "./API.mjs";
1
2
  import { EventEmitter } from "@figliolia/event-emitter";
2
3
  //#region src/State.ts
3
4
  /**
@@ -7,11 +8,11 @@ import { EventEmitter } from "@figliolia/event-emitter";
7
8
  * as isolated instances or be part of your global app
8
9
  * state (via `Galena` instances).
9
10
  *
10
- * There are three ways to create state instances
11
+ * There are two ways to create state instances
11
12
  *
12
13
  * ```typescript
13
14
  * import { State, createState, Profiler } from "@figliolia/galena";
14
- * // for island states that can be shared between react components
15
+
15
16
  * const myState = new State("<any value>", ...middleware);
16
17
  * // or
17
18
  * const myState = createState("<any value>", ...middleware);
@@ -21,16 +22,17 @@ import { EventEmitter } from "@figliolia/event-emitter";
21
22
  * myState.subscribe(nextValue => {});
22
23
  * myState.registerMiddleware(new Profiler());
23
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();
24
27
  * ```
25
28
  */
26
- var State = class {
29
+ var State = class extends API {
27
30
  state;
28
- middleware = [];
29
31
  Emitter = new EventEmitter();
30
32
  constructor(initialState, ...middleware) {
33
+ super(...middleware);
31
34
  this.initialState = initialState;
32
35
  this.state = initialState;
33
- this.registerMiddleware(...middleware);
34
36
  }
35
37
  /**
36
38
  * Set
@@ -63,7 +65,7 @@ var State = class {
63
65
  * Returns the current state. Designed for compatibility with
64
66
  * `useSyncExternalStore`
65
67
  */
66
- getSnapshot = () => {
68
+ getState = () => {
67
69
  return this.state;
68
70
  };
69
71
  /**
@@ -118,11 +120,11 @@ var State = class {
118
120
  * as isolated instances or be part of your global app
119
121
  * state (via `Galena` instances).
120
122
  *
121
- * There are three ways to create state instances
123
+ * There are two ways to create state instances
122
124
  *
123
125
  * ```typescript
124
126
  * import { State, createState, Profiler } from "@figliolia/galena";
125
- * // for island states that can be shared between react components
127
+
126
128
  * const myState = new State("<any value>", ...middleware);
127
129
  * // or
128
130
  * const myState = createState("<any value>", ...middleware);
@@ -132,6 +134,8 @@ var State = class {
132
134
  * myState.subscribe(nextValue => {});
133
135
  * myState.registerMiddleware(new Profiler());
134
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();
135
139
  * ```
136
140
  */
137
141
  function createState(...args) {
@@ -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 three ways to create state instances\n *\n * ```typescript\n * import { State, createState, Profiler } from \"@figliolia/galena\";\n * // for island states that can be shared between react components\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 * ```\n */\nexport class State<T> {\n private state: NonFunction<T>;\n public readonly middleware: Middleware<T>[] = [];\n private readonly Emitter = new EventEmitter<{ change: NonFunction<T> }>();\n constructor(\n public readonly initialState: NonFunction<T>,\n ...middleware: Middleware<T>[]\n ) {\n this.state = initialState;\n this.registerMiddleware(...middleware);\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 getSnapshot = () => {\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 three ways to create state instances\n *\n * ```typescript\n * import { State, createState, Profiler } from \"@figliolia/galena\";\n * // for island states that can be shared between react components\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 * ```\n */\nexport function createState<T>(\n ...args: ConstructorParameters<typeof State<T>>\n) {\n return new State<T>(...args);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,IAAa,QAAb,MAAsB;CACpB;CACA,aAA8C,EAAE;CAChD,UAA2B,IAAI,cAA0C;CACzE,YACE,cACA,GAAG,YACH;AAFgB,OAAA,eAAA;AAGhB,OAAK,QAAQ;AACb,OAAK,mBAAmB,GAAG,WAAW;;;;;;;;CASxC,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,oBAAoC;AAClC,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;;;;;;;;;;;;;;;;;;;;;;;;;;AA4B1B,SAAgB,YACd,GAAG,MACH;AACA,QAAO,IAAI,MAAS,GAAG,KAAK"}
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, StateType, 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, StateType, 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, StateType, 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, StateType, 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
@@ -11,7 +11,8 @@ interface GalenaSnapshot<T extends Record<string, State<any>>, K extends Extract
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
13
  type StateTypes<T extends Record<string, State<any>>> = ReturnType<StateType<T[keyof T]>>;
14
- type StateType<T extends State<any>> = ReturnType<T["getSnapshot"]>;
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]> };
15
16
  //#endregion
16
- export { AppSubscriber, GalenaSnapshot, NonFunction, PartialSupport, Setter, StateType, StateTypes, Subscriber };
17
+ export { AppSubscriber, GalenaSnapshot, GalenaState, NonFunction, PartialSupport, Setter, StateType, StateTypes, Subscriber };
17
18
  //# sourceMappingURL=types.d.cts.map
@@ -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,SAAA,CAAU,CAAA,OAAQ,CAAA;AAAA,KAGR,SAAA,WAAoB,KAAA,SAAc,UAAA,CAAW,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
@@ -11,7 +11,8 @@ interface GalenaSnapshot<T extends Record<string, State<any>>, K extends Extract
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
13
  type StateTypes<T extends Record<string, State<any>>> = ReturnType<StateType<T[keyof T]>>;
14
- type StateType<T extends State<any>> = ReturnType<T["getSnapshot"]>;
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]> };
15
16
  //#endregion
16
- export { AppSubscriber, GalenaSnapshot, NonFunction, PartialSupport, Setter, StateType, StateTypes, Subscriber };
17
+ export { AppSubscriber, GalenaSnapshot, GalenaState, NonFunction, PartialSupport, Setter, StateType, StateTypes, Subscriber };
17
18
  //# sourceMappingURL=types.d.mts.map
@@ -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,SAAA,CAAU,CAAA,OAAQ,CAAA;AAAA,KAGR,SAAA,WAAoB,KAAA,SAAc,UAAA,CAAW,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.0.3",
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,9 +1,11 @@
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
5
  import type {
5
6
  AppSubscriber,
6
7
  GalenaSnapshot,
8
+ GalenaState,
7
9
  Setter,
8
10
  StateType,
9
11
  StateTypes,
@@ -29,22 +31,44 @@ import type {
29
31
  * }, ...middleware);
30
32
  *
31
33
  * // to retreive and work with an individual unit
32
- * const myUnit = AppState.get("<key>"); // Returns State<T>
34
+ * const userState = AppState.get("user"); // Returns State<T>
33
35
  *
34
36
  * // to run a callback anytime a unit of state changes
35
37
  * const listener = AppState.subscribe(({ state, updated }) => {
36
38
  * // do something with the `State` instance that updated
37
39
  * // the entirety of your state
38
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
+ * }));
39
50
  * ```
40
51
  */
41
- 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
+ > {
42
57
  private Emitter = new EventEmitter<{ change: GalenaSnapshot<T> }>();
43
58
  constructor(
44
59
  public readonly state: T,
45
60
  ...middleware: Middleware<StateTypes<T>>[]
46
61
  ) {
47
- this.registerMiddleware(...middleware);
62
+ super(...middleware);
63
+ }
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;
48
72
  }
49
73
 
50
74
  /**
@@ -149,13 +173,22 @@ export class Galena<T extends Record<string, State<any>>> {
149
173
  * }, ...middleware);
150
174
  *
151
175
  * // to retreive and work with an individual unit
152
- * const myUnit = AppState.get("<key>"); // Returns State<T>
176
+ * const userState = AppState.get("user"); // Returns State<T>
153
177
  *
154
178
  * // to run a callback anytime a unit of state changes
155
179
  * const listener = AppState.subscribe(({ state, updated }) => {
156
180
  * // do something with the `State` instance that updated
157
181
  * // the entirety of your state
158
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
+ * }));
159
192
  * ```
160
193
  */
161
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.getSnapshot();
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.getSnapshot(),
43
+ state.getState(),
44
44
  );
45
45
  }
46
46
 
package/src/Middleware.ts CHANGED
@@ -19,7 +19,7 @@ import type { State } from "./State";
19
19
  *
20
20
  * public override onBeforeUpdate(state: State<T>) {
21
21
  * this.startTime = performance.now();
22
- * this.previousState = state.getSnapshot();
22
+ * this.previousState = state.getState();
23
23
  * }
24
24
  *
25
25
  * public override onUpdate(state: T) {
@@ -27,7 +27,7 @@ import type { State } from "./State";
27
27
  * if(diff >= this.threshold) {
28
28
  * console.warn(`A slow state transition was detected when transitioning the following piece of state`);
29
29
  * console.log('Previous state', this.previousState);
30
- * console.log('Current state', state.getSnapshot());
30
+ * console.log('Current state', state.getState());
31
31
  * }
32
32
  * }
33
33
  * }
package/src/Profiler.ts CHANGED
@@ -26,7 +26,7 @@ export class Profiler<T = any> extends Middleware<T> {
26
26
 
27
27
  public override onBeforeUpdate(state: State<T>) {
28
28
  this.startTime = performance.now();
29
- this.previousState = state.getSnapshot();
29
+ this.previousState = state.getState();
30
30
  }
31
31
 
32
32
  public override onUpdate(state: State<T>) {
@@ -46,7 +46,7 @@ export class Profiler<T = any> extends Middleware<T> {
46
46
  console.log(
47
47
  " %cCurrent State ",
48
48
  "color: rgb(17, 118, 249); font-weight: bold",
49
- state.getSnapshot(),
49
+ state.getState(),
50
50
  );
51
51
  }
52
52
  }