@okyrychenko-dev/react-action-guard 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.cjs +87 -85
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +87 -85
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -36,8 +36,8 @@ pnpm add @okyrychenko-dev/react-action-guard zustand
|
|
|
36
36
|
|
|
37
37
|
This package requires the following peer dependencies:
|
|
38
38
|
|
|
39
|
-
- [React](https://react.dev/) ^
|
|
40
|
-
- [Zustand](https://zustand-demo.pmnd.rs/) ^
|
|
39
|
+
- [React](https://react.dev/) ^18.0.0 || ^19.0.0
|
|
40
|
+
- [Zustand](https://zustand-demo.pmnd.rs/) ^5.0.0 - State management library
|
|
41
41
|
|
|
42
42
|
## Quick Start
|
|
43
43
|
|
package/dist/index.cjs
CHANGED
|
@@ -24,16 +24,18 @@ function normalizeScopeToArray(scope) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// src/store/uiBlockingStore.actions.ts
|
|
27
|
-
|
|
27
|
+
function normalizePriority(priority, fallback = DEFAULT_PRIORITY) {
|
|
28
28
|
return priority !== void 0 ? Math.max(0, priority) : fallback;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
29
|
+
}
|
|
30
|
+
function createMiddlewareContext(action, blockerId, config, prevState) {
|
|
31
|
+
return {
|
|
32
|
+
action,
|
|
33
|
+
blockerId,
|
|
34
|
+
config,
|
|
35
|
+
timestamp: Date.now(),
|
|
36
|
+
...prevState && { prevState }
|
|
37
|
+
};
|
|
38
|
+
}
|
|
37
39
|
var createUIBlockingActions = (set, get) => ({
|
|
38
40
|
// State
|
|
39
41
|
activeBlockers: /* @__PURE__ */ new Map(),
|
|
@@ -65,14 +67,14 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
65
67
|
// Actions
|
|
66
68
|
/**
|
|
67
69
|
* Adds a new blocker or overwrites an existing one.
|
|
68
|
-
*
|
|
70
|
+
*
|
|
69
71
|
* If a blocker with the same ID already exists, it will be replaced and any
|
|
70
72
|
* existing timeout will be cleared. The blocker is active immediately after
|
|
71
73
|
* being added. Triggers middleware with 'add' action.
|
|
72
|
-
*
|
|
74
|
+
*
|
|
73
75
|
* @param id - Unique identifier for the blocker. Must be unique within the store.
|
|
74
76
|
* @param config - Blocker configuration. All fields are optional with defaults applied.
|
|
75
|
-
*
|
|
77
|
+
*
|
|
76
78
|
* @example
|
|
77
79
|
* Basic usage
|
|
78
80
|
* ```ts
|
|
@@ -82,7 +84,7 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
82
84
|
* priority: 70
|
|
83
85
|
* });
|
|
84
86
|
* ```
|
|
85
|
-
*
|
|
87
|
+
*
|
|
86
88
|
* @example
|
|
87
89
|
* With timeout
|
|
88
90
|
* ```ts
|
|
@@ -93,7 +95,7 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
93
95
|
* onTimeout: (id) => console.warn(`${id} timed out`)
|
|
94
96
|
* });
|
|
95
97
|
* ```
|
|
96
|
-
*
|
|
98
|
+
*
|
|
97
99
|
* @see {@link removeBlocker} to remove a blocker
|
|
98
100
|
* @see {@link updateBlocker} to update an existing blocker
|
|
99
101
|
*/
|
|
@@ -144,13 +146,13 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
144
146
|
},
|
|
145
147
|
/**
|
|
146
148
|
* Updates an existing blocker or creates it if it doesn't exist.
|
|
147
|
-
*
|
|
149
|
+
*
|
|
148
150
|
* Merges the provided configuration with existing blocker data. If the timeout
|
|
149
151
|
* is changed, the timeout timer is restarted. Triggers middleware with 'update' action.
|
|
150
|
-
*
|
|
152
|
+
*
|
|
151
153
|
* @param id - Identifier of the blocker to update
|
|
152
154
|
* @param config - Partial configuration to merge with existing blocker data
|
|
153
|
-
*
|
|
155
|
+
*
|
|
154
156
|
* @example
|
|
155
157
|
* Update blocker reason
|
|
156
158
|
* ```ts
|
|
@@ -158,7 +160,7 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
158
160
|
* reason: 'Saving additional data...'
|
|
159
161
|
* });
|
|
160
162
|
* ```
|
|
161
|
-
*
|
|
163
|
+
*
|
|
162
164
|
* @example
|
|
163
165
|
* Extend timeout
|
|
164
166
|
* ```ts
|
|
@@ -166,7 +168,7 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
166
168
|
* timeout: 60000 // Extend to 60 seconds
|
|
167
169
|
* });
|
|
168
170
|
* ```
|
|
169
|
-
*
|
|
171
|
+
*
|
|
170
172
|
* @see {@link addBlocker} to create a new blocker
|
|
171
173
|
*/
|
|
172
174
|
updateBlocker: (id, config = {}) => {
|
|
@@ -242,12 +244,12 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
242
244
|
},
|
|
243
245
|
/**
|
|
244
246
|
* Removes a blocker from the store.
|
|
245
|
-
*
|
|
247
|
+
*
|
|
246
248
|
* Clears any associated timeout and triggers middleware with 'remove' action.
|
|
247
249
|
* Safe to call even if the blocker doesn't exist (no-op in that case).
|
|
248
|
-
*
|
|
250
|
+
*
|
|
249
251
|
* @param id - Identifier of the blocker to remove
|
|
250
|
-
*
|
|
252
|
+
*
|
|
251
253
|
* @example
|
|
252
254
|
* ```ts
|
|
253
255
|
* // Add and remove a blocker
|
|
@@ -255,7 +257,7 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
255
257
|
* // ... later
|
|
256
258
|
* store.getState().removeBlocker('temp');
|
|
257
259
|
* ```
|
|
258
|
-
*
|
|
260
|
+
*
|
|
259
261
|
* @see {@link addBlocker} to add a blocker
|
|
260
262
|
* @see {@link clearAllBlockers} to remove all blockers at once
|
|
261
263
|
*/
|
|
@@ -275,28 +277,28 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
275
277
|
},
|
|
276
278
|
/**
|
|
277
279
|
* Checks if one or more scopes are currently blocked.
|
|
278
|
-
*
|
|
280
|
+
*
|
|
279
281
|
* Returns true if ANY blocker affects the specified scope(s). Global scope
|
|
280
282
|
* blockers will cause this to return true for any scope check.
|
|
281
|
-
*
|
|
283
|
+
*
|
|
282
284
|
* @param scope - Scope(s) to check. Defaults to "global" if not specified.
|
|
283
285
|
* Can be a single scope string or array of scopes.
|
|
284
286
|
* @returns true if any of the specified scopes are currently blocked
|
|
285
|
-
*
|
|
287
|
+
*
|
|
286
288
|
* @example
|
|
287
289
|
* Single scope check
|
|
288
290
|
* ```ts
|
|
289
291
|
* const isFormBlocked = store.getState().isBlocked('form');
|
|
290
292
|
* console.log(isFormBlocked); // true or false
|
|
291
293
|
* ```
|
|
292
|
-
*
|
|
294
|
+
*
|
|
293
295
|
* @example
|
|
294
296
|
* Multiple scopes check
|
|
295
297
|
* ```ts
|
|
296
298
|
* const isBlocked = store.getState().isBlocked(['form', 'navigation']);
|
|
297
299
|
* // Returns true if either 'form' OR 'navigation' has active blockers
|
|
298
300
|
* ```
|
|
299
|
-
*
|
|
301
|
+
*
|
|
300
302
|
* @see {@link getBlockingInfo} for detailed blocker information
|
|
301
303
|
*/
|
|
302
304
|
isBlocked: (scope = DEFAULT_SCOPE) => {
|
|
@@ -315,14 +317,14 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
315
317
|
},
|
|
316
318
|
/**
|
|
317
319
|
* Gets detailed information about all blockers affecting a specific scope.
|
|
318
|
-
*
|
|
320
|
+
*
|
|
319
321
|
* Returns an array of blocker objects sorted by priority (highest first).
|
|
320
322
|
* Includes global blockers and scope-specific blockers. Each blocker object
|
|
321
323
|
* contains id, reason, priority, scope, timestamp, and timeout information.
|
|
322
|
-
*
|
|
324
|
+
*
|
|
323
325
|
* @param scope - Scope to get blocking information for
|
|
324
326
|
* @returns Array of {@link BlockerInfo} objects, sorted by priority descending
|
|
325
|
-
*
|
|
327
|
+
*
|
|
326
328
|
* @example
|
|
327
329
|
* Display blocker details
|
|
328
330
|
* ```ts
|
|
@@ -332,7 +334,7 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
332
334
|
* console.log(`Priority: ${blocker.priority}`);
|
|
333
335
|
* });
|
|
334
336
|
* ```
|
|
335
|
-
*
|
|
337
|
+
*
|
|
336
338
|
* @example
|
|
337
339
|
* Get highest priority blocker
|
|
338
340
|
* ```ts
|
|
@@ -342,7 +344,7 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
342
344
|
* console.log(`Top blocker: ${topBlocker.reason}`);
|
|
343
345
|
* }
|
|
344
346
|
* ```
|
|
345
|
-
*
|
|
347
|
+
*
|
|
346
348
|
* @see {@link isBlocked} for a simple boolean check
|
|
347
349
|
* @see {@link BlockerInfo} for the structure of returned objects
|
|
348
350
|
*/
|
|
@@ -359,16 +361,16 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
359
361
|
},
|
|
360
362
|
/**
|
|
361
363
|
* Removes all active blockers from the store.
|
|
362
|
-
*
|
|
364
|
+
*
|
|
363
365
|
* Clears all timeouts and triggers middleware with 'clear' action.
|
|
364
366
|
* Useful for resetting the blocking state.
|
|
365
|
-
*
|
|
367
|
+
*
|
|
366
368
|
* @example
|
|
367
369
|
* ```ts
|
|
368
370
|
* // Clear all blockers on logout
|
|
369
371
|
* store.getState().clearAllBlockers();
|
|
370
372
|
* ```
|
|
371
|
-
*
|
|
373
|
+
*
|
|
372
374
|
* @see {@link clearBlockersForScope} to clear blockers for a specific scope
|
|
373
375
|
*/
|
|
374
376
|
clearAllBlockers: () => {
|
|
@@ -391,26 +393,26 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
391
393
|
},
|
|
392
394
|
/**
|
|
393
395
|
* Removes all blockers that affect a specific scope.
|
|
394
|
-
*
|
|
396
|
+
*
|
|
395
397
|
* Clears timeouts for removed blockers and triggers middleware with
|
|
396
398
|
* 'clear_scope' action. Global scope blockers are NOT cleared by this method.
|
|
397
|
-
*
|
|
399
|
+
*
|
|
398
400
|
* @param scope - Scope to clear blockers for
|
|
399
|
-
*
|
|
401
|
+
*
|
|
400
402
|
* @example
|
|
401
403
|
* Clear form blockers
|
|
402
404
|
* ```ts
|
|
403
405
|
* // Clear all blockers affecting 'form' scope
|
|
404
406
|
* store.getState().clearBlockersForScope('form');
|
|
405
407
|
* ```
|
|
406
|
-
*
|
|
408
|
+
*
|
|
407
409
|
* @example
|
|
408
410
|
* Clear on navigation
|
|
409
411
|
* ```ts
|
|
410
412
|
* // Clear navigation blockers when user navigates away
|
|
411
413
|
* store.getState().clearBlockersForScope('navigation');
|
|
412
414
|
* ```
|
|
413
|
-
*
|
|
415
|
+
*
|
|
414
416
|
* @see {@link clearAllBlockers} to clear all blockers
|
|
415
417
|
*/
|
|
416
418
|
clearBlockersForScope: (scope) => {
|
|
@@ -498,7 +500,7 @@ function useResolvedStoreWithSelector(selector) {
|
|
|
498
500
|
}
|
|
499
501
|
|
|
500
502
|
// src/hooks/useAsyncAction/useAsyncAction.ts
|
|
501
|
-
|
|
503
|
+
function useAsyncAction(actionId, scope, options) {
|
|
502
504
|
const { addBlocker, removeBlocker } = useResolvedStoreWithSelector((state) => ({
|
|
503
505
|
addBlocker: state.addBlocker,
|
|
504
506
|
removeBlocker: state.removeBlocker
|
|
@@ -524,8 +526,8 @@ var useAsyncAction = (actionId, scope, options) => {
|
|
|
524
526
|
[actionId, scope, options?.timeout, options?.onTimeout, addBlocker, removeBlocker]
|
|
525
527
|
);
|
|
526
528
|
return executeWithBlocking;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
+
}
|
|
530
|
+
function useBlocker(blockerId, config, isActive = true) {
|
|
529
531
|
const { addBlocker, removeBlocker } = useResolvedStoreWithSelector((state) => ({
|
|
530
532
|
addBlocker: state.addBlocker,
|
|
531
533
|
removeBlocker: state.removeBlocker
|
|
@@ -539,7 +541,7 @@ var useBlocker = (blockerId, config, isActive = true) => {
|
|
|
539
541
|
removeBlocker(blockerId);
|
|
540
542
|
};
|
|
541
543
|
}, [blockerId, isActive, addBlocker, removeBlocker]);
|
|
542
|
-
}
|
|
544
|
+
}
|
|
543
545
|
|
|
544
546
|
// src/hooks/useBlocker/useBlocker.utils.ts
|
|
545
547
|
function createBlockerConfig(config) {
|
|
@@ -549,13 +551,13 @@ function createBlockerConfig(config) {
|
|
|
549
551
|
priority: config.priority
|
|
550
552
|
};
|
|
551
553
|
}
|
|
552
|
-
|
|
554
|
+
function useBlockingInfo(scope = DEFAULT_SCOPE) {
|
|
553
555
|
const store = useResolvedStore();
|
|
554
556
|
const activeBlockers = zustand.useStore(store, (state) => state.activeBlockers);
|
|
555
557
|
return react.useMemo(() => {
|
|
556
558
|
return store.getState().getBlockingInfo(scope);
|
|
557
559
|
}, [activeBlockers, scope, store]);
|
|
558
|
-
}
|
|
560
|
+
}
|
|
559
561
|
function useConfigRef(config) {
|
|
560
562
|
const configRef = react.useRef(config);
|
|
561
563
|
react.useEffect(() => {
|
|
@@ -565,7 +567,7 @@ function useConfigRef(config) {
|
|
|
565
567
|
}
|
|
566
568
|
|
|
567
569
|
// src/hooks/useConditionalBlocker/useConditionalBlocker.ts
|
|
568
|
-
|
|
570
|
+
function useConditionalBlocker(blockerId, config) {
|
|
569
571
|
const { addBlocker, removeBlocker } = useResolvedStoreWithSelector((state) => ({
|
|
570
572
|
addBlocker: state.addBlocker,
|
|
571
573
|
removeBlocker: state.removeBlocker
|
|
@@ -601,8 +603,8 @@ var useConditionalBlocker = (blockerId, config) => {
|
|
|
601
603
|
}
|
|
602
604
|
};
|
|
603
605
|
}, [checkCondition, blockerId, removeBlocker]);
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
+
}
|
|
607
|
+
function useConfirmableBlocker(blockerId, config) {
|
|
606
608
|
const [isDialogOpen, setIsDialogOpen] = react.useState(false);
|
|
607
609
|
const [isExecuting, setIsExecuting] = react.useState(false);
|
|
608
610
|
useBlocker(
|
|
@@ -645,12 +647,12 @@ var useConfirmableBlocker = (blockerId, config) => {
|
|
|
645
647
|
onConfirm,
|
|
646
648
|
onCancel
|
|
647
649
|
};
|
|
648
|
-
}
|
|
650
|
+
}
|
|
649
651
|
|
|
650
652
|
// src/hooks/useIsBlocked/useIsBlocked.ts
|
|
651
|
-
|
|
653
|
+
function useIsBlocked(scope) {
|
|
652
654
|
return useResolvedStoreWithSelector((state) => state.isBlocked(scope));
|
|
653
|
-
}
|
|
655
|
+
}
|
|
654
656
|
|
|
655
657
|
// src/hooks/useScheduledBlocker/useScheduledBlocker.utils.ts
|
|
656
658
|
var MAX_TIMEOUT_MS = 2147483647;
|
|
@@ -690,7 +692,7 @@ function isScheduleInPast(startTime, endTime, now) {
|
|
|
690
692
|
}
|
|
691
693
|
|
|
692
694
|
// src/hooks/useScheduledBlocker/useScheduledBlocker.ts
|
|
693
|
-
|
|
695
|
+
function useScheduledBlocker(blockerId, config) {
|
|
694
696
|
const { addBlocker, removeBlocker } = useResolvedStoreWithSelector((state) => ({
|
|
695
697
|
addBlocker: state.addBlocker,
|
|
696
698
|
removeBlocker: state.removeBlocker
|
|
@@ -756,13 +758,13 @@ var useScheduledBlocker = (blockerId, config) => {
|
|
|
756
758
|
removeBlocker(blockerId);
|
|
757
759
|
};
|
|
758
760
|
}, [blockerId, addBlocker, removeBlocker, cleanup]);
|
|
759
|
-
}
|
|
761
|
+
}
|
|
760
762
|
|
|
761
763
|
// src/middleware/analyticsMiddleware.utils.ts
|
|
762
|
-
|
|
764
|
+
function capitalizeFirst(str) {
|
|
763
765
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
+
}
|
|
767
|
+
function buildEventData(context) {
|
|
766
768
|
const eventData = {
|
|
767
769
|
blocker_id: context.blockerId
|
|
768
770
|
};
|
|
@@ -777,33 +779,33 @@ var buildEventData = (context) => {
|
|
|
777
779
|
eventData.priority = priority;
|
|
778
780
|
}
|
|
779
781
|
return eventData;
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
+
}
|
|
783
|
+
function trackGoogleAnalytics(action, eventData) {
|
|
782
784
|
if (window.gtag) {
|
|
783
785
|
window.gtag("event", `ui_blocking_${action}`, eventData);
|
|
784
786
|
}
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
+
}
|
|
788
|
+
function trackMixpanel(action, eventData) {
|
|
787
789
|
if (window.mixpanel) {
|
|
788
790
|
const eventName = `UI Blocking ${action.split("_").map(capitalizeFirst).join(" ")}`;
|
|
789
791
|
window.mixpanel.track(eventName, eventData);
|
|
790
792
|
}
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
+
}
|
|
794
|
+
function trackAmplitude(action, eventData) {
|
|
793
795
|
if (window.amplitude) {
|
|
794
796
|
const eventName = `UI Blocking ${action.split("_").map(capitalizeFirst).join(" ")}`;
|
|
795
797
|
window.amplitude.track(eventName, eventData);
|
|
796
798
|
}
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
+
}
|
|
800
|
+
function trackCustom(trackFn, action, eventData) {
|
|
799
801
|
try {
|
|
800
802
|
trackFn(`ui_blocking_${action}`, eventData);
|
|
801
803
|
} catch {
|
|
802
804
|
}
|
|
803
|
-
}
|
|
805
|
+
}
|
|
804
806
|
|
|
805
807
|
// src/middleware/analyticsMiddleware.ts
|
|
806
|
-
|
|
808
|
+
function trackEvent(config, context, eventData) {
|
|
807
809
|
if ("provider" in config) {
|
|
808
810
|
switch (config.provider) {
|
|
809
811
|
case "ga":
|
|
@@ -820,13 +822,13 @@ var trackEvent = (config, context, eventData) => {
|
|
|
820
822
|
if ("track" in config) {
|
|
821
823
|
trackCustom(config.track, context.action, eventData);
|
|
822
824
|
}
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
+
}
|
|
826
|
+
function createAnalyticsMiddleware(config) {
|
|
825
827
|
return (context) => {
|
|
826
828
|
const eventData = buildEventData(context);
|
|
827
829
|
trackEvent(config, context, eventData);
|
|
828
830
|
};
|
|
829
|
-
}
|
|
831
|
+
}
|
|
830
832
|
|
|
831
833
|
// src/middleware/configureMiddleware.ts
|
|
832
834
|
function configureMiddleware(middlewares) {
|
|
@@ -838,7 +840,7 @@ function configureMiddleware(middlewares) {
|
|
|
838
840
|
}
|
|
839
841
|
|
|
840
842
|
// src/middleware/loggerMiddleware.utils.ts
|
|
841
|
-
|
|
843
|
+
function getActionEmoji(action) {
|
|
842
844
|
switch (action) {
|
|
843
845
|
case "add":
|
|
844
846
|
return "\u2795";
|
|
@@ -855,8 +857,8 @@ var getActionEmoji = (action) => {
|
|
|
855
857
|
default:
|
|
856
858
|
return "\u2753";
|
|
857
859
|
}
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
+
}
|
|
861
|
+
function extractConfigDetails(config) {
|
|
860
862
|
if (!config) {
|
|
861
863
|
return {};
|
|
862
864
|
}
|
|
@@ -869,8 +871,8 @@ var extractConfigDetails = (config) => {
|
|
|
869
871
|
details.priority = priority;
|
|
870
872
|
}
|
|
871
873
|
return details;
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
+
}
|
|
875
|
+
function formatLogData(context) {
|
|
874
876
|
const configDetails = extractConfigDetails(context.config);
|
|
875
877
|
const logData = {};
|
|
876
878
|
if (context.scope !== void 0) {
|
|
@@ -889,26 +891,26 @@ var formatLogData = (context) => {
|
|
|
889
891
|
return configDetails;
|
|
890
892
|
}
|
|
891
893
|
return Object.keys(logData).length === 1 && logData.config ? configDetails : logData;
|
|
892
|
-
}
|
|
894
|
+
}
|
|
893
895
|
|
|
894
896
|
// src/middleware/loggerMiddleware.ts
|
|
895
897
|
var LOG_PREFIX = "[UIBlocking]";
|
|
896
|
-
|
|
898
|
+
function loggerMiddleware(context) {
|
|
897
899
|
const emoji = getActionEmoji(context.action);
|
|
898
900
|
const logData = formatLogData(context);
|
|
899
901
|
console.log(LOG_PREFIX, emoji, context.blockerId, logData);
|
|
900
|
-
}
|
|
902
|
+
}
|
|
901
903
|
|
|
902
904
|
// src/middleware/performanceMiddleware.utils.ts
|
|
903
|
-
|
|
905
|
+
function handleAddAction(blockerId, timestamp, blockStartTimes) {
|
|
904
906
|
blockStartTimes.set(blockerId, timestamp);
|
|
905
|
-
}
|
|
907
|
+
}
|
|
906
908
|
|
|
907
909
|
// src/middleware/performanceMiddleware.ts
|
|
908
910
|
var DEFAULT_SLOW_BLOCK_THRESHOLD = 3e3;
|
|
909
911
|
var ACTION_ADD = "add";
|
|
910
912
|
var ACTION_REMOVE = "remove";
|
|
911
|
-
|
|
913
|
+
function handleRemoveAction(context, blockStartTimes, slowBlockThreshold, onSlowBlock) {
|
|
912
914
|
const startTime = blockStartTimes.get(context.blockerId);
|
|
913
915
|
if (startTime === void 0) {
|
|
914
916
|
return;
|
|
@@ -921,8 +923,8 @@ var handleRemoveAction = (context, blockStartTimes, slowBlockThreshold, onSlowBl
|
|
|
921
923
|
);
|
|
922
924
|
onSlowBlock?.(context.blockerId, duration);
|
|
923
925
|
}
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
+
}
|
|
927
|
+
function createPerformanceMiddleware(config = {}) {
|
|
926
928
|
const { slowBlockThreshold = DEFAULT_SLOW_BLOCK_THRESHOLD, onSlowBlock } = config;
|
|
927
929
|
const blockStartTimes = /* @__PURE__ */ new Map();
|
|
928
930
|
return (context) => {
|
|
@@ -932,7 +934,7 @@ var createPerformanceMiddleware = (config = {}) => {
|
|
|
932
934
|
handleRemoveAction(context, blockStartTimes, slowBlockThreshold, onSlowBlock);
|
|
933
935
|
}
|
|
934
936
|
};
|
|
935
|
-
}
|
|
937
|
+
}
|
|
936
938
|
|
|
937
939
|
// src/createTypedHooks.ts
|
|
938
940
|
function createTypedHooks() {
|