@sohanemon/utils 5.1.8 → 5.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.
@@ -1,7 +1,8 @@
1
- type Task = () => Promise<void> | void;
2
- interface ScheduleOpts {
1
+ export type Task = () => Promise<void> | void;
2
+ export interface ScheduleOpts {
3
3
  retry?: number;
4
4
  delay?: number;
5
+ timeout?: number;
5
6
  }
6
7
  /**
7
8
  * Runs a function asynchronously in the background.
@@ -9,4 +10,3 @@ interface ScheduleOpts {
9
10
  * Logs total time taken.
10
11
  */
11
12
  export declare function schedule(task: Task, options?: ScheduleOpts): void;
12
- export {};
@@ -0,0 +1,36 @@
1
+ import * as React from 'react';
2
+ import { ScheduleOpts } from '../functions';
3
+ import { Task } from '../functions/schedule';
4
+ /**
5
+ * useSchedule — run non-urgent work later, without blocking UI.
6
+ */
7
+ export declare function useSchedule(options?: ScheduleOpts): (task: Task) => void;
8
+ /**
9
+ * useScheduledEffect — Runs a non-urgent task in a React component without blocking UI rendering.
10
+ *
11
+ * This hook is like `useEffect`, but the provided task is executed
12
+ * with low priority using `requestIdleCallback` (if available)
13
+ * or a fallback scheduler. Useful for heavy computations, logging,
14
+ * analytics, or background work that doesn't need to block render.
15
+ *
16
+ * @param {Task} task - The function to run later. Can be synchronous or return a Promise.
17
+ * @param {React.DependencyList[]} deps - Dependency array; task will re-run whenever these change.
18
+ * @param {ScheduleOpts} [options] - Optional scheduling options.
19
+ * @param {number} [options.timeout] - Max time (ms) to wait before executing the task. Defaults to 10000.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * import React from 'react';
24
+ * import { useScheduledEffect } from './hooks/useScheduledEffect';
25
+ *
26
+ * function MyComponent({ userId }: { userId: string }) {
27
+ * useScheduledEffect(() => {
28
+ * // non-blocking analytics or heavy work
29
+ * console.log('Sending analytics for user:', userId);
30
+ * }, [userId], { timeout: 5000 });
31
+ *
32
+ * return <div>Component loaded. Task will run later 😎</div>;
33
+ * }
34
+ * ```
35
+ */
36
+ export declare function useScheduledEffect(task: Task, deps?: React.DependencyList, options?: ScheduleOpts): void;
@@ -0,0 +1,61 @@
1
+ import * as React from 'react';
2
+ import { schedule as _schedule } from '../functions/schedule';
3
+ /**
4
+ * useSchedule — run non-urgent work later, without blocking UI.
5
+ */
6
+ export function useSchedule(options = {}) {
7
+ const { timeout = 10000 } = options;
8
+ const schedule = React.useCallback((task) => {
9
+ const exec = () => {
10
+ try {
11
+ React.startTransition(() => {
12
+ task();
13
+ });
14
+ }
15
+ catch (err) {
16
+ console.log('⚡[schedule.tsx] Failed: ', err);
17
+ }
18
+ };
19
+ if ('requestIdleCallback' in window) {
20
+ requestIdleCallback(exec, { timeout });
21
+ }
22
+ else {
23
+ _schedule(exec);
24
+ }
25
+ }, [timeout]);
26
+ return schedule;
27
+ }
28
+ /**
29
+ * useScheduledEffect — Runs a non-urgent task in a React component without blocking UI rendering.
30
+ *
31
+ * This hook is like `useEffect`, but the provided task is executed
32
+ * with low priority using `requestIdleCallback` (if available)
33
+ * or a fallback scheduler. Useful for heavy computations, logging,
34
+ * analytics, or background work that doesn't need to block render.
35
+ *
36
+ * @param {Task} task - The function to run later. Can be synchronous or return a Promise.
37
+ * @param {React.DependencyList[]} deps - Dependency array; task will re-run whenever these change.
38
+ * @param {ScheduleOpts} [options] - Optional scheduling options.
39
+ * @param {number} [options.timeout] - Max time (ms) to wait before executing the task. Defaults to 10000.
40
+ *
41
+ * @example
42
+ * ```tsx
43
+ * import React from 'react';
44
+ * import { useScheduledEffect } from './hooks/useScheduledEffect';
45
+ *
46
+ * function MyComponent({ userId }: { userId: string }) {
47
+ * useScheduledEffect(() => {
48
+ * // non-blocking analytics or heavy work
49
+ * console.log('Sending analytics for user:', userId);
50
+ * }, [userId], { timeout: 5000 });
51
+ *
52
+ * return <div>Component loaded. Task will run later 😎</div>;
53
+ * }
54
+ * ```
55
+ */
56
+ export function useScheduledEffect(task, deps = [], options = {}) {
57
+ const schedule = useSchedule(options);
58
+ React.useEffect(() => {
59
+ schedule(task);
60
+ }, [schedule, ...deps]);
61
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sohanemon/utils",
3
- "version": "5.1.8",
3
+ "version": "5.2.0",
4
4
  "author": "Sohan Emon <sohanemon@outlook.com>",
5
5
  "description": "",
6
6
  "type": "module",
@@ -44,14 +44,14 @@
44
44
  ],
45
45
  "license": "ISC",
46
46
  "devDependencies": {
47
- "@types/node": "^24.0.3",
48
- "@types/react": "^19.1.8",
49
- "typescript": "^5.8.3"
47
+ "@types/node": "^24.10.0",
48
+ "@types/react": "^19.2.2",
49
+ "typescript": "^5.9.3"
50
50
  },
51
51
  "dependencies": {
52
- "@iconify/react": "^6.0.0",
52
+ "@iconify/react": "^6.0.2",
53
53
  "clsx": "^2.1.1",
54
- "react": "^19.1.0",
54
+ "react": "^19.2.0",
55
55
  "tailwind-merge": "^3.3.1"
56
56
  },
57
57
  "packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977"