@okyrychenko-dev/react-action-guard 0.1.0 → 0.2.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/dist/index.d.cts CHANGED
@@ -1,5 +1,43 @@
1
1
  import * as zustand from 'zustand';
2
2
 
3
+ type BlockingAction = "add" | "remove" | "update" | "cancel" | "timeout";
4
+ type MiddlewareBlockerConfig = BlockerConfig;
5
+ interface MiddlewareContext {
6
+ action: BlockingAction;
7
+ blockerId: string;
8
+ config?: MiddlewareBlockerConfig;
9
+ timestamp: number;
10
+ prevState?: MiddlewareBlockerConfig;
11
+ }
12
+ type Middleware = (context: MiddlewareContext) => void | Promise<void>;
13
+
14
+ declare const loggerMiddleware: Middleware;
15
+
16
+ type AnalyticsEventData = Record<string, string | number | ReadonlyArray<string> | undefined>;
17
+ type AnalyticsProvider = "ga" | "mixpanel" | "amplitude";
18
+ interface GoogleAnalyticsConfig {
19
+ provider: "ga";
20
+ }
21
+ interface MixpanelConfig {
22
+ provider: "mixpanel";
23
+ }
24
+ interface AmplitudeConfig {
25
+ provider: "amplitude";
26
+ }
27
+ interface CustomAnalyticsConfig {
28
+ track: (event: string, data: AnalyticsEventData) => void;
29
+ }
30
+ type AnalyticsConfig = GoogleAnalyticsConfig | MixpanelConfig | AmplitudeConfig | CustomAnalyticsConfig;
31
+
32
+ declare const createAnalyticsMiddleware: (config: AnalyticsConfig) => Middleware;
33
+
34
+ interface PerformanceConfig {
35
+ slowBlockThreshold?: number;
36
+ onSlowBlock?: (blockerId: string, duration: number) => void;
37
+ }
38
+
39
+ declare const createPerformanceMiddleware: (config?: PerformanceConfig) => Middleware;
40
+
3
41
  /**
4
42
  * Configuration for a blocker
5
43
  */
@@ -29,6 +67,7 @@ interface BlockerInfo extends StoredBlocker {
29
67
  */
30
68
  interface UIBlockingStoreState {
31
69
  activeBlockers: Map<string, StoredBlocker>;
70
+ middlewares: Map<string, Middleware>;
32
71
  }
33
72
  /**
34
73
  * Store actions
@@ -38,8 +77,11 @@ interface UIBlockingStoreActions {
38
77
  removeBlocker: (id: string) => void;
39
78
  isBlocked: (scope?: string | ReadonlyArray<string>) => boolean;
40
79
  getBlockingInfo: (scope: string) => ReadonlyArray<BlockerInfo>;
41
- clearAllBlockers: () => void;
80
+ clearAllBlockers: VoidFunction;
42
81
  clearBlockersForScope: (scope: string) => void;
82
+ registerMiddleware: (name: string, middleware: Middleware) => void;
83
+ unregisterMiddleware: (name: string) => void;
84
+ runMiddlewares: (context: MiddlewareContext) => Promise<void>;
43
85
  }
44
86
  /**
45
87
  * Complete store type (state + actions)
@@ -115,4 +157,122 @@ declare const useIsBlocked: (scope?: string | ReadonlyArray<string>) => boolean;
115
157
  */
116
158
  declare const useAsyncAction: <T = unknown>(actionId: string, scope?: string | ReadonlyArray<string>) => ((asyncFn: () => Promise<T>) => Promise<T>);
117
159
 
118
- export { type BlockerConfig, type BlockerInfo, type StoredBlocker, type UIBlockingStore, type UIBlockingStoreActions, type UIBlockingStoreState, useAsyncAction, useBlocker, useIsBlocked, useUIBlockingStore };
160
+ /**
161
+ * Configuration for conditional blocker hook.
162
+ *
163
+ * Note: Unlike the base BlockerConfig, the scope property is required here
164
+ * because conditional blockers must have a defined scope to check against.
165
+ */
166
+ interface ConditionalBlockerConfig<TState = unknown> extends Omit<BlockerConfig, "scope"> {
167
+ /** Required scope(s) to block. Unlike base BlockerConfig, this is mandatory for conditional blockers. */
168
+ scope: string | ReadonlyArray<string>;
169
+ /** Function that determines whether blocking should be active */
170
+ condition: (state?: TState) => boolean;
171
+ /** Interval in milliseconds to check the condition (default: 1000ms) */
172
+ checkInterval?: number;
173
+ /** Optional state to pass to the condition function */
174
+ state?: TState;
175
+ }
176
+
177
+ /**
178
+ * Hook for conditional blocking based on a condition function.
179
+ *
180
+ * Periodically checks a condition and blocks/unblocks based on the result.
181
+ * The condition is evaluated at the specified interval (default 1000ms).
182
+ *
183
+ * @param blockerId - Unique identifier for this blocker
184
+ * @param config - Configuration including condition function and check interval
185
+ *
186
+ */
187
+ declare const useConditionalBlocker: <TState = unknown>(blockerId: string, config: ConditionalBlockerConfig<TState>) => void;
188
+
189
+ /**
190
+ * Configuration for the confirmation dialog
191
+ */
192
+ interface ConfirmDialogConfig {
193
+ title: string;
194
+ message: string;
195
+ confirmText: string;
196
+ cancelText: string;
197
+ }
198
+ /**
199
+ * Configuration for confirmable blocker hook.
200
+ *
201
+ * The reason property can be used to provide a different blocking reason
202
+ * than the confirmMessage. If not provided, confirmMessage will be used as the reason.
203
+ */
204
+ interface ConfirmableBlockerConfig extends BlockerConfig {
205
+ /** Message to display in the confirmation dialog */
206
+ confirmMessage: string;
207
+ /** Title for the confirmation dialog (default: "Confirm Action") */
208
+ confirmTitle?: string;
209
+ /** Text for the confirm button (default: "Confirm") */
210
+ confirmButtonText?: string;
211
+ /** Text for the cancel button (default: "Cancel") */
212
+ cancelButtonText?: string;
213
+ /** Callback to execute when confirmed. Can be async. */
214
+ onConfirm: () => void | Promise<void>;
215
+ /** Optional callback to execute when cancelled */
216
+ onCancel?: VoidFunction;
217
+ }
218
+ /**
219
+ * Return type for useConfirmableBlocker hook
220
+ */
221
+ interface UseConfirmableBlockerReturn {
222
+ execute: VoidFunction;
223
+ isDialogOpen: boolean;
224
+ isExecuting: boolean;
225
+ confirmConfig: ConfirmDialogConfig;
226
+ onConfirm: () => Promise<void>;
227
+ onCancel: VoidFunction;
228
+ }
229
+
230
+ /**
231
+ * Hook for creating a confirmable action with blocking UI
232
+ *
233
+ */
234
+ declare const useConfirmableBlocker: (blockerId: string, config: ConfirmableBlockerConfig) => UseConfirmableBlockerReturn;
235
+
236
+ /**
237
+ * Schedule configuration for time-based blocking.
238
+ *
239
+ * You can specify the blocking period in two ways:
240
+ * 1. start + duration: Block for a specific duration after start time
241
+ * 2. start + end: Block between start and end times
242
+ *
243
+ * Note: If both duration and end are provided, duration takes precedence.
244
+ */
245
+ interface BlockingSchedule {
246
+ /** Start time as ISO string, Date object, or timestamp */
247
+ start: string | Date | number;
248
+ /** Optional end time as ISO string, Date object, or timestamp */
249
+ end?: string | Date | number;
250
+ /** Duration in milliseconds (takes precedence over end if both provided) */
251
+ duration?: number;
252
+ }
253
+ /**
254
+ * Configuration for scheduled blocker hook
255
+ */
256
+ interface ScheduledBlockerConfig extends BlockerConfig {
257
+ /** Schedule defining when blocking should be active */
258
+ schedule: BlockingSchedule;
259
+ /** Optional callback to execute when the blocking schedule starts */
260
+ onScheduleStart?: VoidFunction;
261
+ /** Optional callback to execute when the blocking schedule ends */
262
+ onScheduleEnd?: VoidFunction;
263
+ }
264
+
265
+ /**
266
+ * Hook for scheduling UI blocking for a specific time period.
267
+ *
268
+ * Blocks UI during a scheduled maintenance window or time period.
269
+ * Supports start/end times as Date objects, ISO strings, or timestamps.
270
+ * If both duration and end are provided, duration takes precedence.
271
+ *
272
+ * @param blockerId - Unique identifier for this blocker
273
+ * @param config - Configuration including schedule and callbacks
274
+ *
275
+ */
276
+ declare const useScheduledBlocker: (blockerId: string, config: ScheduledBlockerConfig) => void;
277
+
278
+ export { type AmplitudeConfig, type AnalyticsConfig, type AnalyticsEventData, type AnalyticsProvider, type BlockerConfig, type BlockerInfo, type BlockingAction, type BlockingSchedule, type ConditionalBlockerConfig, type ConfirmDialogConfig, type ConfirmableBlockerConfig, type CustomAnalyticsConfig, type GoogleAnalyticsConfig, type Middleware, type MiddlewareContext, type MixpanelConfig, type PerformanceConfig, type ScheduledBlockerConfig, type StoredBlocker, type UIBlockingStore, type UIBlockingStoreActions, type UIBlockingStoreState, type UseConfirmableBlockerReturn, createAnalyticsMiddleware, createPerformanceMiddleware, loggerMiddleware, useAsyncAction, useBlocker, useConditionalBlocker, useConfirmableBlocker, useIsBlocked, useScheduledBlocker, useUIBlockingStore };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,43 @@
1
1
  import * as zustand from 'zustand';
2
2
 
3
+ type BlockingAction = "add" | "remove" | "update" | "cancel" | "timeout";
4
+ type MiddlewareBlockerConfig = BlockerConfig;
5
+ interface MiddlewareContext {
6
+ action: BlockingAction;
7
+ blockerId: string;
8
+ config?: MiddlewareBlockerConfig;
9
+ timestamp: number;
10
+ prevState?: MiddlewareBlockerConfig;
11
+ }
12
+ type Middleware = (context: MiddlewareContext) => void | Promise<void>;
13
+
14
+ declare const loggerMiddleware: Middleware;
15
+
16
+ type AnalyticsEventData = Record<string, string | number | ReadonlyArray<string> | undefined>;
17
+ type AnalyticsProvider = "ga" | "mixpanel" | "amplitude";
18
+ interface GoogleAnalyticsConfig {
19
+ provider: "ga";
20
+ }
21
+ interface MixpanelConfig {
22
+ provider: "mixpanel";
23
+ }
24
+ interface AmplitudeConfig {
25
+ provider: "amplitude";
26
+ }
27
+ interface CustomAnalyticsConfig {
28
+ track: (event: string, data: AnalyticsEventData) => void;
29
+ }
30
+ type AnalyticsConfig = GoogleAnalyticsConfig | MixpanelConfig | AmplitudeConfig | CustomAnalyticsConfig;
31
+
32
+ declare const createAnalyticsMiddleware: (config: AnalyticsConfig) => Middleware;
33
+
34
+ interface PerformanceConfig {
35
+ slowBlockThreshold?: number;
36
+ onSlowBlock?: (blockerId: string, duration: number) => void;
37
+ }
38
+
39
+ declare const createPerformanceMiddleware: (config?: PerformanceConfig) => Middleware;
40
+
3
41
  /**
4
42
  * Configuration for a blocker
5
43
  */
@@ -29,6 +67,7 @@ interface BlockerInfo extends StoredBlocker {
29
67
  */
30
68
  interface UIBlockingStoreState {
31
69
  activeBlockers: Map<string, StoredBlocker>;
70
+ middlewares: Map<string, Middleware>;
32
71
  }
33
72
  /**
34
73
  * Store actions
@@ -38,8 +77,11 @@ interface UIBlockingStoreActions {
38
77
  removeBlocker: (id: string) => void;
39
78
  isBlocked: (scope?: string | ReadonlyArray<string>) => boolean;
40
79
  getBlockingInfo: (scope: string) => ReadonlyArray<BlockerInfo>;
41
- clearAllBlockers: () => void;
80
+ clearAllBlockers: VoidFunction;
42
81
  clearBlockersForScope: (scope: string) => void;
82
+ registerMiddleware: (name: string, middleware: Middleware) => void;
83
+ unregisterMiddleware: (name: string) => void;
84
+ runMiddlewares: (context: MiddlewareContext) => Promise<void>;
43
85
  }
44
86
  /**
45
87
  * Complete store type (state + actions)
@@ -115,4 +157,122 @@ declare const useIsBlocked: (scope?: string | ReadonlyArray<string>) => boolean;
115
157
  */
116
158
  declare const useAsyncAction: <T = unknown>(actionId: string, scope?: string | ReadonlyArray<string>) => ((asyncFn: () => Promise<T>) => Promise<T>);
117
159
 
118
- export { type BlockerConfig, type BlockerInfo, type StoredBlocker, type UIBlockingStore, type UIBlockingStoreActions, type UIBlockingStoreState, useAsyncAction, useBlocker, useIsBlocked, useUIBlockingStore };
160
+ /**
161
+ * Configuration for conditional blocker hook.
162
+ *
163
+ * Note: Unlike the base BlockerConfig, the scope property is required here
164
+ * because conditional blockers must have a defined scope to check against.
165
+ */
166
+ interface ConditionalBlockerConfig<TState = unknown> extends Omit<BlockerConfig, "scope"> {
167
+ /** Required scope(s) to block. Unlike base BlockerConfig, this is mandatory for conditional blockers. */
168
+ scope: string | ReadonlyArray<string>;
169
+ /** Function that determines whether blocking should be active */
170
+ condition: (state?: TState) => boolean;
171
+ /** Interval in milliseconds to check the condition (default: 1000ms) */
172
+ checkInterval?: number;
173
+ /** Optional state to pass to the condition function */
174
+ state?: TState;
175
+ }
176
+
177
+ /**
178
+ * Hook for conditional blocking based on a condition function.
179
+ *
180
+ * Periodically checks a condition and blocks/unblocks based on the result.
181
+ * The condition is evaluated at the specified interval (default 1000ms).
182
+ *
183
+ * @param blockerId - Unique identifier for this blocker
184
+ * @param config - Configuration including condition function and check interval
185
+ *
186
+ */
187
+ declare const useConditionalBlocker: <TState = unknown>(blockerId: string, config: ConditionalBlockerConfig<TState>) => void;
188
+
189
+ /**
190
+ * Configuration for the confirmation dialog
191
+ */
192
+ interface ConfirmDialogConfig {
193
+ title: string;
194
+ message: string;
195
+ confirmText: string;
196
+ cancelText: string;
197
+ }
198
+ /**
199
+ * Configuration for confirmable blocker hook.
200
+ *
201
+ * The reason property can be used to provide a different blocking reason
202
+ * than the confirmMessage. If not provided, confirmMessage will be used as the reason.
203
+ */
204
+ interface ConfirmableBlockerConfig extends BlockerConfig {
205
+ /** Message to display in the confirmation dialog */
206
+ confirmMessage: string;
207
+ /** Title for the confirmation dialog (default: "Confirm Action") */
208
+ confirmTitle?: string;
209
+ /** Text for the confirm button (default: "Confirm") */
210
+ confirmButtonText?: string;
211
+ /** Text for the cancel button (default: "Cancel") */
212
+ cancelButtonText?: string;
213
+ /** Callback to execute when confirmed. Can be async. */
214
+ onConfirm: () => void | Promise<void>;
215
+ /** Optional callback to execute when cancelled */
216
+ onCancel?: VoidFunction;
217
+ }
218
+ /**
219
+ * Return type for useConfirmableBlocker hook
220
+ */
221
+ interface UseConfirmableBlockerReturn {
222
+ execute: VoidFunction;
223
+ isDialogOpen: boolean;
224
+ isExecuting: boolean;
225
+ confirmConfig: ConfirmDialogConfig;
226
+ onConfirm: () => Promise<void>;
227
+ onCancel: VoidFunction;
228
+ }
229
+
230
+ /**
231
+ * Hook for creating a confirmable action with blocking UI
232
+ *
233
+ */
234
+ declare const useConfirmableBlocker: (blockerId: string, config: ConfirmableBlockerConfig) => UseConfirmableBlockerReturn;
235
+
236
+ /**
237
+ * Schedule configuration for time-based blocking.
238
+ *
239
+ * You can specify the blocking period in two ways:
240
+ * 1. start + duration: Block for a specific duration after start time
241
+ * 2. start + end: Block between start and end times
242
+ *
243
+ * Note: If both duration and end are provided, duration takes precedence.
244
+ */
245
+ interface BlockingSchedule {
246
+ /** Start time as ISO string, Date object, or timestamp */
247
+ start: string | Date | number;
248
+ /** Optional end time as ISO string, Date object, or timestamp */
249
+ end?: string | Date | number;
250
+ /** Duration in milliseconds (takes precedence over end if both provided) */
251
+ duration?: number;
252
+ }
253
+ /**
254
+ * Configuration for scheduled blocker hook
255
+ */
256
+ interface ScheduledBlockerConfig extends BlockerConfig {
257
+ /** Schedule defining when blocking should be active */
258
+ schedule: BlockingSchedule;
259
+ /** Optional callback to execute when the blocking schedule starts */
260
+ onScheduleStart?: VoidFunction;
261
+ /** Optional callback to execute when the blocking schedule ends */
262
+ onScheduleEnd?: VoidFunction;
263
+ }
264
+
265
+ /**
266
+ * Hook for scheduling UI blocking for a specific time period.
267
+ *
268
+ * Blocks UI during a scheduled maintenance window or time period.
269
+ * Supports start/end times as Date objects, ISO strings, or timestamps.
270
+ * If both duration and end are provided, duration takes precedence.
271
+ *
272
+ * @param blockerId - Unique identifier for this blocker
273
+ * @param config - Configuration including schedule and callbacks
274
+ *
275
+ */
276
+ declare const useScheduledBlocker: (blockerId: string, config: ScheduledBlockerConfig) => void;
277
+
278
+ export { type AmplitudeConfig, type AnalyticsConfig, type AnalyticsEventData, type AnalyticsProvider, type BlockerConfig, type BlockerInfo, type BlockingAction, type BlockingSchedule, type ConditionalBlockerConfig, type ConfirmDialogConfig, type ConfirmableBlockerConfig, type CustomAnalyticsConfig, type GoogleAnalyticsConfig, type Middleware, type MiddlewareContext, type MixpanelConfig, type PerformanceConfig, type ScheduledBlockerConfig, type StoredBlocker, type UIBlockingStore, type UIBlockingStoreActions, type UIBlockingStoreState, type UseConfirmableBlockerReturn, createAnalyticsMiddleware, createPerformanceMiddleware, loggerMiddleware, useAsyncAction, useBlocker, useConditionalBlocker, useConfirmableBlocker, useIsBlocked, useScheduledBlocker, useUIBlockingStore };