@okyrychenko-dev/react-action-guard 0.3.3 → 0.4.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/LICENSE +1 -1
- package/README.md +120 -10
- package/dist/index.cjs +132 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +172 -2
- package/dist/index.d.ts +172 -2
- package/dist/index.js +129 -16
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -11,13 +11,15 @@
|
|
|
11
11
|
- Priority-based blocking system
|
|
12
12
|
- Scoped blocking (global, specific areas, or multiple scopes)
|
|
13
13
|
- Automatic cleanup on unmount
|
|
14
|
+
- **Timeout mechanism** - auto-remove blockers after specified time
|
|
15
|
+
- **Provider pattern** - isolated stores for SSR, testing, and micro-frontends
|
|
14
16
|
- Advanced hooks for different use cases:
|
|
15
17
|
- Confirmable blockers with custom dialogs
|
|
16
18
|
- Scheduled blocking for maintenance windows
|
|
17
19
|
- Conditional blocking based on application state
|
|
18
|
-
- Async action wrapping
|
|
20
|
+
- Async action wrapping with timeout support
|
|
19
21
|
- Advanced middleware system for analytics, logging, and performance monitoring
|
|
20
|
-
- TypeScript support with full type safety
|
|
22
|
+
- TypeScript support with full type safety (including optional type-safe scopes)
|
|
21
23
|
- Built on Zustand for efficient state management
|
|
22
24
|
- Tree-shakeable - import only what you need
|
|
23
25
|
- Hooks-based API
|
|
@@ -34,8 +36,8 @@ pnpm add @okyrychenko-dev/react-action-guard zustand
|
|
|
34
36
|
|
|
35
37
|
This package requires the following peer dependencies:
|
|
36
38
|
|
|
37
|
-
- [React](https://react.dev/) ^17.0.0 || ^18.0.0
|
|
38
|
-
- [Zustand](https://zustand-demo.pmnd.rs/) - State management library
|
|
39
|
+
- [React](https://react.dev/) ^17.0.0 || ^18.0.0 || ^19.0.0
|
|
40
|
+
- [Zustand](https://zustand-demo.pmnd.rs/) ^4.5.7 || ^5.0.0 - State management library
|
|
39
41
|
|
|
40
42
|
## Quick Start
|
|
41
43
|
|
|
@@ -74,6 +76,8 @@ Automatically adds a blocker when the component mounts and removes it on unmount
|
|
|
74
76
|
- `scope?: string | string[]` - Scope(s) to block (default: "global")
|
|
75
77
|
- `reason?: string` - Reason for blocking (for debugging)
|
|
76
78
|
- `priority?: number` - Priority level (higher = more important)
|
|
79
|
+
- `timeout?: number` - Auto-remove after N milliseconds
|
|
80
|
+
- `onTimeout?: (blockerId: string) => void` - Callback when auto-removed
|
|
77
81
|
- `isActive?: boolean` - Whether the blocker is active (default: true)
|
|
78
82
|
|
|
79
83
|
**Example:**
|
|
@@ -88,6 +92,33 @@ function MyComponent() {
|
|
|
88
92
|
|
|
89
93
|
return <div>Content</div>;
|
|
90
94
|
}
|
|
95
|
+
|
|
96
|
+
// With timeout - auto-removes after 30 seconds
|
|
97
|
+
function SaveButton() {
|
|
98
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
99
|
+
|
|
100
|
+
useBlocker("save-operation", {
|
|
101
|
+
scope: "form",
|
|
102
|
+
reason: "Saving...",
|
|
103
|
+
timeout: 30000,
|
|
104
|
+
onTimeout: (id) => {
|
|
105
|
+
console.warn(`Operation ${id} timed out`);
|
|
106
|
+
showNotification("Operation timed out");
|
|
107
|
+
setIsSaving(false);
|
|
108
|
+
},
|
|
109
|
+
}, isSaving);
|
|
110
|
+
|
|
111
|
+
const handleSave = async () => {
|
|
112
|
+
setIsSaving(true);
|
|
113
|
+
try {
|
|
114
|
+
await saveData();
|
|
115
|
+
} finally {
|
|
116
|
+
setIsSaving(false);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
return <button onClick={handleSave} disabled={isSaving}>Save</button>;
|
|
121
|
+
}
|
|
91
122
|
```
|
|
92
123
|
|
|
93
124
|
#### `useIsBlocked(scope)`
|
|
@@ -147,7 +178,7 @@ function CheckoutButton() {
|
|
|
147
178
|
}
|
|
148
179
|
```
|
|
149
180
|
|
|
150
|
-
#### `useAsyncAction(actionId, scope)`
|
|
181
|
+
#### `useAsyncAction(actionId, scope, options)`
|
|
151
182
|
|
|
152
183
|
Wraps an async function with automatic blocking/unblocking.
|
|
153
184
|
|
|
@@ -155,6 +186,9 @@ Wraps an async function with automatic blocking/unblocking.
|
|
|
155
186
|
|
|
156
187
|
- `actionId: string` - Identifier for the action
|
|
157
188
|
- `scope?: string | string[]` - Scope(s) to block during execution
|
|
189
|
+
- `options?: UseAsyncActionOptions` - Optional configuration
|
|
190
|
+
- `timeout?: number` - Auto-remove blocker after N milliseconds
|
|
191
|
+
- `onTimeout?: (blockerId: string) => void` - Callback when timed out
|
|
158
192
|
|
|
159
193
|
**Returns:** `(asyncFn: () => Promise<T>) => Promise<T>` - Function wrapper
|
|
160
194
|
|
|
@@ -172,6 +206,23 @@ function MyComponent() {
|
|
|
172
206
|
|
|
173
207
|
return <button onClick={handleSave}>Save</button>;
|
|
174
208
|
}
|
|
209
|
+
|
|
210
|
+
// With timeout - prevents infinite blocking if operation hangs
|
|
211
|
+
function ApiComponent() {
|
|
212
|
+
const execute = useAsyncAction("api-call", "global", {
|
|
213
|
+
timeout: 60000, // 1 minute timeout
|
|
214
|
+
onTimeout: (id) => {
|
|
215
|
+
showError("Request timed out. Please try again.");
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
const fetchData = () => execute(async () => {
|
|
220
|
+
const response = await fetch("/api/data");
|
|
221
|
+
return response.json();
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
return <button onClick={fetchData}>Fetch Data</button>;
|
|
225
|
+
}
|
|
175
226
|
```
|
|
176
227
|
|
|
177
228
|
#### `useConfirmableBlocker(blockerId, config, options)`
|
|
@@ -196,7 +247,7 @@ Creates a blocker that requires user confirmation before being removed.
|
|
|
196
247
|
**Example:**
|
|
197
248
|
|
|
198
249
|
```jsx
|
|
199
|
-
function UnsavedChangesGuard() {
|
|
250
|
+
function UnsavedChangesGuard({ hasUnsavedChanges, discardChanges }) {
|
|
200
251
|
const { isBlocking, requestRemoval } = useConfirmableBlocker(
|
|
201
252
|
"unsaved-changes",
|
|
202
253
|
{
|
|
@@ -306,6 +357,56 @@ function NetworkStatusBlocker() {
|
|
|
306
357
|
}
|
|
307
358
|
```
|
|
308
359
|
|
|
360
|
+
### Provider (Optional)
|
|
361
|
+
|
|
362
|
+
#### `UIBlockingProvider`
|
|
363
|
+
|
|
364
|
+
Provides an isolated store instance for SSR, testing, or micro-frontends. Without the provider, hooks use a global store.
|
|
365
|
+
|
|
366
|
+
**Props:**
|
|
367
|
+
|
|
368
|
+
- `children: ReactNode` - Child components
|
|
369
|
+
- `enableDevtools?: boolean` - Enable Redux DevTools (default: true in development)
|
|
370
|
+
- `devtoolsName?: string` - Name for DevTools (default: "UIBlocking")
|
|
371
|
+
- `middlewares?: Middleware[]` - Initial middlewares to register
|
|
372
|
+
|
|
373
|
+
**Example:**
|
|
374
|
+
|
|
375
|
+
```jsx
|
|
376
|
+
import { UIBlockingProvider } from "@okyrychenko-dev/react-action-guard";
|
|
377
|
+
|
|
378
|
+
// SSR - each request gets isolated state
|
|
379
|
+
function App() {
|
|
380
|
+
return (
|
|
381
|
+
<UIBlockingProvider>
|
|
382
|
+
<MyApp />
|
|
383
|
+
</UIBlockingProvider>
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Testing - isolated state per test, no cleanup needed
|
|
388
|
+
function renderWithProvider(ui) {
|
|
389
|
+
return render(
|
|
390
|
+
<UIBlockingProvider>{ui}</UIBlockingProvider>
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Micro-frontends - each app has its own blocking state
|
|
395
|
+
function MicroFrontend() {
|
|
396
|
+
return (
|
|
397
|
+
<UIBlockingProvider devtoolsName="MicroApp-Blocking">
|
|
398
|
+
<MicroApp />
|
|
399
|
+
</UIBlockingProvider>
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
#### Context Hooks
|
|
405
|
+
|
|
406
|
+
- `useUIBlockingContext()` - Get store from context (throws if outside provider)
|
|
407
|
+
- `useIsInsideUIBlockingProvider()` - Check if inside a provider
|
|
408
|
+
- `useUIBlockingStoreFromContext(selector)` - Select state from context store
|
|
409
|
+
|
|
309
410
|
### Store
|
|
310
411
|
|
|
311
412
|
#### `useUIBlockingStore`
|
|
@@ -369,7 +470,10 @@ The library includes a powerful middleware system that allows you to hook into b
|
|
|
369
470
|
Track blocker events with your analytics provider (Google Analytics, Mixpanel, Amplitude, or custom).
|
|
370
471
|
|
|
371
472
|
```jsx
|
|
372
|
-
import {
|
|
473
|
+
import {
|
|
474
|
+
configureMiddleware,
|
|
475
|
+
createAnalyticsMiddleware,
|
|
476
|
+
} from "@okyrychenko-dev/react-action-guard";
|
|
373
477
|
|
|
374
478
|
// Google Analytics
|
|
375
479
|
configureMiddleware([createAnalyticsMiddleware({ provider: "ga" })]);
|
|
@@ -405,7 +509,10 @@ configureMiddleware([loggerMiddleware]);
|
|
|
405
509
|
Monitor blocker performance and detect slow operations.
|
|
406
510
|
|
|
407
511
|
```jsx
|
|
408
|
-
import {
|
|
512
|
+
import {
|
|
513
|
+
configureMiddleware,
|
|
514
|
+
createPerformanceMiddleware,
|
|
515
|
+
} from "@okyrychenko-dev/react-action-guard";
|
|
409
516
|
|
|
410
517
|
configureMiddleware([
|
|
411
518
|
createPerformanceMiddleware({
|
|
@@ -475,7 +582,10 @@ The library is fully tree-shakeable. Import only the features you need to keep y
|
|
|
475
582
|
import { useBlocker } from "@okyrychenko-dev/react-action-guard";
|
|
476
583
|
|
|
477
584
|
// Middleware is not included unless you import it
|
|
478
|
-
import {
|
|
585
|
+
import {
|
|
586
|
+
configureMiddleware,
|
|
587
|
+
createAnalyticsMiddleware,
|
|
588
|
+
} from "@okyrychenko-dev/react-action-guard";
|
|
479
589
|
```
|
|
480
590
|
|
|
481
591
|
The package is configured with `"sideEffects": false`, allowing modern bundlers (Webpack, Rollup, Vite) to eliminate unused code automatically.
|
|
@@ -740,4 +850,4 @@ See [CHANGELOG.md](./CHANGELOG.md) for a detailed list of changes in each versio
|
|
|
740
850
|
|
|
741
851
|
## License
|
|
742
852
|
|
|
743
|
-
MIT ©
|
|
853
|
+
MIT © Oleksii Kyrychenko
|
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var react = require('react');
|
|
4
|
-
var middleware = require('zustand/middleware');
|
|
5
4
|
var zustand = require('zustand');
|
|
5
|
+
var middleware = require('zustand/middleware');
|
|
6
6
|
var shallow = require('zustand/shallow');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
8
|
|
|
8
9
|
// src/hooks/useAsyncAction/useAsyncAction.ts
|
|
9
10
|
|
|
@@ -67,13 +68,40 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
67
68
|
*
|
|
68
69
|
*/
|
|
69
70
|
addBlocker: (id, config = {}) => {
|
|
71
|
+
const existingBlocker = get().activeBlockers.get(id);
|
|
72
|
+
if (existingBlocker?.timeoutId) {
|
|
73
|
+
clearTimeout(existingBlocker.timeoutId);
|
|
74
|
+
}
|
|
75
|
+
let timeoutId;
|
|
76
|
+
if (config.timeout && config.timeout > 0) {
|
|
77
|
+
timeoutId = setTimeout(() => {
|
|
78
|
+
if (get().activeBlockers.has(id)) {
|
|
79
|
+
config.onTimeout?.(id);
|
|
80
|
+
void get().runMiddlewares({
|
|
81
|
+
action: "timeout",
|
|
82
|
+
blockerId: id,
|
|
83
|
+
config: {
|
|
84
|
+
scope: config.scope,
|
|
85
|
+
reason: config.reason,
|
|
86
|
+
priority: config.priority,
|
|
87
|
+
timeout: config.timeout
|
|
88
|
+
},
|
|
89
|
+
timestamp: Date.now()
|
|
90
|
+
});
|
|
91
|
+
get().removeBlocker(id);
|
|
92
|
+
}
|
|
93
|
+
}, config.timeout);
|
|
94
|
+
}
|
|
70
95
|
set((state) => {
|
|
71
96
|
const newBlockers = new Map(state.activeBlockers);
|
|
72
97
|
const storedBlocker = {
|
|
73
98
|
scope: config.scope ?? DEFAULT_SCOPE,
|
|
74
99
|
reason: config.reason ?? DEFAULT_REASON,
|
|
75
100
|
priority: config.priority ?? DEFAULT_PRIORITY,
|
|
76
|
-
timestamp: config.timestamp ?? Date.now()
|
|
101
|
+
timestamp: config.timestamp ?? Date.now(),
|
|
102
|
+
timeout: config.timeout,
|
|
103
|
+
timeoutId,
|
|
104
|
+
onTimeout: config.onTimeout
|
|
77
105
|
};
|
|
78
106
|
newBlockers.set(id, storedBlocker);
|
|
79
107
|
return { activeBlockers: newBlockers };
|
|
@@ -84,7 +112,8 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
84
112
|
config: {
|
|
85
113
|
scope: config.scope,
|
|
86
114
|
reason: config.reason,
|
|
87
|
-
priority: config.priority
|
|
115
|
+
priority: config.priority,
|
|
116
|
+
timeout: config.timeout
|
|
88
117
|
},
|
|
89
118
|
timestamp: Date.now()
|
|
90
119
|
});
|
|
@@ -97,6 +126,9 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
97
126
|
*/
|
|
98
127
|
removeBlocker: (id) => {
|
|
99
128
|
const prevBlocker = get().activeBlockers.get(id);
|
|
129
|
+
if (prevBlocker?.timeoutId) {
|
|
130
|
+
clearTimeout(prevBlocker.timeoutId);
|
|
131
|
+
}
|
|
100
132
|
set((state) => {
|
|
101
133
|
const newBlockers = new Map(state.activeBlockers);
|
|
102
134
|
newBlockers.delete(id);
|
|
@@ -155,6 +187,12 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
155
187
|
* Clear all blockers from the store
|
|
156
188
|
*/
|
|
157
189
|
clearAllBlockers: () => {
|
|
190
|
+
const { activeBlockers } = get();
|
|
191
|
+
for (const [, blocker] of activeBlockers) {
|
|
192
|
+
if (blocker.timeoutId) {
|
|
193
|
+
clearTimeout(blocker.timeoutId);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
158
196
|
set({ activeBlockers: /* @__PURE__ */ new Map() });
|
|
159
197
|
},
|
|
160
198
|
/**
|
|
@@ -164,6 +202,13 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
164
202
|
*
|
|
165
203
|
*/
|
|
166
204
|
clearBlockersForScope: (scope) => {
|
|
205
|
+
const { activeBlockers } = get();
|
|
206
|
+
for (const [, blocker] of activeBlockers) {
|
|
207
|
+
const blockerScopes = normalizeScopeToArray(blocker.scope);
|
|
208
|
+
if (blockerScopes.includes(scope) && blocker.timeoutId) {
|
|
209
|
+
clearTimeout(blocker.timeoutId);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
167
212
|
set((state) => {
|
|
168
213
|
const newBlockers = /* @__PURE__ */ new Map();
|
|
169
214
|
for (const [id, blocker] of state.activeBlockers) {
|
|
@@ -176,6 +221,45 @@ var createUIBlockingActions = (set, get) => ({
|
|
|
176
221
|
});
|
|
177
222
|
}
|
|
178
223
|
});
|
|
224
|
+
var UIBlockingContext = react.createContext(null);
|
|
225
|
+
function UIBlockingProvider({
|
|
226
|
+
children,
|
|
227
|
+
enableDevtools = process.env.NODE_ENV === "development",
|
|
228
|
+
devtoolsName = "UIBlocking",
|
|
229
|
+
middlewares = []
|
|
230
|
+
}) {
|
|
231
|
+
const middlewaresRef = react.useRef(middlewares);
|
|
232
|
+
const store = react.useMemo(() => {
|
|
233
|
+
const baseStore = enableDevtools ? zustand.createStore(
|
|
234
|
+
middleware.devtools(createUIBlockingActions, {
|
|
235
|
+
name: devtoolsName,
|
|
236
|
+
enabled: enableDevtools
|
|
237
|
+
})
|
|
238
|
+
) : zustand.createStore(createUIBlockingActions);
|
|
239
|
+
middlewaresRef.current.forEach((mw, index) => {
|
|
240
|
+
baseStore.getState().registerMiddleware(`provider-middleware-${index.toString()}`, mw);
|
|
241
|
+
});
|
|
242
|
+
return baseStore;
|
|
243
|
+
}, [enableDevtools, devtoolsName]);
|
|
244
|
+
return /* @__PURE__ */ jsxRuntime.jsx(UIBlockingContext.Provider, { value: store, children });
|
|
245
|
+
}
|
|
246
|
+
function useUIBlockingContext() {
|
|
247
|
+
const store = react.useContext(UIBlockingContext);
|
|
248
|
+
if (!store) {
|
|
249
|
+
throw new Error(
|
|
250
|
+
"useUIBlockingContext must be used within UIBlockingProvider. Either wrap your app in <UIBlockingProvider> or use the global store via useUIBlockingStore."
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
return store;
|
|
254
|
+
}
|
|
255
|
+
function useIsInsideUIBlockingProvider() {
|
|
256
|
+
const store = react.useContext(UIBlockingContext);
|
|
257
|
+
return store !== null;
|
|
258
|
+
}
|
|
259
|
+
function useUIBlockingStoreFromContext(selector) {
|
|
260
|
+
const store = useUIBlockingContext();
|
|
261
|
+
return zustand.useStore(store, shallow.useShallow(selector));
|
|
262
|
+
}
|
|
179
263
|
|
|
180
264
|
// src/store/uiBlockingStore.config.ts
|
|
181
265
|
var devtoolsConfig = {
|
|
@@ -186,9 +270,19 @@ var devtoolsConfig = {
|
|
|
186
270
|
// src/store/uiBlockingStore.store.ts
|
|
187
271
|
var { useStore: useUIBlockingStore, useStoreApi: uiBlockingStoreApi } = createShallowStore(middleware.devtools(createUIBlockingActions, devtoolsConfig));
|
|
188
272
|
|
|
273
|
+
// src/context/useResolvedStore.ts
|
|
274
|
+
function useResolvedStore() {
|
|
275
|
+
const contextStore = react.useContext(UIBlockingContext);
|
|
276
|
+
return contextStore ?? uiBlockingStoreApi;
|
|
277
|
+
}
|
|
278
|
+
function useResolvedStoreWithSelector(selector) {
|
|
279
|
+
const store = useResolvedStore();
|
|
280
|
+
return zustand.useStore(store, shallow.useShallow(selector));
|
|
281
|
+
}
|
|
282
|
+
|
|
189
283
|
// src/hooks/useAsyncAction/useAsyncAction.ts
|
|
190
|
-
var useAsyncAction = (actionId, scope) => {
|
|
191
|
-
const { addBlocker, removeBlocker } =
|
|
284
|
+
var useAsyncAction = (actionId, scope, options) => {
|
|
285
|
+
const { addBlocker, removeBlocker } = useResolvedStoreWithSelector((state) => ({
|
|
192
286
|
addBlocker: state.addBlocker,
|
|
193
287
|
removeBlocker: state.removeBlocker
|
|
194
288
|
}));
|
|
@@ -199,19 +293,21 @@ var useAsyncAction = (actionId, scope) => {
|
|
|
199
293
|
addBlocker(blockerId, {
|
|
200
294
|
scope,
|
|
201
295
|
reason: `Executing ${actionId}`,
|
|
202
|
-
priority: ASYNC_ACTION_PRIORITY
|
|
296
|
+
priority: ASYNC_ACTION_PRIORITY,
|
|
297
|
+
timeout: options?.timeout,
|
|
298
|
+
onTimeout: options?.onTimeout
|
|
203
299
|
});
|
|
204
300
|
return await asyncFn();
|
|
205
301
|
} finally {
|
|
206
302
|
removeBlocker(blockerId);
|
|
207
303
|
}
|
|
208
304
|
},
|
|
209
|
-
[actionId, scope, addBlocker, removeBlocker]
|
|
305
|
+
[actionId, scope, options?.timeout, options?.onTimeout, addBlocker, removeBlocker]
|
|
210
306
|
);
|
|
211
307
|
return executeWithBlocking;
|
|
212
308
|
};
|
|
213
309
|
var useBlocker = (blockerId, config, isActive = true) => {
|
|
214
|
-
const { addBlocker, removeBlocker } =
|
|
310
|
+
const { addBlocker, removeBlocker } = useResolvedStoreWithSelector((state) => ({
|
|
215
311
|
addBlocker: state.addBlocker,
|
|
216
312
|
removeBlocker: state.removeBlocker
|
|
217
313
|
}));
|
|
@@ -235,10 +331,11 @@ function createBlockerConfig(config) {
|
|
|
235
331
|
};
|
|
236
332
|
}
|
|
237
333
|
var useBlockingInfo = (scope = DEFAULT_SCOPE) => {
|
|
238
|
-
const
|
|
334
|
+
const store = useResolvedStore();
|
|
335
|
+
const activeBlockers = zustand.useStore(store, (state) => state.activeBlockers);
|
|
239
336
|
return react.useMemo(() => {
|
|
240
|
-
return
|
|
241
|
-
}, [activeBlockers, scope]);
|
|
337
|
+
return store.getState().getBlockingInfo(scope);
|
|
338
|
+
}, [activeBlockers, scope, store]);
|
|
242
339
|
};
|
|
243
340
|
function useConfigRef(config) {
|
|
244
341
|
const configRef = react.useRef(config);
|
|
@@ -250,7 +347,7 @@ function useConfigRef(config) {
|
|
|
250
347
|
|
|
251
348
|
// src/hooks/useConditionalBlocker/useConditionalBlocker.ts
|
|
252
349
|
var useConditionalBlocker = (blockerId, config) => {
|
|
253
|
-
const { addBlocker, removeBlocker } =
|
|
350
|
+
const { addBlocker, removeBlocker } = useResolvedStoreWithSelector((state) => ({
|
|
254
351
|
addBlocker: state.addBlocker,
|
|
255
352
|
removeBlocker: state.removeBlocker
|
|
256
353
|
}));
|
|
@@ -333,7 +430,7 @@ var useConfirmableBlocker = (blockerId, config) => {
|
|
|
333
430
|
|
|
334
431
|
// src/hooks/useIsBlocked/useIsBlocked.ts
|
|
335
432
|
var useIsBlocked = (scope) => {
|
|
336
|
-
return
|
|
433
|
+
return useResolvedStoreWithSelector((state) => state.isBlocked(scope));
|
|
337
434
|
};
|
|
338
435
|
|
|
339
436
|
// src/hooks/useScheduledBlocker/useScheduledBlocker.utils.ts
|
|
@@ -375,7 +472,7 @@ function isScheduleInPast(startTime, endTime, now) {
|
|
|
375
472
|
|
|
376
473
|
// src/hooks/useScheduledBlocker/useScheduledBlocker.ts
|
|
377
474
|
var useScheduledBlocker = (blockerId, config) => {
|
|
378
|
-
const { addBlocker, removeBlocker } =
|
|
475
|
+
const { addBlocker, removeBlocker } = useResolvedStoreWithSelector((state) => ({
|
|
379
476
|
addBlocker: state.addBlocker,
|
|
380
477
|
removeBlocker: state.removeBlocker
|
|
381
478
|
}));
|
|
@@ -606,9 +703,27 @@ var createPerformanceMiddleware = (config = {}) => {
|
|
|
606
703
|
};
|
|
607
704
|
};
|
|
608
705
|
|
|
706
|
+
// src/createTypedHooks.ts
|
|
707
|
+
function createTypedHooks() {
|
|
708
|
+
return {
|
|
709
|
+
useBlocker: (blockerId, config, isActive) => {
|
|
710
|
+
useBlocker(blockerId, config, isActive);
|
|
711
|
+
},
|
|
712
|
+
useIsBlocked: (scope) => {
|
|
713
|
+
return useIsBlocked(scope);
|
|
714
|
+
},
|
|
715
|
+
useAsyncAction: (actionId, scope, options) => {
|
|
716
|
+
return useAsyncAction(actionId, scope, options);
|
|
717
|
+
},
|
|
718
|
+
useBlockingInfo: (scope) => useBlockingInfo(scope)
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
exports.UIBlockingProvider = UIBlockingProvider;
|
|
609
723
|
exports.configureMiddleware = configureMiddleware;
|
|
610
724
|
exports.createAnalyticsMiddleware = createAnalyticsMiddleware;
|
|
611
725
|
exports.createPerformanceMiddleware = createPerformanceMiddleware;
|
|
726
|
+
exports.createTypedHooks = createTypedHooks;
|
|
612
727
|
exports.loggerMiddleware = loggerMiddleware;
|
|
613
728
|
exports.uiBlockingStoreApi = uiBlockingStoreApi;
|
|
614
729
|
exports.useAsyncAction = useAsyncAction;
|
|
@@ -617,7 +732,10 @@ exports.useBlockingInfo = useBlockingInfo;
|
|
|
617
732
|
exports.useConditionalBlocker = useConditionalBlocker;
|
|
618
733
|
exports.useConfirmableBlocker = useConfirmableBlocker;
|
|
619
734
|
exports.useIsBlocked = useIsBlocked;
|
|
735
|
+
exports.useIsInsideUIBlockingProvider = useIsInsideUIBlockingProvider;
|
|
620
736
|
exports.useScheduledBlocker = useScheduledBlocker;
|
|
737
|
+
exports.useUIBlockingContext = useUIBlockingContext;
|
|
621
738
|
exports.useUIBlockingStore = useUIBlockingStore;
|
|
739
|
+
exports.useUIBlockingStoreFromContext = useUIBlockingStoreFromContext;
|
|
622
740
|
//# sourceMappingURL=index.cjs.map
|
|
623
741
|
//# sourceMappingURL=index.cjs.map
|