@angular-helpers/browser-web-apis 21.11.0 → 21.12.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.
package/README.es.md CHANGED
@@ -45,6 +45,9 @@ Paquete de servicios Angular para acceder de forma estructurada y segura a Brows
45
45
  - `IdleDetectorService` - Detectar estado idle del usuario y bloqueo de pantalla
46
46
  - `GamepadService` - Polling de entrada de controladores de juego
47
47
  - `WebAudioService` - Contexto de audio, osciladores y analizadores
48
+ - `WebLocksService` - Coordinacion de locks entre pestanas
49
+ - `StorageManagerService` - Cuotas y persistencia de almacenamiento
50
+ - `CompressionService` - Streams de compresion gzip/deflate
48
51
 
49
52
  ### APIs de red
50
53
 
@@ -706,6 +709,88 @@ export class MyComponent {
706
709
  }
707
710
  ```
708
711
 
712
+ ### injectClipboard
713
+
714
+ ```typescript
715
+ import { injectClipboard } from '@angular-helpers/browser-web-apis';
716
+
717
+ @Component({...})
718
+ export class MyComponent {
719
+ readonly cb = injectClipboard();
720
+
721
+ // cb.text() → string | null (ultimo texto copiado)
722
+ // cb.error() → string | null
723
+ // cb.busy() → boolean
724
+ // cb.isSupported() → boolean
725
+
726
+ async copy(text: string) {
727
+ await this.cb.writeText(text);
728
+ }
729
+ }
730
+ ```
731
+
732
+ ### injectGeolocation
733
+
734
+ ```typescript
735
+ import { injectGeolocation } from '@angular-helpers/browser-web-apis';
736
+
737
+ @Component({...})
738
+ export class MyComponent {
739
+ readonly geo = injectGeolocation({ watch: true });
740
+
741
+ // geo.position() → GeolocationPosition | null
742
+ // geo.error() → GeolocationPositionError | null
743
+ // geo.watching() → boolean
744
+ // geo.isSupported() → boolean
745
+
746
+ stopWatching() {
747
+ this.geo.stop();
748
+ }
749
+ }
750
+ ```
751
+
752
+ ### injectBattery
753
+
754
+ ```typescript
755
+ import { injectBattery } from '@angular-helpers/browser-web-apis';
756
+
757
+ @Component({...})
758
+ export class MyComponent {
759
+ readonly battery = injectBattery();
760
+
761
+ // battery.info() → BatteryInfo | null (nivel, carga, tiempos)
762
+ // battery.error() → string | null
763
+ // battery.isSupported() → boolean
764
+
765
+ async refresh() {
766
+ await this.battery.refresh();
767
+ }
768
+ }
769
+ ```
770
+
771
+ ### injectWakeLock
772
+
773
+ ```typescript
774
+ import { injectWakeLock } from '@angular-helpers/browser-web-apis';
775
+
776
+ @Component({...})
777
+ export class MyComponent {
778
+ readonly wakeLock = injectWakeLock();
779
+
780
+ // wakeLock.active() → boolean
781
+ // wakeLock.error() → string | null
782
+ // wakeLock.isSupported() → boolean
783
+
784
+ async toggle() {
785
+ if (this.wakeLock.active()) {
786
+ await this.wakeLock.release();
787
+ } else {
788
+ await this.wakeLock.request();
789
+ }
790
+ }
791
+ }
792
+ ```
793
+
709
794
  ### Tipo ElementInput
710
795
 
711
796
  Tanto `injectResizeObserver` como `injectIntersectionObserver` aceptan el tipo `ElementInput`:
package/README.md CHANGED
@@ -45,6 +45,9 @@ Angular services package for a structured and secure access layer over browser W
45
45
  - `IdleDetectorService` - Detect user idle state and screen lock
46
46
  - `GamepadService` - Game controller input polling
47
47
  - `WebAudioService` - Audio context, oscillators, and analysers
48
+ - `WebLocksService` - Cross-tab resource locking coordination
49
+ - `StorageManagerService` - Storage quotas and persistence
50
+ - `CompressionService` - Gzip/deflate compression streams
48
51
 
49
52
  ### Network APIs
50
53
 
@@ -101,13 +104,21 @@ npm install @angular-helpers/browser-web-apis
101
104
 
102
105
  ```typescript
103
106
  import { provideBrowserWebApis } from '@angular-helpers/browser-web-apis';
107
+ import {
108
+ CameraService,
109
+ GeolocationService,
110
+ NotificationService,
111
+ } from '@angular-helpers/browser-web-apis';
104
112
 
105
113
  bootstrapApplication(AppComponent, {
106
114
  providers: [
107
115
  provideBrowserWebApis({
108
- enableCamera: true,
109
- enableGeolocation: true,
110
- enableNotifications: true,
116
+ services: [
117
+ CameraService,
118
+ GeolocationService,
119
+ NotificationService,
120
+ // Add more services as needed
121
+ ],
111
122
  }),
112
123
  ],
113
124
  });
@@ -152,6 +163,9 @@ Every service has a matching `provideX()` function:
152
163
  | `providePerformanceObserver()` | `PerformanceObserverService` |
153
164
  | `providePageVisibility()` | `PageVisibilityService` |
154
165
  | `provideNetworkInformation()` | `NetworkInformationService` |
166
+ | `provideWebLocks()` | `WebLocksService` |
167
+ | `provideStorageManager()` | `StorageManagerService` |
168
+ | `provideCompression()` | `CompressionService` |
155
169
  | …and 22 more | See `src/providers/` |
156
170
 
157
171
  ### Combo providers
@@ -755,6 +769,88 @@ export class MyComponent {
755
769
  }
756
770
  ```
757
771
 
772
+ ### injectClipboard
773
+
774
+ ```typescript
775
+ import { injectClipboard } from '@angular-helpers/browser-web-apis';
776
+
777
+ @Component({...})
778
+ export class MyComponent {
779
+ readonly cb = injectClipboard();
780
+
781
+ // cb.text() → string | null (last copied text)
782
+ // cb.error() → string | null
783
+ // cb.busy() → boolean
784
+ // cb.isSupported() → boolean
785
+
786
+ async copy(text: string) {
787
+ await this.cb.writeText(text);
788
+ }
789
+ }
790
+ ```
791
+
792
+ ### injectGeolocation
793
+
794
+ ```typescript
795
+ import { injectGeolocation } from '@angular-helpers/browser-web-apis';
796
+
797
+ @Component({...})
798
+ export class MyComponent {
799
+ readonly geo = injectGeolocation({ watch: true });
800
+
801
+ // geo.position() → GeolocationPosition | null
802
+ // geo.error() → GeolocationPositionError | null
803
+ // geo.watching() → boolean
804
+ // geo.isSupported() → boolean
805
+
806
+ stopWatching() {
807
+ this.geo.stop();
808
+ }
809
+ }
810
+ ```
811
+
812
+ ### injectBattery
813
+
814
+ ```typescript
815
+ import { injectBattery } from '@angular-helpers/browser-web-apis';
816
+
817
+ @Component({...})
818
+ export class MyComponent {
819
+ readonly battery = injectBattery();
820
+
821
+ // battery.info() → BatteryInfo | null (level, charging, times)
822
+ // battery.error() → string | null
823
+ // battery.isSupported() → boolean
824
+
825
+ async refresh() {
826
+ await this.battery.refresh();
827
+ }
828
+ }
829
+ ```
830
+
831
+ ### injectWakeLock
832
+
833
+ ```typescript
834
+ import { injectWakeLock } from '@angular-helpers/browser-web-apis';
835
+
836
+ @Component({...})
837
+ export class MyComponent {
838
+ readonly wakeLock = injectWakeLock();
839
+
840
+ // wakeLock.active() → boolean
841
+ // wakeLock.error() → string | null
842
+ // wakeLock.isSupported() → boolean
843
+
844
+ async toggle() {
845
+ if (this.wakeLock.active()) {
846
+ await this.wakeLock.release();
847
+ } else {
848
+ await this.wakeLock.request();
849
+ }
850
+ }
851
+ }
852
+ ```
853
+
758
854
  ### ElementInput type
759
855
 
760
856
  Both `injectResizeObserver` and `injectIntersectionObserver` accept the `ElementInput` type:
@@ -1051,19 +1051,22 @@ let legacyDeprecationLogged$1 = false;
1051
1051
  class WebStorageService extends BrowserApiBaseService {
1052
1052
  storageLogger = inject(BROWSER_API_LOGGER);
1053
1053
  storageEvents = signal(null, ...(ngDevMode ? [{ debugName: "storageEvents" }] : /* istanbul ignore next */ []));
1054
- eventBus = {
1055
- emit: (event) => this.storageEvents.set(event),
1056
- events$: toObservable(this.storageEvents).pipe(filter((event) => event !== null), distinctUntilChanged((a, b) => a.key === b.key &&
1057
- a.newValue === b.newValue &&
1058
- a.oldValue === b.oldValue &&
1059
- a.storageArea === b.storageArea)),
1060
- };
1054
+ eventBus;
1061
1055
  /** Local storage namespace. */
1062
- local = new StorageNamespaceImpl('localStorage', this.eventBus, this.storageLogger);
1056
+ local;
1063
1057
  /** Session storage namespace. */
1064
- session = new StorageNamespaceImpl('sessionStorage', this.eventBus, this.storageLogger);
1058
+ session;
1065
1059
  constructor() {
1066
1060
  super();
1061
+ this.eventBus = {
1062
+ emit: (event) => this.storageEvents.set(event),
1063
+ events$: toObservable(this.storageEvents).pipe(filter((event) => event !== null), distinctUntilChanged((a, b) => a.key === b.key &&
1064
+ a.newValue === b.newValue &&
1065
+ a.oldValue === b.oldValue &&
1066
+ a.storageArea === b.storageArea)),
1067
+ };
1068
+ this.local = new StorageNamespaceImpl('localStorage', this.eventBus, this.storageLogger);
1069
+ this.session = new StorageNamespaceImpl('sessionStorage', this.eventBus, this.storageLogger);
1067
1070
  this.setupCrossTabListener();
1068
1071
  }
1069
1072
  getApiName() {
@@ -1707,6 +1710,8 @@ class WebWorkerService extends BrowserApiBaseService {
1707
1710
  this.entries.delete(name);
1708
1711
  }
1709
1712
  terminateAllWorkers() {
1713
+ // Snapshot keys before mutating the map inside terminateWorker.
1714
+ // oxlint-disable-next-line unicorn/no-useless-spread
1710
1715
  for (const name of [...this.entries.keys()]) {
1711
1716
  this.terminateWorker(name);
1712
1717
  }
@@ -2116,17 +2121,17 @@ class BroadcastChannelService extends ConnectionRegistryBaseService {
2116
2121
  if (!channel) {
2117
2122
  channel = new BroadcastChannel(name);
2118
2123
  this.connections.set(name, channel);
2124
+ // Register cleanup once per channel, not per subscription.
2125
+ this.destroyRef.onDestroy(() => this.close(name));
2119
2126
  }
2120
2127
  const handler = (event) => observer.next(event.data);
2121
2128
  const errorHandler = () => observer.error(new Error(`BroadcastChannel "${name}" error`));
2122
2129
  channel.addEventListener('message', handler);
2123
2130
  channel.addEventListener('messageerror', errorHandler);
2124
- const cleanup = () => {
2131
+ return () => {
2125
2132
  channel.removeEventListener('message', handler);
2126
2133
  channel.removeEventListener('messageerror', errorHandler);
2127
2134
  };
2128
- this.destroyRef.onDestroy(() => this.close(name));
2129
- return cleanup;
2130
2135
  });
2131
2136
  }
2132
2137
  post(name, data) {
@@ -2135,6 +2140,7 @@ class BroadcastChannelService extends ConnectionRegistryBaseService {
2135
2140
  if (!channel) {
2136
2141
  channel = new BroadcastChannel(name);
2137
2142
  this.connections.set(name, channel);
2143
+ // Register cleanup once per channel creation.
2138
2144
  this.destroyRef.onDestroy(() => this.close(name));
2139
2145
  }
2140
2146
  channel.postMessage(data);
@@ -2225,6 +2231,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
2225
2231
 
2226
2232
  class ScreenWakeLockService extends BrowserApiBaseService {
2227
2233
  sentinel = null;
2234
+ releaseRegistered = false;
2228
2235
  getApiName() {
2229
2236
  return 'screen-wake-lock';
2230
2237
  }
@@ -2246,7 +2253,11 @@ class ScreenWakeLockService extends BrowserApiBaseService {
2246
2253
  this.sentinel.addEventListener('release', () => {
2247
2254
  this.sentinel = null;
2248
2255
  });
2249
- this.destroyRef.onDestroy(() => this.release());
2256
+ // Register the destroy cleanup only once across multiple request() calls.
2257
+ if (!this.releaseRegistered) {
2258
+ this.releaseRegistered = true;
2259
+ this.destroyRef.onDestroy(() => this.release());
2260
+ }
2250
2261
  return { active: true, type, released: false };
2251
2262
  }
2252
2263
  catch (error) {
@@ -2283,9 +2294,7 @@ class ScreenWakeLockService extends BrowserApiBaseService {
2283
2294
  };
2284
2295
  document.addEventListener('visibilitychange', handleVisibilityChange);
2285
2296
  emit();
2286
- const cleanup = () => document.removeEventListener('visibilitychange', handleVisibilityChange);
2287
- this.destroyRef.onDestroy(cleanup);
2288
- return cleanup;
2297
+ return () => document.removeEventListener('visibilitychange', handleVisibilityChange);
2289
2298
  });
2290
2299
  }
2291
2300
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ScreenWakeLockService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
@@ -2445,12 +2454,10 @@ class FullscreenService extends BrowserApiBaseService {
2445
2454
  document.addEventListener('fullscreenchange', handler);
2446
2455
  document.addEventListener('webkitfullscreenchange', handler);
2447
2456
  observer.next(this.isFullscreen);
2448
- const cleanup = () => {
2457
+ return () => {
2449
2458
  document.removeEventListener('fullscreenchange', handler);
2450
2459
  document.removeEventListener('webkitfullscreenchange', handler);
2451
2460
  };
2452
- this.destroyRef.onDestroy(cleanup);
2453
- return cleanup;
2454
2461
  });
2455
2462
  }
2456
2463
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FullscreenService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
@@ -2686,11 +2693,9 @@ class ServerSentEventsService extends ConnectionRegistryBaseService {
2686
2693
  source.addEventListener(type, messageHandler);
2687
2694
  }
2688
2695
  }
2689
- const cleanup = () => {
2696
+ return () => {
2690
2697
  this.disconnect(url);
2691
2698
  };
2692
- this.destroyRef.onDestroy(cleanup);
2693
- return cleanup;
2694
2699
  });
2695
2700
  }
2696
2701
  disconnect(url) {
@@ -2793,9 +2798,7 @@ class SpeechSynthesisService extends BrowserApiBaseService {
2793
2798
  const emit = () => observer.next(speechSynthesis.getVoices());
2794
2799
  speechSynthesis.addEventListener('voiceschanged', emit);
2795
2800
  emit();
2796
- const cleanup = () => speechSynthesis.removeEventListener('voiceschanged', emit);
2797
- this.destroyRef.onDestroy(cleanup);
2798
- return cleanup;
2801
+ return () => speechSynthesis.removeEventListener('voiceschanged', emit);
2799
2802
  });
2800
2803
  }
2801
2804
  speak(text, options = {}) {
@@ -2824,12 +2827,19 @@ class SpeechSynthesisService extends BrowserApiBaseService {
2824
2827
  };
2825
2828
  observer.next('speaking');
2826
2829
  speechSynthesis.speak(utterance);
2827
- const cleanup = () => {
2830
+ let completed = false;
2831
+ const origOnEnd = utterance.onend;
2832
+ utterance.onend = (ev) => {
2833
+ completed = true;
2834
+ origOnEnd?.call(utterance, ev);
2835
+ };
2836
+ return () => {
2828
2837
  speechSynthesis.cancel();
2829
- observer.next('idle');
2838
+ // Only emit idle if the Observable hasn't already completed via onend/onerror.
2839
+ if (!completed) {
2840
+ observer.next('idle');
2841
+ }
2830
2842
  };
2831
- this.destroyRef.onDestroy(cleanup);
2832
- return cleanup;
2833
2843
  });
2834
2844
  }
2835
2845
  pause() {
@@ -2941,6 +2951,7 @@ class WebAudioService extends BrowserApiBaseService {
2941
2951
  return 'web-audio';
2942
2952
  }
2943
2953
  context = null;
2954
+ destroyRegistered = false;
2944
2955
  getCapabilityId() {
2945
2956
  return 'webAudio';
2946
2957
  }
@@ -2950,7 +2961,10 @@ class WebAudioService extends BrowserApiBaseService {
2950
2961
  }
2951
2962
  if (!this.context || this.context.state === 'closed') {
2952
2963
  this.context = new AudioContext();
2953
- this.destroyRef.onDestroy(() => this.close());
2964
+ if (!this.destroyRegistered) {
2965
+ this.destroyRegistered = true;
2966
+ this.destroyRef.onDestroy(() => this.close());
2967
+ }
2954
2968
  }
2955
2969
  return this.context;
2956
2970
  }
@@ -3145,6 +3159,121 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
3145
3159
  type: Injectable
3146
3160
  }] });
3147
3161
 
3162
+ class EyeDropperService extends BrowserApiBaseService {
3163
+ getApiName() {
3164
+ return 'eye-dropper';
3165
+ }
3166
+ getCapabilityId() {
3167
+ return 'eyeDropper';
3168
+ }
3169
+ /** Override to also assert secure context (required by the spec). */
3170
+ isSupported() {
3171
+ return (super.isSupported() &&
3172
+ typeof window !== 'undefined' &&
3173
+ 'EyeDropper' in window &&
3174
+ window.isSecureContext);
3175
+ }
3176
+ ensureSupported() {
3177
+ super.ensureSupported();
3178
+ if (!window.isSecureContext) {
3179
+ throw new Error('EyeDropper API requires a secure context (HTTPS)');
3180
+ }
3181
+ }
3182
+ /**
3183
+ * Opens the system eye dropper tool and returns the selected color.
3184
+ *
3185
+ * @param options Optional configuration including an AbortSignal to cancel the dropper.
3186
+ * @returns A promise that resolves with the selected color in sRGB Hex format (e.g., "#000000").
3187
+ * @throws DOMException if the user cancels the selection (AbortError).
3188
+ */
3189
+ async open(options) {
3190
+ this.ensureSupported();
3191
+ const EyeDropperClass = window.EyeDropper;
3192
+ if (!EyeDropperClass) {
3193
+ throw new Error('EyeDropper is not supported in this browser.');
3194
+ }
3195
+ const eyeDropper = new EyeDropperClass();
3196
+ return eyeDropper.open(options);
3197
+ }
3198
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: EyeDropperService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
3199
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: EyeDropperService });
3200
+ }
3201
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: EyeDropperService, decorators: [{
3202
+ type: Injectable
3203
+ }] });
3204
+
3205
+ class IdleDetectorService extends BrowserApiBaseService {
3206
+ getApiName() {
3207
+ return 'idle-detector';
3208
+ }
3209
+ getCapabilityId() {
3210
+ return 'idleDetector';
3211
+ }
3212
+ isSupported() {
3213
+ return (super.isSupported() &&
3214
+ typeof window !== 'undefined' &&
3215
+ 'IdleDetector' in window &&
3216
+ window.isSecureContext);
3217
+ }
3218
+ ensureSupported() {
3219
+ super.ensureSupported();
3220
+ if (!window.isSecureContext) {
3221
+ throw new Error('IdleDetector API requires a secure context (HTTPS)');
3222
+ }
3223
+ }
3224
+ async requestPermission() {
3225
+ this.ensureSupported();
3226
+ const IdleDetectorClass = window.IdleDetector;
3227
+ return IdleDetectorClass.requestPermission();
3228
+ }
3229
+ /**
3230
+ * Starts tracking idle state. Emits the current state and subsequent changes.
3231
+ * Note: You must call requestPermission() and be granted access before starting.
3232
+ *
3233
+ * @param options Configuration for the idle detector, including the threshold (minimum 60000ms).
3234
+ * @returns An Observable of the IdleState.
3235
+ */
3236
+ watch(options) {
3237
+ return new Observable((observer) => {
3238
+ this.ensureSupported();
3239
+ const IdleDetectorClass = window.IdleDetector;
3240
+ const detector = new IdleDetectorClass();
3241
+ const emit = () => {
3242
+ observer.next({
3243
+ userState: detector.userState,
3244
+ screenState: detector.screenState,
3245
+ });
3246
+ };
3247
+ detector.addEventListener('change', emit);
3248
+ // We use a custom AbortController if one wasn't provided,
3249
+ // so we can abort the detector when the observable is unsubscribed.
3250
+ const abortController = new AbortController();
3251
+ const signal = options.signal || abortController.signal;
3252
+ const combinedOptions = { ...options, signal };
3253
+ // Stop tracking if an external signal aborts
3254
+ if (options.signal) {
3255
+ options.signal.addEventListener('abort', () => {
3256
+ observer.complete();
3257
+ }, { once: true });
3258
+ }
3259
+ detector.start(combinedOptions).catch((err) => {
3260
+ observer.error(err);
3261
+ });
3262
+ return () => {
3263
+ detector.removeEventListener('change', emit);
3264
+ if (!signal.aborted) {
3265
+ abortController.abort();
3266
+ }
3267
+ };
3268
+ });
3269
+ }
3270
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: IdleDetectorService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
3271
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: IdleDetectorService });
3272
+ }
3273
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: IdleDetectorService, decorators: [{
3274
+ type: Injectable
3275
+ }] });
3276
+
3148
3277
  /**
3149
3278
  * Service wrapping `navigator.locks` (Web Locks API). Coordinates exclusive or
3150
3279
  * shared access to a named resource across tabs and workers.
@@ -3738,6 +3867,9 @@ function injectWakeLock() {
3738
3867
  let sentinel = null;
3739
3868
  let disposed = false;
3740
3869
  const onRelease = () => {
3870
+ if (sentinel) {
3871
+ sentinel.removeEventListener('release', onRelease);
3872
+ }
3741
3873
  if (!disposed)
3742
3874
  active.set(false);
3743
3875
  sentinel = null;
@@ -3777,8 +3909,11 @@ function injectWakeLock() {
3777
3909
  };
3778
3910
  destroyRef.onDestroy(() => {
3779
3911
  disposed = true;
3780
- if (sentinel && !sentinel.released) {
3781
- void sentinel.release();
3912
+ if (sentinel) {
3913
+ sentinel.removeEventListener('release', onRelease);
3914
+ if (!sentinel.released) {
3915
+ void sentinel.release();
3916
+ }
3782
3917
  }
3783
3918
  sentinel = null;
3784
3919
  });
@@ -3791,6 +3926,153 @@ function injectWakeLock() {
3791
3926
  };
3792
3927
  }
3793
3928
 
3929
+ function injectEyeDropper() {
3930
+ const platformId = inject(PLATFORM_ID);
3931
+ const isBrowser = isPlatformBrowser(platformId);
3932
+ const hasDropper = isBrowser && typeof window !== 'undefined' && 'EyeDropper' in window;
3933
+ const supported = signal(hasDropper && window.isSecureContext, ...(ngDevMode ? [{ debugName: "supported" }] : /* istanbul ignore next */ []));
3934
+ const color = signal(null, ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
3935
+ const error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
3936
+ const isOpening = signal(false, ...(ngDevMode ? [{ debugName: "isOpening" }] : /* istanbul ignore next */ []));
3937
+ const open = async (options) => {
3938
+ if (!supported()) {
3939
+ error.set(new Error('EyeDropper API is not supported in this environment'));
3940
+ return null;
3941
+ }
3942
+ const EyeDropperClass = window.EyeDropper;
3943
+ const dropper = new EyeDropperClass();
3944
+ isOpening.set(true);
3945
+ error.set(null);
3946
+ try {
3947
+ const result = await dropper.open(options);
3948
+ color.set(result.sRGBHex);
3949
+ return result;
3950
+ }
3951
+ catch (e) {
3952
+ if (e instanceof DOMException && e.name === 'AbortError') {
3953
+ // User canceled, not an error
3954
+ return null;
3955
+ }
3956
+ const err = e instanceof Error ? e : new Error(String(e));
3957
+ error.set(err);
3958
+ return null;
3959
+ }
3960
+ finally {
3961
+ isOpening.set(false);
3962
+ }
3963
+ };
3964
+ return {
3965
+ isSupported: supported.asReadonly(),
3966
+ color: color.asReadonly(),
3967
+ error: error.asReadonly(),
3968
+ isOpening: isOpening.asReadonly(),
3969
+ open,
3970
+ };
3971
+ }
3972
+
3973
+ function injectIdleDetector() {
3974
+ const platformId = inject(PLATFORM_ID);
3975
+ const destroyRef = inject(DestroyRef);
3976
+ const isBrowser = isPlatformBrowser(platformId);
3977
+ const hasDetector = isBrowser && typeof window !== 'undefined' && 'IdleDetector' in window;
3978
+ const supported = signal(hasDetector && window.isSecureContext, ...(ngDevMode ? [{ debugName: "supported" }] : /* istanbul ignore next */ []));
3979
+ const state = signal(null, ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
3980
+ const error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
3981
+ const isTracking = signal(false, ...(ngDevMode ? [{ debugName: "isTracking" }] : /* istanbul ignore next */ []));
3982
+ let detector = null;
3983
+ let abortController = null;
3984
+ let disposed = false;
3985
+ const onStateChange = () => {
3986
+ if (disposed || !detector)
3987
+ return;
3988
+ state.set({
3989
+ userState: detector.userState,
3990
+ screenState: detector.screenState,
3991
+ });
3992
+ };
3993
+ const stop = () => {
3994
+ if (detector) {
3995
+ detector.removeEventListener('change', onStateChange);
3996
+ }
3997
+ if (abortController) {
3998
+ abortController.abort();
3999
+ abortController = null;
4000
+ }
4001
+ detector = null;
4002
+ if (!disposed) {
4003
+ isTracking.set(false);
4004
+ }
4005
+ };
4006
+ destroyRef.onDestroy(() => {
4007
+ disposed = true;
4008
+ stop();
4009
+ });
4010
+ const requestPermission = async () => {
4011
+ if (!supported())
4012
+ return 'denied';
4013
+ const IdleDetectorClass = window.IdleDetector;
4014
+ return IdleDetectorClass.requestPermission();
4015
+ };
4016
+ const start = async (options) => {
4017
+ if (!supported() || disposed) {
4018
+ error.set(new Error('IdleDetector API is not supported in this environment'));
4019
+ return;
4020
+ }
4021
+ stop();
4022
+ error.set(null);
4023
+ const IdleDetectorClass = window.IdleDetector;
4024
+ detector = new IdleDetectorClass();
4025
+ abortController = new AbortController();
4026
+ const combinedSignal = options.signal
4027
+ ? abortSignalAny([options.signal, abortController.signal])
4028
+ : abortController.signal;
4029
+ detector.addEventListener('change', onStateChange);
4030
+ try {
4031
+ await detector.start({ ...options, signal: combinedSignal });
4032
+ if (!disposed) {
4033
+ isTracking.set(true);
4034
+ // Initial state emit
4035
+ onStateChange();
4036
+ }
4037
+ }
4038
+ catch (e) {
4039
+ stop();
4040
+ if (!disposed) {
4041
+ if (e instanceof DOMException && e.name === 'AbortError') {
4042
+ // Expected when stopped manually
4043
+ return;
4044
+ }
4045
+ error.set(e instanceof Error ? e : new Error(String(e)));
4046
+ }
4047
+ }
4048
+ };
4049
+ // Helper to combine abort signals since AbortSignal.any is relatively new
4050
+ function abortSignalAny(signals) {
4051
+ if (typeof AbortSignal !== 'undefined' && 'any' in AbortSignal) {
4052
+ return AbortSignal.any(signals);
4053
+ }
4054
+ const controller = new AbortController();
4055
+ for (const s of signals) {
4056
+ if (s.aborted) {
4057
+ controller.abort(s.reason);
4058
+ return controller.signal;
4059
+ }
4060
+ s.addEventListener('abort', () => controller.abort(s.reason), { once: true });
4061
+ }
4062
+ return controller.signal;
4063
+ }
4064
+ return {
4065
+ isSupported: supported.asReadonly(),
4066
+ state: state.asReadonly(),
4067
+ error: error.asReadonly(),
4068
+ isTracking: isTracking.asReadonly(),
4069
+ isIdle: computed(() => state()?.userState === 'idle'),
4070
+ start,
4071
+ stop,
4072
+ requestPermission,
4073
+ };
4074
+ }
4075
+
3794
4076
  class BrowserSupportUtil {
3795
4077
  static isSupported(feature) {
3796
4078
  if (typeof window === 'undefined' || typeof navigator === 'undefined') {
@@ -3896,6 +4178,7 @@ const permissionGuard = (permission) => {
3896
4178
  return true;
3897
4179
  }
3898
4180
  catch (error) {
4181
+ // oxlint-disable-next-line no-console -- guard errors must surface to DevTools; no injectable logger here
3899
4182
  console.error('Permission guard error:', error);
3900
4183
  router.navigate(['/permission-denied'], {
3901
4184
  queryParams: { permission },
@@ -4029,6 +4312,14 @@ function provideCompression() {
4029
4312
  return makeEnvironmentProviders([CompressionService]);
4030
4313
  }
4031
4314
 
4315
+ function provideEyeDropper() {
4316
+ return makeEnvironmentProviders([EyeDropperService, PermissionsService]);
4317
+ }
4318
+
4319
+ function provideIdleDetector() {
4320
+ return makeEnvironmentProviders([IdleDetectorService, PermissionsService]);
4321
+ }
4322
+
4032
4323
  function provideMediaApis() {
4033
4324
  return makeEnvironmentProviders([PermissionsService, CameraService, MediaDevicesService]);
4034
4325
  }
@@ -4075,6 +4366,8 @@ const defaultBrowserWebApisConfig = {
4075
4366
  enablePerformanceObserver: false,
4076
4367
  enableWebAudio: false,
4077
4368
  enableGamepad: false,
4369
+ enableEyeDropper: false,
4370
+ enableIdleDetector: false,
4078
4371
  };
4079
4372
  let legacyFlagsDeprecationLogged = false;
4080
4373
  function provideBrowserWebApis(config = {}) {
@@ -4131,6 +4424,8 @@ function provideBrowserWebApis(config = {}) {
4131
4424
  [mergedConfig.enablePerformanceObserver, PerformanceObserverService],
4132
4425
  [mergedConfig.enableWebAudio, WebAudioService],
4133
4426
  [mergedConfig.enableGamepad, GamepadService],
4427
+ [mergedConfig.enableEyeDropper, EyeDropperService],
4428
+ [mergedConfig.enableIdleDetector, IdleDetectorService],
4134
4429
  ];
4135
4430
  for (const [enabled, provider] of conditionalProviders) {
4136
4431
  if (enabled) {
@@ -4148,4 +4443,4 @@ const version = '0.1.0';
4148
4443
  * Generated bundle index. Do not edit.
4149
4444
  */
4150
4445
 
4151
- export { BROWSER_API_EXPERIMENTAL_SILENT, BROWSER_API_LOGGER, BROWSER_API_LOG_LEVEL, BatteryService, BroadcastChannelService, BrowserApiBaseService, BrowserCapabilityService, BrowserSupportUtil, CameraService, ClipboardService, CompressionService, ConnectionRegistryBaseService, FileSystemAccessService, FullscreenService, GamepadService, GeolocationService, IntersectionObserverService, MediaDevicesService, MediaRecorderService, MutationObserverService, NetworkInformationService, NotificationService, PageVisibilityService, PerformanceObserverService, PermissionsService, ResizeObserverService, ScreenOrientationService, ScreenWakeLockService, ServerSentEventsService, SpeechSynthesisService, StorageManagerService, VibrationService, WebAudioService, WebLocksService, WebShareService, WebSocketClient, WebSocketService, WebStorageService, WebWorkerService, permissionGuard as createPermissionGuard, defaultBrowserWebApisConfig, injectBattery, injectClipboard, injectGamepad, injectGeolocation, injectIntersectionObserver, injectMutationObserver, injectNetworkInformation, injectPageVisibility, injectPerformanceObserver, injectResizeObserver, injectScreenOrientation, injectWakeLock, permissionGuard, provideBattery, provideBroadcastChannel, provideBrowserApiLogLevel, provideBrowserWebApis, provideCamera, provideClipboard, provideCommunicationApis, provideCompression, provideFileSystemAccess, provideFullscreen, provideGamepad, provideGeolocation, provideIntersectionObserver, provideLocationApis, provideMediaApis, provideMediaDevices, provideMediaRecorder, provideMutationObserver, provideNetworkInformation, provideNotifications, providePageVisibility, providePerformanceObserver, providePermissions, provideResizeObserver, provideScreenOrientation, provideScreenWakeLock, provideServerSentEvents, provideSpeechSynthesis, provideStorageApis, provideStorageManager, provideVibration, provideWebAudio, provideWebLocks, provideWebShare, provideWebSocket, provideWebStorage, provideWebWorker, version, warnExperimental };
4446
+ export { BROWSER_API_EXPERIMENTAL_SILENT, BROWSER_API_LOGGER, BROWSER_API_LOG_LEVEL, BatteryService, BroadcastChannelService, BrowserApiBaseService, BrowserCapabilityService, BrowserSupportUtil, CameraService, ClipboardService, CompressionService, ConnectionRegistryBaseService, EyeDropperService, FileSystemAccessService, FullscreenService, GamepadService, GeolocationService, IdleDetectorService, IntersectionObserverService, MediaDevicesService, MediaRecorderService, MutationObserverService, NetworkInformationService, NotificationService, PageVisibilityService, PerformanceObserverService, PermissionsService, ResizeObserverService, ScreenOrientationService, ScreenWakeLockService, ServerSentEventsService, SpeechSynthesisService, StorageManagerService, VibrationService, WebAudioService, WebLocksService, WebShareService, WebSocketClient, WebSocketService, WebStorageService, WebWorkerService, permissionGuard as createPermissionGuard, defaultBrowserWebApisConfig, injectBattery, injectClipboard, injectEyeDropper, injectGamepad, injectGeolocation, injectIdleDetector, injectIntersectionObserver, injectMutationObserver, injectNetworkInformation, injectPageVisibility, injectPerformanceObserver, injectResizeObserver, injectScreenOrientation, injectWakeLock, permissionGuard, provideBattery, provideBroadcastChannel, provideBrowserApiLogLevel, provideBrowserWebApis, provideCamera, provideClipboard, provideCommunicationApis, provideCompression, provideEyeDropper, provideFileSystemAccess, provideFullscreen, provideGamepad, provideGeolocation, provideIdleDetector, provideIntersectionObserver, provideLocationApis, provideMediaApis, provideMediaDevices, provideMediaRecorder, provideMutationObserver, provideNetworkInformation, provideNotifications, providePageVisibility, providePerformanceObserver, providePermissions, provideResizeObserver, provideScreenOrientation, provideScreenWakeLock, provideServerSentEvents, provideSpeechSynthesis, provideStorageApis, provideStorageManager, provideVibration, provideWebAudio, provideWebLocks, provideWebShare, provideWebSocket, provideWebStorage, provideWebWorker, version, warnExperimental };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular-helpers/browser-web-apis",
3
- "version": "21.11.0",
3
+ "version": "21.12.0",
4
4
  "description": "Sistema de servicios Angular para acceso formalizado a Browser Web APIs (cámara, permisos, geolocalización, etc.)",
5
5
  "homepage": "https://gaspar1992.github.io/angular-helpers/docs/browser-web-apis",
6
6
  "repository": {
@@ -49,6 +49,7 @@
49
49
  "default": "./fesm2022/angular-helpers-browser-web-apis-experimental.mjs"
50
50
  }
51
51
  },
52
+ "type": "module",
52
53
  "dependencies": {
53
54
  "tslib": "^2.3.0"
54
55
  }
@@ -890,6 +890,7 @@ interface WakeLockStatus {
890
890
  }
891
891
  declare class ScreenWakeLockService extends BrowserApiBaseService {
892
892
  private sentinel;
893
+ private releaseRegistered;
893
894
  protected getApiName(): string;
894
895
  protected getCapabilityId(): BrowserCapabilityId;
895
896
  get isActive(): boolean;
@@ -1118,6 +1119,7 @@ interface AudioAnalyserData {
1118
1119
  declare class WebAudioService extends BrowserApiBaseService {
1119
1120
  protected getApiName(): string;
1120
1121
  private context;
1122
+ private destroyRegistered;
1121
1123
  protected getCapabilityId(): BrowserCapabilityId;
1122
1124
  getContext(): AudioContext;
1123
1125
  resume(): Promise<void>;
@@ -1159,6 +1161,59 @@ declare class GamepadService extends BrowserApiBaseService {
1159
1161
  static ɵprov: i0.ɵɵInjectableDeclaration<GamepadService>;
1160
1162
  }
1161
1163
 
1164
+ interface EyeDropperResult {
1165
+ sRGBHex: string;
1166
+ }
1167
+ declare class EyeDropperService extends BrowserApiBaseService {
1168
+ protected getApiName(): string;
1169
+ protected getCapabilityId(): BrowserCapabilityId;
1170
+ /** Override to also assert secure context (required by the spec). */
1171
+ isSupported(): boolean;
1172
+ protected ensureSupported(): void;
1173
+ /**
1174
+ * Opens the system eye dropper tool and returns the selected color.
1175
+ *
1176
+ * @param options Optional configuration including an AbortSignal to cancel the dropper.
1177
+ * @returns A promise that resolves with the selected color in sRGB Hex format (e.g., "#000000").
1178
+ * @throws DOMException if the user cancels the selection (AbortError).
1179
+ */
1180
+ open(options?: {
1181
+ signal?: AbortSignal;
1182
+ }): Promise<EyeDropperResult>;
1183
+ static ɵfac: i0.ɵɵFactoryDeclaration<EyeDropperService, never>;
1184
+ static ɵprov: i0.ɵɵInjectableDeclaration<EyeDropperService>;
1185
+ }
1186
+
1187
+ type UserIdleState = 'active' | 'idle';
1188
+ type ScreenIdleState = 'locked' | 'unlocked';
1189
+ interface IdleState {
1190
+ userState: UserIdleState | null;
1191
+ screenState: ScreenIdleState | null;
1192
+ }
1193
+ interface IdleDetectorOptions {
1194
+ /** The minimum number of milliseconds of inactivity before the user is considered idle. Must be at least 60000. */
1195
+ threshold: number;
1196
+ /** An AbortSignal to abort the idle detection. */
1197
+ signal?: AbortSignal;
1198
+ }
1199
+ declare class IdleDetectorService extends BrowserApiBaseService {
1200
+ protected getApiName(): string;
1201
+ protected getCapabilityId(): BrowserCapabilityId;
1202
+ isSupported(): boolean;
1203
+ protected ensureSupported(): void;
1204
+ requestPermission(): Promise<PermissionState>;
1205
+ /**
1206
+ * Starts tracking idle state. Emits the current state and subsequent changes.
1207
+ * Note: You must call requestPermission() and be granted access before starting.
1208
+ *
1209
+ * @param options Configuration for the idle detector, including the threshold (minimum 60000ms).
1210
+ * @returns An Observable of the IdleState.
1211
+ */
1212
+ watch(options: IdleDetectorOptions): Observable<IdleState>;
1213
+ static ɵfac: i0.ɵɵFactoryDeclaration<IdleDetectorService, never>;
1214
+ static ɵprov: i0.ɵɵInjectableDeclaration<IdleDetectorService>;
1215
+ }
1216
+
1162
1217
  interface LockOptionsLike {
1163
1218
  mode?: 'exclusive' | 'shared';
1164
1219
  ifAvailable?: boolean;
@@ -1486,6 +1541,29 @@ interface WakeLockRef {
1486
1541
  }
1487
1542
  declare function injectWakeLock(): WakeLockRef;
1488
1543
 
1544
+ interface EyeDropperRef {
1545
+ readonly isSupported: Signal<boolean>;
1546
+ readonly color: Signal<string | null>;
1547
+ readonly error: Signal<Error | null>;
1548
+ readonly isOpening: Signal<boolean>;
1549
+ open(options?: {
1550
+ signal?: AbortSignal;
1551
+ }): Promise<EyeDropperResult | null>;
1552
+ }
1553
+ declare function injectEyeDropper(): EyeDropperRef;
1554
+
1555
+ interface IdleDetectorRef {
1556
+ readonly isSupported: Signal<boolean>;
1557
+ readonly state: Signal<IdleState | null>;
1558
+ readonly error: Signal<Error | null>;
1559
+ readonly isTracking: Signal<boolean>;
1560
+ readonly isIdle: Signal<boolean>;
1561
+ start(options: IdleDetectorOptions): Promise<void>;
1562
+ stop(): void;
1563
+ requestPermission(): Promise<PermissionState>;
1564
+ }
1565
+ declare function injectIdleDetector(): IdleDetectorRef;
1566
+
1489
1567
  declare class BrowserSupportUtil {
1490
1568
  static isSupported(feature: string): boolean;
1491
1569
  static getUnsupportedFeatures(): string[];
@@ -1573,6 +1651,10 @@ declare function provideStorageManager(): EnvironmentProviders;
1573
1651
 
1574
1652
  declare function provideCompression(): EnvironmentProviders;
1575
1653
 
1654
+ declare function provideEyeDropper(): EnvironmentProviders;
1655
+
1656
+ declare function provideIdleDetector(): EnvironmentProviders;
1657
+
1576
1658
  declare function provideMediaApis(): EnvironmentProviders;
1577
1659
  declare function provideLocationApis(): EnvironmentProviders;
1578
1660
  declare function provideStorageApis(): EnvironmentProviders;
@@ -1619,11 +1701,13 @@ interface BrowserWebApisConfig extends BrowserWebApisCompositionConfig {
1619
1701
  enablePerformanceObserver?: boolean;
1620
1702
  enableWebAudio?: boolean;
1621
1703
  enableGamepad?: boolean;
1704
+ enableEyeDropper?: boolean;
1705
+ enableIdleDetector?: boolean;
1622
1706
  }
1623
1707
  declare const defaultBrowserWebApisConfig: BrowserWebApisConfig;
1624
1708
  declare function provideBrowserWebApis(config?: BrowserWebApisConfig): EnvironmentProviders;
1625
1709
 
1626
1710
  declare const version = "0.1.0";
1627
1711
 
1628
- export { BROWSER_API_EXPERIMENTAL_SILENT, BROWSER_API_LOGGER, BROWSER_API_LOG_LEVEL, BatteryService, BroadcastChannelService, BrowserApiBaseService, BrowserCapabilityService, BrowserSupportUtil, CameraService, ClipboardService, CompressionService, ConnectionRegistryBaseService, FileSystemAccessService, FullscreenService, GamepadService, GeolocationService, IntersectionObserverService, MediaDevicesService, MediaRecorderService, MutationObserverService, NetworkInformationService, NotificationService, PageVisibilityService, PerformanceObserverService, PermissionsService, ResizeObserverService, ScreenOrientationService, ScreenWakeLockService, ServerSentEventsService, SpeechSynthesisService, StorageManagerService, VibrationService, WebAudioService, WebLocksService, WebShareService, WebSocketClient, WebSocketService, WebStorageService, WebWorkerService, permissionGuard as createPermissionGuard, defaultBrowserWebApisConfig, injectBattery, injectClipboard, injectGamepad, injectGeolocation, injectIntersectionObserver, injectMutationObserver, injectNetworkInformation, injectPageVisibility, injectPerformanceObserver, injectResizeObserver, injectScreenOrientation, injectWakeLock, permissionGuard, provideBattery, provideBroadcastChannel, provideBrowserApiLogLevel, provideBrowserWebApis, provideCamera, provideClipboard, provideCommunicationApis, provideCompression, provideFileSystemAccess, provideFullscreen, provideGamepad, provideGeolocation, provideIntersectionObserver, provideLocationApis, provideMediaApis, provideMediaDevices, provideMediaRecorder, provideMutationObserver, provideNetworkInformation, provideNotifications, providePageVisibility, providePerformanceObserver, providePermissions, provideResizeObserver, provideScreenOrientation, provideScreenWakeLock, provideServerSentEvents, provideSpeechSynthesis, provideStorageApis, provideStorageManager, provideVibration, provideWebAudio, provideWebLocks, provideWebShare, provideWebSocket, provideWebStorage, provideWebWorker, version, warnExperimental };
1629
- export type { AudioAnalyserData, AudioContextState, BatteryInfo, BatteryManager, BatteryRef, BrowserApiLogLevel, BrowserApiLogger, BrowserCapabilityId, BrowserError, BrowserPermissions, BrowserWebApisCompositionConfig, BrowserWebApisConfig, CameraCapabilities, CameraInfo, ClipboardRef, CompressionFormat, ConnectionType, EffectiveConnectionType, ElementInput, ElementSize, ErrorCallback, EventHandler, ExperimentalWarnContext, FileOpenOptions, FileSaveOptions, GamepadRef, GamepadState, GeolocationCoordinates, GeolocationError, GeolocationOptions, GeolocationPosition$1 as GeolocationPosition, GeolocationRef, GeolocationWatchOptions, IntersectionObserverOptions, IntersectionRef, MediaDevice, MediaDeviceKind, MediaDevicesInfo, MediaStreamConstraints$1 as MediaStreamConstraints, MediaTrackConstraints$1 as MediaTrackConstraints, MutationObserverOptions, MutationRef, NetworkInformation, NetworkInformationRef, OrientationInfo, OrientationLockType, OrientationType, PageVisibilityRef, PerformanceEntryType, PerformanceObserverConfig, PerformanceObserverRef, PermissionNameExt, PermissionRequest, RecordingOptions, RecordingResult, RecordingState, ResizeObserverOptions, ResizeRef, SSEConfig, SSEConnectionState, SSEMessage, ScreenOrientationRef, SpeechOptions, SpeechState, StorageEvent, StorageNamespace, StorageOptions, StorageQuotaEstimate, StorageValue, VibrationPattern, VibrationPreset, VisibilityState, WakeLockRef, WakeLockStatus, WakeLockType, WebSocketClientConfig, WebSocketConfig, WebSocketMessage, WebSocketRequestOptions, WebSocketState, WebSocketStatus, WebSocketStatusV2, WorkerMessage, WorkerRequestOptions, WorkerStatus, WorkerTask };
1712
+ export { BROWSER_API_EXPERIMENTAL_SILENT, BROWSER_API_LOGGER, BROWSER_API_LOG_LEVEL, BatteryService, BroadcastChannelService, BrowserApiBaseService, BrowserCapabilityService, BrowserSupportUtil, CameraService, ClipboardService, CompressionService, ConnectionRegistryBaseService, EyeDropperService, FileSystemAccessService, FullscreenService, GamepadService, GeolocationService, IdleDetectorService, IntersectionObserverService, MediaDevicesService, MediaRecorderService, MutationObserverService, NetworkInformationService, NotificationService, PageVisibilityService, PerformanceObserverService, PermissionsService, ResizeObserverService, ScreenOrientationService, ScreenWakeLockService, ServerSentEventsService, SpeechSynthesisService, StorageManagerService, VibrationService, WebAudioService, WebLocksService, WebShareService, WebSocketClient, WebSocketService, WebStorageService, WebWorkerService, permissionGuard as createPermissionGuard, defaultBrowserWebApisConfig, injectBattery, injectClipboard, injectEyeDropper, injectGamepad, injectGeolocation, injectIdleDetector, injectIntersectionObserver, injectMutationObserver, injectNetworkInformation, injectPageVisibility, injectPerformanceObserver, injectResizeObserver, injectScreenOrientation, injectWakeLock, permissionGuard, provideBattery, provideBroadcastChannel, provideBrowserApiLogLevel, provideBrowserWebApis, provideCamera, provideClipboard, provideCommunicationApis, provideCompression, provideEyeDropper, provideFileSystemAccess, provideFullscreen, provideGamepad, provideGeolocation, provideIdleDetector, provideIntersectionObserver, provideLocationApis, provideMediaApis, provideMediaDevices, provideMediaRecorder, provideMutationObserver, provideNetworkInformation, provideNotifications, providePageVisibility, providePerformanceObserver, providePermissions, provideResizeObserver, provideScreenOrientation, provideScreenWakeLock, provideServerSentEvents, provideSpeechSynthesis, provideStorageApis, provideStorageManager, provideVibration, provideWebAudio, provideWebLocks, provideWebShare, provideWebSocket, provideWebStorage, provideWebWorker, version, warnExperimental };
1713
+ export type { AudioAnalyserData, AudioContextState, BatteryInfo, BatteryManager, BatteryRef, BrowserApiLogLevel, BrowserApiLogger, BrowserCapabilityId, BrowserError, BrowserPermissions, BrowserWebApisCompositionConfig, BrowserWebApisConfig, CameraCapabilities, CameraInfo, ClipboardRef, CompressionFormat, ConnectionType, EffectiveConnectionType, ElementInput, ElementSize, ErrorCallback, EventHandler, ExperimentalWarnContext, EyeDropperRef, EyeDropperResult, FileOpenOptions, FileSaveOptions, GamepadRef, GamepadState, GeolocationCoordinates, GeolocationError, GeolocationOptions, GeolocationPosition$1 as GeolocationPosition, GeolocationRef, GeolocationWatchOptions, IdleDetectorOptions, IdleDetectorRef, IdleState, IntersectionObserverOptions, IntersectionRef, MediaDevice, MediaDeviceKind, MediaDevicesInfo, MediaStreamConstraints$1 as MediaStreamConstraints, MediaTrackConstraints$1 as MediaTrackConstraints, MutationObserverOptions, MutationRef, NetworkInformation, NetworkInformationRef, OrientationInfo, OrientationLockType, OrientationType, PageVisibilityRef, PerformanceEntryType, PerformanceObserverConfig, PerformanceObserverRef, PermissionNameExt, PermissionRequest, RecordingOptions, RecordingResult, RecordingState, ResizeObserverOptions, ResizeRef, SSEConfig, SSEConnectionState, SSEMessage, ScreenIdleState, ScreenOrientationRef, SpeechOptions, SpeechState, StorageEvent, StorageNamespace, StorageOptions, StorageQuotaEstimate, StorageValue, UserIdleState, VibrationPattern, VibrationPreset, VisibilityState, WakeLockRef, WakeLockStatus, WakeLockType, WebSocketClientConfig, WebSocketConfig, WebSocketMessage, WebSocketRequestOptions, WebSocketState, WebSocketStatus, WebSocketStatusV2, WorkerMessage, WorkerRequestOptions, WorkerStatus, WorkerTask };