@take-out/helpers 0.2.9 → 0.3.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 (388) hide show
  1. package/dist/cjs/constants.cjs +1 -1
  2. package/dist/cjs/constants.native.js +1 -1
  3. package/dist/cjs/constants.native.js.map +1 -1
  4. package/dist/cjs/string/pluralize.cjs +4 -1
  5. package/dist/esm/async/abortable.mjs.map +1 -1
  6. package/dist/esm/constants.mjs +1 -1
  7. package/dist/esm/constants.mjs.map +1 -1
  8. package/dist/esm/constants.native.js +1 -1
  9. package/dist/esm/constants.native.js.map +1 -1
  10. package/dist/esm/index.js +72 -74
  11. package/dist/esm/index.js.map +1 -6
  12. package/dist/esm/string/pluralize.mjs +4 -1
  13. package/dist/esm/string/pluralize.mjs.map +1 -1
  14. package/package.json +3 -3
  15. package/src/async/abortable.ts +3 -3
  16. package/src/async/asyncContext.native.ts +5 -5
  17. package/src/async/asyncContext.ts +5 -5
  18. package/src/async/idle.ts +2 -2
  19. package/src/async/interval.ts +1 -1
  20. package/src/async/useAsync.ts +1 -1
  21. package/src/async/useAsyncEffect.ts +8 -8
  22. package/src/async/useLazyMount.ts +1 -1
  23. package/src/async/useLazyValue.ts +2 -2
  24. package/src/browser/clearIndexedDB.ts +1 -1
  25. package/src/browser/openPopup.ts +1 -1
  26. package/src/constants.ts +1 -1
  27. package/src/debug/debugUseState.ts +2 -2
  28. package/src/emitter.tsx +16 -16
  29. package/src/ensure/ensure.ts +2 -2
  30. package/src/function/throttle.ts +3 -3
  31. package/src/global/globalValue.ts +1 -1
  32. package/src/object/decorateObject.ts +1 -1
  33. package/src/object/mapObject.ts +1 -1
  34. package/src/object/object.ts +4 -4
  35. package/src/storage/storage.test.ts +1 -1
  36. package/src/string/pickLast.ts +1 -1
  37. package/src/string/pluralize.ts +5 -2
  38. package/src/string/truncateList.ts +1 -1
  39. package/src/time/formatDate.tsx +1 -1
  40. package/src/time/formatDateRelative.ts +4 -4
  41. package/src/time/useTimer.ts +2 -2
  42. package/src/url/urlValidate.ts +1 -1
  43. package/types/async/abortable.d.ts.map +1 -1
  44. package/types/async/asyncContext.d.ts.map +1 -1
  45. package/types/async/asyncContext.native.d.ts.map +1 -1
  46. package/types/async/idle.d.ts.map +1 -1
  47. package/types/async/interval.d.ts.map +1 -1
  48. package/types/async/useAsync.d.ts.map +1 -1
  49. package/types/async/useAsyncEffect.d.ts.map +1 -1
  50. package/types/async/useLazyMount.d.ts.map +1 -1
  51. package/types/async/useLazyValue.d.ts.map +1 -1
  52. package/types/browser/clearIndexedDB.d.ts.map +1 -1
  53. package/types/browser/openPopup.d.ts.map +1 -1
  54. package/types/constants.d.ts.map +1 -1
  55. package/types/debug/debugUseState.d.ts.map +1 -1
  56. package/types/emitter.d.ts.map +1 -1
  57. package/types/ensure/ensure.d.ts.map +1 -1
  58. package/types/function/throttle.d.ts.map +1 -1
  59. package/types/global/globalValue.d.ts.map +1 -1
  60. package/types/object/decorateObject.d.ts.map +1 -1
  61. package/types/object/mapObject.d.ts.map +1 -1
  62. package/types/object/object.d.ts.map +1 -1
  63. package/types/storage/storage.test.d.ts.map +1 -1
  64. package/types/string/pickLast.d.ts.map +1 -1
  65. package/types/string/pluralize.d.ts.map +2 -2
  66. package/types/string/truncateList.d.ts.map +1 -1
  67. package/types/time/formatDate.d.ts.map +1 -1
  68. package/types/time/formatDateRelative.d.ts.map +1 -1
  69. package/types/time/useTimer.d.ts.map +1 -1
  70. package/types/url/urlValidate.d.ts.map +1 -1
  71. package/dist/cjs/array/getRandomItem.js +0 -25
  72. package/dist/cjs/array/getRandomItem.js.map +0 -6
  73. package/dist/cjs/array/takeLast.js +0 -21
  74. package/dist/cjs/array/takeLast.js.map +0 -6
  75. package/dist/cjs/array/uniqBy.js +0 -28
  76. package/dist/cjs/array/uniqBy.js.map +0 -6
  77. package/dist/cjs/assert.js +0 -44
  78. package/dist/cjs/assert.js.map +0 -6
  79. package/dist/cjs/async/abortable.js +0 -47
  80. package/dist/cjs/async/abortable.js.map +0 -6
  81. package/dist/cjs/async/asyncContext.js +0 -101
  82. package/dist/cjs/async/asyncContext.js.map +0 -6
  83. package/dist/cjs/async/idle.js +0 -36
  84. package/dist/cjs/async/idle.js.map +0 -6
  85. package/dist/cjs/async/interval.js +0 -25
  86. package/dist/cjs/async/interval.js.map +0 -6
  87. package/dist/cjs/async/isAborted.js +0 -21
  88. package/dist/cjs/async/isAborted.js.map +0 -6
  89. package/dist/cjs/async/sleep.js +0 -25
  90. package/dist/cjs/async/sleep.js.map +0 -6
  91. package/dist/cjs/async/useAsync.js +0 -37
  92. package/dist/cjs/async/useAsync.js.map +0 -6
  93. package/dist/cjs/async/useAsyncEffect.js +0 -85
  94. package/dist/cjs/async/useAsyncEffect.js.map +0 -6
  95. package/dist/cjs/async/useLazyMount.js +0 -38
  96. package/dist/cjs/async/useLazyMount.js.map +0 -6
  97. package/dist/cjs/async/useLazyValue.js +0 -35
  98. package/dist/cjs/async/useLazyValue.js.map +0 -6
  99. package/dist/cjs/browser/clearIndexedDB.js +0 -31
  100. package/dist/cjs/browser/clearIndexedDB.js.map +0 -6
  101. package/dist/cjs/browser/isActiveElementFormField.js +0 -23
  102. package/dist/cjs/browser/isActiveElementFormField.js.map +0 -6
  103. package/dist/cjs/browser/openPopup.js +0 -31
  104. package/dist/cjs/browser/openPopup.js.map +0 -6
  105. package/dist/cjs/client-only.js +0 -2
  106. package/dist/cjs/client-only.js.map +0 -6
  107. package/dist/cjs/clipboard/clipboard.js +0 -27
  108. package/dist/cjs/clipboard/clipboard.js.map +0 -6
  109. package/dist/cjs/color/extractOpacityFromColor.js +0 -29
  110. package/dist/cjs/color/extractOpacityFromColor.js.map +0 -6
  111. package/dist/cjs/color/generateColors.js +0 -64
  112. package/dist/cjs/color/generateColors.js.map +0 -6
  113. package/dist/cjs/color/lum.js +0 -61
  114. package/dist/cjs/color/lum.js.map +0 -6
  115. package/dist/cjs/color/toHex.js +0 -27
  116. package/dist/cjs/color/toHex.js.map +0 -6
  117. package/dist/cjs/constants.js +0 -37
  118. package/dist/cjs/constants.js.map +0 -6
  119. package/dist/cjs/debug/debugLog.js +0 -24
  120. package/dist/cjs/debug/debugLog.js.map +0 -6
  121. package/dist/cjs/debug/debugUseState.js +0 -41
  122. package/dist/cjs/debug/debugUseState.js.map +0 -6
  123. package/dist/cjs/emitter.js +0 -183
  124. package/dist/cjs/emitter.js.map +0 -6
  125. package/dist/cjs/ensure/ensure.js +0 -40
  126. package/dist/cjs/ensure/ensure.js.map +0 -6
  127. package/dist/cjs/ensure/ensureOne.js +0 -27
  128. package/dist/cjs/ensure/ensureOne.js.map +0 -6
  129. package/dist/cjs/error/errors.js +0 -50
  130. package/dist/cjs/error/errors.js.map +0 -6
  131. package/dist/cjs/function/emptyFn.js +0 -22
  132. package/dist/cjs/function/emptyFn.js.map +0 -6
  133. package/dist/cjs/function/identityFn.js +0 -21
  134. package/dist/cjs/function/identityFn.js.map +0 -6
  135. package/dist/cjs/function/throttle.js +0 -40
  136. package/dist/cjs/function/throttle.js.map +0 -6
  137. package/dist/cjs/global/globalEffect.js +0 -26
  138. package/dist/cjs/global/globalEffect.js.map +0 -6
  139. package/dist/cjs/global/globalValue.js +0 -24
  140. package/dist/cjs/global/globalValue.js.map +0 -6
  141. package/dist/cjs/index.js +0 -91
  142. package/dist/cjs/index.js.map +0 -6
  143. package/dist/cjs/number/formatNumber.js +0 -56
  144. package/dist/cjs/number/formatNumber.js.map +0 -6
  145. package/dist/cjs/object/decorateObject.js +0 -26
  146. package/dist/cjs/object/decorateObject.js.map +0 -6
  147. package/dist/cjs/object/isEqualDeep.js +0 -23
  148. package/dist/cjs/object/isEqualDeep.js.map +0 -6
  149. package/dist/cjs/object/isEqualIdentity.js +0 -21
  150. package/dist/cjs/object/isEqualIdentity.js.map +0 -6
  151. package/dist/cjs/object/isEqualJSON.js +0 -21
  152. package/dist/cjs/object/isEqualJSON.js.map +0 -6
  153. package/dist/cjs/object/isEqualNever.js +0 -21
  154. package/dist/cjs/object/isEqualNever.js.map +0 -6
  155. package/dist/cjs/object/mapObject.js +0 -26
  156. package/dist/cjs/object/mapObject.js.map +0 -6
  157. package/dist/cjs/object/object.js +0 -37
  158. package/dist/cjs/object/object.js.map +0 -6
  159. package/dist/cjs/object/objectUniqueKey.js +0 -24
  160. package/dist/cjs/object/objectUniqueKey.js.map +0 -6
  161. package/dist/cjs/react/createGlobalContext.js +0 -24
  162. package/dist/cjs/react/createGlobalContext.js.map +0 -6
  163. package/dist/cjs/react/getCurrentComponentStack.js +0 -51
  164. package/dist/cjs/react/getCurrentComponentStack.js.map +0 -6
  165. package/dist/cjs/server/ensureEnv.js +0 -31
  166. package/dist/cjs/server/ensureEnv.js.map +0 -6
  167. package/dist/cjs/server/getHeaders.js +0 -26
  168. package/dist/cjs/server/getHeaders.js.map +0 -6
  169. package/dist/cjs/server/isServerRuntime.js +0 -23
  170. package/dist/cjs/server/isServerRuntime.js.map +0 -6
  171. package/dist/cjs/server/prettyPrintRequest.js +0 -23
  172. package/dist/cjs/server/prettyPrintRequest.js.map +0 -6
  173. package/dist/cjs/server/prettyPrintResponse.js +0 -30
  174. package/dist/cjs/server/prettyPrintResponse.js.map +0 -6
  175. package/dist/cjs/server/streamToString.js +0 -36
  176. package/dist/cjs/server/streamToString.js.map +0 -6
  177. package/dist/cjs/server-only.js +0 -3
  178. package/dist/cjs/server-only.js.map +0 -6
  179. package/dist/cjs/storage/createStorage.js +0 -85
  180. package/dist/cjs/storage/createStorage.js.map +0 -6
  181. package/dist/cjs/storage/driver.js +0 -33
  182. package/dist/cjs/storage/driver.js.map +0 -6
  183. package/dist/cjs/storage/storage.test.js +0 -71
  184. package/dist/cjs/storage/storage.test.js.map +0 -6
  185. package/dist/cjs/storage/types.js +0 -14
  186. package/dist/cjs/storage/types.js.map +0 -6
  187. package/dist/cjs/string/dedent.js +0 -33
  188. package/dist/cjs/string/dedent.js.map +0 -6
  189. package/dist/cjs/string/ellipsis.js +0 -24
  190. package/dist/cjs/string/ellipsis.js.map +0 -6
  191. package/dist/cjs/string/hash.js +0 -27
  192. package/dist/cjs/string/hash.js.map +0 -6
  193. package/dist/cjs/string/insertAtIndex.js +0 -25
  194. package/dist/cjs/string/insertAtIndex.js.map +0 -6
  195. package/dist/cjs/string/nbspLastWord.js +0 -25
  196. package/dist/cjs/string/nbspLastWord.js.map +0 -6
  197. package/dist/cjs/string/pickLast.js +0 -24
  198. package/dist/cjs/string/pickLast.js.map +0 -6
  199. package/dist/cjs/string/pluralize.js +0 -38
  200. package/dist/cjs/string/pluralize.js.map +0 -6
  201. package/dist/cjs/string/randomId.js +0 -21
  202. package/dist/cjs/string/randomId.js.map +0 -6
  203. package/dist/cjs/string/slugify.js +0 -21
  204. package/dist/cjs/string/slugify.js.map +0 -6
  205. package/dist/cjs/string/truncateList.js +0 -26
  206. package/dist/cjs/string/truncateList.js.map +0 -6
  207. package/dist/cjs/time/formatDate.js +0 -51
  208. package/dist/cjs/time/formatDate.js.map +0 -6
  209. package/dist/cjs/time/formatDateRelative.js +0 -48
  210. package/dist/cjs/time/formatDateRelative.js.map +0 -6
  211. package/dist/cjs/time/formatDistanceToNow.js +0 -24
  212. package/dist/cjs/time/formatDistanceToNow.js.map +0 -6
  213. package/dist/cjs/time/time.js +0 -40
  214. package/dist/cjs/time/time.js.map +0 -6
  215. package/dist/cjs/time/useTimer.js +0 -51
  216. package/dist/cjs/time/useTimer.js.map +0 -6
  217. package/dist/cjs/types/NullToOptional.js +0 -14
  218. package/dist/cjs/types/NullToOptional.js.map +0 -6
  219. package/dist/cjs/types/object.js +0 -14
  220. package/dist/cjs/types/object.js.map +0 -6
  221. package/dist/cjs/types/react.js +0 -14
  222. package/dist/cjs/types/react.js.map +0 -6
  223. package/dist/cjs/types/timer.js +0 -14
  224. package/dist/cjs/types/timer.js.map +0 -6
  225. package/dist/cjs/types/tuple.js +0 -14
  226. package/dist/cjs/types/tuple.js.map +0 -6
  227. package/dist/cjs/url/urlSanitize.js +0 -31
  228. package/dist/cjs/url/urlSanitize.js.map +0 -6
  229. package/dist/cjs/url/urlValidate.js +0 -26
  230. package/dist/cjs/url/urlValidate.js.map +0 -6
  231. package/dist/esm/array/getRandomItem.js +0 -9
  232. package/dist/esm/array/getRandomItem.js.map +0 -6
  233. package/dist/esm/array/takeLast.js +0 -5
  234. package/dist/esm/array/takeLast.js.map +0 -6
  235. package/dist/esm/array/uniqBy.js +0 -12
  236. package/dist/esm/array/uniqBy.js.map +0 -6
  237. package/dist/esm/assert.js +0 -28
  238. package/dist/esm/assert.js.map +0 -6
  239. package/dist/esm/async/abortable.js +0 -31
  240. package/dist/esm/async/abortable.js.map +0 -6
  241. package/dist/esm/async/asyncContext.js +0 -85
  242. package/dist/esm/async/asyncContext.js.map +0 -6
  243. package/dist/esm/async/idle.js +0 -21
  244. package/dist/esm/async/idle.js.map +0 -6
  245. package/dist/esm/async/interval.js +0 -9
  246. package/dist/esm/async/interval.js.map +0 -6
  247. package/dist/esm/async/isAborted.js +0 -5
  248. package/dist/esm/async/isAborted.js.map +0 -6
  249. package/dist/esm/async/sleep.js +0 -9
  250. package/dist/esm/async/sleep.js.map +0 -6
  251. package/dist/esm/async/useAsync.js +0 -21
  252. package/dist/esm/async/useAsync.js.map +0 -6
  253. package/dist/esm/async/useAsyncEffect.js +0 -72
  254. package/dist/esm/async/useAsyncEffect.js.map +0 -6
  255. package/dist/esm/async/useLazyMount.js +0 -24
  256. package/dist/esm/async/useLazyMount.js.map +0 -6
  257. package/dist/esm/async/useLazyValue.js +0 -21
  258. package/dist/esm/async/useLazyValue.js.map +0 -6
  259. package/dist/esm/browser/clearIndexedDB.js +0 -15
  260. package/dist/esm/browser/clearIndexedDB.js.map +0 -6
  261. package/dist/esm/browser/isActiveElementFormField.js +0 -7
  262. package/dist/esm/browser/isActiveElementFormField.js.map +0 -6
  263. package/dist/esm/browser/openPopup.js +0 -15
  264. package/dist/esm/browser/openPopup.js.map +0 -6
  265. package/dist/esm/client-only.js +0 -2
  266. package/dist/esm/client-only.js.map +0 -6
  267. package/dist/esm/clipboard/clipboard.js +0 -11
  268. package/dist/esm/clipboard/clipboard.js.map +0 -6
  269. package/dist/esm/color/extractOpacityFromColor.js +0 -13
  270. package/dist/esm/color/extractOpacityFromColor.js.map +0 -6
  271. package/dist/esm/color/generateColors.js +0 -48
  272. package/dist/esm/color/generateColors.js.map +0 -6
  273. package/dist/esm/color/lum.js +0 -45
  274. package/dist/esm/color/lum.js.map +0 -6
  275. package/dist/esm/color/toHex.js +0 -11
  276. package/dist/esm/color/toHex.js.map +0 -6
  277. package/dist/esm/constants.js +0 -22
  278. package/dist/esm/constants.js.map +0 -6
  279. package/dist/esm/debug/debugLog.js +0 -8
  280. package/dist/esm/debug/debugLog.js.map +0 -6
  281. package/dist/esm/debug/debugUseState.js +0 -25
  282. package/dist/esm/debug/debugUseState.js.map +0 -6
  283. package/dist/esm/emitter.js +0 -167
  284. package/dist/esm/emitter.js.map +0 -6
  285. package/dist/esm/ensure/ensure.js +0 -24
  286. package/dist/esm/ensure/ensure.js.map +0 -6
  287. package/dist/esm/ensure/ensureOne.js +0 -11
  288. package/dist/esm/ensure/ensureOne.js.map +0 -6
  289. package/dist/esm/error/errors.js +0 -34
  290. package/dist/esm/error/errors.js.map +0 -6
  291. package/dist/esm/function/emptyFn.js +0 -6
  292. package/dist/esm/function/emptyFn.js.map +0 -6
  293. package/dist/esm/function/identityFn.js +0 -5
  294. package/dist/esm/function/identityFn.js.map +0 -6
  295. package/dist/esm/function/throttle.js +0 -24
  296. package/dist/esm/function/throttle.js.map +0 -6
  297. package/dist/esm/global/globalEffect.js +0 -10
  298. package/dist/esm/global/globalEffect.js.map +0 -6
  299. package/dist/esm/global/globalValue.js +0 -8
  300. package/dist/esm/global/globalValue.js.map +0 -6
  301. package/dist/esm/number/formatNumber.js +0 -40
  302. package/dist/esm/number/formatNumber.js.map +0 -6
  303. package/dist/esm/object/decorateObject.js +0 -10
  304. package/dist/esm/object/decorateObject.js.map +0 -6
  305. package/dist/esm/object/isEqualDeep.js +0 -8
  306. package/dist/esm/object/isEqualDeep.js.map +0 -6
  307. package/dist/esm/object/isEqualIdentity.js +0 -5
  308. package/dist/esm/object/isEqualIdentity.js.map +0 -6
  309. package/dist/esm/object/isEqualJSON.js +0 -5
  310. package/dist/esm/object/isEqualJSON.js.map +0 -6
  311. package/dist/esm/object/isEqualNever.js +0 -5
  312. package/dist/esm/object/isEqualNever.js.map +0 -6
  313. package/dist/esm/object/mapObject.js +0 -10
  314. package/dist/esm/object/mapObject.js.map +0 -6
  315. package/dist/esm/object/object.js +0 -21
  316. package/dist/esm/object/object.js.map +0 -6
  317. package/dist/esm/object/objectUniqueKey.js +0 -8
  318. package/dist/esm/object/objectUniqueKey.js.map +0 -6
  319. package/dist/esm/react/createGlobalContext.js +0 -9
  320. package/dist/esm/react/createGlobalContext.js.map +0 -6
  321. package/dist/esm/react/getCurrentComponentStack.js +0 -27
  322. package/dist/esm/react/getCurrentComponentStack.js.map +0 -6
  323. package/dist/esm/server/ensureEnv.js +0 -15
  324. package/dist/esm/server/ensureEnv.js.map +0 -6
  325. package/dist/esm/server/getHeaders.js +0 -10
  326. package/dist/esm/server/getHeaders.js.map +0 -6
  327. package/dist/esm/server/isServerRuntime.js +0 -7
  328. package/dist/esm/server/isServerRuntime.js.map +0 -6
  329. package/dist/esm/server/prettyPrintRequest.js +0 -7
  330. package/dist/esm/server/prettyPrintRequest.js.map +0 -6
  331. package/dist/esm/server/prettyPrintResponse.js +0 -15
  332. package/dist/esm/server/prettyPrintResponse.js.map +0 -6
  333. package/dist/esm/server/streamToString.js +0 -20
  334. package/dist/esm/server/streamToString.js.map +0 -6
  335. package/dist/esm/server-only.js +0 -3
  336. package/dist/esm/server-only.js.map +0 -6
  337. package/dist/esm/storage/createStorage.js +0 -69
  338. package/dist/esm/storage/createStorage.js.map +0 -6
  339. package/dist/esm/storage/driver.js +0 -17
  340. package/dist/esm/storage/driver.js.map +0 -6
  341. package/dist/esm/storage/storage.test.js +0 -73
  342. package/dist/esm/storage/storage.test.js.map +0 -6
  343. package/dist/esm/storage/types.js +0 -1
  344. package/dist/esm/storage/types.js.map +0 -6
  345. package/dist/esm/string/dedent.js +0 -17
  346. package/dist/esm/string/dedent.js.map +0 -6
  347. package/dist/esm/string/ellipsis.js +0 -8
  348. package/dist/esm/string/ellipsis.js.map +0 -6
  349. package/dist/esm/string/hash.js +0 -11
  350. package/dist/esm/string/hash.js.map +0 -6
  351. package/dist/esm/string/insertAtIndex.js +0 -9
  352. package/dist/esm/string/insertAtIndex.js.map +0 -6
  353. package/dist/esm/string/nbspLastWord.js +0 -9
  354. package/dist/esm/string/nbspLastWord.js.map +0 -6
  355. package/dist/esm/string/pickLast.js +0 -8
  356. package/dist/esm/string/pickLast.js.map +0 -6
  357. package/dist/esm/string/pluralize.js +0 -22
  358. package/dist/esm/string/pluralize.js.map +0 -6
  359. package/dist/esm/string/randomId.js +0 -5
  360. package/dist/esm/string/randomId.js.map +0 -6
  361. package/dist/esm/string/slugify.js +0 -5
  362. package/dist/esm/string/slugify.js.map +0 -6
  363. package/dist/esm/string/truncateList.js +0 -10
  364. package/dist/esm/string/truncateList.js.map +0 -6
  365. package/dist/esm/time/formatDate.js +0 -35
  366. package/dist/esm/time/formatDate.js.map +0 -6
  367. package/dist/esm/time/formatDateRelative.js +0 -32
  368. package/dist/esm/time/formatDateRelative.js.map +0 -6
  369. package/dist/esm/time/formatDistanceToNow.js +0 -8
  370. package/dist/esm/time/formatDistanceToNow.js.map +0 -6
  371. package/dist/esm/time/time.js +0 -24
  372. package/dist/esm/time/time.js.map +0 -6
  373. package/dist/esm/time/useTimer.js +0 -35
  374. package/dist/esm/time/useTimer.js.map +0 -6
  375. package/dist/esm/types/NullToOptional.js +0 -1
  376. package/dist/esm/types/NullToOptional.js.map +0 -6
  377. package/dist/esm/types/object.js +0 -1
  378. package/dist/esm/types/object.js.map +0 -6
  379. package/dist/esm/types/react.js +0 -1
  380. package/dist/esm/types/react.js.map +0 -6
  381. package/dist/esm/types/timer.js +0 -1
  382. package/dist/esm/types/timer.js.map +0 -6
  383. package/dist/esm/types/tuple.js +0 -1
  384. package/dist/esm/types/tuple.js.map +0 -6
  385. package/dist/esm/url/urlSanitize.js +0 -15
  386. package/dist/esm/url/urlSanitize.js.map +0 -6
  387. package/dist/esm/url/urlValidate.js +0 -10
  388. package/dist/esm/url/urlValidate.js.map +0 -6
package/src/emitter.tsx CHANGED
@@ -16,7 +16,7 @@ import type { JSX, PropsWithChildren } from 'react'
16
16
  function useGet<A>(
17
17
  currentValue: A,
18
18
  initialValue?: any,
19
- forwardToFunction?: boolean
19
+ forwardToFunction?: boolean,
20
20
  ): () => A {
21
21
  const curRef = React.useRef<any>(initialValue ?? currentValue)
22
22
 
@@ -29,7 +29,7 @@ function useGet<A>(
29
29
  forwardToFunction
30
30
  ? (...args) => curRef.current?.apply(null, args)
31
31
  : () => curRef.current,
32
- [curRef, forwardToFunction]
32
+ [curRef, forwardToFunction],
33
33
  )
34
34
  }
35
35
 
@@ -78,7 +78,7 @@ this will emit the same value again, which can be desirable, but we warn to ensu
78
78
 
79
79
  - if you want this behavior, add { comparator: isEqualNever }
80
80
  - if you want only non-equal values: { comparator: isEqualIdentity }
81
- - if you want only deeply non-equal values: { comparator: isEqualDeep }`
81
+ - if you want only deeply non-equal values: { comparator: isEqualDeep }`,
82
82
  )
83
83
  }
84
84
  }
@@ -110,7 +110,7 @@ this will emit the same value again, which can be desirable, but we warn to ensu
110
110
  export function createGlobalEmitter<T>(
111
111
  name: string,
112
112
  defaultValue: T,
113
- options?: CreateEmitterOpts<T>
113
+ options?: CreateEmitterOpts<T>,
114
114
  ): Emitter<T> {
115
115
  return globalValue(name, () => createEmitter(name, defaultValue, options))
116
116
  }
@@ -118,7 +118,7 @@ export function createGlobalEmitter<T>(
118
118
  export function createEmitter<T>(
119
119
  name: string,
120
120
  defaultValue: T,
121
- options?: CreateEmitterOpts<T>
121
+ options?: CreateEmitterOpts<T>,
122
122
  ): Emitter<T> {
123
123
  const existing = createOrUpdateCache(name, defaultValue) as T
124
124
  return new Emitter<T>(existing || defaultValue, { name, ...options })
@@ -130,7 +130,7 @@ export type EmitterType<E extends Emitter<any>> =
130
130
  export const useEmitter = <E extends Emitter<any>>(
131
131
  emitter: E,
132
132
  cb: (cb: EmitterType<E>) => void,
133
- args?: any[]
133
+ args?: any[],
134
134
  ): void => {
135
135
  const getCallback = useGet(cb)
136
136
 
@@ -150,7 +150,7 @@ export const useEmitter = <E extends Emitter<any>>(
150
150
 
151
151
  export const useEmitterValue = <E extends Emitter<any>>(
152
152
  emitter: E,
153
- options?: { disable?: boolean }
153
+ options?: { disable?: boolean },
154
154
  ): EmitterType<E> => {
155
155
  const disabled = options?.disable
156
156
 
@@ -204,7 +204,7 @@ export const useEmitterSelector = <E extends Emitter<any>, T extends EmitterType
204
204
  disable?: boolean
205
205
  lazy?: boolean
206
206
  },
207
- args: any[] = EMPTY_ARRAY
207
+ args: any[] = EMPTY_ARRAY,
208
208
  ): R => {
209
209
  const [state, setState] = useState<R>(() => selector(emitter.value))
210
210
  const disabled = options?.disable
@@ -240,7 +240,7 @@ export const useEmitterSelector = <E extends Emitter<any>, T extends EmitterType
240
240
  export const useEmittersSelector = <const E extends readonly Emitter<any>[], R>(
241
241
  emitters: E,
242
242
  selector: (values: { [K in keyof E]: EmitterType<E[K]> }) => R,
243
- options?: { disable?: boolean; isEqual?: (a: R, b: R) => boolean }
243
+ options?: { disable?: boolean; isEqual?: (a: R, b: R) => boolean },
244
244
  ): R => {
245
245
  const getSelector = useGet(selector)
246
246
  const disabled = options?.disable
@@ -290,23 +290,23 @@ export const useEmittersSelector = <const E extends readonly Emitter<any>[], R>(
290
290
  }
291
291
 
292
292
  export const createUseEmitter = <E extends Emitter<any>>(
293
- emitter: E
293
+ emitter: E,
294
294
  ): ((cb: (val: EmitterType<E>) => void, args?: any[]) => void) => {
295
295
  return (cb: (val: EmitterType<E>) => void, args?: any[]) =>
296
296
  useEmitter(emitter, cb, args)
297
297
  }
298
298
 
299
299
  export const createUseSelector = <E extends Emitter<any>>(
300
- emitter: E
300
+ emitter: E,
301
301
  ): (<R>(
302
302
  selector: (value: EmitterType<E>) => R,
303
303
  options?: { disable?: boolean; lazy?: boolean },
304
- args?: any[]
304
+ args?: any[],
305
305
  ) => R) => {
306
306
  return <R,>(
307
307
  selector: (value: EmitterType<E>) => R,
308
308
  options?: { disable?: boolean; lazy?: boolean },
309
- args?: any[]
309
+ args?: any[],
310
310
  ): R => {
311
311
  return useEmitterSelector(emitter, selector, options, args)
312
312
  }
@@ -315,7 +315,7 @@ export const createUseSelector = <E extends Emitter<any>>(
315
315
  export function createContextualEmitter<T>(
316
316
  name: string,
317
317
  defaultValue: T,
318
- defaultOptions?: Omit<EmitterOptions<T>, 'name'>
318
+ defaultOptions?: Omit<EmitterOptions<T>, 'name'>,
319
319
  ): readonly [
320
320
  () => Emitter<T>,
321
321
  (props: PropsWithChildren<{ value?: T; silent?: boolean }>) => JSX.Element,
@@ -323,7 +323,7 @@ export function createContextualEmitter<T>(
323
323
  const id = Math.random().toString(36)
324
324
  const EmitterContext = createGlobalContext<Emitter<T> | null>(
325
325
  `contextual-emitter/${id}`,
326
- null
326
+ null,
327
327
  )
328
328
 
329
329
  const useContextEmitter = () => {
@@ -342,7 +342,7 @@ export function createContextualEmitter<T>(
342
342
  const ProvideEmitter = (props: ProvideEmitterProps) => {
343
343
  const { children, value, silent } = props
344
344
  const [emitter] = useState(
345
- () => new Emitter<T>(value ?? defaultValue, { name, silent, ...defaultOptions })
345
+ () => new Emitter<T>(value ?? defaultValue, { name, silent, ...defaultOptions }),
346
346
  )
347
347
 
348
348
  useLayoutEffect(() => {
@@ -2,7 +2,7 @@ import { EnsureError } from '../error/errors'
2
2
 
3
3
  export function ensureExists<T>(
4
4
  value: T | undefined | null,
5
- msg = ''
5
+ msg = '',
6
6
  ): asserts value is T {
7
7
  if (value === undefined || value === null) {
8
8
  throw new EnsureError(`Invalid nullish value (${value}): ${msg}`)
@@ -11,7 +11,7 @@ export function ensureExists<T>(
11
11
 
12
12
  export function ensure<T>(
13
13
  value: T,
14
- msg = ''
14
+ msg = '',
15
15
  ): asserts value is Exclude<T, null | undefined | false> {
16
16
  if (!value) {
17
17
  throw new EnsureError(`ensure() invalid: (${value}): ${msg} ${new Error().stack}`)
@@ -25,7 +25,7 @@ interface Throttler<T extends unknown[]> {
25
25
  export function throttle<T extends unknown[]>(
26
26
  callback: (...args: T) => unknown,
27
27
  wait = 0,
28
- { start = true, middle = true, once = false }: ThrottleOptions = {}
28
+ { start = true, middle = true, once = false }: ThrottleOptions = {},
29
29
  ): Throttler<T> {
30
30
  let innerStart = start
31
31
  let last = 0
@@ -52,7 +52,7 @@ export function throttle<T extends unknown[]>(
52
52
  callback.apply(this, args)
53
53
  if (once) fn.cancel()
54
54
  },
55
- !middle ? wait : wait - delta
55
+ !middle ? wait : wait - delta,
56
56
  )
57
57
  }
58
58
  }
@@ -66,7 +66,7 @@ export function throttle<T extends unknown[]>(
66
66
  export function debounce<T extends unknown[]>(
67
67
  callback: (...args: T) => unknown,
68
68
  wait = 0,
69
- { start = false, middle = false, once = false }: ThrottleOptions = {}
69
+ { start = false, middle = false, once = false }: ThrottleOptions = {},
70
70
  ): Throttler<T> {
71
71
  return throttle(callback, wait, { start, middle, once })
72
72
  }
@@ -23,7 +23,7 @@ export function globalValue<T>(
23
23
  factory: () => T,
24
24
  opts?: {
25
25
  warnMessage?: string
26
- }
26
+ },
27
27
  ): T {
28
28
  const symbolKey = Symbol.for(key)
29
29
  const g = globalThis as Record<symbol, unknown>
@@ -1,6 +1,6 @@
1
1
  export function decorateObject<T extends Record<string, any>>(
2
2
  obj: T,
3
- decorator: (fn: Function) => Function
3
+ decorator: (fn: Function) => Function,
4
4
  ): T {
5
5
  const decorated = {} as T
6
6
 
@@ -1,6 +1,6 @@
1
1
  export function mapObject<T extends Record<string, any>, R>(
2
2
  obj: T,
3
- fn: <K extends keyof T>(value: T[K], key: K) => R
3
+ fn: <K extends keyof T>(value: T[K], key: K) => R,
4
4
  ): { [K in keyof T]: R } {
5
5
  const result = {} as { [K in keyof T]: R }
6
6
 
@@ -7,17 +7,17 @@ import type {
7
7
 
8
8
  export function postfixObjKeys<A extends { [key: string]: string }, B extends string>(
9
9
  obj: A,
10
- postfix: B
10
+ postfix: B,
11
11
  ): {
12
12
  [Key in `${keyof A extends string ? keyof A : never}${B}`]: string
13
13
  } {
14
14
  return Object.fromEntries(
15
- Object.entries(obj).map(([k, v]) => [`${k}${postfix}`, v])
15
+ Object.entries(obj).map(([k, v]) => [`${k}${postfix}`, v]),
16
16
  ) as any
17
17
  }
18
18
 
19
19
  export function objectFromEntries<ARR_T extends EntriesType>(
20
- arr: ARR_T
20
+ arr: ARR_T,
21
21
  ): EntriesToObject<ARR_T> {
22
22
  return Object.fromEntries(arr) as EntriesToObject<ARR_T>
23
23
  }
@@ -27,7 +27,7 @@ export function objectKeys<O extends object>(obj: O) {
27
27
  }
28
28
 
29
29
  export function objectEntries<OBJ_T extends ObjectType>(
30
- obj: OBJ_T
30
+ obj: OBJ_T,
31
31
  ): ObjectEntries<OBJ_T> {
32
32
  return Object.entries(obj) as ObjectEntries<OBJ_T>
33
33
  }
@@ -65,7 +65,7 @@ describe('storage driver system', () => {
65
65
 
66
66
  it('should handle JSON serialization', () => {
67
67
  const storage = createStorage<'obj', { name: string; count: number }>(
68
- `test-${Date.now()}-3`
68
+ `test-${Date.now()}-3`,
69
69
  )
70
70
  const obj = { name: 'test', count: 42 }
71
71
  storage.set('obj', obj)
@@ -1,6 +1,6 @@
1
1
  export function pickLast<T extends string | null | undefined>(
2
2
  a: T,
3
- b: T
3
+ b: T,
4
4
  ): T extends string ? string : T {
5
5
  if (a == null && b == null) return undefined as any
6
6
  if (a == null) return b as any
@@ -7,9 +7,12 @@ export function pluralize(count: number, singular: string, plural: string): stri
7
7
  return `${count} ${singular}`
8
8
  case 'other':
9
9
  return `${count} ${plural}`
10
- default:
10
+ case 'zero':
11
+ case 'two':
12
+ case 'few':
13
+ case 'many':
11
14
  throw new Error(
12
- `Can't pluralize: ${grammaticalNumber} for ${count} / ${singular} / ${plural}`
15
+ `Can't pluralize: ${grammaticalNumber} for ${count} / ${singular} / ${plural}`,
13
16
  )
14
17
  }
15
18
  }
@@ -15,7 +15,7 @@
15
15
  export const truncateList = (
16
16
  items: string[],
17
17
  maxItems: number,
18
- separator: string = ', '
18
+ separator: string = ', ',
19
19
  ): string => {
20
20
  if (items.length <= maxItems) {
21
21
  return items.join(separator)
@@ -2,7 +2,7 @@ const currentYear = new Date().getFullYear()
2
2
 
3
3
  export function formatDate(
4
4
  date: Date,
5
- options?: { daySuffix?: boolean }
5
+ options?: { daySuffix?: boolean },
6
6
  ): [string, string] | [string, string, string] {
7
7
  const months = [
8
8
  'January',
@@ -33,7 +33,7 @@ export function formatDateRelative(date: Date | string | number): string {
33
33
  new Intl.DateTimeFormat('en', {
34
34
  hour: 'numeric',
35
35
  minute: 'numeric',
36
- }).format(messageDate)
36
+ }).format(messageDate),
37
37
  )
38
38
  }
39
39
 
@@ -43,7 +43,7 @@ export function formatDateRelative(date: Date | string | number): string {
43
43
  new Intl.DateTimeFormat('en', {
44
44
  hour: 'numeric',
45
45
  minute: 'numeric',
46
- }).format(messageDate)
46
+ }).format(messageDate),
47
47
  )
48
48
  }
49
49
 
@@ -55,7 +55,7 @@ export function formatDateRelative(date: Date | string | number): string {
55
55
  day: 'numeric',
56
56
  hour: 'numeric',
57
57
  minute: 'numeric',
58
- }).format(messageDate)
58
+ }).format(messageDate),
59
59
  )
60
60
  }
61
61
 
@@ -67,6 +67,6 @@ export function formatDateRelative(date: Date | string | number): string {
67
67
  year: 'numeric',
68
68
  hour: 'numeric',
69
69
  minute: 'numeric',
70
- }).format(messageDate)
70
+ }).format(messageDate),
71
71
  )
72
72
  }
@@ -36,7 +36,7 @@ export const useTimer = (): UseTimerReturn => {
36
36
  }, 1000)
37
37
  }
38
38
  },
39
- [clearTimer]
39
+ [clearTimer],
40
40
  )
41
41
 
42
42
  const pauseTimer = useCallback(() => {
@@ -75,6 +75,6 @@ export const useTimer = (): UseTimerReturn => {
75
75
  resume: resumeTimer,
76
76
  clear: clearTimer,
77
77
  }),
78
- [timerCount, clearTimer, pauseTimer, resetTimer, resumeTimer]
78
+ [timerCount, clearTimer, pauseTimer, resetTimer, resumeTimer],
79
79
  )
80
80
  }
@@ -1,7 +1,7 @@
1
1
  // Source: https://stackoverflow.com/a/8234912/2013580
2
2
 
3
3
  const urlRegExp = new RegExp(
4
- /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))?)/
4
+ /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))?)/,
5
5
  )
6
6
 
7
7
  export function urlValidate(url: string): boolean {
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "import { AbortError, EnsureError } from '../error/errors'\n\ntype AbortableOptions = { message?: string }\n\nexport function abortable<T>(cb: () => T, options?: AbortableOptions): T | undefined\nexport function abortable<T>(\n cb: () => Promise<T>,\n options?: AbortableOptions\n): Promise<T | undefined>\nexport function abortable<T>(\n cb: () => T | Promise<T>,\n options?: AbortableOptions\n): T | undefined | Promise<T | undefined> {\n try {\n const value = cb()\n\n if (value instanceof Promise) {\n return value.catch((err) => {\n if (didAbort(err, options)) {\n return undefined\n }\n throw err\n })\n }\n\n return value\n } catch (err) {\n if (didAbort(err, options)) {\n return undefined\n }\n throw err\n }\n}\n\nexport function didAbort(err: unknown, options?: AbortableOptions): boolean {\n if (err instanceof AbortError || err instanceof EnsureError) {\n if (options?.message) {\n console.warn(`Aborted: ${options.message}`)\n }\n return true\n }\n return false\n}\n\nexport function handleAbortError(error: any, debug?: boolean): void {\n if (error instanceof AbortError || error instanceof EnsureError) {\n if (debug || process.env.DEBUG) {\n console.info(`🐛 useAsyncEffect aborted: ${error.message}`)\n }\n return\n }\n\n // js handles aborting a promise as an error. ignore them since they're\n // a normal part of the expected async workflow\n if (typeof error === 'object' && error.name === 'AbortError') {\n return\n }\n\n throw error\n}\n"
9
+ "import { AbortError, EnsureError } from '../error/errors'\n\ntype AbortableOptions = { message?: string }\n\nexport function abortable<T>(cb: () => T, options?: AbortableOptions): T | undefined\nexport function abortable<T>(\n cb: () => Promise<T>,\n options?: AbortableOptions,\n): Promise<T | undefined>\nexport function abortable<T>(\n cb: () => T | Promise<T>,\n options?: AbortableOptions,\n): T | undefined | Promise<T | undefined> {\n try {\n const value = cb()\n\n if (value instanceof Promise) {\n return value.catch((err: unknown) => {\n if (didAbort(err, options)) {\n return undefined\n }\n throw err\n })\n }\n\n return value\n } catch (err) {\n if (didAbort(err, options)) {\n return undefined\n }\n throw err\n }\n}\n\nexport function didAbort(err: unknown, options?: AbortableOptions): boolean {\n if (err instanceof AbortError || err instanceof EnsureError) {\n if (options?.message) {\n console.warn(`Aborted: ${options.message}`)\n }\n return true\n }\n return false\n}\n\nexport function handleAbortError(error: any, debug?: boolean): void {\n if (error instanceof AbortError || error instanceof EnsureError) {\n if (debug || process.env.DEBUG) {\n console.info(`🐛 useAsyncEffect aborted: ${error.message}`)\n }\n return\n }\n\n // js handles aborting a promise as an error. ignore them since they're\n // a normal part of the expected async workflow\n if (typeof error === 'object' && error.name === 'AbortError') {\n return\n }\n\n throw error\n}\n"
10
10
  ]
11
11
  }
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "import { isServerRuntime } from '../server/isServerRuntime'\n\ninterface AsyncContext<T> {\n get(): T | undefined\n run<R>(value: T, fn: () => R | Promise<R>): Promise<R>\n}\n\ninterface NodeAsyncLocalStorage<T> {\n getStore(): T | undefined\n run<R>(store: T, callback: () => R): R\n}\n\ninterface AsyncLocalStorageConstructor {\n new <T>(): NodeAsyncLocalStorage<T>\n}\n\nlet nodeAsyncLocalStorageCache: AsyncLocalStorageConstructor | null = null\n\n// hide from vite/esbuild static analysis to avoid browser compat warning\nconst nodeModuleId = ['node', 'async_hooks'].join(':')\n\nasync function getNodeAsyncLocalStorage(): Promise<AsyncLocalStorageConstructor | null> {\n if (!nodeAsyncLocalStorageCache) {\n try {\n const module = await import(/* @vite-ignore */ nodeModuleId)\n nodeAsyncLocalStorageCache =\n module.AsyncLocalStorage as AsyncLocalStorageConstructor\n } catch {\n return null\n }\n }\n return nodeAsyncLocalStorageCache\n}\n\nexport function createAsyncContext<T>(): AsyncContext<T> {\n if (isServerRuntime()) {\n let storage: NodeAsyncLocalStorage<T> | null = null\n\n getNodeAsyncLocalStorage().then((AsyncLocalStorage) => {\n if (AsyncLocalStorage && !storage) {\n storage = new AsyncLocalStorage<T>()\n }\n })\n\n return {\n get(): T | undefined {\n if (!storage) {\n console.warn(`⚠️ called AsyncContext before load!`)\n return\n }\n\n return storage.getStore()\n },\n\n async run<R>(value: T, fn: () => R | Promise<R>): Promise<R> {\n if (!storage) {\n throw new Error(`⚠️ called AsyncContext before load!`)\n }\n return storage.run(value, fn)\n },\n }\n } else {\n // browser implementation using promise patching\n return createBrowserAsyncContext<T>()\n }\n}\n\nfunction createBrowserAsyncContext<T>(): AsyncContext<T> {\n let currentContext: T | undefined\n const contextStack: (T | undefined)[] = []\n\n return {\n get(): T | undefined {\n return currentContext\n },\n async run<R>(value: T, fn: () => R | Promise<R>): Promise<R> {\n const prevContext = currentContext\n currentContext = value\n contextStack.push(prevContext)\n\n // store original Promise methods\n const OriginalPromise = Promise\n const OriginalThen = OriginalPromise.prototype.then\n const OriginalCatch = OriginalPromise.prototype.catch\n const OriginalFinally = OriginalPromise.prototype.finally\n\n function wrapCallback(\n callback: Function | undefined | null,\n context: T | undefined\n ): Function | undefined | null {\n if (!callback) return callback\n return (...args: any[]) => {\n const prevContext = currentContext\n currentContext = context\n try {\n return callback(...args)\n } finally {\n currentContext = prevContext\n }\n }\n }\n\n // patch Promise methods to capture and restore context\n // eslint-disable-next-line no-then-property -- intentional patching for context propagation\n OriginalPromise.prototype.then = function (\n this: Promise<any>,\n onFulfilled?: any,\n onRejected?: any\n ): Promise<any> {\n const context = currentContext\n return OriginalThen.call(\n this,\n wrapCallback(onFulfilled, context) as any,\n wrapCallback(onRejected, context) as any\n )\n }\n\n OriginalPromise.prototype.catch = function (\n this: Promise<any>,\n onRejected?: any\n ): Promise<any> {\n const context = currentContext\n return OriginalCatch.call(this, wrapCallback(onRejected, context) as any)\n }\n\n OriginalPromise.prototype.finally = function (\n this: Promise<any>,\n onFinally?: any\n ): Promise<any> {\n const context = currentContext\n return OriginalFinally.call(this, wrapCallback(onFinally, context) as any)\n }\n\n try {\n const result = await fn()\n return result\n } finally {\n // restore original Promise methods\n // eslint-disable-next-line no-then-property -- restoring original methods\n OriginalPromise.prototype.then = OriginalThen\n OriginalPromise.prototype.catch = OriginalCatch\n OriginalPromise.prototype.finally = OriginalFinally\n\n contextStack.pop()\n currentContext = prevContext\n }\n },\n }\n}\n"
9
+ "import { isServerRuntime } from '../server/isServerRuntime'\n\ninterface AsyncContext<T> {\n get(): T | undefined\n run<R>(value: T, fn: () => R | Promise<R>): Promise<R>\n}\n\ninterface NodeAsyncLocalStorage<T> {\n getStore(): T | undefined\n run<R>(store: T, callback: () => R): R\n}\n\ninterface AsyncLocalStorageConstructor {\n new <T>(): NodeAsyncLocalStorage<T>\n}\n\nlet nodeAsyncLocalStorageCache: AsyncLocalStorageConstructor | null = null\n\n// hide from vite/esbuild static analysis to avoid browser compat warning\nconst nodeModuleId = ['node', 'async_hooks'].join(':')\n\nasync function getNodeAsyncLocalStorage(): Promise<AsyncLocalStorageConstructor | null> {\n if (!nodeAsyncLocalStorageCache) {\n try {\n const module = await import(/* @vite-ignore */ nodeModuleId)\n nodeAsyncLocalStorageCache =\n module.AsyncLocalStorage as AsyncLocalStorageConstructor\n } catch {\n return null\n }\n }\n return nodeAsyncLocalStorageCache\n}\n\nexport function createAsyncContext<T>(): AsyncContext<T> {\n if (isServerRuntime()) {\n let storage: NodeAsyncLocalStorage<T> | null = null\n\n getNodeAsyncLocalStorage().then((AsyncLocalStorage) => {\n if (AsyncLocalStorage && !storage) {\n storage = new AsyncLocalStorage<T>()\n }\n })\n\n return {\n get(): T | undefined {\n if (!storage) {\n console.warn(`⚠️ called AsyncContext before load!`)\n return\n }\n\n return storage.getStore()\n },\n\n async run<R>(value: T, fn: () => R | Promise<R>): Promise<R> {\n if (!storage) {\n throw new Error(`⚠️ called AsyncContext before load!`)\n }\n return storage.run(value, fn)\n },\n }\n } else {\n // browser implementation using promise patching\n return createBrowserAsyncContext<T>()\n }\n}\n\nfunction createBrowserAsyncContext<T>(): AsyncContext<T> {\n let currentContext: T | undefined\n const contextStack: (T | undefined)[] = []\n\n return {\n get(): T | undefined {\n return currentContext\n },\n async run<R>(value: T, fn: () => R | Promise<R>): Promise<R> {\n const prevContext = currentContext\n currentContext = value\n contextStack.push(prevContext)\n\n // store original Promise methods\n const OriginalPromise = Promise\n const OriginalThen = OriginalPromise.prototype.then\n const OriginalCatch = OriginalPromise.prototype.catch\n const OriginalFinally = OriginalPromise.prototype.finally\n\n function wrapCallback(\n callback: Function | undefined | null,\n context: T | undefined,\n ): Function | undefined | null {\n if (!callback) return callback\n return (...args: any[]) => {\n const prevContext = currentContext\n currentContext = context\n try {\n return callback(...args)\n } finally {\n currentContext = prevContext\n }\n }\n }\n\n // patch Promise methods to capture and restore context\n // eslint-disable-next-line no-then-property -- intentional patching for context propagation\n OriginalPromise.prototype.then = function (\n this: Promise<any>,\n onFulfilled?: any,\n onRejected?: any,\n ): Promise<any> {\n const context = currentContext\n return OriginalThen.call(\n this,\n wrapCallback(onFulfilled, context) as any,\n wrapCallback(onRejected, context) as any,\n )\n }\n\n OriginalPromise.prototype.catch = function (\n this: Promise<any>,\n onRejected?: any,\n ): Promise<any> {\n const context = currentContext\n return OriginalCatch.call(this, wrapCallback(onRejected, context) as any)\n }\n\n OriginalPromise.prototype.finally = function (\n this: Promise<any>,\n onFinally?: any,\n ): Promise<any> {\n const context = currentContext\n return OriginalFinally.call(this, wrapCallback(onFinally, context) as any)\n }\n\n try {\n const result = await fn()\n return result\n } finally {\n // restore original Promise methods\n // eslint-disable-next-line no-then-property -- restoring original methods\n OriginalPromise.prototype.then = OriginalThen\n OriginalPromise.prototype.catch = OriginalCatch\n OriginalPromise.prototype.finally = OriginalFinally\n\n contextStack.pop()\n currentContext = prevContext\n }\n },\n }\n}\n"
10
10
  ]
11
11
  }
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "interface AsyncContext<T> {\n get(): T | undefined\n run<R>(value: T, fn: () => R | Promise<R>): Promise<R>\n}\n\n// react native implementation - no node:async_hooks available\nexport function createAsyncContext<T>(): AsyncContext<T> {\n let currentContext: T | undefined\n const contextStack: (T | undefined)[] = []\n\n return {\n get(): T | undefined {\n return currentContext\n },\n async run<R>(value: T, fn: () => R | Promise<R>): Promise<R> {\n const prevContext = currentContext\n currentContext = value\n contextStack.push(prevContext)\n\n // store original Promise methods\n const OriginalPromise = Promise\n const OriginalThen = OriginalPromise.prototype.then\n const OriginalCatch = OriginalPromise.prototype.catch\n const OriginalFinally = OriginalPromise.prototype.finally\n\n function wrapCallback(\n callback: Function | undefined | null,\n context: T | undefined\n ): Function | undefined | null {\n if (!callback) return callback\n return (...args: any[]) => {\n const prevContext = currentContext\n currentContext = context\n try {\n return callback(...args)\n } finally {\n currentContext = prevContext\n }\n }\n }\n\n // patch Promise methods to capture and restore context\n // eslint-disable-next-line no-then-property -- intentional patching for context propagation\n OriginalPromise.prototype.then = function (\n this: Promise<any>,\n onFulfilled?: any,\n onRejected?: any\n ): Promise<any> {\n const context = currentContext\n return OriginalThen.call(\n this,\n wrapCallback(onFulfilled, context) as any,\n wrapCallback(onRejected, context) as any\n )\n }\n\n OriginalPromise.prototype.catch = function (\n this: Promise<any>,\n onRejected?: any\n ): Promise<any> {\n const context = currentContext\n return OriginalCatch.call(this, wrapCallback(onRejected, context) as any)\n }\n\n OriginalPromise.prototype.finally = function (\n this: Promise<any>,\n onFinally?: any\n ): Promise<any> {\n const context = currentContext\n return OriginalFinally.call(this, wrapCallback(onFinally, context) as any)\n }\n\n try {\n const result = await fn()\n return result\n } finally {\n // restore original Promise methods\n // eslint-disable-next-line no-then-property -- restoring original methods\n OriginalPromise.prototype.then = OriginalThen\n OriginalPromise.prototype.catch = OriginalCatch\n OriginalPromise.prototype.finally = OriginalFinally\n\n contextStack.pop()\n currentContext = prevContext\n }\n },\n }\n}\n"
9
+ "interface AsyncContext<T> {\n get(): T | undefined\n run<R>(value: T, fn: () => R | Promise<R>): Promise<R>\n}\n\n// react native implementation - no node:async_hooks available\nexport function createAsyncContext<T>(): AsyncContext<T> {\n let currentContext: T | undefined\n const contextStack: (T | undefined)[] = []\n\n return {\n get(): T | undefined {\n return currentContext\n },\n async run<R>(value: T, fn: () => R | Promise<R>): Promise<R> {\n const prevContext = currentContext\n currentContext = value\n contextStack.push(prevContext)\n\n // store original Promise methods\n const OriginalPromise = Promise\n const OriginalThen = OriginalPromise.prototype.then\n const OriginalCatch = OriginalPromise.prototype.catch\n const OriginalFinally = OriginalPromise.prototype.finally\n\n function wrapCallback(\n callback: Function | undefined | null,\n context: T | undefined,\n ): Function | undefined | null {\n if (!callback) return callback\n return (...args: any[]) => {\n const prevContext = currentContext\n currentContext = context\n try {\n return callback(...args)\n } finally {\n currentContext = prevContext\n }\n }\n }\n\n // patch Promise methods to capture and restore context\n // eslint-disable-next-line no-then-property -- intentional patching for context propagation\n OriginalPromise.prototype.then = function (\n this: Promise<any>,\n onFulfilled?: any,\n onRejected?: any,\n ): Promise<any> {\n const context = currentContext\n return OriginalThen.call(\n this,\n wrapCallback(onFulfilled, context) as any,\n wrapCallback(onRejected, context) as any,\n )\n }\n\n OriginalPromise.prototype.catch = function (\n this: Promise<any>,\n onRejected?: any,\n ): Promise<any> {\n const context = currentContext\n return OriginalCatch.call(this, wrapCallback(onRejected, context) as any)\n }\n\n OriginalPromise.prototype.finally = function (\n this: Promise<any>,\n onFinally?: any,\n ): Promise<any> {\n const context = currentContext\n return OriginalFinally.call(this, wrapCallback(onFinally, context) as any)\n }\n\n try {\n const result = await fn()\n return result\n } finally {\n // restore original Promise methods\n // eslint-disable-next-line no-then-property -- restoring original methods\n OriginalPromise.prototype.then = OriginalThen\n OriginalPromise.prototype.catch = OriginalCatch\n OriginalPromise.prototype.finally = OriginalFinally\n\n contextStack.pop()\n currentContext = prevContext\n }\n },\n }\n}\n"
10
10
  ]
11
11
  }
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "import { AbortError } from '../error/errors'\nimport { sleep } from './sleep'\n\n/**\n * Two helpers wrapping requestIdleCallback in async, abortable.\n */\n\ntype CallbackFn = (...args: any[]) => any | (() => any)\ntype CallbackerFn = (cb: CallbackFn) => void\n\nconst idleCb: CallbackerFn =\n typeof requestIdleCallback === 'undefined'\n ? (cb: CallbackFn) => setTimeout(cb, 1)\n : requestIdleCallback\n\nconst idleAsync = () => {\n return new Promise((res) => {\n idleCb(res)\n })\n}\n\nexport type IdleOptions = {\n max?: number\n min?: number\n fully?: boolean\n}\n\nexport const idle = async (\n options?: IdleOptions,\n signal?: AbortSignal\n): Promise<void> => {\n const { max, min, fully } = options || {}\n\n const idleFn = fully ? fullyIdle : idleAsync\n\n if (max && min && min < max) {\n await Promise.race([Promise.all([idleFn(), sleep(min)]), sleep(max)])\n } else if (max) {\n await Promise.race([idleFn(), sleep(max)])\n } else if (min) {\n await Promise.all([idleFn(), sleep(min)])\n } else {\n await idleFn()\n }\n\n if (signal?.aborted) {\n throw new AbortError()\n }\n}\n\nconst fullyIdle = async (signal?: AbortSignal): Promise<void> => {\n while (true) {\n const startTime = Date.now()\n await idle({}, signal)\n const endTime = Date.now()\n const duration = endTime - startTime\n\n // If idle callback took less than 15ms, consider it truly idle\n if (duration < 15) {\n break\n }\n\n // Check for abort signal after each iteration\n if (signal?.aborted) {\n throw new AbortError()\n }\n }\n}\n"
9
+ "import { AbortError } from '../error/errors'\nimport { sleep } from './sleep'\n\n/**\n * Two helpers wrapping requestIdleCallback in async, abortable.\n */\n\ntype CallbackFn = (...args: any[]) => any\ntype CallbackerFn = (cb: CallbackFn) => void\n\nconst idleCb: CallbackerFn =\n typeof requestIdleCallback === 'undefined'\n ? (cb: CallbackFn) => setTimeout(cb, 1)\n : requestIdleCallback\n\nconst idleAsync = () => {\n return new Promise((res) => {\n idleCb(res)\n })\n}\n\nexport type IdleOptions = {\n max?: number\n min?: number\n fully?: boolean\n}\n\nexport const idle = async (\n options?: IdleOptions,\n signal?: AbortSignal,\n): Promise<void> => {\n const { max, min, fully } = options || {}\n\n const idleFn = fully ? fullyIdle : idleAsync\n\n if (max && min && min < max) {\n await Promise.race([Promise.all([idleFn(), sleep(min)]), sleep(max)])\n } else if (max) {\n await Promise.race([idleFn(), sleep(max)])\n } else if (min) {\n await Promise.all([idleFn(), sleep(min)])\n } else {\n await idleFn()\n }\n\n if (signal?.aborted) {\n throw new AbortError()\n }\n}\n\nconst fullyIdle = async (signal?: AbortSignal): Promise<void> => {\n while (true) {\n const startTime = Date.now()\n await idle({}, signal)\n const endTime = Date.now()\n const duration = endTime - startTime\n\n // If idle callback took less than 15ms, consider it truly idle\n if (duration < 15) {\n break\n }\n\n // Check for abort signal after each iteration\n if (signal?.aborted) {\n throw new AbortError()\n }\n }\n}\n"
10
10
  ]
11
11
  }
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "import { sleep } from './sleep'\n\nexport const interval = async (\n callback: () => void,\n ms: number,\n signal?: AbortSignal\n): Promise<never> => {\n while (true) {\n callback()\n await sleep(ms, signal)\n }\n}\n"
9
+ "import { sleep } from './sleep'\n\nexport const interval = async (\n callback: () => void,\n ms: number,\n signal?: AbortSignal,\n): Promise<never> => {\n while (true) {\n callback()\n await sleep(ms, signal)\n }\n}\n"
10
10
  ]
11
11
  }
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "import { useState, useEffect } from 'react'\n\nexport function useAsync<T>(\n promiseFn: () => Promise<T>,\n args: any[]\n): [T, 'loading' | 'idle' | 'error', Error | null] {\n const [data, setData] = useState<T | null>(null)\n const [error, setError] = useState<Error | null>(null)\n const [loading, setLoading] = useState<boolean>(true)\n\n useEffect(() => {\n let isMounted = true\n\n const fetchData = async () => {\n try {\n const result = await promiseFn()\n if (isMounted) {\n setData(result)\n setLoading(false)\n }\n } catch (err) {\n if (isMounted) {\n setError(err as Error)\n setLoading(false)\n }\n }\n }\n\n fetchData()\n\n return () => {\n isMounted = false\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, args)\n\n return [data as T, error ? 'error' : loading ? 'loading' : 'idle', error]\n}\n"
9
+ "import { useState, useEffect } from 'react'\n\nexport function useAsync<T>(\n promiseFn: () => Promise<T>,\n args: any[],\n): [T, 'loading' | 'idle' | 'error', Error | null] {\n const [data, setData] = useState<T | null>(null)\n const [error, setError] = useState<Error | null>(null)\n const [loading, setLoading] = useState<boolean>(true)\n\n useEffect(() => {\n let isMounted = true\n\n const fetchData = async () => {\n try {\n const result = await promiseFn()\n if (isMounted) {\n setData(result)\n setLoading(false)\n }\n } catch (err) {\n if (isMounted) {\n setError(err as Error)\n setLoading(false)\n }\n }\n }\n\n fetchData()\n\n return () => {\n isMounted = false\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, args)\n\n return [data as T, error ? 'error' : loading ? 'loading' : 'idle', error]\n}\n"
10
10
  ]
11
11
  }
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "// adopted from https://github.com/franciscop/use-async/blob/master/src/index.js\n\nimport { useEffect, useId, useLayoutEffect } from 'react'\n\nimport { EMPTY_OBJECT } from '../constants'\nimport { getCurrentComponentStack } from '../react/getCurrentComponentStack'\nimport { handleAbortError } from './abortable'\n\ntype Cleanup = () => void\n\ntype AsyncEffectCallback = (\n signal: AbortSignal,\n ...deps: any[]\n) => Promise<Cleanup | void> | void\n\ntype AsyncEffectOptions = {\n circuitBreakAfter?: number\n circuitBreakPeriod?: number\n debug?: boolean\n}\n\nexport function useAsyncEffect(\n cb: AsyncEffectCallback,\n deps: any[] = [],\n options?: AsyncEffectOptions\n): void {\n useAsyncEffectImpl(false, cb, deps, options)\n}\n\nexport function useAsyncLayoutEffect(\n cb: AsyncEffectCallback,\n deps: any[] = [],\n options?: AsyncEffectOptions\n): void {\n useAsyncEffectImpl(true, cb, deps, options)\n}\n\nfunction useAsyncEffectImpl(\n isLayoutEffect: boolean,\n cb: AsyncEffectCallback,\n deps: any[] = [],\n options: AsyncEffectOptions = EMPTY_OBJECT\n): void {\n const effectHook = isLayoutEffect ? useLayoutEffect : useEffect\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const effectId = process.env.NODE_ENV === 'development' ? useId() : ''\n\n effectHook(() => {\n // Generate a unique ID for this effect instance for loop detection\n checkEffectLoop(\n effectId,\n cb,\n deps,\n options.circuitBreakAfter,\n options.circuitBreakPeriod\n )\n const controller = new AbortController()\n const signal = controller.signal\n\n // wrap in try in case its not async (for simple use cases)\n try {\n const value = cb(signal, ...deps)\n\n Promise.resolve(value)\n .then(async (res) => {\n if (res && typeof res === 'function') {\n if (signal.aborted) return res()\n signal.addEventListener('abort', res)\n }\n })\n .catch(handleAbortError)\n } catch (error) {\n handleAbortError(error, options.debug)\n }\n\n return () => {\n if (signal.aborted) return\n controller.abort()\n }\n }, deps)\n}\n\n// loop detection in dev mode\nlet effectRunCounts: Map<string, number[]>\nlet checkEffectLoop: (\n effectId: string,\n cb: AsyncEffectCallback,\n deps: any[],\n circuitBreakAfter?: number,\n circuitBreakPeriod?: number\n) => void\n\nfunction formatDeps(deps: any[]): string {\n try {\n return JSON.stringify(\n deps,\n (_, v) => {\n if (typeof v === 'function') return `[Function: ${v.name || 'anonymous'}]`\n if (typeof v === 'symbol') return v.toString()\n if (v instanceof Error) return `[Error: ${v.message}]`\n return v\n },\n 2\n )\n } catch {\n return `[${deps.length} deps - not serializable]`\n }\n}\n\nif (process.env.NODE_ENV === 'development') {\n effectRunCounts = new Map<string, number[]>()\n\n checkEffectLoop = (\n effectId: string,\n cb: AsyncEffectCallback,\n deps: any[],\n circuitBreakAfter: number = 20,\n circuitBreakPeriod: number = 1000\n ) => {\n const now = Date.now()\n const runs = effectRunCounts.get(effectId) || []\n\n runs.push(now)\n\n // keep only runs from the specified period\n const recentRuns = runs.filter((time) => now - time < circuitBreakPeriod)\n effectRunCounts.set(effectId, recentRuns)\n\n const runCount = recentRuns.length\n\n if (runCount > circuitBreakAfter) {\n const message = `🚨 useAsyncEffect infinite loop detected! Effect ran ${runCount} times in <${circuitBreakPeriod}ms`\n if (process.env.NODE_ENV === 'development') {\n console.error(message)\n console.error('Effect function:', cb.toString().slice(0, 500))\n console.error('Dependencies:', formatDeps(deps))\n console.error('Stack:', getCurrentComponentStack())\n // eslint-disable-next-line no-debugger\n debugger\n } else {\n alert(message)\n throw new Error(message)\n }\n } else if (runCount > circuitBreakAfter / 2) {\n console.warn(\n `⚠️ useAsyncEffect potential loop: Effect ran ${runCount} times in <${circuitBreakPeriod}ms`\n )\n console.warn('Effect function:', cb.toString().slice(0, 500))\n console.warn('Dependencies:', formatDeps(deps))\n console.warn('Stack:', getCurrentComponentStack())\n }\n }\n} else {\n checkEffectLoop = (_id, _cb, _deps, _after, _period) => {}\n}\n"
9
+ "// adopted from https://github.com/franciscop/use-async/blob/master/src/index.js\n\nimport { useEffect, useId, useLayoutEffect } from 'react'\n\nimport { EMPTY_OBJECT } from '../constants'\nimport { getCurrentComponentStack } from '../react/getCurrentComponentStack'\nimport { handleAbortError } from './abortable'\n\ntype Cleanup = () => void\n\ntype AsyncEffectCallback = (\n signal: AbortSignal,\n ...deps: any[]\n) => Promise<Cleanup | void> | void\n\ntype AsyncEffectOptions = {\n circuitBreakAfter?: number\n circuitBreakPeriod?: number\n debug?: boolean\n}\n\nexport function useAsyncEffect(\n cb: AsyncEffectCallback,\n deps: any[] = [],\n options?: AsyncEffectOptions,\n): void {\n useAsyncEffectImpl(false, cb, deps, options)\n}\n\nexport function useAsyncLayoutEffect(\n cb: AsyncEffectCallback,\n deps: any[] = [],\n options?: AsyncEffectOptions,\n): void {\n useAsyncEffectImpl(true, cb, deps, options)\n}\n\nfunction useAsyncEffectImpl(\n isLayoutEffect: boolean,\n cb: AsyncEffectCallback,\n deps: any[] = [],\n options: AsyncEffectOptions = EMPTY_OBJECT,\n): void {\n const effectHook = isLayoutEffect ? useLayoutEffect : useEffect\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const effectId = process.env.NODE_ENV === 'development' ? useId() : ''\n\n effectHook(() => {\n // Generate a unique ID for this effect instance for loop detection\n checkEffectLoop(\n effectId,\n cb,\n deps,\n options.circuitBreakAfter,\n options.circuitBreakPeriod,\n )\n const controller = new AbortController()\n const signal = controller.signal\n\n // wrap in try in case its not async (for simple use cases)\n try {\n const value = cb(signal, ...deps)\n\n Promise.resolve(value)\n .then(async (res) => {\n if (res && typeof res === 'function') {\n if (signal.aborted) return res()\n signal.addEventListener('abort', res)\n }\n })\n .catch(handleAbortError)\n } catch (error) {\n handleAbortError(error, options.debug)\n }\n\n return () => {\n if (signal.aborted) return\n controller.abort()\n }\n }, deps)\n}\n\n// loop detection in dev mode\nlet effectRunCounts: Map<string, number[]>\nlet checkEffectLoop: (\n effectId: string,\n cb: AsyncEffectCallback,\n deps: any[],\n circuitBreakAfter?: number,\n circuitBreakPeriod?: number,\n) => void\n\nfunction formatDeps(deps: any[]): string {\n try {\n return JSON.stringify(\n deps,\n (_, v) => {\n if (typeof v === 'function') return `[Function: ${v.name || 'anonymous'}]`\n if (typeof v === 'symbol') return v.toString()\n if (v instanceof Error) return `[Error: ${v.message}]`\n return v\n },\n 2,\n )\n } catch {\n return `[${deps.length} deps - not serializable]`\n }\n}\n\nif (process.env.NODE_ENV === 'development') {\n effectRunCounts = new Map<string, number[]>()\n\n checkEffectLoop = (\n effectId: string,\n cb: AsyncEffectCallback,\n deps: any[],\n circuitBreakAfter: number = 20,\n circuitBreakPeriod: number = 1000,\n ) => {\n const now = Date.now()\n const runs = effectRunCounts.get(effectId) || []\n\n runs.push(now)\n\n // keep only runs from the specified period\n const recentRuns = runs.filter((time) => now - time < circuitBreakPeriod)\n effectRunCounts.set(effectId, recentRuns)\n\n const runCount = recentRuns.length\n\n if (runCount > circuitBreakAfter) {\n const message = `🚨 useAsyncEffect infinite loop detected! Effect ran ${runCount} times in <${circuitBreakPeriod}ms`\n if (process.env.NODE_ENV === 'development') {\n console.error(message)\n console.error('Effect function:', cb.toString().slice(0, 500))\n console.error('Dependencies:', formatDeps(deps))\n console.error('Stack:', getCurrentComponentStack())\n // eslint-disable-next-line no-debugger\n debugger\n } else {\n alert(message)\n throw new Error(message)\n }\n } else if (runCount > circuitBreakAfter / 2) {\n console.warn(\n `⚠️ useAsyncEffect potential loop: Effect ran ${runCount} times in <${circuitBreakPeriod}ms`,\n )\n console.warn('Effect function:', cb.toString().slice(0, 500))\n console.warn('Dependencies:', formatDeps(deps))\n console.warn('Stack:', getCurrentComponentStack())\n }\n }\n} else {\n checkEffectLoop = (_id, _cb, _deps, _after, _period) => {}\n}\n"
10
10
  ]
11
11
  }
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "import { startTransition, useState } from 'react'\n\nimport { idle, type IdleOptions } from './idle'\nimport { useAsyncEffect } from './useAsyncEffect'\n\nimport type React from 'react'\n\nexport type LazyMountProps = IdleOptions\n\nexport const useLazyMount = (props: LazyMountProps = { max: 100 }): boolean => {\n const [mounted, setMounted] = useState(false)\n\n useAsyncEffect(\n async (signal) => {\n await idle(props, signal)\n startTransition(() => {\n setMounted(true)\n })\n },\n [\n // no need for deps it only ever mounts once\n ]\n )\n\n return mounted\n}\n\nexport const LazyMount = ({\n children,\n ...idleProps\n}: LazyMountProps & { children: any }): React.ReactNode => {\n const mounted = useLazyMount(idleProps)\n return mounted ? children : null\n}\n"
9
+ "import { startTransition, useState } from 'react'\n\nimport { idle, type IdleOptions } from './idle'\nimport { useAsyncEffect } from './useAsyncEffect'\n\nimport type React from 'react'\n\nexport type LazyMountProps = IdleOptions\n\nexport const useLazyMount = (props: LazyMountProps = { max: 100 }): boolean => {\n const [mounted, setMounted] = useState(false)\n\n useAsyncEffect(\n async (signal) => {\n await idle(props, signal)\n startTransition(() => {\n setMounted(true)\n })\n },\n [\n // no need for deps it only ever mounts once\n ],\n )\n\n return mounted\n}\n\nexport const LazyMount = ({\n children,\n ...idleProps\n}: LazyMountProps & { children: any }): React.ReactNode => {\n const mounted = useLazyMount(idleProps)\n return mounted ? children : null\n}\n"
10
10
  ]
11
11
  }
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "import { startTransition, useState } from 'react'\n\nimport { idle, type IdleOptions } from './idle'\nimport { useAsyncEffect } from './useAsyncEffect'\n\nexport const useLazyValue = <T>(\n value: T,\n {\n immediateFirstUpdate,\n ...idleOptions\n }: IdleOptions & { immediateFirstUpdate?: boolean } = {}\n): T => {\n const [lazyValue, setLazyValue] = useState(value)\n\n // first update to a real value immediate\n if (value && lazyValue === undefined && lazyValue !== value && immediateFirstUpdate) {\n setLazyValue(value)\n }\n\n useAsyncEffect(\n async (signal) => {\n await idle(idleOptions, signal)\n startTransition(() => {\n setLazyValue(value)\n })\n },\n [value]\n )\n\n return lazyValue\n}\n"
9
+ "import { startTransition, useState } from 'react'\n\nimport { idle, type IdleOptions } from './idle'\nimport { useAsyncEffect } from './useAsyncEffect'\n\nexport const useLazyValue = <T>(\n value: T,\n {\n immediateFirstUpdate,\n ...idleOptions\n }: IdleOptions & { immediateFirstUpdate?: boolean } = {},\n): T => {\n const [lazyValue, setLazyValue] = useState(value)\n\n // first update to a real value immediate\n if (value && lazyValue === undefined && lazyValue !== value && immediateFirstUpdate) {\n setLazyValue(value)\n }\n\n useAsyncEffect(\n async (signal) => {\n await idle(idleOptions, signal)\n startTransition(() => {\n setLazyValue(value)\n })\n },\n [value],\n )\n\n return lazyValue\n}\n"
10
10
  ]
11
11
  }
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "export async function clearIndexedDB(): Promise<void> {\n if ('indexedDB' in window) {\n const databases = await indexedDB.databases()\n await Promise.all(\n databases.map((db) => {\n if (db.name) {\n return new Promise<void>((resolve, reject) => {\n const deleteReq = indexedDB.deleteDatabase(db.name!)\n deleteReq.onsuccess = () => resolve()\n deleteReq.onerror = () => reject(deleteReq.error)\n deleteReq.onblocked = () => reject(new Error('database deletion blocked'))\n })\n }\n return Promise.resolve()\n })\n )\n }\n}\n"
9
+ "export async function clearIndexedDB(): Promise<void> {\n if ('indexedDB' in window) {\n const databases = await indexedDB.databases()\n await Promise.all(\n databases.map((db) => {\n if (db.name) {\n return new Promise<void>((resolve, reject) => {\n const deleteReq = indexedDB.deleteDatabase(db.name!)\n deleteReq.onsuccess = () => resolve()\n deleteReq.onerror = () => reject(deleteReq.error)\n deleteReq.onblocked = () => reject(new Error('database deletion blocked'))\n })\n }\n return Promise.resolve()\n }),\n )\n }\n}\n"
10
10
  ]
11
11
  }
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "// note safari enhanced privacy will break this as it reports screen height as smaller\n\nexport function openCenteredPopup(\n url: string,\n title: string,\n width: number,\n height: number\n): Window | null {\n // availWidth/availHeight accounts for taskbars, docks, and other UI elements\n const screenWidth = screen.availWidth || screen.width\n const screenHeight = screen.availHeight || screen.height\n\n const shouldGuess = screenHeight < height\n\n // if we are guessing, at least make it a bit more likely to be centered\n // and not just touching the top which looks broken\n const left = Math.max(0, (screenWidth - width) / 2) + (shouldGuess ? 100 : 0)\n const top = Math.max(150, shouldGuess ? 150 : Math.max(0, (screenHeight - height) / 2))\n\n const windowFeatures = `\n width=${width},\n height=${height},\n left=${left},\n top=${top},\n scrollbars=yes,\n resizable=yes\n `\n\n return window.open(url, title, windowFeatures)\n}\n"
9
+ "// note safari enhanced privacy will break this as it reports screen height as smaller\n\nexport function openCenteredPopup(\n url: string,\n title: string,\n width: number,\n height: number,\n): Window | null {\n // availWidth/availHeight accounts for taskbars, docks, and other UI elements\n const screenWidth = screen.availWidth || screen.width\n const screenHeight = screen.availHeight || screen.height\n\n const shouldGuess = screenHeight < height\n\n // if we are guessing, at least make it a bit more likely to be centered\n // and not just touching the top which looks broken\n const left = Math.max(0, (screenWidth - width) / 2) + (shouldGuess ? 100 : 0)\n const top = Math.max(150, shouldGuess ? 150 : Math.max(0, (screenHeight - height) / 2))\n\n const windowFeatures = `\n width=${width},\n height=${height},\n left=${left},\n top=${top},\n scrollbars=yes,\n resizable=yes\n `\n\n return window.open(url, title, windowFeatures)\n}\n"
10
10
  ]
11
11
  }
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "import { isWeb } from '@tamagui/constants'\n\nexport const isTauri: boolean = typeof window !== 'undefined' && '__TAURI__' in window\n\nexport const isNative: boolean = !isWeb && !isTauri\n\n// TODO move to probably ~/interface/constants\n\nexport const IS_MAC_DESKTOP: boolean =\n typeof navigator !== 'undefined' && /Macintosh|MacIntel/.test(navigator.platform)\n\nexport const IS_SAFARI: boolean =\n isTauri ||\n (typeof navigator !== 'undefined' &&\n /Version\\/[\\d.]+.*Safari/.test(navigator.userAgent) &&\n /Apple Computer/.test(navigator.vendor))\n\nexport { isAndroid, isBrowser, isIos, isServer, isWeb } from '@tamagui/constants'\n\nexport const EMPTY_ARRAY = [] as never\nexport const EMPTY_OBJECT = {} as never\n\nconst getDebugLevelFromUrl = (): number | null => {\n if (typeof window === 'undefined') return null\n const match = window.location?.search?.match(/debug=(\\d+)/)\n return match?.[1] ? parseInt(match[1], 10) : null\n}\n\nexport const DEBUG_LEVEL: number = process.env.DEBUG_LEVEL\n ? +process.env.DEBUG_LEVEL\n : (getDebugLevelFromUrl() ?? (process.env.NODE_ENV === 'development' ? 1 : 0))\n"
9
+ "import { isWeb } from '@tamagui/constants'\n\nexport const isTauri: boolean = typeof window !== 'undefined' && '__TAURI__' in window\n\nexport const isNative: boolean = !isWeb && !isTauri\n\n// TODO move to probably ~/interface/constants\n\nexport const IS_MAC_DESKTOP: boolean =\n typeof navigator !== 'undefined' && /Macintosh|MacIntel/.test(navigator.platform)\n\nexport const IS_SAFARI: boolean =\n isTauri ||\n (typeof navigator !== 'undefined' &&\n /Version\\/[\\d.]+.*Safari/.test(navigator.userAgent) &&\n navigator.vendor.includes('Apple Computer'))\n\nexport { isAndroid, isBrowser, isIos, isServer, isWeb } from '@tamagui/constants'\n\nexport const EMPTY_ARRAY = [] as never\nexport const EMPTY_OBJECT = {} as never\n\nconst getDebugLevelFromUrl = (): number | null => {\n if (typeof window === 'undefined') return null\n const match = window.location?.search?.match(/debug=(\\d+)/)\n return match?.[1] ? parseInt(match[1], 10) : null\n}\n\nexport const DEBUG_LEVEL: number = process.env.DEBUG_LEVEL\n ? +process.env.DEBUG_LEVEL\n : (getDebugLevelFromUrl() ?? (process.env.NODE_ENV === 'development' ? 1 : 0))\n"
10
10
  ]
11
11
  }
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "import { useCallback } from 'react'\n\nexport function useDebugState<T>(\n useState: [T, React.Dispatch<React.SetStateAction<T>>]\n): [T, React.Dispatch<React.SetStateAction<T>>] {\n const [state, setState] = useState\n\n const wrappedSetState = useCallback(\n (newValue: T | ((prevState: T) => T)) => {\n if (typeof newValue === 'function') {\n // Handle callback style\n setState((prevState: T) => {\n const nextState = (newValue as (prevState: T) => T)(prevState)\n console.trace('State update (callback):', {\n prevState,\n nextState,\n stack: new Error().stack,\n })\n return nextState\n })\n } else {\n // Handle direct value style\n console.trace('State update (direct):', {\n prevState: state,\n nextState: newValue,\n stack: new Error().stack,\n })\n setState(newValue)\n }\n },\n [setState, state]\n )\n\n return [state, wrappedSetState]\n}\n"
9
+ "import { useCallback } from 'react'\n\nexport function useDebugState<T>(\n useState: [T, React.Dispatch<React.SetStateAction<T>>],\n): [T, React.Dispatch<React.SetStateAction<T>>] {\n const [state, setState] = useState\n\n const wrappedSetState = useCallback(\n (newValue: T | ((prevState: T) => T)) => {\n if (typeof newValue === 'function') {\n // Handle callback style\n setState((prevState: T) => {\n const nextState = (newValue as (prevState: T) => T)(prevState)\n console.trace('State update (callback):', {\n prevState,\n nextState,\n stack: new Error().stack,\n })\n return nextState\n })\n } else {\n // Handle direct value style\n console.trace('State update (direct):', {\n prevState: state,\n nextState: newValue,\n stack: new Error().stack,\n })\n setState(newValue)\n }\n },\n [setState, state],\n )\n\n return [state, wrappedSetState]\n}\n"
10
10
  ]
11
11
  }
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "import { dequal } from 'dequal'\nimport * as React from 'react'\nimport { use, useLayoutEffect, useState } from 'react'\n\nimport { handleAbortError } from './async/abortable'\nimport { DEBUG_LEVEL, EMPTY_ARRAY } from './constants'\nimport { AbortError } from './error/errors'\nimport { globalValue } from './global/globalValue'\nimport { createGlobalContext } from './react/createGlobalContext'\n\nimport type { JSX, PropsWithChildren } from 'react'\n\n// keeps a reference to the current value easily\n\n// TODO can replace with useEffectEvent\nfunction useGet<A>(\n currentValue: A,\n initialValue?: any,\n forwardToFunction?: boolean\n): () => A {\n const curRef = React.useRef<any>(initialValue ?? currentValue)\n\n useLayoutEffect(() => {\n curRef.current = currentValue\n })\n\n // oxlint-disable-next-line exhaustive-deps\n return React.useCallback(\n forwardToFunction\n ? (...args) => curRef.current?.apply(null, args)\n : () => curRef.current,\n [curRef, forwardToFunction]\n )\n}\n\ntype EmitterOptions<T> = CreateEmitterOpts<T> & {\n name: string\n}\n\ntype CreateEmitterOpts<T> = {\n silent?: boolean\n comparator?: (a: T, b: T) => boolean\n}\n\nexport class Emitter<const T> {\n private disposables = new Set<(cb: any) => void>()\n value: T\n options?: EmitterOptions<T>\n\n constructor(value: T, options?: EmitterOptions<T>) {\n this.value = value\n this.options = options\n }\n\n listen = (disposable: (cb: T) => void): (() => void) => {\n this.disposables.add(disposable)\n return (): void => {\n this.disposables.delete(disposable)\n }\n }\n\n emit = (next: T): void => {\n if (process.env.NODE_ENV === 'development') {\n setCache(this, next)\n }\n const compare = this.options?.comparator\n if (compare) {\n if (this.value && compare(this.value, next)) {\n return\n }\n } else {\n if (this.value === next) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n `[emitter] ${this.options?.name} no comparator option but received same value!\n \nthis will emit the same value again, which can be desirable, but we warn to ensure it's not unintended:\n\n- if you want this behavior, add { comparator: isEqualNever }\n- if you want only non-equal values: { comparator: isEqualIdentity }\n- if you want only deeply non-equal values: { comparator: isEqualDeep }`\n )\n }\n }\n }\n this.value = next\n if (DEBUG_LEVEL > 1) {\n if (!this.options?.silent) {\n const name = this.options?.name\n console.groupCollapsed(`📣 ${name}`)\n console.info(next)\n console.trace(`trace >`)\n console.groupEnd()\n }\n }\n this.disposables.forEach((cb) => cb(next))\n }\n\n nextValue = (): Promise<T> => {\n return new Promise<T>((res) => {\n const dispose = this.listen((val) => {\n dispose()\n res(val)\n })\n })\n }\n}\n\n// just createEmitter but ensures it doesn't mess up on HMR\nexport function createGlobalEmitter<T>(\n name: string,\n defaultValue: T,\n options?: CreateEmitterOpts<T>\n): Emitter<T> {\n return globalValue(name, () => createEmitter(name, defaultValue, options))\n}\n\nexport function createEmitter<T>(\n name: string,\n defaultValue: T,\n options?: CreateEmitterOpts<T>\n): Emitter<T> {\n const existing = createOrUpdateCache(name, defaultValue) as T\n return new Emitter<T>(existing || defaultValue, { name, ...options })\n}\n\nexport type EmitterType<E extends Emitter<any>> =\n E extends Emitter<infer Val> ? Val : never\n\nexport const useEmitter = <E extends Emitter<any>>(\n emitter: E,\n cb: (cb: EmitterType<E>) => void,\n args?: any[]\n): void => {\n const getCallback = useGet(cb)\n\n useLayoutEffect(() => {\n return emitter.listen((val) => {\n try {\n getCallback()(val)\n } catch (err) {\n handleAbortError(err)\n }\n })\n }, [emitter, getCallback])\n}\n\n// i think this was useSyncExternalStore but removed for concurrent rendering improvements\n// wondering if we could just always return a deferred value? or default to it?\n\nexport const useEmitterValue = <E extends Emitter<any>>(\n emitter: E,\n options?: { disable?: boolean }\n): EmitterType<E> => {\n const disabled = options?.disable\n\n // use a function initializer to get current emitter value\n const [state, setState] = useState<EmitterType<E>>(() => emitter.value)\n\n useLayoutEffect(() => {\n if (disabled) return\n\n // sync immediately in case emitter changed between render and effect\n if (emitter.value !== state) {\n setState(emitter.value)\n }\n\n return emitter.listen(setState)\n }, [state, disabled, emitter])\n\n return state\n}\n\n/**\n * By default selectors run every render, as well as when emitters update. This is a change\n * from the previous behavior where they only ran when emitters changed value.\n *\n * The reason for this is because emitters capture the variables in scope of the component\n * each render already by using \"useGet\" by default, which makes them easier to use - you\n * don't need to pass an args[] array except for edge cases.\n *\n * Before explaining why we switched to the default, understand the different uses:\n *\n * - Default behavior - selector is updated every render, and ran every render, as well as\n * when emitter value changes, so you basically are always up to date.\n *\n * - Set an args[] array as the fourth argument - this will stop the automatic capturing\n * and instead update selector only when you change args[] yourself. This is good for when you\n * want explicit control over re-selection and rendering.\n *\n * - With { lazy: true }, the selector only runs when the emitter value changes. If used with\n * args[], you capture the context of the selector based on args[], if not, it's based on the\n * current render.\n *\n * I made this change when we had 16 usages of useEmitterSelector and 100% of them are doing very\n * cheap calculations, so this feels like the right pattern. For the rare case of a heavy selector,\n * you have the option to control it.\n *\n */\nexport const useEmitterSelector = <E extends Emitter<any>, T extends EmitterType<E>, R>(\n emitter: E,\n selector: (value: T) => R,\n options?: {\n disable?: boolean\n lazy?: boolean\n },\n args: any[] = EMPTY_ARRAY\n): R => {\n const [state, setState] = useState<R>(() => selector(emitter.value))\n const disabled = options?.disable\n const getSelector = useGet(selector)\n\n if (options?.lazy !== true) {\n const next = selector(emitter.value)\n if (next !== state) {\n setState(next)\n }\n }\n\n useLayoutEffect(() => {\n if (disabled) return\n return emitter.listen((val) => {\n try {\n const selectorFn = args !== EMPTY_ARRAY ? selector : getSelector()\n const next = selectorFn(val)\n setState(next)\n } catch (error) {\n if (error instanceof AbortError) {\n return\n }\n throw error\n }\n })\n // oxlint-disable-next-line exhaustive-deps\n }, [disabled, emitter, getSelector, ...args])\n\n return state\n}\n\nexport const useEmittersSelector = <const E extends readonly Emitter<any>[], R>(\n emitters: E,\n selector: (values: { [K in keyof E]: EmitterType<E[K]> }) => R,\n options?: { disable?: boolean; isEqual?: (a: R, b: R) => boolean }\n): R => {\n const getSelector = useGet(selector)\n const disabled = options?.disable\n\n const [state, setState] = useState<R>(() => {\n const values = emitters.map((e) => e.value) as { [K in keyof E]: EmitterType<E[K]> }\n return getSelector()(values)\n })\n\n useLayoutEffect(() => {\n if (disabled) {\n return\n }\n\n const handler = () => {\n const values = emitters.map((e) => e.value) as {\n [K in keyof E]: EmitterType<E[K]>\n }\n try {\n const next = getSelector()(values)\n setState((prev) => {\n if (options?.isEqual?.(prev, next)) {\n return prev\n }\n if (dequal(prev, next)) {\n return prev\n }\n return next\n })\n } catch (error) {\n if (error instanceof AbortError) {\n return\n }\n throw error\n }\n }\n\n const disposals = emitters.map((emitter) => emitter.listen(handler))\n\n return () => {\n disposals.forEach((d) => d())\n }\n // oxlint-disable-next-line exhaustive-deps\n }, [disabled, getSelector, ...emitters])\n\n return state\n}\n\nexport const createUseEmitter = <E extends Emitter<any>>(\n emitter: E\n): ((cb: (val: EmitterType<E>) => void, args?: any[]) => void) => {\n return (cb: (val: EmitterType<E>) => void, args?: any[]) =>\n useEmitter(emitter, cb, args)\n}\n\nexport const createUseSelector = <E extends Emitter<any>>(\n emitter: E\n): (<R>(\n selector: (value: EmitterType<E>) => R,\n options?: { disable?: boolean; lazy?: boolean },\n args?: any[]\n) => R) => {\n return <R,>(\n selector: (value: EmitterType<E>) => R,\n options?: { disable?: boolean; lazy?: boolean },\n args?: any[]\n ): R => {\n return useEmitterSelector(emitter, selector, options, args)\n }\n}\n\nexport function createContextualEmitter<T>(\n name: string,\n defaultValue: T,\n defaultOptions?: Omit<EmitterOptions<T>, 'name'>\n): readonly [\n () => Emitter<T>,\n (props: PropsWithChildren<{ value?: T; silent?: boolean }>) => JSX.Element,\n] {\n const id = Math.random().toString(36)\n const EmitterContext = createGlobalContext<Emitter<T> | null>(\n `contextual-emitter/${id}`,\n null\n )\n\n const useContextEmitter = () => {\n const emitter = use(EmitterContext)\n if (!emitter) {\n throw new Error('useContextEmitter must be used within an EmitterProvider')\n }\n return emitter\n }\n\n type ProvideEmitterProps = PropsWithChildren<{\n value?: T\n silent?: boolean\n }>\n\n const ProvideEmitter = (props: ProvideEmitterProps) => {\n const { children, value, silent } = props\n const [emitter] = useState(\n () => new Emitter<T>(value ?? defaultValue, { name, silent, ...defaultOptions })\n )\n\n useLayoutEffect(() => {\n if (value !== undefined && value !== emitter.value) {\n emitter.emit(value)\n }\n }, [value, emitter])\n\n return <EmitterContext.Provider value={emitter}>{children}</EmitterContext.Provider>\n }\n\n return [useContextEmitter, ProvideEmitter] as const\n}\n\nconst HMRCache =\n process.env.NODE_ENV === 'development'\n ? new Map<string, { originalDefaultValue: unknown; currentValue: unknown }>()\n : null\n\nfunction setCache(emitter: Emitter<any>, value: unknown) {\n const name = emitter.options?.name\n if (!name) return\n const cache = HMRCache?.get(name)\n if (!cache) return\n cache.currentValue = value\n}\n\nfunction createOrUpdateCache(name: string, defaultValueProp: unknown) {\n const existing = HMRCache?.get(name)\n const defaultValue = dequal(existing?.originalDefaultValue, defaultValueProp)\n ? existing?.currentValue\n : defaultValueProp\n\n if (!existing) {\n HMRCache?.set(name, {\n originalDefaultValue: defaultValueProp,\n currentValue: defaultValue,\n })\n }\n\n return defaultValue\n}\n"
9
+ "import { dequal } from 'dequal'\nimport * as React from 'react'\nimport { use, useLayoutEffect, useState } from 'react'\n\nimport { handleAbortError } from './async/abortable'\nimport { DEBUG_LEVEL, EMPTY_ARRAY } from './constants'\nimport { AbortError } from './error/errors'\nimport { globalValue } from './global/globalValue'\nimport { createGlobalContext } from './react/createGlobalContext'\n\nimport type { JSX, PropsWithChildren } from 'react'\n\n// keeps a reference to the current value easily\n\n// TODO can replace with useEffectEvent\nfunction useGet<A>(\n currentValue: A,\n initialValue?: any,\n forwardToFunction?: boolean,\n): () => A {\n const curRef = React.useRef<any>(initialValue ?? currentValue)\n\n useLayoutEffect(() => {\n curRef.current = currentValue\n })\n\n // oxlint-disable-next-line exhaustive-deps\n return React.useCallback(\n forwardToFunction\n ? (...args) => curRef.current?.apply(null, args)\n : () => curRef.current,\n [curRef, forwardToFunction],\n )\n}\n\ntype EmitterOptions<T> = CreateEmitterOpts<T> & {\n name: string\n}\n\ntype CreateEmitterOpts<T> = {\n silent?: boolean\n comparator?: (a: T, b: T) => boolean\n}\n\nexport class Emitter<const T> {\n private disposables = new Set<(cb: any) => void>()\n value: T\n options?: EmitterOptions<T>\n\n constructor(value: T, options?: EmitterOptions<T>) {\n this.value = value\n this.options = options\n }\n\n listen = (disposable: (cb: T) => void): (() => void) => {\n this.disposables.add(disposable)\n return (): void => {\n this.disposables.delete(disposable)\n }\n }\n\n emit = (next: T): void => {\n if (process.env.NODE_ENV === 'development') {\n setCache(this, next)\n }\n const compare = this.options?.comparator\n if (compare) {\n if (this.value && compare(this.value, next)) {\n return\n }\n } else {\n if (this.value === next) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n `[emitter] ${this.options?.name} no comparator option but received same value!\n \nthis will emit the same value again, which can be desirable, but we warn to ensure it's not unintended:\n\n- if you want this behavior, add { comparator: isEqualNever }\n- if you want only non-equal values: { comparator: isEqualIdentity }\n- if you want only deeply non-equal values: { comparator: isEqualDeep }`,\n )\n }\n }\n }\n this.value = next\n if (DEBUG_LEVEL > 1) {\n if (!this.options?.silent) {\n const name = this.options?.name\n console.groupCollapsed(`📣 ${name}`)\n console.info(next)\n console.trace(`trace >`)\n console.groupEnd()\n }\n }\n this.disposables.forEach((cb) => cb(next))\n }\n\n nextValue = (): Promise<T> => {\n return new Promise<T>((res) => {\n const dispose = this.listen((val) => {\n dispose()\n res(val)\n })\n })\n }\n}\n\n// just createEmitter but ensures it doesn't mess up on HMR\nexport function createGlobalEmitter<T>(\n name: string,\n defaultValue: T,\n options?: CreateEmitterOpts<T>,\n): Emitter<T> {\n return globalValue(name, () => createEmitter(name, defaultValue, options))\n}\n\nexport function createEmitter<T>(\n name: string,\n defaultValue: T,\n options?: CreateEmitterOpts<T>,\n): Emitter<T> {\n const existing = createOrUpdateCache(name, defaultValue) as T\n return new Emitter<T>(existing || defaultValue, { name, ...options })\n}\n\nexport type EmitterType<E extends Emitter<any>> =\n E extends Emitter<infer Val> ? Val : never\n\nexport const useEmitter = <E extends Emitter<any>>(\n emitter: E,\n cb: (cb: EmitterType<E>) => void,\n args?: any[],\n): void => {\n const getCallback = useGet(cb)\n\n useLayoutEffect(() => {\n return emitter.listen((val) => {\n try {\n getCallback()(val)\n } catch (err) {\n handleAbortError(err)\n }\n })\n }, [emitter, getCallback])\n}\n\n// i think this was useSyncExternalStore but removed for concurrent rendering improvements\n// wondering if we could just always return a deferred value? or default to it?\n\nexport const useEmitterValue = <E extends Emitter<any>>(\n emitter: E,\n options?: { disable?: boolean },\n): EmitterType<E> => {\n const disabled = options?.disable\n\n // use a function initializer to get current emitter value\n const [state, setState] = useState<EmitterType<E>>(() => emitter.value)\n\n useLayoutEffect(() => {\n if (disabled) return\n\n // sync immediately in case emitter changed between render and effect\n if (emitter.value !== state) {\n setState(emitter.value)\n }\n\n return emitter.listen(setState)\n }, [state, disabled, emitter])\n\n return state\n}\n\n/**\n * By default selectors run every render, as well as when emitters update. This is a change\n * from the previous behavior where they only ran when emitters changed value.\n *\n * The reason for this is because emitters capture the variables in scope of the component\n * each render already by using \"useGet\" by default, which makes them easier to use - you\n * don't need to pass an args[] array except for edge cases.\n *\n * Before explaining why we switched to the default, understand the different uses:\n *\n * - Default behavior - selector is updated every render, and ran every render, as well as\n * when emitter value changes, so you basically are always up to date.\n *\n * - Set an args[] array as the fourth argument - this will stop the automatic capturing\n * and instead update selector only when you change args[] yourself. This is good for when you\n * want explicit control over re-selection and rendering.\n *\n * - With { lazy: true }, the selector only runs when the emitter value changes. If used with\n * args[], you capture the context of the selector based on args[], if not, it's based on the\n * current render.\n *\n * I made this change when we had 16 usages of useEmitterSelector and 100% of them are doing very\n * cheap calculations, so this feels like the right pattern. For the rare case of a heavy selector,\n * you have the option to control it.\n *\n */\nexport const useEmitterSelector = <E extends Emitter<any>, T extends EmitterType<E>, R>(\n emitter: E,\n selector: (value: T) => R,\n options?: {\n disable?: boolean\n lazy?: boolean\n },\n args: any[] = EMPTY_ARRAY,\n): R => {\n const [state, setState] = useState<R>(() => selector(emitter.value))\n const disabled = options?.disable\n const getSelector = useGet(selector)\n\n if (options?.lazy !== true) {\n const next = selector(emitter.value)\n if (next !== state) {\n setState(next)\n }\n }\n\n useLayoutEffect(() => {\n if (disabled) return\n return emitter.listen((val) => {\n try {\n const selectorFn = args !== EMPTY_ARRAY ? selector : getSelector()\n const next = selectorFn(val)\n setState(next)\n } catch (error) {\n if (error instanceof AbortError) {\n return\n }\n throw error\n }\n })\n // oxlint-disable-next-line exhaustive-deps\n }, [disabled, emitter, getSelector, ...args])\n\n return state\n}\n\nexport const useEmittersSelector = <const E extends readonly Emitter<any>[], R>(\n emitters: E,\n selector: (values: { [K in keyof E]: EmitterType<E[K]> }) => R,\n options?: { disable?: boolean; isEqual?: (a: R, b: R) => boolean },\n): R => {\n const getSelector = useGet(selector)\n const disabled = options?.disable\n\n const [state, setState] = useState<R>(() => {\n const values = emitters.map((e) => e.value) as { [K in keyof E]: EmitterType<E[K]> }\n return getSelector()(values)\n })\n\n useLayoutEffect(() => {\n if (disabled) {\n return\n }\n\n const handler = () => {\n const values = emitters.map((e) => e.value) as {\n [K in keyof E]: EmitterType<E[K]>\n }\n try {\n const next = getSelector()(values)\n setState((prev) => {\n if (options?.isEqual?.(prev, next)) {\n return prev\n }\n if (dequal(prev, next)) {\n return prev\n }\n return next\n })\n } catch (error) {\n if (error instanceof AbortError) {\n return\n }\n throw error\n }\n }\n\n const disposals = emitters.map((emitter) => emitter.listen(handler))\n\n return () => {\n disposals.forEach((d) => d())\n }\n // oxlint-disable-next-line exhaustive-deps\n }, [disabled, getSelector, ...emitters])\n\n return state\n}\n\nexport const createUseEmitter = <E extends Emitter<any>>(\n emitter: E,\n): ((cb: (val: EmitterType<E>) => void, args?: any[]) => void) => {\n return (cb: (val: EmitterType<E>) => void, args?: any[]) =>\n useEmitter(emitter, cb, args)\n}\n\nexport const createUseSelector = <E extends Emitter<any>>(\n emitter: E,\n): (<R>(\n selector: (value: EmitterType<E>) => R,\n options?: { disable?: boolean; lazy?: boolean },\n args?: any[],\n) => R) => {\n return <R,>(\n selector: (value: EmitterType<E>) => R,\n options?: { disable?: boolean; lazy?: boolean },\n args?: any[],\n ): R => {\n return useEmitterSelector(emitter, selector, options, args)\n }\n}\n\nexport function createContextualEmitter<T>(\n name: string,\n defaultValue: T,\n defaultOptions?: Omit<EmitterOptions<T>, 'name'>,\n): readonly [\n () => Emitter<T>,\n (props: PropsWithChildren<{ value?: T; silent?: boolean }>) => JSX.Element,\n] {\n const id = Math.random().toString(36)\n const EmitterContext = createGlobalContext<Emitter<T> | null>(\n `contextual-emitter/${id}`,\n null,\n )\n\n const useContextEmitter = () => {\n const emitter = use(EmitterContext)\n if (!emitter) {\n throw new Error('useContextEmitter must be used within an EmitterProvider')\n }\n return emitter\n }\n\n type ProvideEmitterProps = PropsWithChildren<{\n value?: T\n silent?: boolean\n }>\n\n const ProvideEmitter = (props: ProvideEmitterProps) => {\n const { children, value, silent } = props\n const [emitter] = useState(\n () => new Emitter<T>(value ?? defaultValue, { name, silent, ...defaultOptions }),\n )\n\n useLayoutEffect(() => {\n if (value !== undefined && value !== emitter.value) {\n emitter.emit(value)\n }\n }, [value, emitter])\n\n return <EmitterContext.Provider value={emitter}>{children}</EmitterContext.Provider>\n }\n\n return [useContextEmitter, ProvideEmitter] as const\n}\n\nconst HMRCache =\n process.env.NODE_ENV === 'development'\n ? new Map<string, { originalDefaultValue: unknown; currentValue: unknown }>()\n : null\n\nfunction setCache(emitter: Emitter<any>, value: unknown) {\n const name = emitter.options?.name\n if (!name) return\n const cache = HMRCache?.get(name)\n if (!cache) return\n cache.currentValue = value\n}\n\nfunction createOrUpdateCache(name: string, defaultValueProp: unknown) {\n const existing = HMRCache?.get(name)\n const defaultValue = dequal(existing?.originalDefaultValue, defaultValueProp)\n ? existing?.currentValue\n : defaultValueProp\n\n if (!existing) {\n HMRCache?.set(name, {\n originalDefaultValue: defaultValueProp,\n currentValue: defaultValue,\n })\n }\n\n return defaultValue\n}\n"
10
10
  ]
11
11
  }