@reactuses/core 3.0.0 → 3.0.1

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
@@ -3412,34 +3412,95 @@ 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
+ const permissionStatus = yield navigator.permissions.query({
3476
+ name: "camera"
3477
+ });
3478
+ if (permissionStatus.state !== "granted") {
3479
+ stream.current = yield navigator.mediaDevices.getUserMedia(constraints);
3480
+ onChange();
3481
+ permissionGranted.current = true;
3482
+ } else {
3483
+ permissionGranted.current = false;
3484
+ }
3485
+ return permissionGranted.current;
3486
+ }), [onChange, isSupported, constraints]);
3417
3487
  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
- };
3488
+ if (!isSupported) {
3489
+ return;
3490
+ }
3491
+ if (requestPermissions) {
3492
+ ensurePermissions();
3493
+ }
3433
3494
  on(navigator.mediaDevices, "devicechange", onChange);
3434
3495
  onChange();
3435
3496
  return () => {
3436
- mounted = false;
3437
3497
  off(navigator.mediaDevices, "devicechange", onChange);
3438
3498
  };
3439
- }, []);
3440
- return state;
3499
+ }, [onChange, isSupported, requestPermissions, ensurePermissions]);
3500
+ return [state, ensurePermissions];
3441
3501
  }
3442
- const useMediaDevicesMock = () => ({ devices: [] });
3502
+ const useMediaDevicesMock = () => [{ devices: [] }, () => {
3503
+ }];
3443
3504
  var index$3 = isNavigator && !!navigator.mediaDevices ? useMediaDevices : useMediaDevicesMock;
3444
3505
 
3445
3506
  function useTextDirection(options = {}) {
@@ -5222,15 +5283,6 @@ const useCountDown = (time, format = getHMSTime, callback) => {
5222
5283
  return [hour, minute, secoud];
5223
5284
  };
5224
5285
 
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
5286
  function useTextSelection() {
5235
5287
  const [selection, setSelection] = React.useState(null);
5236
5288
  const forceUpdate = useUpdate();
package/dist/index.d.ts CHANGED
@@ -287,15 +287,32 @@ 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>];
313
+ declare const _default$3: typeof useMediaDevices | (() => ((() => void) | {
314
+ devices: never[];
315
+ })[]);
299
316
 
300
317
  type UseTextDirectionValue = "ltr" | "rtl" | "auto";
301
318
  interface UseTextDirectionOptions {
@@ -852,4 +869,4 @@ declare function useSetState<T extends Record<string, any>>(initialState: T): re
852
869
  type UseMeasureRect = Omit<DOMRectReadOnly, "toJSON">;
853
870
  declare function useMeasure(target: BasicTarget, options?: ResizeObserverOptions): readonly [UseMeasureRect, () => void];
854
871
 
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 };
872
+ 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, _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 };
package/dist/index.mjs CHANGED
@@ -3404,34 +3404,95 @@ 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
+ const permissionStatus = yield navigator.permissions.query({
3468
+ name: "camera"
3469
+ });
3470
+ if (permissionStatus.state !== "granted") {
3471
+ stream.current = yield navigator.mediaDevices.getUserMedia(constraints);
3472
+ onChange();
3473
+ permissionGranted.current = true;
3474
+ } else {
3475
+ permissionGranted.current = false;
3476
+ }
3477
+ return permissionGranted.current;
3478
+ }), [onChange, isSupported, constraints]);
3409
3479
  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
- };
3480
+ if (!isSupported) {
3481
+ return;
3482
+ }
3483
+ if (requestPermissions) {
3484
+ ensurePermissions();
3485
+ }
3425
3486
  on(navigator.mediaDevices, "devicechange", onChange);
3426
3487
  onChange();
3427
3488
  return () => {
3428
- mounted = false;
3429
3489
  off(navigator.mediaDevices, "devicechange", onChange);
3430
3490
  };
3431
- }, []);
3432
- return state;
3491
+ }, [onChange, isSupported, requestPermissions, ensurePermissions]);
3492
+ return [state, ensurePermissions];
3433
3493
  }
3434
- const useMediaDevicesMock = () => ({ devices: [] });
3494
+ const useMediaDevicesMock = () => [{ devices: [] }, () => {
3495
+ }];
3435
3496
  var index$3 = isNavigator && !!navigator.mediaDevices ? useMediaDevices : useMediaDevicesMock;
3436
3497
 
3437
3498
  function useTextDirection(options = {}) {
@@ -5214,15 +5275,6 @@ const useCountDown = (time, format = getHMSTime, callback) => {
5214
5275
  return [hour, minute, secoud];
5215
5276
  };
5216
5277
 
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
5278
  function useTextSelection() {
5227
5279
  const [selection, setSelection] = useState(null);
5228
5280
  const forceUpdate = useUpdate();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactuses/core",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "license": "Unlicense",
5
5
  "homepage": "https://www.reactuse.com/",
6
6
  "repository": {