@figliolia/galena 2.3.5 → 3.0.1

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 (106) hide show
  1. package/README.md +172 -476
  2. package/dist/Galena.cjs +102 -0
  3. package/dist/Galena.d.cts +80 -0
  4. package/dist/Galena.d.cts.map +1 -0
  5. package/dist/Galena.d.mts +80 -0
  6. package/dist/Galena.d.mts.map +1 -0
  7. package/dist/Galena.mjs +103 -0
  8. package/dist/Galena.mjs.map +1 -0
  9. package/dist/Logger.cjs +46 -0
  10. package/dist/Logger.d.cts +35 -0
  11. package/dist/Logger.d.cts.map +1 -0
  12. package/dist/Logger.d.mts +35 -0
  13. package/dist/Logger.d.mts.map +1 -0
  14. package/dist/Logger.mjs +48 -0
  15. package/dist/Logger.mjs.map +1 -0
  16. package/dist/Middleware.cjs +62 -0
  17. package/dist/Middleware.d.cts +65 -0
  18. package/dist/Middleware.d.cts.map +1 -0
  19. package/dist/Middleware.d.mts +65 -0
  20. package/dist/Middleware.d.mts.map +1 -0
  21. package/dist/Middleware.mjs +64 -0
  22. package/dist/Middleware.mjs.map +1 -0
  23. package/dist/Profiler.cjs +41 -0
  24. package/dist/Profiler.d.cts +31 -0
  25. package/dist/Profiler.d.cts.map +1 -0
  26. package/dist/Profiler.d.mts +31 -0
  27. package/dist/Profiler.d.mts.map +1 -0
  28. package/dist/Profiler.mjs +43 -0
  29. package/dist/Profiler.mjs.map +1 -0
  30. package/dist/State.cjs +147 -0
  31. package/dist/State.d.cts +114 -0
  32. package/dist/State.d.cts.map +1 -0
  33. package/dist/State.d.mts +114 -0
  34. package/dist/State.d.mts.map +1 -0
  35. package/dist/State.mjs +148 -0
  36. package/dist/State.mjs.map +1 -0
  37. package/dist/index.cjs +13 -0
  38. package/dist/index.d.cts +7 -0
  39. package/dist/index.d.mts +7 -0
  40. package/dist/index.mjs +6 -0
  41. package/dist/types.d.cts +16 -0
  42. package/dist/types.d.cts.map +1 -0
  43. package/dist/types.d.mts +16 -0
  44. package/dist/types.d.mts.map +1 -0
  45. package/media/Logging.png +0 -0
  46. package/media/Profiling.png +0 -0
  47. package/package.json +38 -59
  48. package/src/Galena.ts +120 -0
  49. package/src/{Middlewares/Logger.ts → Logger.ts} +15 -14
  50. package/src/Middleware.ts +62 -0
  51. package/src/Profiler.ts +53 -0
  52. package/src/State.ts +167 -0
  53. package/src/index.ts +6 -3
  54. package/src/types.ts +28 -0
  55. package/dist/cjs/Galena/Galena.js +0 -223
  56. package/dist/cjs/Galena/Guards.js +0 -40
  57. package/dist/cjs/Galena/Scheduler.js +0 -84
  58. package/dist/cjs/Galena/State.js +0 -314
  59. package/dist/cjs/Galena/index.js +0 -22
  60. package/dist/cjs/Galena/types.js +0 -9
  61. package/dist/cjs/Middleware/Middleware.js +0 -46
  62. package/dist/cjs/Middleware/index.js +0 -20
  63. package/dist/cjs/Middleware/types.js +0 -8
  64. package/dist/cjs/Middlewares/Logger.js +0 -51
  65. package/dist/cjs/Middlewares/Profiler.js +0 -38
  66. package/dist/cjs/Middlewares/index.js +0 -7
  67. package/dist/cjs/index.js +0 -19
  68. package/dist/cjs/package.json +0 -3
  69. package/dist/mjs/Galena/Galena.js +0 -218
  70. package/dist/mjs/Galena/Guards.js +0 -36
  71. package/dist/mjs/Galena/Scheduler.js +0 -79
  72. package/dist/mjs/Galena/State.js +0 -313
  73. package/dist/mjs/Galena/index.js +0 -3
  74. package/dist/mjs/Galena/types.js +0 -6
  75. package/dist/mjs/Middleware/Middleware.js +0 -42
  76. package/dist/mjs/Middleware/index.js +0 -2
  77. package/dist/mjs/Middleware/types.js +0 -5
  78. package/dist/mjs/Middlewares/Logger.js +0 -44
  79. package/dist/mjs/Middlewares/Profiler.js +0 -35
  80. package/dist/mjs/Middlewares/index.js +0 -2
  81. package/dist/mjs/index.js +0 -3
  82. package/dist/mjs/package.json +0 -4
  83. package/dist/types/Galena/Galena.d.ts +0 -160
  84. package/dist/types/Galena/Guards.d.ts +0 -29
  85. package/dist/types/Galena/Scheduler.d.ts +0 -51
  86. package/dist/types/Galena/State.d.ts +0 -235
  87. package/dist/types/Galena/index.d.ts +0 -3
  88. package/dist/types/Galena/types.d.ts +0 -13
  89. package/dist/types/Middleware/Middleware.d.ts +0 -43
  90. package/dist/types/Middleware/index.d.ts +0 -2
  91. package/dist/types/Middleware/types.d.ts +0 -4
  92. package/dist/types/Middlewares/Logger.d.ts +0 -27
  93. package/dist/types/Middlewares/Profiler.d.ts +0 -22
  94. package/dist/types/Middlewares/index.d.ts +0 -2
  95. package/dist/types/index.d.ts +0 -3
  96. package/src/Galena/Galena.ts +0 -252
  97. package/src/Galena/Guards.ts +0 -49
  98. package/src/Galena/Scheduler.ts +0 -85
  99. package/src/Galena/State.ts +0 -344
  100. package/src/Galena/index.ts +0 -3
  101. package/src/Galena/types.ts +0 -18
  102. package/src/Middleware/Middleware.ts +0 -45
  103. package/src/Middleware/index.ts +0 -2
  104. package/src/Middleware/types.ts +0 -4
  105. package/src/Middlewares/Profiler.ts +0 -41
  106. package/src/Middlewares/index.ts +0 -2
@@ -1,5 +0,0 @@
1
- export var MiddlewareEvents;
2
- (function (MiddlewareEvents) {
3
- MiddlewareEvents["onUpdate"] = "onUpdate";
4
- MiddlewareEvents["onBeforeUpdate"] = "onBeforeUpdate";
5
- })(MiddlewareEvents || (MiddlewareEvents = {}));
@@ -1,44 +0,0 @@
1
- import { State } from "../Galena/State.js";
2
- import { Middleware } from "../Middleware/Middleware.js";
3
- /**
4
- * Logger
5
- *
6
- * A middleware for Redux-style logging! Each state transition
7
- * will log to the console the `State` instance that changed
8
- * along with a before and after snapshot of the current state:
9
- *
10
- * ```typescript
11
- * const State = new Galena([new Logger()]);
12
- * // if using isolated state instances:
13
- * const MyState = new State(...args);
14
- * MyState.registerMiddleware(new Logger())
15
- * ```
16
- */
17
- export class Logger extends Middleware {
18
- previousState = null;
19
- onBeforeUpdate(state) {
20
- this.previousState = State.clone(state.state);
21
- }
22
- onUpdate(state) {
23
- console.log("%cMutation:", "color: rgb(187, 186, 186); font-weight: bold", state.name, "@", this.time);
24
- console.log(" %cPrevious State", "color: #26ad65; font-weight: bold", this.previousState);
25
- console.log(" %cNext State ", "color: rgb(17, 118, 249); font-weight: bold", state.getState());
26
- this.previousState = null;
27
- }
28
- /**
29
- * Time
30
- *
31
- * Returns the time in which a given state transition completed
32
- */
33
- get time() {
34
- const date = new Date();
35
- const mHours = date.getHours();
36
- const hours = mHours > 12 ? mHours - 12 : mHours;
37
- const mins = date.getMinutes();
38
- const minutes = mins.toString().length === 1 ? `0${mins}` : mins;
39
- const secs = date.getSeconds();
40
- const seconds = secs.toString().length === 1 ? `0${secs}` : secs;
41
- const milliseconds = date.getMilliseconds();
42
- return `${hours}:${minutes}:${seconds}:${milliseconds}`;
43
- }
44
- }
@@ -1,35 +0,0 @@
1
- import { Middleware } from "../Middleware/Middleware.js";
2
- /**
3
- * Profiler
4
- *
5
- * A logger for state transitions exceeding a given threshold
6
- * for duration:
7
- *
8
- * ```typescript
9
- * const State = new Galena([new Profiler()]);
10
- * // if using isolated state instances:
11
- * const MyState = new State(...args);
12
- * MyState.registerMiddleware(new Profiler())
13
- * ```
14
- */
15
- export class Profiler extends Middleware {
16
- threshold;
17
- startTime = null;
18
- constructor(threshold = 16) {
19
- super();
20
- this.threshold = threshold;
21
- }
22
- onBeforeUpdate(_) {
23
- this.startTime = performance.now();
24
- }
25
- onUpdate(nextState) {
26
- if (this.startTime) {
27
- const endTime = performance.now();
28
- const diff = endTime - this.startTime;
29
- if (diff > this.threshold) {
30
- console.warn(`A slow state transition was detected on ${nextState.name}`, nextState.getState());
31
- console.warn(`The last transition took ${diff}ms`);
32
- }
33
- }
34
- }
35
- }
@@ -1,2 +0,0 @@
1
- export { Logger } from "./Logger.js";
2
- export { Profiler } from "./Profiler.js";
package/dist/mjs/index.js DELETED
@@ -1,3 +0,0 @@
1
- export * from "./Galena/index.js";
2
- export * from "./Middleware/index.js";
3
- export * from "./Middlewares/index.js";
@@ -1,4 +0,0 @@
1
- {
2
- "type": "module",
3
- "exports": "./index.js"
4
- }
@@ -1,160 +0,0 @@
1
- import { State } from "./State";
2
- import type { Middleware } from "../Middleware/Middleware";
3
- import { Guards } from "./Guards";
4
- import type { Subscription } from "./types";
5
- /**
6
- * ## Galena
7
- *
8
- * A performant global state solution that scales
9
- *
10
- * ### Creating State
11
- *
12
- * ```typescript
13
- * // AppState.ts
14
- * import { Galena } from "@figliolia/galena";
15
- *
16
- * const AppState = new Galena([...middleware]);
17
- *
18
- * const NavigationState = AppState.composeState("navigation", {
19
- * currentRoute: "/",
20
- * userID: "12345",
21
- * permittedRoutes: ["/*"]
22
- * });
23
- * ```
24
- *
25
- * ### Subscribing to State Changes
26
- * #### Using the Galena Instance
27
- * ```typescript
28
- * import { AppState } from "./AppState";
29
- *
30
- * AppState.subscribe(appState => {
31
- * const navState = appState.get("navigation");
32
- * const { currentRoute } = navState.state;
33
- * // do something with state changes!
34
- * });
35
- * ```
36
- * #### Using the State Instance
37
- * ```typescript
38
- * NavigationState.subscribe(navigation => {
39
- * const { currentRoute } = navigation
40
- * // do something with state changes!
41
- * });
42
- * ```
43
- *
44
- * #### Using Global Subscriptions
45
- * ```typescript
46
- * NavigationState.subscribeAll(nextState => {
47
- * const { currentRoute } = nextState.navigation
48
- * // do something with state changes!
49
- * });
50
- * ```
51
- *
52
- * ### Mutating State
53
- * ```typescript
54
- * NavigationState.update(state => {
55
- * state.currentRoute = "/profile";
56
- * // You can mutate state without creating new objects!
57
- * });
58
- * ```
59
- */
60
- export declare class Galena<T extends Record<string, State<any>> = Record<string, State<any>>> extends Guards {
61
- readonly state: T;
62
- private readonly middleware;
63
- private readonly IDs;
64
- private readonly subscriptions;
65
- constructor(middleware?: Middleware[]);
66
- /**
67
- * Compose State
68
- *
69
- * Creates a new `State` instance and returns it. Your new state
70
- * becomes immediately available on your `Galena` instance and
71
- * is wired into your middleware. All existing subscriptions to
72
- * state will automatically receive updates when your new unit of
73
- * state updates
74
- */
75
- composeState<S extends Record<string, any>, M extends typeof State<S>>(name: string, initialState: S, Model?: M): InstanceType<M>;
76
- /**
77
- * Get State
78
- *
79
- * Returns a mutable state instance
80
- */
81
- getState(): Readonly<T>;
82
- /**
83
- * Get
84
- *
85
- * Returns a unit of `State` by name
86
- */
87
- get<K extends Extract<keyof T, string>>(name: K): T[K];
88
- /**
89
- * Mutable
90
- *
91
- * Returns a mutable state instance
92
- */
93
- private get mutable();
94
- /**
95
- * Update
96
- *
97
- * Runs a mutation on the specified unit of state
98
- */
99
- update<K extends Extract<keyof T, string>>(name: K, mutation: Parameters<T[K]["update"]>["0"]): any;
100
- /**
101
- * Background Update
102
- *
103
- * Runs a higher priority mutation on the specified unit of
104
- * state
105
- */
106
- backgroundUpdate<K extends Extract<keyof T, string>>(name: K, mutation: Parameters<T[K]["backgroundUpdate"]>["0"]): any;
107
- /**
108
- * Priority Update
109
- *
110
- * Runs an immediate priority mutation on the specified unit
111
- * of state
112
- */
113
- priorityUpdate<K extends Extract<keyof T, string>>(name: K, mutation: Parameters<T[K]["priorityUpdate"]>["0"]): any;
114
- /**
115
- * Subscribe
116
- *
117
- * Given the name of a unit of state, this method registers
118
- * a subscription on the target state instance. The callback
119
- * you provide will execute each time state changes. Returns
120
- * a unique identifier for your subscription. To clean up your
121
- * subscription, call `Galena.unsubscribe()` with the ID returned
122
- * by this method
123
- */
124
- subscribe<K extends Extract<keyof T, string>>(name: K, callback: Parameters<T[K]["subscribe"]>["0"]): string;
125
- /**
126
- * Unsubscribe
127
- *
128
- * Given a subscription ID returned from the `subscribe` method,
129
- * this method removes and cleans up the corresponding subscription
130
- */
131
- unsubscribe<K extends Extract<keyof T, string>>(name: K, ID: string): boolean | undefined;
132
- /**
133
- * Subscribe All
134
- *
135
- * Registers a callback on each registered `State` instance and
136
- * is invoked each time your state changes. Using `Galena`'s
137
- * `subscribeAll` method, although performant, can be less
138
- * performant than subscribing directly to a target `State`
139
- * instance using `Galena.subscribe()`. To clean up your
140
- * subscription, call `Galena.unsubscribeAll()` with the ID
141
- * returned
142
- */
143
- subscribeAll(callback: Subscription<T>): string;
144
- /**
145
- * Unsubscribe
146
- *
147
- * Given a subscription ID returned from the `subscribeAll()` method,
148
- * this method removes and cleans up the corresponding subscription
149
- */
150
- unsubscribeAll(ID: string): void;
151
- /**
152
- * ReIndex Subscriptions
153
- *
154
- * When units of state are created lazily, this method updates
155
- * each existing subscription to receive mutations occurring on
156
- * recently created `State` instances that post-date prior
157
- * subscriptions
158
- */
159
- private reIndexSubscriptions;
160
- }
@@ -1,29 +0,0 @@
1
- import type { State } from "./State";
2
- /**
3
- * Guards
4
- *
5
- * Development-only warnings and runtime errors designed to
6
- * guard developers against possible pitfalls when using
7
- * Galena. This interface provides composable error and
8
- * warning methods that can be used to prevent invalid usage
9
- * of the library
10
- */
11
- export declare class Guards {
12
- /**
13
- * Warn For Undefined States
14
- *
15
- * In Galena, it's normal to lazy initialize a unit of state
16
- * in attached to a `Galena` instance. This warning lets
17
- * developers know that they are attempting to manipulate a
18
- * unit of state that has not yet been initialized
19
- */
20
- protected warnForUndefinedStates<T extends Record<string, State<any>>>(name: string, state: T): void;
21
- /**
22
- * Guard Duplicate States
23
- *
24
- * Throws an error if a developer attempts to create
25
- * more than one state with the same name on a single
26
- * `Galena` instance
27
- */
28
- protected guardDuplicateStates<T extends Record<string, State<any>>>(name: string, state: T): void;
29
- }
@@ -1,51 +0,0 @@
1
- import type { Task } from "./types";
2
- import { Priority } from "./types";
3
- /**
4
- * Scheduler
5
- *
6
- * Scheduling dispatched events to state consumers is how Galena
7
- * out-performs just about every state management library out there.
8
- * The scheduler offers the ability to dispatch state updates on 3
9
- * priorities:
10
- *
11
- * 1. Immediate - Immediate synchronous task execution and propagation of
12
- * changes to consumers
13
- * 2. Microtask - Immediate task execution and scheduled propagation of
14
- * changes to consumers
15
- * 3. Batched - Immediate task execution and batched propagation of
16
- * changes to consumers
17
- *
18
- * This module manages the propagation of changes to State consumers
19
- * by implementing the three priorities outlined above
20
- */
21
- export declare class Scheduler<T extends Task = Task> {
22
- private task;
23
- private schedule;
24
- constructor();
25
- /**
26
- * Schedule Task
27
- *
28
- * Given a task (the emission of state changes to consumers)
29
- * and a priority, this method executes the task on the priority
30
- * level specified
31
- */
32
- protected scheduleTask(task: T, priority: Priority): void | Promise<void>;
33
- /**
34
- * Create Schedule
35
- *
36
- * Schedules the execution of the current task after 5 milliseconds
37
- */
38
- private createSchedule;
39
- /**
40
- * Clear Schedule
41
- *
42
- * Clears the schedule if it exists
43
- */
44
- private clearSchedule;
45
- /**
46
- * Execute Tasks
47
- *
48
- * Clears the schedule if it exists and executes the current task
49
- */
50
- private executeTasks;
51
- }
@@ -1,235 +0,0 @@
1
- import type { Middleware } from "../Middleware/Middleware";
2
- import { Scheduler } from "./Scheduler";
3
- import type { Subscription } from "./types";
4
- import { Priority } from "./types";
5
- /**
6
- * ### State
7
- *
8
- * The root of all reactivity in Galena. State instances can
9
- * operate in isolation by calling `new State(...args)` or as
10
- * part of your application's larger global state by using
11
- * `new Galena().composeState()`.
12
- *
13
- * `State` instances operate on the premise of pub-sub and mutability.
14
- * This provides significant performance improvement over more traditional
15
- * state management tools because
16
- *
17
- * 1. Mutations can occur in O(1) space
18
- * 2. Mutations can be batched when dispatching updates to subscribers
19
- *
20
- * When deciding how many `State` instances are required for your
21
- * applications needs, we suggest creating and organizing state in
22
- * accordance with your application logic. Meaning, you might have a
23
- * `State` instance for navigation/routing, another `State` instance
24
- * for storing user information, and so on. Performance can improve
25
- * significantly when state is dispersed amongst multiple instances
26
- *
27
- * #### Creating State Instances
28
- *
29
- * ```typescript
30
- * const MyState = new State("MyState", {
31
- * someData: true,
32
- * listItems: [1, 2, 3, 4];
33
- * // ...etc
34
- * });
35
- * ```
36
- *
37
- * #### Updating State
38
- * ##### Synchronous updates
39
- * ```typescript
40
- * MyState.update((state) => {
41
- * state.listItems.push(5);
42
- * });
43
- * ```
44
- * ##### Asynchronous updates
45
- * ```typescript
46
- * MyState.update(async (state) => {
47
- * const listItems = await fetch("/list-items");
48
- * state.listItems = listItems;
49
- * });
50
- * ```
51
- *
52
- * #### Subscribing to State Changes
53
- * ```typescript
54
- * MyState.subscribe((state) => {
55
- * const { listItems } = state
56
- * // Do something with your list items!
57
- * });
58
- * ```
59
- */
60
- export declare class State<T extends any = any> extends Scheduler {
61
- state: T;
62
- readonly name: string;
63
- readonly initialState: T;
64
- private readonly middleware;
65
- private readonly emitter;
66
- constructor(name: string, initialState: T);
67
- /**
68
- * Get State
69
- *
70
- * Returns a readonly snapshot of the current state
71
- */
72
- getState(): Readonly<T>;
73
- /**
74
- * Update
75
- *
76
- * Mutates state and notifies any open subscriptions. This method
77
- * by default uses task batching for optimized performance. In almost
78
- * every use-case, this method is the correct way to mutate state. If
79
- * you need to bypass batching for higher-priority state updates, you
80
- * can use `State.priorityUpdate()` or `State.backgroundUpdate()`
81
- *
82
- * ##### Synchronous updates
83
- * ```typescript
84
- * MyState.update((state, initialState) => {
85
- * state.listItems.push(5);
86
- * });
87
- * ```
88
- * ##### Asynchronous updates
89
- * ```typescript
90
- * MyState.update(async (state, initialState) => {
91
- * const listItems = await fetch("/list-items");
92
- * state.listItems = listItems;
93
- * });
94
- * ```
95
- */
96
- update: (func: (state: T, initialState: T) => void | Promise<void>) => any;
97
- /**
98
- * Background Update
99
- *
100
- * Mutates state and notifies any open subscriptions. This method
101
- * bypasses Galena's internal task batching for a more immediate
102
- * state update and propagation of state to consumers. It utilizes
103
- * a micro-task that allows for the current call stack to clear
104
- * ahead of propagating state updates to consumers
105
- *
106
- * ##### Synchronous updates
107
- * ```typescript
108
- * MyState.backgroundUpdate((state, initialState) => {
109
- * state.listItems.push(5);
110
- * });
111
- * ```
112
- * ##### Asynchronous updates
113
- * ```typescript
114
- * MyState.backgroundUpdate(async (state, initialState) => {
115
- * const listItems = await fetch("/list-items");
116
- * state.listItems = listItems;
117
- * });
118
- * ```
119
- */
120
- backgroundUpdate: (func: (state: T, initialState: T) => void | Promise<void>) => any;
121
- /**
122
- * Priority Update
123
- *
124
- * Mutates state and notifies any open subscriptions. This method
125
- * bypasses optimizations for task batching and scheduling. This means
126
- * that state updates made with this method propagate to subscriptions
127
- * as immediately as possible. Overusing this method can cause your
128
- * state updates to perform slower in certain cases. The usage of this
129
- * method should be conserved for state mutations that need to occur
130
- * at a certain frame rate
131
- *
132
- * ##### Synchronous updates
133
- * ```typescript
134
- * MyState.priorityUpdate((state, initialState) => {
135
- * state.listItems.push(5);
136
- * });
137
- * ```
138
- * ##### Asynchronous updates
139
- * ```typescript
140
- * MyState.priorityUpdate(async (state, initialState) => {
141
- * const listItems = await fetch("/list-items");
142
- * state.listItems = listItems;
143
- * });
144
- * ```
145
- */
146
- priorityUpdate: (func: (state: T, initialState: T) => void | Promise<void>) => any;
147
- /**
148
- * Reset
149
- *
150
- * Resets the current state to its initial state
151
- */
152
- reset: () => any;
153
- /**
154
- * Mutation
155
- *
156
- * This method can be used to wrap arbitrary functions that when invoked
157
- * will:
158
- * 1. Notify your subscriptions with the latest state
159
- * 2. Execute any registered middleware (such as loggers or profiling tools)
160
- *
161
- * Using this method, developers can compose and extend `Galena`'s internal
162
- * infrastructure for state mutations to create proprietary models for your
163
- * state
164
- *
165
- * ```typescript
166
- * import { State } from "@figliolia/galena";
167
- *
168
- * // Extend of Galena State
169
- * class MyState extends State {
170
- * addListItem = mutation((newListItem) => {
171
- * this.state.list.push(newListItem);
172
- * });
173
- * }
174
- *
175
- * // Create an instance
176
- * const myState = new MyState("myState", { list: [] });
177
- *
178
- * // Invoke your custom mutation method
179
- * myState.addListItem("new-item");
180
- * ```
181
- */
182
- protected mutation<F extends (...args: any[]) => any>(func: F, priority?: Priority): (...args: Parameters<F>) => any;
183
- /**
184
- * Schedule Update
185
- *
186
- * Schedules an update to State subscribers and emits the
187
- * `onUpdate` lifecycle hook
188
- */
189
- private scheduleUpdate;
190
- /**
191
- * Register Middleware
192
- *
193
- * Caches a `Middleware` instance and invokes its
194
- * lifecycle subscriptions on all state transitions
195
- */
196
- registerMiddleware(...middleware: Middleware[]): void;
197
- /**
198
- * Subscribe
199
- *
200
- * Registers a subscription on the state instance. The
201
- * callback you provide will execute each time state changes.
202
- * Returns a unique identifier for your subscription
203
- */
204
- subscribe(callback: Subscription<T>): string;
205
- /**
206
- * Unsubscribe
207
- *
208
- * Given a subscription ID, removes a registered subscription
209
- * from the `State` instance
210
- */
211
- unsubscribe(ID: string): boolean | undefined;
212
- /**
213
- * Clear All Subscriptions
214
- *
215
- * Removes all open subscriptions to the `State` instance
216
- */
217
- clearAllSubscriptions(): void;
218
- /**
219
- * Life Cycle Event
220
- *
221
- * Triggers a life cycle event for each registered middleware
222
- */
223
- private lifeCycleEvent;
224
- /**
225
- * Clone
226
- *
227
- * `State` instances accept any value as a form of reactive
228
- * state. In order to maintain the initial state past any state
229
- * transitions, this method clones the initial values provided
230
- * to the `State` constructor and caches them to allow for
231
- * developers to easily reset their current state back to its
232
- * initial value
233
- */
234
- static clone<T>(state: T): T;
235
- }
@@ -1,3 +0,0 @@
1
- export { Galena } from "./Galena";
2
- export { State } from "./State";
3
- export * from "./types";
@@ -1,13 +0,0 @@
1
- import type { Callback } from "@figliolia/event-emitter";
2
- import type { State } from "./State";
3
- export type MutationEvent<T extends any> = {
4
- [key: State<T>["name"]]: T;
5
- };
6
- export declare enum Priority {
7
- "IMMEDIATE" = 1,
8
- "MICROTASK" = 2,
9
- "BATCHED" = 3
10
- }
11
- export type Task = () => void;
12
- export type SubscriptionTuple = [state: string, ID: string];
13
- export type Subscription<T> = Callback<[nextState: T]>;
@@ -1,43 +0,0 @@
1
- import type { State } from "../Galena/State";
2
- /**
3
- * # Middleware
4
- *
5
- * A root interface for all `Galena` Middleware. When creating
6
- * a middleware for your `Galena` state, simply extend this
7
- * class any override any of its public lifecycle methods.
8
- *
9
- * ### Creating a Profiling Middleware
10
- *
11
- * ```typescript
12
- * export class ProfilerMiddleware extends Middleware {
13
- * updateState: number | null = null;
14
- *
15
- * override onBeforeUpdate(state: State) {
16
- * this.updateStart = performance.now();
17
- * }
18
- *
19
- * override onUpdate(state: State) {
20
- * if(this.updateStart) {
21
- * const timeToUpdate = performance.now() - this.updateStart;
22
- * if(timeToUpdate > 16) {
23
- * console.warn("A state transition took more than 16 milliseconds!", State);
24
- * }
25
- * }
26
- * }
27
- * }
28
- * ```
29
- */
30
- export declare class Middleware<T extends any = any> {
31
- /**
32
- * On Before Update
33
- *
34
- * An event emitted each time a `State` mutation is enqueued
35
- */
36
- onBeforeUpdate(_state: State<T>): void;
37
- /**
38
- * On Update
39
- *
40
- * An event emitted each time a `State` instance is mutated
41
- */
42
- onUpdate(_state: State<T>): void;
43
- }
@@ -1,2 +0,0 @@
1
- export { Middleware } from "./Middleware";
2
- export * from "./types";
@@ -1,4 +0,0 @@
1
- export declare enum MiddlewareEvents {
2
- "onUpdate" = "onUpdate",
3
- "onBeforeUpdate" = "onBeforeUpdate"
4
- }
@@ -1,27 +0,0 @@
1
- import { State } from "../Galena/State";
2
- import { Middleware } from "../Middleware/Middleware";
3
- /**
4
- * Logger
5
- *
6
- * A middleware for Redux-style logging! Each state transition
7
- * will log to the console the `State` instance that changed
8
- * along with a before and after snapshot of the current state:
9
- *
10
- * ```typescript
11
- * const State = new Galena([new Logger()]);
12
- * // if using isolated state instances:
13
- * const MyState = new State(...args);
14
- * MyState.registerMiddleware(new Logger())
15
- * ```
16
- */
17
- export declare class Logger extends Middleware {
18
- private previousState;
19
- onBeforeUpdate(state: State): void;
20
- onUpdate(state: State): void;
21
- /**
22
- * Time
23
- *
24
- * Returns the time in which a given state transition completed
25
- */
26
- private get time();
27
- }