@figliolia/galena 2.3.4 → 3.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 (144) 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/GalenaProvider.cjs +50 -0
  10. package/dist/GalenaProvider.d.cts +35 -0
  11. package/dist/GalenaProvider.d.cts.map +1 -0
  12. package/dist/GalenaProvider.d.mts +35 -0
  13. package/dist/GalenaProvider.d.mts.map +1 -0
  14. package/dist/GalenaProvider.mjs +52 -0
  15. package/dist/GalenaProvider.mjs.map +1 -0
  16. package/dist/Logger.cjs +46 -0
  17. package/dist/Logger.d.cts +35 -0
  18. package/dist/Logger.d.cts.map +1 -0
  19. package/dist/Logger.d.mts +35 -0
  20. package/dist/Logger.d.mts.map +1 -0
  21. package/dist/Logger.mjs +48 -0
  22. package/dist/Logger.mjs.map +1 -0
  23. package/dist/Middleware.cjs +62 -0
  24. package/dist/Middleware.d.cts +65 -0
  25. package/dist/Middleware.d.cts.map +1 -0
  26. package/dist/Middleware.d.mts +65 -0
  27. package/dist/Middleware.d.mts.map +1 -0
  28. package/dist/Middleware.mjs +64 -0
  29. package/dist/Middleware.mjs.map +1 -0
  30. package/dist/Profiler.cjs +41 -0
  31. package/dist/Profiler.d.cts +31 -0
  32. package/dist/Profiler.d.cts.map +1 -0
  33. package/dist/Profiler.d.mts +31 -0
  34. package/dist/Profiler.d.mts.map +1 -0
  35. package/dist/Profiler.mjs +43 -0
  36. package/dist/Profiler.mjs.map +1 -0
  37. package/dist/State.cjs +147 -0
  38. package/dist/State.d.cts +114 -0
  39. package/dist/State.d.cts.map +1 -0
  40. package/dist/State.d.mts +114 -0
  41. package/dist/State.d.mts.map +1 -0
  42. package/dist/State.mjs +148 -0
  43. package/dist/State.mjs.map +1 -0
  44. package/dist/commonHooks.cjs +17 -0
  45. package/dist/commonHooks.mjs +18 -0
  46. package/dist/commonHooks.mjs.map +1 -0
  47. package/dist/connect-multi.cjs +42 -0
  48. package/dist/connect-multi.d.cts +10 -0
  49. package/dist/connect-multi.d.cts.map +1 -0
  50. package/dist/connect-multi.d.mts +10 -0
  51. package/dist/connect-multi.d.mts.map +1 -0
  52. package/dist/connect-multi.mjs +44 -0
  53. package/dist/connect-multi.mjs.map +1 -0
  54. package/dist/connect.cjs +41 -0
  55. package/dist/connect.d.cts +9 -0
  56. package/dist/connect.d.cts.map +1 -0
  57. package/dist/connect.d.mts +9 -0
  58. package/dist/connect.d.mts.map +1 -0
  59. package/dist/connect.mjs +43 -0
  60. package/dist/connect.mjs.map +1 -0
  61. package/dist/createUseState.cjs +47 -0
  62. package/dist/createUseState.d.cts +46 -0
  63. package/dist/createUseState.d.cts.map +1 -0
  64. package/dist/createUseState.d.mts +46 -0
  65. package/dist/createUseState.d.mts.map +1 -0
  66. package/dist/createUseState.mjs +49 -0
  67. package/dist/createUseState.mjs.map +1 -0
  68. package/dist/index.cjs +23 -0
  69. package/dist/index.d.cts +12 -0
  70. package/dist/index.d.mts +12 -0
  71. package/dist/index.mjs +11 -0
  72. package/dist/types.d.cts +23 -0
  73. package/dist/types.d.cts.map +1 -0
  74. package/dist/types.d.mts +23 -0
  75. package/dist/types.d.mts.map +1 -0
  76. package/dist/useState.cjs +45 -0
  77. package/dist/useState.d.cts +43 -0
  78. package/dist/useState.d.cts.map +1 -0
  79. package/dist/useState.d.mts +43 -0
  80. package/dist/useState.d.mts.map +1 -0
  81. package/dist/useState.mjs +47 -0
  82. package/dist/useState.mjs.map +1 -0
  83. package/media/Logging.png +0 -0
  84. package/media/Profiling.png +0 -0
  85. package/package.json +38 -59
  86. package/src/Galena.ts +120 -0
  87. package/src/{Middlewares/Logger.ts → Logger.ts} +15 -14
  88. package/src/Middleware.ts +62 -0
  89. package/src/Profiler.ts +53 -0
  90. package/src/State.ts +167 -0
  91. package/src/index.ts +6 -3
  92. package/src/types.ts +28 -0
  93. package/dist/cjs/Galena/Galena.js +0 -223
  94. package/dist/cjs/Galena/Guards.js +0 -40
  95. package/dist/cjs/Galena/Scheduler.js +0 -84
  96. package/dist/cjs/Galena/State.js +0 -314
  97. package/dist/cjs/Galena/index.js +0 -22
  98. package/dist/cjs/Galena/types.js +0 -9
  99. package/dist/cjs/Middleware/Middleware.js +0 -46
  100. package/dist/cjs/Middleware/index.js +0 -20
  101. package/dist/cjs/Middleware/types.js +0 -8
  102. package/dist/cjs/Middlewares/Logger.js +0 -51
  103. package/dist/cjs/Middlewares/Profiler.js +0 -38
  104. package/dist/cjs/Middlewares/index.js +0 -7
  105. package/dist/cjs/index.js +0 -19
  106. package/dist/cjs/package.json +0 -3
  107. package/dist/mjs/Galena/Galena.js +0 -218
  108. package/dist/mjs/Galena/Guards.js +0 -36
  109. package/dist/mjs/Galena/Scheduler.js +0 -79
  110. package/dist/mjs/Galena/State.js +0 -313
  111. package/dist/mjs/Galena/index.js +0 -3
  112. package/dist/mjs/Galena/types.js +0 -6
  113. package/dist/mjs/Middleware/Middleware.js +0 -42
  114. package/dist/mjs/Middleware/index.js +0 -2
  115. package/dist/mjs/Middleware/types.js +0 -5
  116. package/dist/mjs/Middlewares/Logger.js +0 -44
  117. package/dist/mjs/Middlewares/Profiler.js +0 -35
  118. package/dist/mjs/Middlewares/index.js +0 -2
  119. package/dist/mjs/index.js +0 -3
  120. package/dist/mjs/package.json +0 -4
  121. package/dist/types/Galena/Galena.d.ts +0 -160
  122. package/dist/types/Galena/Guards.d.ts +0 -29
  123. package/dist/types/Galena/Scheduler.d.ts +0 -51
  124. package/dist/types/Galena/State.d.ts +0 -235
  125. package/dist/types/Galena/index.d.ts +0 -3
  126. package/dist/types/Galena/types.d.ts +0 -13
  127. package/dist/types/Middleware/Middleware.d.ts +0 -43
  128. package/dist/types/Middleware/index.d.ts +0 -2
  129. package/dist/types/Middleware/types.d.ts +0 -4
  130. package/dist/types/Middlewares/Logger.d.ts +0 -27
  131. package/dist/types/Middlewares/Profiler.d.ts +0 -22
  132. package/dist/types/Middlewares/index.d.ts +0 -2
  133. package/dist/types/index.d.ts +0 -3
  134. package/src/Galena/Galena.ts +0 -252
  135. package/src/Galena/Guards.ts +0 -49
  136. package/src/Galena/Scheduler.ts +0 -85
  137. package/src/Galena/State.ts +0 -344
  138. package/src/Galena/index.ts +0 -3
  139. package/src/Galena/types.ts +0 -18
  140. package/src/Middleware/Middleware.ts +0 -45
  141. package/src/Middleware/index.ts +0 -2
  142. package/src/Middleware/types.ts +0 -4
  143. package/src/Middlewares/Profiler.ts +0 -41
  144. package/src/Middlewares/index.ts +0 -2
@@ -1,46 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Middleware = void 0;
4
- /**
5
- * # Middleware
6
- *
7
- * A root interface for all `Galena` Middleware. When creating
8
- * a middleware for your `Galena` state, simply extend this
9
- * class any override any of its public lifecycle methods.
10
- *
11
- * ### Creating a Profiling Middleware
12
- *
13
- * ```typescript
14
- * export class ProfilerMiddleware extends Middleware {
15
- * updateState: number | null = null;
16
- *
17
- * override onBeforeUpdate(state: State) {
18
- * this.updateStart = performance.now();
19
- * }
20
- *
21
- * override onUpdate(state: State) {
22
- * if(this.updateStart) {
23
- * const timeToUpdate = performance.now() - this.updateStart;
24
- * if(timeToUpdate > 16) {
25
- * console.warn("A state transition took more than 16 milliseconds!", State);
26
- * }
27
- * }
28
- * }
29
- * }
30
- * ```
31
- */
32
- class Middleware {
33
- /**
34
- * On Before Update
35
- *
36
- * An event emitted each time a `State` mutation is enqueued
37
- */
38
- onBeforeUpdate(_state) { }
39
- /**
40
- * On Update
41
- *
42
- * An event emitted each time a `State` instance is mutated
43
- */
44
- onUpdate(_state) { }
45
- }
46
- exports.Middleware = Middleware;
@@ -1,20 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.Middleware = void 0;
18
- var Middleware_1 = require("./Middleware");
19
- Object.defineProperty(exports, "Middleware", { enumerable: true, get: function () { return Middleware_1.Middleware; } });
20
- __exportStar(require("./types"), exports);
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MiddlewareEvents = void 0;
4
- var MiddlewareEvents;
5
- (function (MiddlewareEvents) {
6
- MiddlewareEvents["onUpdate"] = "onUpdate";
7
- MiddlewareEvents["onBeforeUpdate"] = "onBeforeUpdate";
8
- })(MiddlewareEvents || (exports.MiddlewareEvents = MiddlewareEvents = {}));
@@ -1,51 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Logger = void 0;
4
- const State_1 = require("../Galena/State");
5
- const Middleware_1 = require("../Middleware/Middleware");
6
- /**
7
- * Logger
8
- *
9
- * A middleware for Redux-style logging! Each state transition
10
- * will log to the console the `State` instance that changed
11
- * along with a before and after snapshot of the current state:
12
- *
13
- * ```typescript
14
- * const State = new Galena([new Logger()]);
15
- * // if using isolated state instances:
16
- * const MyState = new State(...args);
17
- * MyState.registerMiddleware(new Logger())
18
- * ```
19
- */
20
- class Logger extends Middleware_1.Middleware {
21
- constructor() {
22
- super(...arguments);
23
- this.previousState = null;
24
- }
25
- onBeforeUpdate(state) {
26
- this.previousState = State_1.State.clone(state.state);
27
- }
28
- onUpdate(state) {
29
- console.log("%cMutation:", "color: rgb(187, 186, 186); font-weight: bold", state.name, "@", this.time);
30
- console.log(" %cPrevious State", "color: #26ad65; font-weight: bold", this.previousState);
31
- console.log(" %cNext State ", "color: rgb(17, 118, 249); font-weight: bold", state.getState());
32
- this.previousState = null;
33
- }
34
- /**
35
- * Time
36
- *
37
- * Returns the time in which a given state transition completed
38
- */
39
- get time() {
40
- const date = new Date();
41
- const mHours = date.getHours();
42
- const hours = mHours > 12 ? mHours - 12 : mHours;
43
- const mins = date.getMinutes();
44
- const minutes = mins.toString().length === 1 ? `0${mins}` : mins;
45
- const secs = date.getSeconds();
46
- const seconds = secs.toString().length === 1 ? `0${secs}` : secs;
47
- const milliseconds = date.getMilliseconds();
48
- return `${hours}:${minutes}:${seconds}:${milliseconds}`;
49
- }
50
- }
51
- exports.Logger = Logger;
@@ -1,38 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Profiler = void 0;
4
- const Middleware_1 = require("../Middleware/Middleware");
5
- /**
6
- * Profiler
7
- *
8
- * A logger for state transitions exceeding a given threshold
9
- * for duration:
10
- *
11
- * ```typescript
12
- * const State = new Galena([new Profiler()]);
13
- * // if using isolated state instances:
14
- * const MyState = new State(...args);
15
- * MyState.registerMiddleware(new Profiler())
16
- * ```
17
- */
18
- class Profiler extends Middleware_1.Middleware {
19
- constructor(threshold = 16) {
20
- super();
21
- this.startTime = null;
22
- this.threshold = threshold;
23
- }
24
- onBeforeUpdate(_) {
25
- this.startTime = performance.now();
26
- }
27
- onUpdate(nextState) {
28
- if (this.startTime) {
29
- const endTime = performance.now();
30
- const diff = endTime - this.startTime;
31
- if (diff > this.threshold) {
32
- console.warn(`A slow state transition was detected on ${nextState.name}`, nextState.getState());
33
- console.warn(`The last transition took ${diff}ms`);
34
- }
35
- }
36
- }
37
- }
38
- exports.Profiler = Profiler;
@@ -1,7 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Profiler = exports.Logger = void 0;
4
- var Logger_1 = require("./Logger");
5
- Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return Logger_1.Logger; } });
6
- var Profiler_1 = require("./Profiler");
7
- Object.defineProperty(exports, "Profiler", { enumerable: true, get: function () { return Profiler_1.Profiler; } });
package/dist/cjs/index.js DELETED
@@ -1,19 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./Galena"), exports);
18
- __exportStar(require("./Middleware"), exports);
19
- __exportStar(require("./Middlewares"), exports);
@@ -1,3 +0,0 @@
1
- {
2
- "type": "commonjs"
3
- }
@@ -1,218 +0,0 @@
1
- import { AutoIncrementingID } from "@figliolia/event-emitter";
2
- import { State } from "./State.js";
3
- import { Guards } from "./Guards.js";
4
- /**
5
- * ## Galena
6
- *
7
- * A performant global state solution that scales
8
- *
9
- * ### Creating State
10
- *
11
- * ```typescript
12
- * // AppState.ts
13
- * import { Galena } from "@figliolia/galena";
14
- *
15
- * const AppState = new Galena([...middleware]);
16
- *
17
- * const NavigationState = AppState.composeState("navigation", {
18
- * currentRoute: "/",
19
- * userID: "12345",
20
- * permittedRoutes: ["/*"]
21
- * });
22
- * ```
23
- *
24
- * ### Subscribing to State Changes
25
- * #### Using the Galena Instance
26
- * ```typescript
27
- * import { AppState } from "./AppState";
28
- *
29
- * AppState.subscribe(appState => {
30
- * const navState = appState.get("navigation");
31
- * const { currentRoute } = navState.state;
32
- * // do something with state changes!
33
- * });
34
- * ```
35
- * #### Using the State Instance
36
- * ```typescript
37
- * NavigationState.subscribe(navigation => {
38
- * const { currentRoute } = navigation
39
- * // do something with state changes!
40
- * });
41
- * ```
42
- *
43
- * #### Using Global Subscriptions
44
- * ```typescript
45
- * NavigationState.subscribeAll(nextState => {
46
- * const { currentRoute } = nextState.navigation
47
- * // do something with state changes!
48
- * });
49
- * ```
50
- *
51
- * ### Mutating State
52
- * ```typescript
53
- * NavigationState.update(state => {
54
- * state.currentRoute = "/profile";
55
- * // You can mutate state without creating new objects!
56
- * });
57
- * ```
58
- */
59
- export class Galena extends Guards {
60
- state = {};
61
- middleware = [];
62
- IDs = new AutoIncrementingID();
63
- subscriptions = new Map();
64
- constructor(middleware = []) {
65
- super();
66
- this.middleware = middleware;
67
- }
68
- /**
69
- * Compose State
70
- *
71
- * Creates a new `State` instance and returns it. Your new state
72
- * becomes immediately available on your `Galena` instance and
73
- * is wired into your middleware. All existing subscriptions to
74
- * state will automatically receive updates when your new unit of
75
- * state updates
76
- */
77
- composeState(name, initialState, Model) {
78
- this.guardDuplicateStates(name, this.state);
79
- const StateModel = Model || (State);
80
- const state = new StateModel(name, initialState);
81
- state.registerMiddleware(...this.middleware);
82
- this.mutable[name] = state;
83
- this.reIndexSubscriptions(name);
84
- return state;
85
- }
86
- /**
87
- * Get State
88
- *
89
- * Returns a mutable state instance
90
- */
91
- getState() {
92
- return this.state;
93
- }
94
- /**
95
- * Get
96
- *
97
- * Returns a unit of `State` by name
98
- */
99
- get(name) {
100
- this.warnForUndefinedStates(name, this.state);
101
- return this.state[name];
102
- }
103
- /**
104
- * Mutable
105
- *
106
- * Returns a mutable state instance
107
- */
108
- get mutable() {
109
- return this.state;
110
- }
111
- /**
112
- * Update
113
- *
114
- * Runs a mutation on the specified unit of state
115
- */
116
- update(name, mutation) {
117
- return this.get(name).update(mutation);
118
- }
119
- /**
120
- * Background Update
121
- *
122
- * Runs a higher priority mutation on the specified unit of
123
- * state
124
- */
125
- backgroundUpdate(name, mutation) {
126
- return this.get(name).backgroundUpdate(mutation);
127
- }
128
- /**
129
- * Priority Update
130
- *
131
- * Runs an immediate priority mutation on the specified unit
132
- * of state
133
- */
134
- priorityUpdate(name, mutation) {
135
- return this.get(name).priorityUpdate(mutation);
136
- }
137
- /**
138
- * Subscribe
139
- *
140
- * Given the name of a unit of state, this method registers
141
- * a subscription on the target state instance. The callback
142
- * you provide will execute each time state changes. Returns
143
- * a unique identifier for your subscription. To clean up your
144
- * subscription, call `Galena.unsubscribe()` with the ID returned
145
- * by this method
146
- */
147
- subscribe(name, callback) {
148
- return this.get(name).subscribe(callback);
149
- }
150
- /**
151
- * Unsubscribe
152
- *
153
- * Given a subscription ID returned from the `subscribe` method,
154
- * this method removes and cleans up the corresponding subscription
155
- */
156
- unsubscribe(name, ID) {
157
- return this.get(name).unsubscribe(ID);
158
- }
159
- /**
160
- * Subscribe All
161
- *
162
- * Registers a callback on each registered `State` instance and
163
- * is invoked each time your state changes. Using `Galena`'s
164
- * `subscribeAll` method, although performant, can be less
165
- * performant than subscribing directly to a target `State`
166
- * instance using `Galena.subscribe()`. To clean up your
167
- * subscription, call `Galena.unsubscribeAll()` with the ID
168
- * returned
169
- */
170
- subscribeAll(callback) {
171
- const stateSubscriptions = [];
172
- for (const key in this.state) {
173
- stateSubscriptions.push([
174
- key,
175
- this.state[key].subscribe(() => {
176
- void callback(this.state);
177
- }),
178
- ]);
179
- }
180
- const subscriptionID = this.IDs.get();
181
- this.subscriptions.set(subscriptionID, stateSubscriptions);
182
- return subscriptionID;
183
- }
184
- /**
185
- * Unsubscribe
186
- *
187
- * Given a subscription ID returned from the `subscribeAll()` method,
188
- * this method removes and cleans up the corresponding subscription
189
- */
190
- unsubscribeAll(ID) {
191
- const IDs = this.subscriptions.get(ID);
192
- if (IDs) {
193
- for (const [state, ID] of IDs) {
194
- this.state[state].unsubscribe(ID);
195
- }
196
- this.subscriptions.delete(ID);
197
- }
198
- }
199
- /**
200
- * ReIndex Subscriptions
201
- *
202
- * When units of state are created lazily, this method updates
203
- * each existing subscription to receive mutations occurring on
204
- * recently created `State` instances that post-date prior
205
- * subscriptions
206
- */
207
- reIndexSubscriptions(name) {
208
- for (const [ID, unitSubscriptions] of this.subscriptions) {
209
- const [stateName, listenerID] = unitSubscriptions[0];
210
- const subscriptions = this.state[stateName]["emitter"].storage.get(stateName);
211
- const listener = subscriptions?.storage?.get(listenerID);
212
- if (listener) {
213
- unitSubscriptions.push([name, this.state[name].subscribe(listener)]);
214
- this.subscriptions.set(ID, unitSubscriptions);
215
- }
216
- }
217
- }
218
- }
@@ -1,36 +0,0 @@
1
- /**
2
- * Guards
3
- *
4
- * Development-only warnings and runtime errors designed to
5
- * guard developers against possible pitfalls when using
6
- * Galena. This interface provides composable error and
7
- * warning methods that can be used to prevent invalid usage
8
- * of the library
9
- */
10
- export class Guards {
11
- /**
12
- * Warn For Undefined States
13
- *
14
- * In Galena, it's normal to lazy initialize a unit of state
15
- * in attached to a `Galena` instance. This warning lets
16
- * developers know that they are attempting to manipulate a
17
- * unit of state that has not yet been initialized
18
- */
19
- warnForUndefinedStates(name, state) {
20
- if (!(name in state)) {
21
- console.warn(`A unit of state with the name "${name}" does not yet exist on this Galena instance. If this is expected, you can ignore this warning`);
22
- }
23
- }
24
- /**
25
- * Guard Duplicate States
26
- *
27
- * Throws an error if a developer attempts to create
28
- * more than one state with the same name on a single
29
- * `Galena` instance
30
- */
31
- guardDuplicateStates(name, state) {
32
- if (name in state) {
33
- console.warn(`A unit of state with the name "${name}" already exists on this Galena instance. Please re-name this new unit of state to something unique`);
34
- }
35
- }
36
- }
@@ -1,79 +0,0 @@
1
- import { Priority } from "./types.js";
2
- /**
3
- * Scheduler
4
- *
5
- * Scheduling dispatched events to state consumers is how Galena
6
- * out-performs just about every state management library out there.
7
- * The scheduler offers the ability to dispatch state updates on 3
8
- * priorities:
9
- *
10
- * 1. Immediate - Immediate synchronous task execution and propagation of
11
- * changes to consumers
12
- * 2. Microtask - Immediate task execution and scheduled propagation of
13
- * changes to consumers
14
- * 3. Batched - Immediate task execution and batched propagation of
15
- * changes to consumers
16
- *
17
- * This module manages the propagation of changes to State consumers
18
- * by implementing the three priorities outlined above
19
- */
20
- export class Scheduler {
21
- task = null;
22
- schedule = null;
23
- constructor() {
24
- this.executeTasks = this.executeTasks.bind(this);
25
- }
26
- /**
27
- * Schedule Task
28
- *
29
- * Given a task (the emission of state changes to consumers)
30
- * and a priority, this method executes the task on the priority
31
- * level specified
32
- */
33
- scheduleTask(task, priority) {
34
- this.task = task;
35
- switch (priority) {
36
- case Priority.IMMEDIATE:
37
- return this.executeTasks();
38
- case Priority.MICROTASK:
39
- return Promise.resolve().then(() => {
40
- return this.executeTasks();
41
- });
42
- case Priority.BATCHED:
43
- default:
44
- if (!this.schedule) {
45
- this.createSchedule();
46
- }
47
- }
48
- }
49
- /**
50
- * Create Schedule
51
- *
52
- * Schedules the execution of the current task after 5 milliseconds
53
- */
54
- createSchedule() {
55
- this.clearSchedule();
56
- this.schedule = setTimeout(this.executeTasks, 5);
57
- }
58
- /**
59
- * Clear Schedule
60
- *
61
- * Clears the schedule if it exists
62
- */
63
- clearSchedule() {
64
- if (this.schedule !== null) {
65
- clearTimeout(this.schedule);
66
- this.schedule = null;
67
- }
68
- }
69
- /**
70
- * Execute Tasks
71
- *
72
- * Clears the schedule if it exists and executes the current task
73
- */
74
- executeTasks() {
75
- this.clearSchedule();
76
- this.task?.();
77
- this.task = null;
78
- }
79
- }