@tamagui/use-async 1.128.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.
Files changed (62) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/errors.cjs +30 -0
  3. package/dist/cjs/errors.js +25 -0
  4. package/dist/cjs/errors.js.map +6 -0
  5. package/dist/cjs/errors.native.js +124 -0
  6. package/dist/cjs/errors.native.js.map +6 -0
  7. package/dist/cjs/idle.cjs +38 -0
  8. package/dist/cjs/idle.js +34 -0
  9. package/dist/cjs/idle.js.map +6 -0
  10. package/dist/cjs/idle.native.js +45 -0
  11. package/dist/cjs/idle.native.js.map +6 -0
  12. package/dist/cjs/index.cjs +21 -0
  13. package/dist/cjs/index.js +18 -0
  14. package/dist/cjs/index.js.map +6 -0
  15. package/dist/cjs/index.native.js +26 -0
  16. package/dist/cjs/index.native.js.map +6 -0
  17. package/dist/cjs/sleep.cjs +29 -0
  18. package/dist/cjs/sleep.js +25 -0
  19. package/dist/cjs/sleep.js.map +6 -0
  20. package/dist/cjs/sleep.native.js +31 -0
  21. package/dist/cjs/sleep.native.js.map +6 -0
  22. package/dist/cjs/useAsyncEffect.cjs +61 -0
  23. package/dist/cjs/useAsyncEffect.js +56 -0
  24. package/dist/cjs/useAsyncEffect.js.map +6 -0
  25. package/dist/cjs/useAsyncEffect.native.js +65 -0
  26. package/dist/cjs/useAsyncEffect.native.js.map +6 -0
  27. package/dist/esm/errors.js +9 -0
  28. package/dist/esm/errors.js.map +6 -0
  29. package/dist/esm/errors.mjs +7 -0
  30. package/dist/esm/errors.mjs.map +1 -0
  31. package/dist/esm/errors.native.js +94 -0
  32. package/dist/esm/errors.native.js.map +1 -0
  33. package/dist/esm/idle.js +18 -0
  34. package/dist/esm/idle.js.map +6 -0
  35. package/dist/esm/idle.mjs +14 -0
  36. package/dist/esm/idle.mjs.map +1 -0
  37. package/dist/esm/idle.native.js +21 -0
  38. package/dist/esm/idle.native.js.map +1 -0
  39. package/dist/esm/index.js +5 -0
  40. package/dist/esm/index.js.map +6 -0
  41. package/dist/esm/index.mjs +5 -0
  42. package/dist/esm/index.mjs.map +1 -0
  43. package/dist/esm/index.native.js +5 -0
  44. package/dist/esm/index.native.js.map +1 -0
  45. package/dist/esm/sleep.js +9 -0
  46. package/dist/esm/sleep.js.map +6 -0
  47. package/dist/esm/sleep.mjs +6 -0
  48. package/dist/esm/sleep.mjs.map +1 -0
  49. package/dist/esm/sleep.native.js +8 -0
  50. package/dist/esm/sleep.native.js.map +1 -0
  51. package/dist/esm/useAsyncEffect.js +41 -0
  52. package/dist/esm/useAsyncEffect.js.map +6 -0
  53. package/dist/esm/useAsyncEffect.mjs +36 -0
  54. package/dist/esm/useAsyncEffect.mjs.map +1 -0
  55. package/dist/esm/useAsyncEffect.native.js +39 -0
  56. package/dist/esm/useAsyncEffect.native.js.map +1 -0
  57. package/package.json +43 -0
  58. package/src/errors.ts +6 -0
  59. package/src/idle.ts +32 -0
  60. package/src/index.ts +4 -0
  61. package/src/sleep.ts +8 -0
  62. package/src/useAsyncEffect.ts +73 -0
package/src/idle.ts ADDED
@@ -0,0 +1,32 @@
1
+ import { AbortError } from './errors'
2
+
3
+ const idleCb: Function =
4
+ typeof requestIdleCallback === 'undefined'
5
+ ? (cb: Function) => setTimeout(cb, 1)
6
+ : requestIdleCallback
7
+
8
+ export const idle = async (signal?: AbortSignal): Promise<void> => {
9
+ await new Promise((res) => idleCb(res))
10
+ if (signal?.aborted) {
11
+ throw new AbortError()
12
+ }
13
+ }
14
+
15
+ export const fullyIdle = async (signal?: AbortSignal): Promise<void> => {
16
+ while (true) {
17
+ const startTime = Date.now()
18
+ await idle(signal)
19
+ const endTime = Date.now()
20
+ const duration = endTime - startTime
21
+
22
+ // If idle callback took less than 15ms, consider it truly idle
23
+ if (duration < 15) {
24
+ break
25
+ }
26
+
27
+ // Check for abort signal after each iteration
28
+ if (signal?.aborted) {
29
+ throw new AbortError()
30
+ }
31
+ }
32
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from './useAsyncEffect'
2
+ export * from './sleep'
3
+ export * from './idle'
4
+ export * from './errors'
package/src/sleep.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { AbortError } from './errors'
2
+
3
+ export const sleep = async (ms: number, signal?: AbortSignal): Promise<void> => {
4
+ await new Promise((res) => setTimeout(res, ms))
5
+ if (signal?.aborted) {
6
+ throw new AbortError()
7
+ }
8
+ }
@@ -0,0 +1,73 @@
1
+ // adopted from https://github.com/franciscop/use-async/blob/master/src/index.js
2
+
3
+ import { useEffect, useLayoutEffect } from 'react'
4
+ import { AbortError } from './errors'
5
+
6
+ const DEBUG_LEVEL = 0 // You can adjust this based on your needs
7
+
8
+ type Cleanup = () => void
9
+
10
+ type AsyncEffectCallback = (
11
+ signal: AbortSignal,
12
+ ...deps: any[]
13
+ ) => Promise<Cleanup | void> | void
14
+
15
+ export function useAsyncEffect(cb: AsyncEffectCallback, deps: any[] = []): void {
16
+ useAsyncEffectOfType(useEffect, cb, deps)
17
+ }
18
+
19
+ export function useAsyncLayoutEffect(cb: AsyncEffectCallback, deps: any[] = []): void {
20
+ useAsyncEffectOfType(useLayoutEffect, cb, deps)
21
+ }
22
+
23
+ export function useAsyncEffectOfType(
24
+ type: Function,
25
+ cb: AsyncEffectCallback,
26
+ deps: any[] = []
27
+ ): void {
28
+ type(() => {
29
+ const controller = new AbortController()
30
+ const signal = controller.signal
31
+
32
+ // wrap in try in case its not async (for simple use cases)
33
+ try {
34
+ const value = cb(signal, ...deps)
35
+
36
+ Promise.resolve(value)
37
+ .then(async (res) => {
38
+ if (res && typeof res === 'function') {
39
+ if (signal.aborted) return res()
40
+ signal.addEventListener('abort', res)
41
+ }
42
+ })
43
+ .catch(handleError)
44
+ } catch (error) {
45
+ handleError(error)
46
+ }
47
+
48
+ function handleError(error: any) {
49
+ if (error instanceof AbortError) {
50
+ if (DEBUG_LEVEL > 2) {
51
+ console.info(`🐛 useAsyncEffect aborted: ${error.message}`)
52
+ }
53
+ return null
54
+ }
55
+
56
+ // JS handles aborting a promise as an error. Thus, ignore them since they're a normal part
57
+ // of the expected async workflow
58
+ if (typeof error === 'object' && error.name === 'AbortError') {
59
+ return null
60
+ }
61
+
62
+ // Real errors, bubble it up since the CB is expected to handle the
63
+ // errors by itself, so this is like a "fatal error" that should've
64
+ // been handled by the devs
65
+ throw error
66
+ }
67
+
68
+ return () => {
69
+ if (signal.aborted) return
70
+ controller.abort()
71
+ }
72
+ }, deps)
73
+ }