@hanzogui/use-async 8.3.1 → 8.3.2

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.
Files changed (91) hide show
  1. package/dist/cjs/errors.js +11 -0
  2. package/dist/cjs/errors.js.map +1 -0
  3. package/dist/cjs/idle.js +50 -0
  4. package/dist/cjs/idle.js.map +1 -0
  5. package/dist/cjs/index.js +8 -0
  6. package/dist/cjs/index.js.map +1 -0
  7. package/dist/cjs/package.json +1 -0
  8. package/dist/cjs/sleep.js +12 -0
  9. package/dist/cjs/sleep.js.map +1 -0
  10. package/dist/cjs/useAsyncEffect.js +60 -0
  11. package/dist/cjs/useAsyncEffect.js.map +1 -0
  12. package/dist/esm/errors.js +7 -0
  13. package/dist/esm/errors.js.map +1 -0
  14. package/dist/esm/idle.js +46 -0
  15. package/dist/esm/idle.js.map +1 -0
  16. package/dist/esm/index.js +5 -5
  17. package/dist/esm/index.js.map +1 -1
  18. package/dist/esm/sleep.js +8 -0
  19. package/dist/esm/sleep.js.map +1 -0
  20. package/dist/esm/useAsyncEffect.js +55 -0
  21. package/dist/esm/useAsyncEffect.js.map +1 -0
  22. package/package.json +20 -15
  23. package/src/errors.d.ts +4 -0
  24. package/src/errors.d.ts.map +1 -0
  25. package/src/errors.js +7 -0
  26. package/src/errors.js.map +1 -0
  27. package/src/idle.d.ts +6 -0
  28. package/src/idle.d.ts.map +1 -0
  29. package/src/idle.js +44 -0
  30. package/src/idle.js.map +1 -0
  31. package/src/idle.ts +2 -2
  32. package/src/index.d.ts +5 -0
  33. package/src/index.d.ts.map +1 -0
  34. package/src/index.js +5 -0
  35. package/src/index.js.map +1 -0
  36. package/src/index.ts +4 -4
  37. package/src/sleep.d.ts +2 -0
  38. package/src/sleep.d.ts.map +1 -0
  39. package/src/sleep.js +8 -0
  40. package/src/sleep.js.map +1 -0
  41. package/src/sleep.ts +1 -1
  42. package/src/useAsyncEffect.d.ts +7 -0
  43. package/src/useAsyncEffect.d.ts.map +1 -0
  44. package/src/useAsyncEffect.js +52 -0
  45. package/src/useAsyncEffect.js.map +1 -0
  46. package/src/useAsyncEffect.ts +1 -1
  47. package/types/errors.d.ts +4 -0
  48. package/types/errors.d.ts.map +1 -0
  49. package/types/idle.d.ts +6 -0
  50. package/types/idle.d.ts.map +1 -0
  51. package/types/index.d.ts +5 -0
  52. package/types/index.d.ts.map +1 -0
  53. package/types/sleep.d.ts +2 -0
  54. package/types/sleep.d.ts.map +1 -0
  55. package/types/useAsyncEffect.d.ts +7 -0
  56. package/types/useAsyncEffect.d.ts.map +1 -0
  57. package/dist/cjs/errors.cjs +0 -33
  58. package/dist/cjs/errors.native.js +0 -148
  59. package/dist/cjs/errors.native.js.map +0 -1
  60. package/dist/cjs/idle.cjs +0 -69
  61. package/dist/cjs/idle.native.js +0 -74
  62. package/dist/cjs/idle.native.js.map +0 -1
  63. package/dist/cjs/index.cjs +0 -23
  64. package/dist/cjs/index.native.js +0 -26
  65. package/dist/cjs/index.native.js.map +0 -1
  66. package/dist/cjs/sleep.cjs +0 -34
  67. package/dist/cjs/sleep.native.js +0 -39
  68. package/dist/cjs/sleep.native.js.map +0 -1
  69. package/dist/cjs/useAsyncEffect.cjs +0 -71
  70. package/dist/cjs/useAsyncEffect.native.js +0 -89
  71. package/dist/cjs/useAsyncEffect.native.js.map +0 -1
  72. package/dist/esm/errors.mjs +0 -8
  73. package/dist/esm/errors.mjs.map +0 -1
  74. package/dist/esm/errors.native.js +0 -120
  75. package/dist/esm/errors.native.js.map +0 -1
  76. package/dist/esm/idle.mjs +0 -44
  77. package/dist/esm/idle.mjs.map +0 -1
  78. package/dist/esm/idle.native.js +0 -46
  79. package/dist/esm/idle.native.js.map +0 -1
  80. package/dist/esm/index.mjs +0 -5
  81. package/dist/esm/index.mjs.map +0 -1
  82. package/dist/esm/index.native.js +0 -5
  83. package/dist/esm/index.native.js.map +0 -1
  84. package/dist/esm/sleep.mjs +0 -9
  85. package/dist/esm/sleep.mjs.map +0 -1
  86. package/dist/esm/sleep.native.js +0 -11
  87. package/dist/esm/sleep.native.js.map +0 -1
  88. package/dist/esm/useAsyncEffect.mjs +0 -44
  89. package/dist/esm/useAsyncEffect.mjs.map +0 -1
  90. package/dist/esm/useAsyncEffect.native.js +0 -59
  91. package/dist/esm/useAsyncEffect.native.js.map +0 -1
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AbortError = void 0;
4
+ class AbortError extends Error {
5
+ constructor(message = '') {
6
+ super(message);
7
+ this.name = 'AbortError';
8
+ }
9
+ }
10
+ exports.AbortError = AbortError;
11
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";;;AAAA,gBAAwB,SAAQ,KAAK;IACnC,YAAY,OAAO,GAAG,EAAE;QACtB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,YAAY,CAAA;IAC1B,CAAC;CACF"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.idle = void 0;
4
+ const errors_ts_1 = require("./errors.js");
5
+ const sleep_ts_1 = require("./sleep.js");
6
+ const idleCb = typeof requestIdleCallback === 'undefined'
7
+ ? (cb) => setTimeout(cb, 1)
8
+ : requestIdleCallback;
9
+ const idleAsync = () => {
10
+ return new Promise((res) => {
11
+ idleCb(res);
12
+ });
13
+ };
14
+ const idle = async (signal, options) => {
15
+ const { max, min, fully } = options || {};
16
+ const idleFn = fully ? fullyIdle : idleAsync;
17
+ if (max && min && min < max) {
18
+ await Promise.race([Promise.all([idleFn(), (0, sleep_ts_1.sleep)(min)]), (0, sleep_ts_1.sleep)(max)]);
19
+ }
20
+ else if (max) {
21
+ await Promise.race([idleFn(), (0, sleep_ts_1.sleep)(max)]);
22
+ }
23
+ else if (min) {
24
+ await Promise.all([idleFn(), (0, sleep_ts_1.sleep)(min)]);
25
+ }
26
+ else {
27
+ await idleFn();
28
+ }
29
+ if (signal?.aborted) {
30
+ throw new errors_ts_1.AbortError();
31
+ }
32
+ };
33
+ exports.idle = idle;
34
+ const fullyIdle = async (signal) => {
35
+ while (true) {
36
+ const startTime = Date.now();
37
+ await (0, exports.idle)(signal);
38
+ const endTime = Date.now();
39
+ const duration = endTime - startTime;
40
+ // If idle callback took less than 15ms, consider it truly idle
41
+ if (duration < 15) {
42
+ break;
43
+ }
44
+ // Check for abort signal after each iteration
45
+ if (signal?.aborted) {
46
+ throw new errors_ts_1.AbortError();
47
+ }
48
+ }
49
+ };
50
+ //# sourceMappingURL=idle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idle.js","sourceRoot":"","sources":["../../src/idle.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AACxC,yCAAkC;AASlC,MAAM,MAAM,GACV,OAAO,mBAAmB,KAAK,WAAW;IACxC,CAAC,CAAC,CAAC,EAAc,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC,mBAAmB,CAAA;AAEzB,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACzB,MAAM,CAAC,GAAG,CAAC,CAAA;IACb,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAEM,MAAM,IAAI,GAAG,KAAK,EACvB,MAAoB,EACpB,OAIC,EACc,EAAE;IACjB,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,OAAO,IAAI,EAAE,CAAA;IAEzC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;IAE5C,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QAC5B,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,IAAA,gBAAK,EAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAA,gBAAK,EAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IACvE,CAAC;SAAM,IAAI,GAAG,EAAE,CAAC;QACf,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,IAAA,gBAAK,EAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC;SAAM,IAAI,GAAG,EAAE,CAAC;QACf,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,IAAA,gBAAK,EAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAC3C,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,EAAE,CAAA;IAChB,CAAC;IAED,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,sBAAU,EAAE,CAAA;IACxB,CAAC;AACH,CAAC,CAAA;AAzBY,QAAA,IAAI,GAAJ,IAAI,CAyBhB;AAED,MAAM,SAAS,GAAG,KAAK,EAAE,MAAoB,EAAiB,EAAE;IAC9D,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC5B,MAAM,IAAA,QAAA,IAAI,EAAC,MAAM,CAAC,CAAA;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC1B,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAA;QAEpC,+DAA+D;QAC/D,IAAI,QAAQ,GAAG,EAAE,EAAE,CAAC;YAClB,MAAK;QACP,CAAC;QAED,8CAA8C;QAC9C,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,sBAAU,EAAE,CAAA;QACxB,CAAC;IACH,CAAC;AACH,CAAC,CAAA"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./useAsyncEffect.js"), exports);
5
+ tslib_1.__exportStar(require("./sleep.js"), exports);
6
+ tslib_1.__exportStar(require("./idle.js"), exports);
7
+ tslib_1.__exportStar(require("./errors.js"), exports);
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,8DAAmC;AACnC,qDAA0B;AAC1B,oDAAyB;AACzB,sDAA2B"}
@@ -0,0 +1 @@
1
+ { "type": "commonjs" }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sleep = void 0;
4
+ const errors_ts_1 = require("./errors.js");
5
+ const sleep = async (ms, signal) => {
6
+ await new Promise((res) => setTimeout(res, ms));
7
+ if (signal?.aborted) {
8
+ throw new errors_ts_1.AbortError();
9
+ }
10
+ };
11
+ exports.sleep = sleep;
12
+ //# sourceMappingURL=sleep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sleep.js","sourceRoot":"","sources":["../../src/sleep.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AAEjC,MAAM,KAAK,GAAG,KAAK,EAAE,EAAU,EAAE,MAAoB,EAAiB,EAAE;IAC7E,MAAM,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;IAC/C,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,sBAAU,EAAE,CAAA;IACxB,CAAC;AACH,CAAC,CAAA;AALY,QAAA,KAAK,GAAL,KAAK,CAKjB"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ // adopted from https://github.com/franciscop/use-async/blob/master/src/index.js
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.useAsyncEffect = useAsyncEffect;
5
+ exports.useAsyncLayoutEffect = useAsyncLayoutEffect;
6
+ exports.useAsyncEffectOfType = useAsyncEffectOfType;
7
+ const react_1 = require("react");
8
+ const errors_ts_1 = require("./errors.js");
9
+ const DEBUG_LEVEL = 0; // You can adjust this based on your needs
10
+ function useAsyncEffect(cb, deps = []) {
11
+ useAsyncEffectOfType(react_1.useEffect, cb, deps);
12
+ }
13
+ function useAsyncLayoutEffect(cb, deps = []) {
14
+ useAsyncEffectOfType(react_1.useLayoutEffect, cb, deps);
15
+ }
16
+ function useAsyncEffectOfType(type, cb, deps = []) {
17
+ type(() => {
18
+ const controller = new AbortController();
19
+ const signal = controller.signal;
20
+ // wrap in try in case its not async (for simple use cases)
21
+ try {
22
+ const value = cb(signal, ...deps);
23
+ Promise.resolve(value)
24
+ .then(async (res) => {
25
+ if (res && typeof res === 'function') {
26
+ if (signal.aborted)
27
+ return res();
28
+ signal.addEventListener('abort', res);
29
+ }
30
+ })
31
+ .catch(handleError);
32
+ }
33
+ catch (error) {
34
+ handleError(error);
35
+ }
36
+ function handleError(error) {
37
+ if (error instanceof errors_ts_1.AbortError) {
38
+ if (DEBUG_LEVEL > 2) {
39
+ console.info(`🐛 useAsyncEffect aborted: ${error.message}`);
40
+ }
41
+ return null;
42
+ }
43
+ // JS handles aborting a promise as an error. Thus, ignore them since they're a normal part
44
+ // of the expected async workflow
45
+ if (typeof error === 'object' && error.name === 'AbortError') {
46
+ return null;
47
+ }
48
+ // Real errors, bubble it up since the CB is expected to handle the
49
+ // errors by itself, so this is like a "fatal error" that should've
50
+ // been handled by the devs
51
+ throw error;
52
+ }
53
+ return () => {
54
+ if (signal.aborted)
55
+ return;
56
+ controller.abort();
57
+ };
58
+ }, deps);
59
+ }
60
+ //# sourceMappingURL=useAsyncEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAsyncEffect.js","sourceRoot":"","sources":["../../src/useAsyncEffect.ts"],"names":[],"mappings":";AAAA,gFAAgF;;;;;AAEhF,iCAAkD;AAClD,2CAAwC;AAExC,MAAM,WAAW,GAAG,CAAC,CAAA,CAAC,0CAA0C;AAShE,wBAA+B,EAAuB,EAAE,IAAI,GAAU,EAAE;IACtE,oBAAoB,CAAC,iBAAS,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;AAC3C,CAAC;AAED,8BAAqC,EAAuB,EAAE,IAAI,GAAU,EAAE;IAC5E,oBAAoB,CAAC,uBAAe,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;AACjD,CAAC;AAED,8BACE,IAAc,EACd,EAAuB,EACvB,IAAI,GAAU,EAAE;IAEhB,IAAI,CAAC,GAAG,EAAE;QACR,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;QACxC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAA;QAEhC,2DAA2D;QAC3D,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;YAEjC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;iBACnB,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;gBAClB,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE,CAAC;oBACrC,IAAI,MAAM,CAAC,OAAO;wBAAE,OAAO,GAAG,EAAE,CAAA;oBAChC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;gBACvC,CAAC;YACH,CAAC,CAAC;iBACD,KAAK,CAAC,WAAW,CAAC,CAAA;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC;QAED,SAAS,WAAW,CAAC,KAAU;YAC7B,IAAI,KAAK,YAAY,sBAAU,EAAE,CAAC;gBAChC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;oBACpB,OAAO,CAAC,IAAI,CAAC,8BAA8B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;gBAC7D,CAAC;gBACD,OAAO,IAAI,CAAA;YACb,CAAC;YAED,2FAA2F;YAC3F,iCAAiC;YACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC7D,OAAO,IAAI,CAAA;YACb,CAAC;YAED,mEAAmE;YACnE,mEAAmE;YACnE,2BAA2B;YAC3B,MAAM,KAAK,CAAA;QACb,CAAC;QAED,OAAO,GAAG,EAAE;YACV,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAM;YAC1B,UAAU,CAAC,KAAK,EAAE,CAAA;QACpB,CAAC,CAAA;IACH,CAAC,EAAE,IAAI,CAAC,CAAA;AACV,CAAC"}
@@ -0,0 +1,7 @@
1
+ export class AbortError extends Error {
2
+ constructor(message = '') {
3
+ super(message);
4
+ this.name = 'AbortError';
5
+ }
6
+ }
7
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAO,GAAG,EAAE;QACtB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,YAAY,CAAA;IAC1B,CAAC;CACF"}
@@ -0,0 +1,46 @@
1
+ import { AbortError } from './errors.js';
2
+ import { sleep } from './sleep.js';
3
+ const idleCb = typeof requestIdleCallback === 'undefined'
4
+ ? (cb) => setTimeout(cb, 1)
5
+ : requestIdleCallback;
6
+ const idleAsync = () => {
7
+ return new Promise((res) => {
8
+ idleCb(res);
9
+ });
10
+ };
11
+ export const idle = async (signal, options) => {
12
+ const { max, min, fully } = options || {};
13
+ const idleFn = fully ? fullyIdle : idleAsync;
14
+ if (max && min && min < max) {
15
+ await Promise.race([Promise.all([idleFn(), sleep(min)]), sleep(max)]);
16
+ }
17
+ else if (max) {
18
+ await Promise.race([idleFn(), sleep(max)]);
19
+ }
20
+ else if (min) {
21
+ await Promise.all([idleFn(), sleep(min)]);
22
+ }
23
+ else {
24
+ await idleFn();
25
+ }
26
+ if (signal?.aborted) {
27
+ throw new AbortError();
28
+ }
29
+ };
30
+ const fullyIdle = async (signal) => {
31
+ while (true) {
32
+ const startTime = Date.now();
33
+ await idle(signal);
34
+ const endTime = Date.now();
35
+ const duration = endTime - startTime;
36
+ // If idle callback took less than 15ms, consider it truly idle
37
+ if (duration < 15) {
38
+ break;
39
+ }
40
+ // Check for abort signal after each iteration
41
+ if (signal?.aborted) {
42
+ throw new AbortError();
43
+ }
44
+ }
45
+ };
46
+ //# sourceMappingURL=idle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idle.js","sourceRoot":"","sources":["../../src/idle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AASlC,MAAM,MAAM,GACV,OAAO,mBAAmB,KAAK,WAAW;IACxC,CAAC,CAAC,CAAC,EAAc,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC,mBAAmB,CAAA;AAEzB,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACzB,MAAM,CAAC,GAAG,CAAC,CAAA;IACb,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EACvB,MAAoB,EACpB,OAIC,EACc,EAAE;IACjB,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,OAAO,IAAI,EAAE,CAAA;IAEzC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;IAE5C,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QAC5B,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IACvE,CAAC;SAAM,IAAI,GAAG,EAAE,CAAC;QACf,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC;SAAM,IAAI,GAAG,EAAE,CAAC;QACf,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAC3C,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,EAAE,CAAA;IAChB,CAAC;IAED,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,UAAU,EAAE,CAAA;IACxB,CAAC;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,KAAK,EAAE,MAAoB,EAAiB,EAAE;IAC9D,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,CAAA;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC1B,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAA;QAEpC,+DAA+D;QAC/D,IAAI,QAAQ,GAAG,EAAE,EAAE,CAAC;YAClB,MAAK;QACP,CAAC;QAED,8CAA8C;QAC9C,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,UAAU,EAAE,CAAA;QACxB,CAAC;IACH,CAAC;AACH,CAAC,CAAA"}
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
- export * from "./useAsyncEffect.mjs";
2
- export * from "./sleep.mjs";
3
- export * from "./idle.mjs";
4
- export * from "./errors.mjs";
5
- //# sourceMappingURL=index.js.map
1
+ export * from './useAsyncEffect.js';
2
+ export * from './sleep.js';
3
+ export * from './idle.js';
4
+ export * from './errors.js';
5
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc","ignoreList":[]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
@@ -0,0 +1,8 @@
1
+ import { AbortError } from './errors.js';
2
+ export const sleep = async (ms, signal) => {
3
+ await new Promise((res) => setTimeout(res, ms));
4
+ if (signal?.aborted) {
5
+ throw new AbortError();
6
+ }
7
+ };
8
+ //# sourceMappingURL=sleep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sleep.js","sourceRoot":"","sources":["../../src/sleep.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,EAAE,EAAU,EAAE,MAAoB,EAAiB,EAAE;IAC7E,MAAM,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;IAC/C,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,UAAU,EAAE,CAAA;IACxB,CAAC;AACH,CAAC,CAAA"}
@@ -0,0 +1,55 @@
1
+ // adopted from https://github.com/franciscop/use-async/blob/master/src/index.js
2
+ import { useEffect, useLayoutEffect } from 'react';
3
+ import { AbortError } from './errors.js';
4
+ const DEBUG_LEVEL = 0; // You can adjust this based on your needs
5
+ export function useAsyncEffect(cb, deps = []) {
6
+ useAsyncEffectOfType(useEffect, cb, deps);
7
+ }
8
+ export function useAsyncLayoutEffect(cb, deps = []) {
9
+ useAsyncEffectOfType(useLayoutEffect, cb, deps);
10
+ }
11
+ export function useAsyncEffectOfType(type, cb, deps = []) {
12
+ type(() => {
13
+ const controller = new AbortController();
14
+ const signal = controller.signal;
15
+ // wrap in try in case its not async (for simple use cases)
16
+ try {
17
+ const value = cb(signal, ...deps);
18
+ Promise.resolve(value)
19
+ .then(async (res) => {
20
+ if (res && typeof res === 'function') {
21
+ if (signal.aborted)
22
+ return res();
23
+ signal.addEventListener('abort', res);
24
+ }
25
+ })
26
+ .catch(handleError);
27
+ }
28
+ catch (error) {
29
+ handleError(error);
30
+ }
31
+ function handleError(error) {
32
+ if (error instanceof AbortError) {
33
+ if (DEBUG_LEVEL > 2) {
34
+ console.info(`🐛 useAsyncEffect aborted: ${error.message}`);
35
+ }
36
+ return null;
37
+ }
38
+ // JS handles aborting a promise as an error. Thus, ignore them since they're a normal part
39
+ // of the expected async workflow
40
+ if (typeof error === 'object' && error.name === 'AbortError') {
41
+ return null;
42
+ }
43
+ // Real errors, bubble it up since the CB is expected to handle the
44
+ // errors by itself, so this is like a "fatal error" that should've
45
+ // been handled by the devs
46
+ throw error;
47
+ }
48
+ return () => {
49
+ if (signal.aborted)
50
+ return;
51
+ controller.abort();
52
+ };
53
+ }, deps);
54
+ }
55
+ //# sourceMappingURL=useAsyncEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAsyncEffect.js","sourceRoot":"","sources":["../../src/useAsyncEffect.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,OAAO,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,MAAM,WAAW,GAAG,CAAC,CAAA,CAAC,0CAA0C;AAShE,MAAM,UAAU,cAAc,CAAC,EAAuB,EAAE,IAAI,GAAU,EAAE;IACtE,oBAAoB,CAAC,SAAS,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;AAC3C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,EAAuB,EAAE,IAAI,GAAU,EAAE;IAC5E,oBAAoB,CAAC,eAAe,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,IAAc,EACd,EAAuB,EACvB,IAAI,GAAU,EAAE;IAEhB,IAAI,CAAC,GAAG,EAAE;QACR,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;QACxC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAA;QAEhC,2DAA2D;QAC3D,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;YAEjC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;iBACnB,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;gBAClB,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE,CAAC;oBACrC,IAAI,MAAM,CAAC,OAAO;wBAAE,OAAO,GAAG,EAAE,CAAA;oBAChC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;gBACvC,CAAC;YACH,CAAC,CAAC;iBACD,KAAK,CAAC,WAAW,CAAC,CAAA;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC;QAED,SAAS,WAAW,CAAC,KAAU;YAC7B,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;gBAChC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;oBACpB,OAAO,CAAC,IAAI,CAAC,8BAA8B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;gBAC7D,CAAC;gBACD,OAAO,IAAI,CAAA;YACb,CAAC;YAED,2FAA2F;YAC3F,iCAAiC;YACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC7D,OAAO,IAAI,CAAA;YACb,CAAC;YAED,mEAAmE;YACnE,mEAAmE;YACnE,2BAA2B;YAC3B,MAAM,KAAK,CAAA;QACb,CAAC;QAED,OAAO,GAAG,EAAE;YACV,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAM;YAC1B,UAAU,CAAC,KAAK,EAAE,CAAA;QACpB,CAAC,CAAA;IACH,CAAC,EAAE,IAAI,CAAC,CAAA;AACV,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzogui/use-async",
3
- "version": "8.3.1",
3
+ "version": "8.3.2",
4
4
  "files": [
5
5
  "src",
6
6
  "types",
@@ -8,35 +8,40 @@
8
8
  ],
9
9
  "type": "module",
10
10
  "sideEffects": false,
11
- "main": "dist/cjs",
12
- "module": "dist/esm",
13
- "types": "./src",
11
+ "main": "./dist/cjs/index.js",
12
+ "module": "./dist/esm/index.js",
13
+ "types": "./types/index.d.ts",
14
14
  "exports": {
15
15
  "./package.json": "./package.json",
16
16
  ".": {
17
- "types": "./src/index.ts",
18
- "react-native": "./dist/esm/index.native.js",
19
- "browser": "./dist/esm/index.mjs",
20
- "module": "./dist/esm/index.mjs",
21
- "import": "./dist/esm/index.mjs",
22
- "require": "./dist/cjs/index.cjs",
23
- "default": "./dist/esm/index.mjs"
17
+ "types": "./types/index.d.ts",
18
+ "react-native": "./dist/esm/index.js",
19
+ "browser": "./dist/esm/index.js",
20
+ "module": "./dist/esm/index.js",
21
+ "import": "./dist/esm/index.js",
22
+ "require": "./dist/cjs/index.js",
23
+ "default": "./dist/esm/index.js"
24
24
  }
25
25
  },
26
26
  "publishConfig": {
27
27
  "access": "public"
28
28
  },
29
29
  "scripts": {
30
- "build": "hanzogui-build --skip-types",
30
+ "build": "hanzogui-build --skip-native",
31
31
  "watch": "hanzogui-build --skip-types --watch",
32
32
  "clean": "hanzogui-build clean",
33
33
  "clean:build": "hanzogui-build clean:build"
34
34
  },
35
35
  "devDependencies": {
36
- "@hanzogui/build": "8.3.1",
37
- "react": ">=19"
36
+ "@hanzogui/build": "8.3.2",
37
+ "react": "19.2.8"
38
38
  },
39
39
  "peerDependencies": {
40
- "react": ">=19"
40
+ "react": ">=19.2.8"
41
+ },
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/hanzoai/gui.git",
45
+ "directory": "pkgs/use-async"
41
46
  }
42
47
  }
@@ -0,0 +1,4 @@
1
+ export declare class AbortError extends Error {
2
+ constructor(message?: string);
3
+ }
4
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["errors.ts"],"names":[],"mappings":"AAAA,qBAAa,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAO,SAAK,EAGvB;CACF"}
package/src/errors.js ADDED
@@ -0,0 +1,7 @@
1
+ export class AbortError extends Error {
2
+ constructor(message = '') {
3
+ super(message)
4
+ this.name = 'AbortError'
5
+ }
6
+ }
7
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAO,GAAG,EAAE;QACtB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,YAAY,CAAA;IAC1B,CAAC;CACF"}
package/src/idle.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export declare const idle: (signal?: AbortSignal, options?: {
2
+ max?: number;
3
+ min?: number;
4
+ fully?: boolean;
5
+ }) => Promise<void>;
6
+ //# sourceMappingURL=idle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idle.d.ts","sourceRoot":"","sources":["idle.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,IAAI,YACN,WAAW,YACV;IACR,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,KACA,OAAO,CAAC,IAAI,CAkBd,CAAA"}
package/src/idle.js ADDED
@@ -0,0 +1,44 @@
1
+ import { AbortError } from './errors.js'
2
+ import { sleep } from './sleep.js'
3
+ const idleCb =
4
+ typeof requestIdleCallback === 'undefined'
5
+ ? (cb) => setTimeout(cb, 1)
6
+ : requestIdleCallback
7
+ const idleAsync = () => {
8
+ return new Promise((res) => {
9
+ idleCb(res)
10
+ })
11
+ }
12
+ export const idle = async (signal, options) => {
13
+ const { max, min, fully } = options || {}
14
+ const idleFn = fully ? fullyIdle : idleAsync
15
+ if (max && min && min < max) {
16
+ await Promise.race([Promise.all([idleFn(), sleep(min)]), sleep(max)])
17
+ } else if (max) {
18
+ await Promise.race([idleFn(), sleep(max)])
19
+ } else if (min) {
20
+ await Promise.all([idleFn(), sleep(min)])
21
+ } else {
22
+ await idleFn()
23
+ }
24
+ if (signal?.aborted) {
25
+ throw new AbortError()
26
+ }
27
+ }
28
+ const fullyIdle = async (signal) => {
29
+ while (true) {
30
+ const startTime = Date.now()
31
+ await idle(signal)
32
+ const endTime = Date.now()
33
+ const duration = endTime - startTime
34
+ // If idle callback took less than 15ms, consider it truly idle
35
+ if (duration < 15) {
36
+ break
37
+ }
38
+ // Check for abort signal after each iteration
39
+ if (signal?.aborted) {
40
+ throw new AbortError()
41
+ }
42
+ }
43
+ }
44
+ //# sourceMappingURL=idle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idle.js","sourceRoot":"","sources":["idle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AASlC,MAAM,MAAM,GACV,OAAO,mBAAmB,KAAK,WAAW;IACxC,CAAC,CAAC,CAAC,EAAc,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC,mBAAmB,CAAA;AAEzB,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACzB,MAAM,CAAC,GAAG,CAAC,CAAA;IACb,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EACvB,MAAoB,EACpB,OAIC,EACc,EAAE;IACjB,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,OAAO,IAAI,EAAE,CAAA;IAEzC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;IAE5C,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QAC5B,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IACvE,CAAC;SAAM,IAAI,GAAG,EAAE,CAAC;QACf,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC;SAAM,IAAI,GAAG,EAAE,CAAC;QACf,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAC3C,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,EAAE,CAAA;IAChB,CAAC;IAED,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,UAAU,EAAE,CAAA;IACxB,CAAC;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,KAAK,EAAE,MAAoB,EAAiB,EAAE;IAC9D,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,CAAA;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC1B,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAA;QAEpC,+DAA+D;QAC/D,IAAI,QAAQ,GAAG,EAAE,EAAE,CAAC;YAClB,MAAK;QACP,CAAC;QAED,8CAA8C;QAC9C,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,UAAU,EAAE,CAAA;QACxB,CAAC;IACH,CAAC;AACH,CAAC,CAAA"}
package/src/idle.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { AbortError } from './errors'
2
- import { sleep } from './sleep'
1
+ import { AbortError } from './errors.ts'
2
+ import { sleep } from './sleep.ts'
3
3
 
4
4
  /**
5
5
  * Two helpers wrapping requestIdleCallback in async, abortable.
package/src/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from './useAsyncEffect.ts';
2
+ export * from './sleep.ts';
3
+ export * from './idle.ts';
4
+ export * from './errors.ts';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
package/src/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from './useAsyncEffect.js'
2
+ export * from './sleep.js'
3
+ export * from './idle.js'
4
+ export * from './errors.js'
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from './useAsyncEffect'
2
- export * from './sleep'
3
- export * from './idle'
4
- export * from './errors'
1
+ export * from './useAsyncEffect.ts'
2
+ export * from './sleep.ts'
3
+ export * from './idle.ts'
4
+ export * from './errors.ts'
package/src/sleep.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare const sleep: (ms: number, signal?: AbortSignal) => Promise<void>;
2
+ //# sourceMappingURL=sleep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sleep.d.ts","sourceRoot":"","sources":["sleep.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,KAAK,OAAc,MAAM,WAAW,WAAW,KAAG,OAAO,CAAC,IAAI,CAK1E,CAAA"}
package/src/sleep.js ADDED
@@ -0,0 +1,8 @@
1
+ import { AbortError } from './errors.js'
2
+ export const sleep = async (ms, signal) => {
3
+ await new Promise((res) => setTimeout(res, ms))
4
+ if (signal?.aborted) {
5
+ throw new AbortError()
6
+ }
7
+ }
8
+ //# sourceMappingURL=sleep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sleep.js","sourceRoot":"","sources":["sleep.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,EAAE,EAAU,EAAE,MAAoB,EAAiB,EAAE;IAC7E,MAAM,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;IAC/C,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,UAAU,EAAE,CAAA;IACxB,CAAC;AACH,CAAC,CAAA"}
package/src/sleep.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AbortError } from './errors'
1
+ import { AbortError } from './errors.ts'
2
2
 
3
3
  export const sleep = async (ms: number, signal?: AbortSignal): Promise<void> => {
4
4
  await new Promise((res) => setTimeout(res, ms))
@@ -0,0 +1,7 @@
1
+ type Cleanup = () => void;
2
+ type AsyncEffectCallback = (signal: AbortSignal, ...deps: any[]) => Promise<Cleanup | void> | void;
3
+ export declare function useAsyncEffect(cb: AsyncEffectCallback, deps?: any[]): void;
4
+ export declare function useAsyncLayoutEffect(cb: AsyncEffectCallback, deps?: any[]): void;
5
+ export declare function useAsyncEffectOfType(type: Function, cb: AsyncEffectCallback, deps?: any[]): void;
6
+ export {};
7
+ //# sourceMappingURL=useAsyncEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAsyncEffect.d.ts","sourceRoot":"","sources":["useAsyncEffect.ts"],"names":[],"mappings":"AAOA,KAAK,OAAO,GAAG,MAAM,IAAI,CAAA;AAEzB,KAAK,mBAAmB,GAAG,CACzB,MAAM,EAAE,WAAW,EACnB,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;AAEnC,wBAAgB,cAAc,CAAC,EAAE,EAAE,mBAAmB,EAAE,IAAI,GAAE,GAAG,EAAO,GAAG,IAAI,CAE9E;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,mBAAmB,EAAE,IAAI,GAAE,GAAG,EAAO,GAAG,IAAI,CAEpF;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,EACd,EAAE,EAAE,mBAAmB,EACvB,IAAI,GAAE,GAAG,EAAO,GACf,IAAI,CA8CN"}
@@ -0,0 +1,52 @@
1
+ // adopted from https://github.com/franciscop/use-async/blob/master/src/index.js
2
+ import { useEffect, useLayoutEffect } from 'react'
3
+ import { AbortError } from './errors.js'
4
+ const DEBUG_LEVEL = 0 // You can adjust this based on your needs
5
+ export function useAsyncEffect(cb, deps = []) {
6
+ useAsyncEffectOfType(useEffect, cb, deps)
7
+ }
8
+ export function useAsyncLayoutEffect(cb, deps = []) {
9
+ useAsyncEffectOfType(useLayoutEffect, cb, deps)
10
+ }
11
+ export function useAsyncEffectOfType(type, cb, deps = []) {
12
+ type(() => {
13
+ const controller = new AbortController()
14
+ const signal = controller.signal
15
+ // wrap in try in case its not async (for simple use cases)
16
+ try {
17
+ const value = cb(signal, ...deps)
18
+ Promise.resolve(value)
19
+ .then(async (res) => {
20
+ if (res && typeof res === 'function') {
21
+ if (signal.aborted) return res()
22
+ signal.addEventListener('abort', res)
23
+ }
24
+ })
25
+ .catch(handleError)
26
+ } catch (error) {
27
+ handleError(error)
28
+ }
29
+ function handleError(error) {
30
+ if (error instanceof AbortError) {
31
+ if (DEBUG_LEVEL > 2) {
32
+ console.info(`🐛 useAsyncEffect aborted: ${error.message}`)
33
+ }
34
+ return null
35
+ }
36
+ // JS handles aborting a promise as an error. Thus, ignore them since they're a normal part
37
+ // of the expected async workflow
38
+ if (typeof error === 'object' && error.name === 'AbortError') {
39
+ return null
40
+ }
41
+ // Real errors, bubble it up since the CB is expected to handle the
42
+ // errors by itself, so this is like a "fatal error" that should've
43
+ // been handled by the devs
44
+ throw error
45
+ }
46
+ return () => {
47
+ if (signal.aborted) return
48
+ controller.abort()
49
+ }
50
+ }, deps)
51
+ }
52
+ //# sourceMappingURL=useAsyncEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAsyncEffect.js","sourceRoot":"","sources":["useAsyncEffect.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,OAAO,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,MAAM,WAAW,GAAG,CAAC,CAAA,CAAC,0CAA0C;AAShE,MAAM,UAAU,cAAc,CAAC,EAAuB,EAAE,IAAI,GAAU,EAAE;IACtE,oBAAoB,CAAC,SAAS,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;AAC3C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,EAAuB,EAAE,IAAI,GAAU,EAAE;IAC5E,oBAAoB,CAAC,eAAe,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,IAAc,EACd,EAAuB,EACvB,IAAI,GAAU,EAAE;IAEhB,IAAI,CAAC,GAAG,EAAE;QACR,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;QACxC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAA;QAEhC,2DAA2D;QAC3D,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;YAEjC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;iBACnB,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;gBAClB,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE,CAAC;oBACrC,IAAI,MAAM,CAAC,OAAO;wBAAE,OAAO,GAAG,EAAE,CAAA;oBAChC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;gBACvC,CAAC;YACH,CAAC,CAAC;iBACD,KAAK,CAAC,WAAW,CAAC,CAAA;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC;QAED,SAAS,WAAW,CAAC,KAAU;YAC7B,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;gBAChC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;oBACpB,OAAO,CAAC,IAAI,CAAC,8BAA8B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;gBAC7D,CAAC;gBACD,OAAO,IAAI,CAAA;YACb,CAAC;YAED,2FAA2F;YAC3F,iCAAiC;YACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC7D,OAAO,IAAI,CAAA;YACb,CAAC;YAED,mEAAmE;YACnE,mEAAmE;YACnE,2BAA2B;YAC3B,MAAM,KAAK,CAAA;QACb,CAAC;QAED,OAAO,GAAG,EAAE;YACV,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAM;YAC1B,UAAU,CAAC,KAAK,EAAE,CAAA;QACpB,CAAC,CAAA;IACH,CAAC,EAAE,IAAI,CAAC,CAAA;AACV,CAAC"}
@@ -1,7 +1,7 @@
1
1
  // adopted from https://github.com/franciscop/use-async/blob/master/src/index.js
2
2
 
3
3
  import { useEffect, useLayoutEffect } from 'react'
4
- import { AbortError } from './errors'
4
+ import { AbortError } from './errors.ts'
5
5
 
6
6
  const DEBUG_LEVEL = 0 // You can adjust this based on your needs
7
7