@figliolia/galena 2.3.3 → 2.3.4

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.
@@ -208,10 +208,11 @@ class Galena extends Guards_1.Guards {
208
208
  * subscriptions
209
209
  */
210
210
  reIndexSubscriptions(name) {
211
+ var _a;
211
212
  for (const [ID, unitSubscriptions] of this.subscriptions) {
212
- const [state, listenerID] = unitSubscriptions[0];
213
- const subscriptions = this.state[state]["emitter"].get(state);
214
- const listener = subscriptions === null || subscriptions === void 0 ? void 0 : subscriptions.get(listenerID);
213
+ const [stateName, listenerID] = unitSubscriptions[0];
214
+ const subscriptions = this.state[stateName]["emitter"].storage.get(stateName);
215
+ const listener = (_a = subscriptions === null || subscriptions === void 0 ? void 0 : subscriptions.storage) === null || _a === void 0 ? void 0 : _a.get(listenerID);
215
216
  if (listener) {
216
217
  unitSubscriptions.push([name, this.state[name].subscribe(listener)]);
217
218
  this.subscriptions.set(ID, unitSubscriptions);
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.State = void 0;
4
- const types_1 = require("../Middleware/types");
5
4
  const event_emitter_1 = require("@figliolia/event-emitter");
5
+ const types_1 = require("../Middleware/types");
6
6
  const Scheduler_1 = require("./Scheduler");
7
7
  const types_2 = require("./types");
8
8
  /**
@@ -199,7 +199,7 @@ class State extends Scheduler_1.Scheduler {
199
199
  this.lifeCycleEvent(types_1.MiddlewareEvents.onBeforeUpdate);
200
200
  const returnValue = func(...args);
201
201
  if (returnValue instanceof Promise) {
202
- return returnValue.then((v) => {
202
+ return returnValue.then(v => {
203
203
  this.scheduleUpdate(priority);
204
204
  return v;
205
205
  });
@@ -252,7 +252,7 @@ class State extends Scheduler_1.Scheduler {
252
252
  * Removes all open subscriptions to the `State` instance
253
253
  */
254
254
  clearAllSubscriptions() {
255
- return this.emitter.clear();
255
+ return this.emitter.storage.clear();
256
256
  }
257
257
  /**
258
258
  * Life Cycle Event
@@ -276,19 +276,39 @@ class State extends Scheduler_1.Scheduler {
276
276
  * initial value
277
277
  */
278
278
  static clone(state) {
279
- if (Array.isArray(state)) {
280
- return [...state];
281
- }
282
- if (state instanceof Set) {
283
- return new Set(state);
284
- }
285
- if (state instanceof Map) {
286
- return new Map(state);
287
- }
288
- if (state && typeof state === "object") {
289
- return Object.assign({}, state);
279
+ switch (typeof state) {
280
+ case "string":
281
+ return String(state);
282
+ case "bigint":
283
+ return BigInt(state);
284
+ case "boolean":
285
+ return Boolean(state);
286
+ case "number":
287
+ return Number(state);
288
+ case "symbol":
289
+ case "function":
290
+ return state;
291
+ case "undefined":
292
+ return undefined;
293
+ case "object":
294
+ default:
295
+ if (!state) {
296
+ return null;
297
+ }
298
+ if (Array.isArray(state)) {
299
+ return [...state];
300
+ }
301
+ if (state instanceof Set) {
302
+ return new Set(state);
303
+ }
304
+ if (state instanceof Map) {
305
+ return new Map(state);
306
+ }
307
+ if (state && typeof state === "object") {
308
+ return Object.assign({}, state);
309
+ }
310
+ return state;
290
311
  }
291
- return state;
292
312
  }
293
313
  }
294
314
  exports.State = State;
@@ -6,4 +6,4 @@ var Priority;
6
6
  Priority[Priority["IMMEDIATE"] = 1] = "IMMEDIATE";
7
7
  Priority[Priority["MICROTASK"] = 2] = "MICROTASK";
8
8
  Priority[Priority["BATCHED"] = 3] = "BATCHED";
9
- })(Priority = exports.Priority || (exports.Priority = {}));
9
+ })(Priority || (exports.Priority = Priority = {}));
@@ -35,12 +35,12 @@ class Middleware {
35
35
  *
36
36
  * An event emitted each time a `State` mutation is enqueued
37
37
  */
38
- onBeforeUpdate(state) { }
38
+ onBeforeUpdate(_state) { }
39
39
  /**
40
40
  * On Update
41
41
  *
42
42
  * An event emitted each time a `State` instance is mutated
43
43
  */
44
- onUpdate(state) { }
44
+ onUpdate(_state) { }
45
45
  }
46
46
  exports.Middleware = Middleware;
@@ -5,4 +5,4 @@ var MiddlewareEvents;
5
5
  (function (MiddlewareEvents) {
6
6
  MiddlewareEvents["onUpdate"] = "onUpdate";
7
7
  MiddlewareEvents["onBeforeUpdate"] = "onBeforeUpdate";
8
- })(MiddlewareEvents = exports.MiddlewareEvents || (exports.MiddlewareEvents = {}));
8
+ })(MiddlewareEvents || (exports.MiddlewareEvents = MiddlewareEvents = {}));
@@ -206,9 +206,9 @@ export class Galena extends Guards {
206
206
  */
207
207
  reIndexSubscriptions(name) {
208
208
  for (const [ID, unitSubscriptions] of this.subscriptions) {
209
- const [state, listenerID] = unitSubscriptions[0];
210
- const subscriptions = this.state[state]["emitter"].get(state);
211
- const listener = subscriptions?.get(listenerID);
209
+ const [stateName, listenerID] = unitSubscriptions[0];
210
+ const subscriptions = this.state[stateName]["emitter"].storage.get(stateName);
211
+ const listener = subscriptions?.storage?.get(listenerID);
212
212
  if (listener) {
213
213
  unitSubscriptions.push([name, this.state[name].subscribe(listener)]);
214
214
  this.subscriptions.set(ID, unitSubscriptions);
@@ -1,5 +1,5 @@
1
- import { MiddlewareEvents } from "../Middleware/types.js";
2
1
  import { EventEmitter } from "@figliolia/event-emitter";
2
+ import { MiddlewareEvents } from "../Middleware/types.js";
3
3
  import { Scheduler } from "./Scheduler.js";
4
4
  import { Priority } from "./types.js";
5
5
  /**
@@ -199,7 +199,7 @@ export class State extends Scheduler {
199
199
  this.lifeCycleEvent(MiddlewareEvents.onBeforeUpdate);
200
200
  const returnValue = func(...args);
201
201
  if (returnValue instanceof Promise) {
202
- return returnValue.then((v) => {
202
+ return returnValue.then(v => {
203
203
  this.scheduleUpdate(priority);
204
204
  return v;
205
205
  });
@@ -252,7 +252,7 @@ export class State extends Scheduler {
252
252
  * Removes all open subscriptions to the `State` instance
253
253
  */
254
254
  clearAllSubscriptions() {
255
- return this.emitter.clear();
255
+ return this.emitter.storage.clear();
256
256
  }
257
257
  /**
258
258
  * Life Cycle Event
@@ -276,18 +276,38 @@ export class State extends Scheduler {
276
276
  * initial value
277
277
  */
278
278
  static clone(state) {
279
- if (Array.isArray(state)) {
280
- return [...state];
281
- }
282
- if (state instanceof Set) {
283
- return new Set(state);
284
- }
285
- if (state instanceof Map) {
286
- return new Map(state);
287
- }
288
- if (state && typeof state === "object") {
289
- return { ...state };
279
+ switch (typeof state) {
280
+ case "string":
281
+ return String(state);
282
+ case "bigint":
283
+ return BigInt(state);
284
+ case "boolean":
285
+ return Boolean(state);
286
+ case "number":
287
+ return Number(state);
288
+ case "symbol":
289
+ case "function":
290
+ return state;
291
+ case "undefined":
292
+ return undefined;
293
+ case "object":
294
+ default:
295
+ if (!state) {
296
+ return null;
297
+ }
298
+ if (Array.isArray(state)) {
299
+ return [...state];
300
+ }
301
+ if (state instanceof Set) {
302
+ return new Set(state);
303
+ }
304
+ if (state instanceof Map) {
305
+ return new Map(state);
306
+ }
307
+ if (state && typeof state === "object") {
308
+ return { ...state };
309
+ }
310
+ return state;
290
311
  }
291
- return state;
292
312
  }
293
313
  }
@@ -32,11 +32,11 @@ export class Middleware {
32
32
  *
33
33
  * An event emitted each time a `State` mutation is enqueued
34
34
  */
35
- onBeforeUpdate(state) { }
35
+ onBeforeUpdate(_state) { }
36
36
  /**
37
37
  * On Update
38
38
  *
39
39
  * An event emitted each time a `State` instance is mutated
40
40
  */
41
- onUpdate(state) { }
41
+ onUpdate(_state) { }
42
42
  }
@@ -1,5 +1,5 @@
1
- import type { Middleware } from "../Middleware/Middleware";
2
1
  import { State } from "./State";
2
+ import type { Middleware } from "../Middleware/Middleware";
3
3
  import { Guards } from "./Guards";
4
4
  import type { Subscription } from "./types";
5
5
  /**
@@ -1,3 +1,4 @@
1
+ import type { Callback } from "@figliolia/event-emitter";
1
2
  import type { State } from "./State";
2
3
  export type MutationEvent<T extends any> = {
3
4
  [key: State<T>["name"]]: T;
@@ -9,4 +10,4 @@ export declare enum Priority {
9
10
  }
10
11
  export type Task = () => void;
11
12
  export type SubscriptionTuple = [state: string, ID: string];
12
- export type Subscription<T> = (nextState: T) => void | Promise<void>;
13
+ export type Subscription<T> = Callback<[nextState: T]>;
@@ -33,11 +33,11 @@ export declare class Middleware<T extends any = any> {
33
33
  *
34
34
  * An event emitted each time a `State` mutation is enqueued
35
35
  */
36
- onBeforeUpdate(state: State<T>): void;
36
+ onBeforeUpdate(_state: State<T>): void;
37
37
  /**
38
38
  * On Update
39
39
  *
40
40
  * An event emitted each time a `State` instance is mutated
41
41
  */
42
- onUpdate(state: State<T>): void;
42
+ onUpdate(_state: State<T>): void;
43
43
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@figliolia/galena",
3
- "version": "2.3.3",
3
+ "version": "2.3.4",
4
4
  "description": "A performant state management library supporting mutable state, batched updates, middleware and a rich development API",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/mjs/index.js",
@@ -36,34 +36,36 @@
36
36
  "performance"
37
37
  ],
38
38
  "scripts": {
39
- "test": "jest",
40
- "coverage": "jest --env=jsdom --coverage --testResultsProcessor ./node_modules/jest-junit",
41
- "build": "npx ts-packager -e src",
42
- "lint": "tsc --noemit && eslint ./ --fix"
39
+ "build": "ts-packager -e src",
40
+ "lint": "tsx ci/commands/Lint.ts",
41
+ "test": "tsx ci/commands/Test.ts"
43
42
  },
44
43
  "dependencies": {
45
- "@figliolia/event-emitter": "^1.1.4"
44
+ "@figliolia/event-emitter": "^1.1.5"
46
45
  },
47
46
  "peerDependencies": {
48
- "@figliolia/event-emitter": "^1.1.4"
47
+ "@figliolia/event-emitter": "^1.1.5"
49
48
  },
50
49
  "devDependencies": {
51
- "@figliolia/ts-packager": "^1.0.3",
52
- "@types/node": "^16.7.13",
50
+ "@figliolia/child-process": "^1.0.1",
51
+ "@figliolia/ts-packager": "^1.1.0",
52
+ "@types/node": "^20.11.19",
53
53
  "@typescript-eslint/eslint-plugin": "^5.59.1",
54
54
  "@typescript-eslint/parser": "^5.59.1",
55
55
  "eslint": "^8.39.0",
56
56
  "eslint-config-airbnb": "^19.0.4",
57
57
  "eslint-config-airbnb-typescript": "^17.0.0",
58
58
  "eslint-config-prettier": "^8.8.0",
59
- "eslint-import-resolver-typescript": "^3.5.5",
59
+ "eslint-import-resolver-typescript": "^3.6.1",
60
60
  "eslint-plugin-import": "^2.27.5",
61
- "eslint-plugin-prettier": "^4.2.1",
61
+ "eslint-plugin-json-format": "^2.0.1",
62
+ "eslint-plugin-prettier": "^5.1.3",
62
63
  "eslint-plugin-simple-import-sort": "^10.0.0",
63
- "prettier": "^2.8.8",
64
- "ts-node": "^10.9.1",
65
- "tsc-alias": "^1.8.6",
66
- "typescript": "^4.4.2"
64
+ "eslint-plugin-unused-imports": "3",
65
+ "prettier": "^3.2.4",
66
+ "tsc-alias": "^1.8.8",
67
+ "tsx": "^4.7.1",
68
+ "typescript": "^5.3.3"
67
69
  },
68
70
  "publishConfig": {
69
71
  "access": "public"
@@ -1,6 +1,6 @@
1
1
  import { AutoIncrementingID } from "@figliolia/event-emitter";
2
- import type { Middleware } from "Middleware/Middleware";
3
2
  import { State } from "Galena/State";
3
+ import type { Middleware } from "Middleware/Middleware";
4
4
  import { Guards } from "./Guards";
5
5
  import type { Subscription, SubscriptionTuple } from "./types";
6
6
 
@@ -60,7 +60,7 @@ import type { Subscription, SubscriptionTuple } from "./types";
60
60
  * ```
61
61
  */
62
62
  export class Galena<
63
- T extends Record<string, State<any>> = Record<string, State<any>>
63
+ T extends Record<string, State<any>> = Record<string, State<any>>,
64
64
  > extends Guards {
65
65
  public readonly state = {} as T;
66
66
  private readonly middleware: Middleware[] = [];
@@ -83,7 +83,7 @@ export class Galena<
83
83
  public composeState<S extends Record<string, any>, M extends typeof State<S>>(
84
84
  name: string,
85
85
  initialState: S,
86
- Model?: M
86
+ Model?: M,
87
87
  ) {
88
88
  this.guardDuplicateStates(name, this.state);
89
89
  const StateModel = Model || State<S>;
@@ -129,7 +129,7 @@ export class Galena<
129
129
  */
130
130
  public update<K extends Extract<keyof T, string>>(
131
131
  name: K,
132
- mutation: Parameters<T[K]["update"]>["0"]
132
+ mutation: Parameters<T[K]["update"]>["0"],
133
133
  ) {
134
134
  return this.get(name).update(mutation);
135
135
  }
@@ -142,7 +142,7 @@ export class Galena<
142
142
  */
143
143
  public backgroundUpdate<K extends Extract<keyof T, string>>(
144
144
  name: K,
145
- mutation: Parameters<T[K]["backgroundUpdate"]>["0"]
145
+ mutation: Parameters<T[K]["backgroundUpdate"]>["0"],
146
146
  ) {
147
147
  return this.get(name).backgroundUpdate(mutation);
148
148
  }
@@ -155,7 +155,7 @@ export class Galena<
155
155
  */
156
156
  public priorityUpdate<K extends Extract<keyof T, string>>(
157
157
  name: K,
158
- mutation: Parameters<T[K]["priorityUpdate"]>["0"]
158
+ mutation: Parameters<T[K]["priorityUpdate"]>["0"],
159
159
  ) {
160
160
  return this.get(name).priorityUpdate(mutation);
161
161
  }
@@ -172,7 +172,7 @@ export class Galena<
172
172
  */
173
173
  public subscribe<K extends Extract<keyof T, string>>(
174
174
  name: K,
175
- callback: Parameters<T[K]["subscribe"]>["0"]
175
+ callback: Parameters<T[K]["subscribe"]>["0"],
176
176
  ) {
177
177
  return this.get(name).subscribe(callback);
178
178
  }
@@ -239,9 +239,10 @@ export class Galena<
239
239
  */
240
240
  private reIndexSubscriptions(name: string) {
241
241
  for (const [ID, unitSubscriptions] of this.subscriptions) {
242
- const [state, listenerID] = unitSubscriptions[0];
243
- const subscriptions = this.state[state]["emitter"].get(state);
244
- const listener = subscriptions?.get(listenerID);
242
+ const [stateName, listenerID] = unitSubscriptions[0];
243
+ const subscriptions =
244
+ this.state[stateName]["emitter"].storage.get(stateName);
245
+ const listener = subscriptions?.storage?.get(listenerID);
245
246
  if (listener) {
246
247
  unitSubscriptions.push([name, this.state[name].subscribe(listener)]);
247
248
  this.subscriptions.set(ID, unitSubscriptions);
@@ -20,11 +20,11 @@ export class Guards {
20
20
  */
21
21
  protected warnForUndefinedStates<T extends Record<string, State<any>>>(
22
22
  name: string,
23
- state: T
23
+ state: T,
24
24
  ) {
25
25
  if (!(name in state)) {
26
26
  console.warn(
27
- `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`
27
+ `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`,
28
28
  );
29
29
  }
30
30
  }
@@ -38,11 +38,11 @@ export class Guards {
38
38
  */
39
39
  protected guardDuplicateStates<T extends Record<string, State<any>>>(
40
40
  name: string,
41
- state: T
41
+ state: T,
42
42
  ) {
43
43
  if (name in state) {
44
44
  console.warn(
45
- `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`
45
+ `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`,
46
46
  );
47
47
  }
48
48
  }
@@ -1,9 +1,9 @@
1
- import { MiddlewareEvents } from "Middleware/types";
2
- import type { Middleware } from "Middleware/Middleware";
3
1
  import { EventEmitter } from "@figliolia/event-emitter";
2
+ import type { Middleware } from "Middleware/Middleware";
3
+ import { MiddlewareEvents } from "Middleware/types";
4
4
  import { Scheduler } from "./Scheduler";
5
- import type { Subscription } from "./types";
6
- import { Priority, type MutationEvent } from "./types";
5
+ import type { MutationEvent, Subscription } from "./types";
6
+ import { Priority } from "./types";
7
7
 
8
8
  /**
9
9
  * ### State
@@ -109,7 +109,7 @@ export class State<T extends any = any> extends Scheduler {
109
109
  (func: (state: T, initialState: T) => void | Promise<void>) => {
110
110
  return func(this.state, this.initialState);
111
111
  },
112
- Priority.BATCHED
112
+ Priority.BATCHED,
113
113
  );
114
114
 
115
115
  /**
@@ -139,7 +139,7 @@ export class State<T extends any = any> extends Scheduler {
139
139
  (func: (state: T, initialState: T) => void | Promise<void>) => {
140
140
  return func(this.state, this.initialState);
141
141
  },
142
- Priority.MICROTASK
142
+ Priority.MICROTASK,
143
143
  );
144
144
 
145
145
  /**
@@ -171,7 +171,7 @@ export class State<T extends any = any> extends Scheduler {
171
171
  (func: (state: T, initialState: T) => void | Promise<void>) => {
172
172
  return func(this.state, this.initialState);
173
173
  },
174
- Priority.IMMEDIATE
174
+ Priority.IMMEDIATE,
175
175
  );
176
176
 
177
177
  /**
@@ -214,13 +214,13 @@ export class State<T extends any = any> extends Scheduler {
214
214
  */
215
215
  protected mutation<F extends (...args: any[]) => any>(
216
216
  func: F,
217
- priority: Priority = Priority.BATCHED
217
+ priority: Priority = Priority.BATCHED,
218
218
  ) {
219
219
  return (...args: Parameters<F>) => {
220
220
  this.lifeCycleEvent(MiddlewareEvents.onBeforeUpdate);
221
221
  const returnValue = func(...args);
222
222
  if (returnValue instanceof Promise) {
223
- return returnValue.then((v) => {
223
+ return returnValue.then(v => {
224
224
  this.scheduleUpdate(priority);
225
225
  return v;
226
226
  });
@@ -240,7 +240,7 @@ export class State<T extends any = any> extends Scheduler {
240
240
  this.lifeCycleEvent(MiddlewareEvents.onUpdate);
241
241
  void this.scheduleTask(
242
242
  () => this.emitter.emit(this.name, this.state),
243
- priority
243
+ priority,
244
244
  );
245
245
  }
246
246
 
@@ -281,7 +281,7 @@ export class State<T extends any = any> extends Scheduler {
281
281
  * Removes all open subscriptions to the `State` instance
282
282
  */
283
283
  public clearAllSubscriptions() {
284
- return this.emitter.clear();
284
+ return this.emitter.storage.clear();
285
285
  }
286
286
 
287
287
  /**
@@ -307,18 +307,38 @@ export class State<T extends any = any> extends Scheduler {
307
307
  * initial value
308
308
  */
309
309
  public static clone<T>(state: T): T {
310
- if (Array.isArray(state)) {
311
- return [...state] as T;
312
- }
313
- if (state instanceof Set) {
314
- return new Set(state) as T;
315
- }
316
- if (state instanceof Map) {
317
- return new Map(state) as T;
318
- }
319
- if (state && typeof state === "object") {
320
- return { ...state } as T;
310
+ switch (typeof state) {
311
+ case "string":
312
+ return String(state) as T;
313
+ case "bigint":
314
+ return BigInt(state) as T;
315
+ case "boolean":
316
+ return Boolean(state) as T;
317
+ case "number":
318
+ return Number(state) as T;
319
+ case "symbol":
320
+ case "function":
321
+ return state;
322
+ case "undefined":
323
+ return undefined as T;
324
+ case "object":
325
+ default:
326
+ if (!state) {
327
+ return null as T;
328
+ }
329
+ if (Array.isArray(state)) {
330
+ return [...state] as T;
331
+ }
332
+ if (state instanceof Set) {
333
+ return new Set(state) as T;
334
+ }
335
+ if (state instanceof Map) {
336
+ return new Map(state) as T;
337
+ }
338
+ if (state && typeof state === "object") {
339
+ return { ...state } as T;
340
+ }
341
+ return state;
321
342
  }
322
- return state;
323
343
  }
324
344
  }
@@ -1,3 +1,4 @@
1
+ import type { Callback } from "@figliolia/event-emitter";
1
2
  import type { State } from "./State";
2
3
 
3
4
  export type MutationEvent<T extends any> = {
@@ -14,4 +15,4 @@ export type Task = () => void;
14
15
 
15
16
  export type SubscriptionTuple = [state: string, ID: string];
16
17
 
17
- export type Subscription<T> = (nextState: T) => void | Promise<void>;
18
+ export type Subscription<T> = Callback<[nextState: T]>;
@@ -34,12 +34,12 @@ export class Middleware<T extends any = any> {
34
34
  *
35
35
  * An event emitted each time a `State` mutation is enqueued
36
36
  */
37
- public onBeforeUpdate(state: State<T>) {}
37
+ public onBeforeUpdate(_state: State<T>) {}
38
38
 
39
39
  /**
40
40
  * On Update
41
41
  *
42
42
  * An event emitted each time a `State` instance is mutated
43
43
  */
44
- public onUpdate(state: State<T>) {}
44
+ public onUpdate(_state: State<T>) {}
45
45
  }
@@ -28,17 +28,17 @@ export class Logger extends Middleware {
28
28
  "color: rgb(187, 186, 186); font-weight: bold",
29
29
  state.name,
30
30
  "@",
31
- this.time
31
+ this.time,
32
32
  );
33
33
  console.log(
34
34
  " %cPrevious State",
35
35
  "color: #26ad65; font-weight: bold",
36
- this.previousState
36
+ this.previousState,
37
37
  );
38
38
  console.log(
39
39
  " %cNext State ",
40
40
  "color: rgb(17, 118, 249); font-weight: bold",
41
- state.getState()
41
+ state.getState(),
42
42
  );
43
43
  this.previousState = null;
44
44
  }
@@ -32,7 +32,7 @@ export class Profiler extends Middleware {
32
32
  if (diff > this.threshold) {
33
33
  console.warn(
34
34
  `A slow state transition was detected on ${nextState.name}`,
35
- nextState.getState()
35
+ nextState.getState(),
36
36
  );
37
37
  console.warn(`The last transition took ${diff}ms`);
38
38
  }