@reactuses/core 3.0.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -44,7 +44,7 @@ const createUpdateEffect = (hook) => (effect, deps) => {
44
44
 
45
45
  var useUpdateEffect = createUpdateEffect(React.useEffect);
46
46
 
47
- var index$4 = createUpdateEffect(React.useLayoutEffect);
47
+ var index$3 = createUpdateEffect(React.useLayoutEffect);
48
48
 
49
49
  var _a;
50
50
  const isFunction$1 = (val) => typeof val === "function";
@@ -3412,35 +3412,98 @@ function useIdle(ms = oneMinute, initialState = false, events = defaultEvents$1)
3412
3412
  return state;
3413
3413
  }
3414
3414
 
3415
- function useMediaDevices() {
3415
+ function useSupported(callback, sync = false) {
3416
+ const [supported, setSupported] = React.useState(false);
3417
+ const effect = sync ? useIsomorphicLayoutEffect : React.useEffect;
3418
+ effect(() => {
3419
+ setSupported(Boolean(callback()));
3420
+ }, []);
3421
+ return supported;
3422
+ }
3423
+
3424
+ var __async$4 = (__this, __arguments, generator) => {
3425
+ return new Promise((resolve, reject) => {
3426
+ var fulfilled = (value) => {
3427
+ try {
3428
+ step(generator.next(value));
3429
+ } catch (e) {
3430
+ reject(e);
3431
+ }
3432
+ };
3433
+ var rejected = (value) => {
3434
+ try {
3435
+ step(generator.throw(value));
3436
+ } catch (e) {
3437
+ reject(e);
3438
+ }
3439
+ };
3440
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
3441
+ step((generator = generator.apply(__this, __arguments)).next());
3442
+ });
3443
+ };
3444
+ function useMediaDevices(options = {}) {
3445
+ const { requestPermissions, constraints = { audio: true, video: true } } = options;
3416
3446
  const [state, setState] = React.useState({ devices: [] });
3447
+ const isSupported = useSupported(
3448
+ () => navigator && navigator.mediaDevices && navigator.mediaDevices.enumerateDevices
3449
+ );
3450
+ const permissionGranted = React.useRef(false);
3451
+ const stream = React.useRef(null);
3452
+ const onChange = React.useCallback(() => {
3453
+ navigator.mediaDevices.enumerateDevices().then((devices) => {
3454
+ if (stream.current) {
3455
+ stream.current.getTracks().forEach((t) => t.stop());
3456
+ stream.current = null;
3457
+ }
3458
+ setState({
3459
+ devices: devices.map(({ deviceId, groupId, kind, label }) => ({
3460
+ deviceId,
3461
+ groupId,
3462
+ kind,
3463
+ label
3464
+ }))
3465
+ });
3466
+ }).catch(noop);
3467
+ }, []);
3468
+ const ensurePermissions = React.useCallback(() => __async$4(this, null, function* () {
3469
+ if (!isSupported) {
3470
+ return false;
3471
+ }
3472
+ if (permissionGranted.current) {
3473
+ return true;
3474
+ }
3475
+ let state2 = void 0;
3476
+ try {
3477
+ state2 = (yield navigator.permissions.query({
3478
+ name: "camera"
3479
+ })).state;
3480
+ } catch (error) {
3481
+ state2 = "prompt";
3482
+ }
3483
+ if (state2 !== "granted") {
3484
+ stream.current = yield navigator.mediaDevices.getUserMedia(constraints);
3485
+ onChange();
3486
+ permissionGranted.current = true;
3487
+ } else {
3488
+ permissionGranted.current = false;
3489
+ }
3490
+ return permissionGranted.current;
3491
+ }), [onChange, isSupported, constraints]);
3417
3492
  React.useEffect(() => {
3418
- let mounted = true;
3419
- const onChange = () => {
3420
- navigator.mediaDevices.enumerateDevices().then((devices) => {
3421
- if (mounted) {
3422
- setState({
3423
- devices: devices.map(({ deviceId, groupId, kind, label }) => ({
3424
- deviceId,
3425
- groupId,
3426
- kind,
3427
- label
3428
- }))
3429
- });
3430
- }
3431
- }).catch(noop);
3432
- };
3493
+ if (!isSupported) {
3494
+ return;
3495
+ }
3496
+ if (requestPermissions) {
3497
+ ensurePermissions();
3498
+ }
3433
3499
  on(navigator.mediaDevices, "devicechange", onChange);
3434
3500
  onChange();
3435
3501
  return () => {
3436
- mounted = false;
3437
3502
  off(navigator.mediaDevices, "devicechange", onChange);
3438
3503
  };
3439
- }, []);
3440
- return state;
3504
+ }, [onChange, isSupported, requestPermissions, ensurePermissions]);
3505
+ return [state, ensurePermissions];
3441
3506
  }
3442
- const useMediaDevicesMock = () => ({ devices: [] });
3443
- var index$3 = isNavigator && !!navigator.mediaDevices ? useMediaDevices : useMediaDevicesMock;
3444
3507
 
3445
3508
  function useTextDirection(options = {}) {
3446
3509
  const { selector = "html", initialValue = "ltr" } = options;
@@ -5222,15 +5285,6 @@ const useCountDown = (time, format = getHMSTime, callback) => {
5222
5285
  return [hour, minute, secoud];
5223
5286
  };
5224
5287
 
5225
- function useSupported(callback, sync = false) {
5226
- const [supported, setSupported] = React.useState(false);
5227
- const effect = sync ? useIsomorphicLayoutEffect : React.useEffect;
5228
- effect(() => {
5229
- setSupported(Boolean(callback()));
5230
- }, []);
5231
- return supported;
5232
- }
5233
-
5234
5288
  function useTextSelection() {
5235
5289
  const [selection, setSelection] = React.useState(null);
5236
5290
  const forceUpdate = useUpdate();
@@ -5604,7 +5658,7 @@ exports.useLatest = useLatest;
5604
5658
  exports.useLocalStorage = useLocalStorage;
5605
5659
  exports.useLongPress = useLongPress;
5606
5660
  exports.useMeasure = useMeasure;
5607
- exports.useMediaDevices = index$3;
5661
+ exports.useMediaDevices = useMediaDevices;
5608
5662
  exports.useMediaQuery = useMediaQuery;
5609
5663
  exports.useMount = useMount;
5610
5664
  exports.useMountedState = useMountedState;
@@ -5646,7 +5700,7 @@ exports.useToggle = useToggle;
5646
5700
  exports.useUnmount = useUnmount;
5647
5701
  exports.useUpdate = useUpdate;
5648
5702
  exports.useUpdateEffect = useUpdateEffect;
5649
- exports.useUpdateLayoutEffect = index$4;
5703
+ exports.useUpdateLayoutEffect = index$3;
5650
5704
  exports.useVirtualList = useVirtualList;
5651
5705
  exports.useWindowScroll = useWindowScroll;
5652
5706
  exports.useWindowSize = useWindowSize;
package/dist/index.d.ts CHANGED
@@ -9,9 +9,9 @@ declare function useLatest<T>(value: T): MutableRefObject<T>;
9
9
 
10
10
  declare function useFirstMountState(): boolean;
11
11
 
12
- declare const _default$5: typeof useEffect | typeof react.useLayoutEffect;
12
+ declare const _default$4: typeof useEffect | typeof react.useLayoutEffect;
13
13
 
14
- declare const _default$4: typeof react.useEffect | typeof useLayoutEffect;
14
+ declare const _default$3: typeof react.useEffect | typeof useLayoutEffect;
15
15
 
16
16
  interface Serializer<T> {
17
17
  read(raw: string): T;
@@ -287,15 +287,29 @@ declare function useObjectUrl(object: Blob | MediaSource | undefined): string |
287
287
 
288
288
  declare function useIdle(ms?: number, initialState?: boolean, events?: (keyof WindowEventMap)[]): boolean;
289
289
 
290
- declare function useMediaDevices(): {
290
+ interface UseMediaDeviceOptions {
291
+ /**
292
+ * Request for permissions immediately if it's not granted,
293
+ * otherwise label and deviceIds could be empty
294
+ *
295
+ * @default false
296
+ */
297
+ requestPermissions?: boolean;
298
+ /**
299
+ * Request for types of media permissions
300
+ *
301
+ * @default { audio: true, video: true }
302
+ */
303
+ constraints?: MediaStreamConstraints;
304
+ }
305
+ declare function useMediaDevices(options?: UseMediaDeviceOptions): readonly [{
291
306
  devices: {
292
307
  deviceId: string;
293
308
  groupId: string;
294
309
  kind: MediaDeviceKind;
295
310
  label: string;
296
311
  }[];
297
- };
298
- declare const _default$3: typeof useMediaDevices;
312
+ }, () => Promise<boolean>];
299
313
 
300
314
  type UseTextDirectionValue = "ltr" | "rtl" | "auto";
301
315
  interface UseTextDirectionOptions {
@@ -852,4 +866,4 @@ declare function useSetState<T extends Record<string, any>>(initialState: T): re
852
866
  type UseMeasureRect = Omit<DOMRectReadOnly, "toJSON">;
853
867
  declare function useMeasure(target: BasicTarget, options?: ResizeObserverOptions): readonly [UseMeasureRect, () => void];
854
868
 
855
- export { ColorScheme, Contrast, CookieOptions, CookieState, CursorState, EyeDropperOpenReturnType, GeneralPermissionDescriptor, IDisposable, IEvent, IEventOnce, IListener, INetworkInformation, IState, IUseNetworkState, KeyModifier, MousePressedOptions, MouseSourceType, OrientationState, RafLoopReturns, ScrollIntoViewAnimation, ScrollIntoViewParams, State, Status, Target, UseDarkOptions, UseDraggableOptions, UseElementBoundingOptions, UseEventEmitterReturn, UseEyeDropperReturn, UseFileDialogOptions, UseFpsOptions, UseFullScreenOptions, UseInfiniteScrollOptions, UseLongPressOptions, UseMeasureRect, UseModifierOptions, UseScriptTagOptions, UseScrollOptions, UseStickyParams, UseTextDirectionOptions, UseTextDirectionValue, UseTimeoutFnOptions, UseVirtualListItem, UseVirtualListOptions, UseVirtualListReturn, WindowSize, getHMSTime, useActiveElement, useAsyncEffect, useClickOutSide as useClickOutside, useClipBorad as useClipboard, useControlled, useCookie, useCountDown, useCounter, useCustomCompareEffect, useCycleList, useDarkMode, useDebounce, useDebounceFn, useDeepCompareEffect, useDocumentVisibility, useDoubleClick, useDraggable, useDropZone, useElementBounding, useElementSize, useElementVisibility, useEvent, useEventEmitter, useEventListener, useEyeDropper, useFavicon, useFileDialog, useFirstMountState, useFocus, _default$2 as useFps, useFullscreen, useGeolocation, useIdle, useInfiniteScroll, useIntersectionObserver, useInterval, useIsomorphicLayoutEffect, useKeyModifier, useLatest, useLocalStorage, useLongPress, useMeasure, _default$3 as useMediaDevices, useMediaQuery, useMount, useMountedState, useMouse, useMousePressed, useMutationObserver, useNetwork, useObjectUrl, _default$1 as useOnceEffect, _default as useOnceLayoutEffect, useOnline, useOrientation, usePageLeave, usePermission, usePreferredColorScheme, usePreferredContrast, usePreferredDark, usePrevious, useRafFn, useRafState, useReducedMotion, useResizeObserver, useScriptTag, useScroll, useScrollIntoView, useScrollLock, useSessionStorage, useSetState, useSticky, useSupported, useTextDirection, useTextSelection, useThrottle, useThrottleFn, useTimeout, useTimeoutFn, useTitle, useToggle, useUnmount, useUpdate, _default$5 as useUpdateEffect, _default$4 as useUpdateLayoutEffect, useVirtualList, useWindowScroll, useWindowSize, useWindowsFocus };
869
+ export { ColorScheme, Contrast, CookieOptions, CookieState, CursorState, EyeDropperOpenReturnType, GeneralPermissionDescriptor, IDisposable, IEvent, IEventOnce, IListener, INetworkInformation, IState, IUseNetworkState, KeyModifier, MousePressedOptions, MouseSourceType, OrientationState, RafLoopReturns, ScrollIntoViewAnimation, ScrollIntoViewParams, State, Status, Target, UseDarkOptions, UseDraggableOptions, UseElementBoundingOptions, UseEventEmitterReturn, UseEyeDropperReturn, UseFileDialogOptions, UseFpsOptions, UseFullScreenOptions, UseInfiniteScrollOptions, UseLongPressOptions, UseMeasureRect, UseMediaDeviceOptions, UseModifierOptions, UseScriptTagOptions, UseScrollOptions, UseStickyParams, UseTextDirectionOptions, UseTextDirectionValue, UseTimeoutFnOptions, UseVirtualListItem, UseVirtualListOptions, UseVirtualListReturn, WindowSize, getHMSTime, useActiveElement, useAsyncEffect, useClickOutSide as useClickOutside, useClipBorad as useClipboard, useControlled, useCookie, useCountDown, useCounter, useCustomCompareEffect, useCycleList, useDarkMode, useDebounce, useDebounceFn, useDeepCompareEffect, useDocumentVisibility, useDoubleClick, useDraggable, useDropZone, useElementBounding, useElementSize, useElementVisibility, useEvent, useEventEmitter, useEventListener, useEyeDropper, useFavicon, useFileDialog, useFirstMountState, useFocus, _default$2 as useFps, useFullscreen, useGeolocation, useIdle, useInfiniteScroll, useIntersectionObserver, useInterval, useIsomorphicLayoutEffect, useKeyModifier, useLatest, useLocalStorage, useLongPress, useMeasure, useMediaDevices, useMediaQuery, useMount, useMountedState, useMouse, useMousePressed, useMutationObserver, useNetwork, useObjectUrl, _default$1 as useOnceEffect, _default as useOnceLayoutEffect, useOnline, useOrientation, usePageLeave, usePermission, usePreferredColorScheme, usePreferredContrast, usePreferredDark, usePrevious, useRafFn, useRafState, useReducedMotion, useResizeObserver, useScriptTag, useScroll, useScrollIntoView, useScrollLock, useSessionStorage, useSetState, useSticky, useSupported, useTextDirection, useTextSelection, useThrottle, useThrottleFn, useTimeout, useTimeoutFn, useTitle, useToggle, useUnmount, useUpdate, _default$4 as useUpdateEffect, _default$3 as useUpdateLayoutEffect, useVirtualList, useWindowScroll, useWindowSize, useWindowsFocus };
package/dist/index.mjs CHANGED
@@ -36,7 +36,7 @@ const createUpdateEffect = (hook) => (effect, deps) => {
36
36
 
37
37
  var useUpdateEffect = createUpdateEffect(useEffect);
38
38
 
39
- var index$4 = createUpdateEffect(useLayoutEffect);
39
+ var index$3 = createUpdateEffect(useLayoutEffect);
40
40
 
41
41
  var _a;
42
42
  const isFunction$1 = (val) => typeof val === "function";
@@ -3404,35 +3404,98 @@ function useIdle(ms = oneMinute, initialState = false, events = defaultEvents$1)
3404
3404
  return state;
3405
3405
  }
3406
3406
 
3407
- function useMediaDevices() {
3407
+ function useSupported(callback, sync = false) {
3408
+ const [supported, setSupported] = useState(false);
3409
+ const effect = sync ? useIsomorphicLayoutEffect : useEffect;
3410
+ effect(() => {
3411
+ setSupported(Boolean(callback()));
3412
+ }, []);
3413
+ return supported;
3414
+ }
3415
+
3416
+ var __async$4 = (__this, __arguments, generator) => {
3417
+ return new Promise((resolve, reject) => {
3418
+ var fulfilled = (value) => {
3419
+ try {
3420
+ step(generator.next(value));
3421
+ } catch (e) {
3422
+ reject(e);
3423
+ }
3424
+ };
3425
+ var rejected = (value) => {
3426
+ try {
3427
+ step(generator.throw(value));
3428
+ } catch (e) {
3429
+ reject(e);
3430
+ }
3431
+ };
3432
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
3433
+ step((generator = generator.apply(__this, __arguments)).next());
3434
+ });
3435
+ };
3436
+ function useMediaDevices(options = {}) {
3437
+ const { requestPermissions, constraints = { audio: true, video: true } } = options;
3408
3438
  const [state, setState] = useState({ devices: [] });
3439
+ const isSupported = useSupported(
3440
+ () => navigator && navigator.mediaDevices && navigator.mediaDevices.enumerateDevices
3441
+ );
3442
+ const permissionGranted = useRef(false);
3443
+ const stream = useRef(null);
3444
+ const onChange = useCallback(() => {
3445
+ navigator.mediaDevices.enumerateDevices().then((devices) => {
3446
+ if (stream.current) {
3447
+ stream.current.getTracks().forEach((t) => t.stop());
3448
+ stream.current = null;
3449
+ }
3450
+ setState({
3451
+ devices: devices.map(({ deviceId, groupId, kind, label }) => ({
3452
+ deviceId,
3453
+ groupId,
3454
+ kind,
3455
+ label
3456
+ }))
3457
+ });
3458
+ }).catch(noop);
3459
+ }, []);
3460
+ const ensurePermissions = useCallback(() => __async$4(this, null, function* () {
3461
+ if (!isSupported) {
3462
+ return false;
3463
+ }
3464
+ if (permissionGranted.current) {
3465
+ return true;
3466
+ }
3467
+ let state2 = void 0;
3468
+ try {
3469
+ state2 = (yield navigator.permissions.query({
3470
+ name: "camera"
3471
+ })).state;
3472
+ } catch (error) {
3473
+ state2 = "prompt";
3474
+ }
3475
+ if (state2 !== "granted") {
3476
+ stream.current = yield navigator.mediaDevices.getUserMedia(constraints);
3477
+ onChange();
3478
+ permissionGranted.current = true;
3479
+ } else {
3480
+ permissionGranted.current = false;
3481
+ }
3482
+ return permissionGranted.current;
3483
+ }), [onChange, isSupported, constraints]);
3409
3484
  useEffect(() => {
3410
- let mounted = true;
3411
- const onChange = () => {
3412
- navigator.mediaDevices.enumerateDevices().then((devices) => {
3413
- if (mounted) {
3414
- setState({
3415
- devices: devices.map(({ deviceId, groupId, kind, label }) => ({
3416
- deviceId,
3417
- groupId,
3418
- kind,
3419
- label
3420
- }))
3421
- });
3422
- }
3423
- }).catch(noop);
3424
- };
3485
+ if (!isSupported) {
3486
+ return;
3487
+ }
3488
+ if (requestPermissions) {
3489
+ ensurePermissions();
3490
+ }
3425
3491
  on(navigator.mediaDevices, "devicechange", onChange);
3426
3492
  onChange();
3427
3493
  return () => {
3428
- mounted = false;
3429
3494
  off(navigator.mediaDevices, "devicechange", onChange);
3430
3495
  };
3431
- }, []);
3432
- return state;
3496
+ }, [onChange, isSupported, requestPermissions, ensurePermissions]);
3497
+ return [state, ensurePermissions];
3433
3498
  }
3434
- const useMediaDevicesMock = () => ({ devices: [] });
3435
- var index$3 = isNavigator && !!navigator.mediaDevices ? useMediaDevices : useMediaDevicesMock;
3436
3499
 
3437
3500
  function useTextDirection(options = {}) {
3438
3501
  const { selector = "html", initialValue = "ltr" } = options;
@@ -5214,15 +5277,6 @@ const useCountDown = (time, format = getHMSTime, callback) => {
5214
5277
  return [hour, minute, secoud];
5215
5278
  };
5216
5279
 
5217
- function useSupported(callback, sync = false) {
5218
- const [supported, setSupported] = useState(false);
5219
- const effect = sync ? useIsomorphicLayoutEffect : useEffect;
5220
- effect(() => {
5221
- setSupported(Boolean(callback()));
5222
- }, []);
5223
- return supported;
5224
- }
5225
-
5226
5280
  function useTextSelection() {
5227
5281
  const [selection, setSelection] = useState(null);
5228
5282
  const forceUpdate = useUpdate();
@@ -5553,4 +5607,4 @@ function useMeasure(target, options = {}) {
5553
5607
  return [rect, stop];
5554
5608
  }
5555
5609
 
5556
- export { getHMSTime, useActiveElement, useAsyncEffect, useClickOutSide as useClickOutside, useClipBorad as useClipboard, useControlled, useCookie, useCountDown, useCounter, useCustomCompareEffect, useCycleList, useDarkMode, useDebounce, useDebounceFn, useDeepCompareEffect, useDocumentVisibility, useDoubleClick, useDraggable, useDropZone, useElementBounding, useElementSize, useElementVisibility, useEvent, useEventEmitter, useEventListener, useEyeDropper, useFavicon, useFileDialog, useFirstMountState, useFocus, index$2 as useFps, useFullscreen, useGeolocation, useIdle, useInfiniteScroll, useIntersectionObserver, useInterval, useIsomorphicLayoutEffect, useKeyModifier, useLatest, useLocalStorage, useLongPress, useMeasure, index$3 as useMediaDevices, useMediaQuery, useMount, useMountedState, useMouse, useMousePressed, useMutationObserver, useNetwork, useObjectUrl, index$1 as useOnceEffect, index as useOnceLayoutEffect, useOnline, useOrientation, usePageLeave, usePermission, usePreferredColorScheme, usePreferredContrast, usePreferredDark, usePrevious, useRafFn, useRafState, useReducedMotion, useResizeObserver, useScriptTag, useScroll, useScrollIntoView, useScrollLock, useSessionStorage, useSetState, useSticky, useSupported, useTextDirection, useTextSelection, useThrottle, useThrottleFn, useTimeout, useTimeoutFn, useTitle, useToggle, useUnmount, useUpdate, useUpdateEffect, index$4 as useUpdateLayoutEffect, useVirtualList, useWindowScroll, useWindowSize, useWindowsFocus };
5610
+ export { getHMSTime, useActiveElement, useAsyncEffect, useClickOutSide as useClickOutside, useClipBorad as useClipboard, useControlled, useCookie, useCountDown, useCounter, useCustomCompareEffect, useCycleList, useDarkMode, useDebounce, useDebounceFn, useDeepCompareEffect, useDocumentVisibility, useDoubleClick, useDraggable, useDropZone, useElementBounding, useElementSize, useElementVisibility, useEvent, useEventEmitter, useEventListener, useEyeDropper, useFavicon, useFileDialog, useFirstMountState, useFocus, index$2 as useFps, useFullscreen, useGeolocation, useIdle, useInfiniteScroll, useIntersectionObserver, useInterval, useIsomorphicLayoutEffect, useKeyModifier, useLatest, useLocalStorage, useLongPress, useMeasure, useMediaDevices, useMediaQuery, useMount, useMountedState, useMouse, useMousePressed, useMutationObserver, useNetwork, useObjectUrl, index$1 as useOnceEffect, index as useOnceLayoutEffect, useOnline, useOrientation, usePageLeave, usePermission, usePreferredColorScheme, usePreferredContrast, usePreferredDark, usePrevious, useRafFn, useRafState, useReducedMotion, useResizeObserver, useScriptTag, useScroll, useScrollIntoView, useScrollLock, useSessionStorage, useSetState, useSticky, useSupported, useTextDirection, useTextSelection, useThrottle, useThrottleFn, useTimeout, useTimeoutFn, useTitle, useToggle, useUnmount, useUpdate, useUpdateEffect, index$3 as useUpdateLayoutEffect, useVirtualList, useWindowScroll, useWindowSize, useWindowsFocus };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactuses/core",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "license": "Unlicense",
5
5
  "homepage": "https://www.reactuse.com/",
6
6
  "repository": {