@angular-helpers/browser-web-apis 21.3.0 → 21.5.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 +68 -4
- package/README.md +64 -5
- package/fesm2022/angular-helpers-browser-web-apis.mjs +618 -477
- package/package.json +10 -2
- package/types/angular-helpers-browser-web-apis.d.ts +235 -145
|
@@ -1,77 +1,62 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { InjectionToken, inject, DestroyRef, PLATFORM_ID, Injectable, signal, computed, isSignal, effect, ElementRef, makeEnvironmentProviders } from '@angular/core';
|
|
3
3
|
import { isPlatformBrowser, isPlatformServer } from '@angular/common';
|
|
4
|
-
import { Observable, fromEvent, Subject, of, map as map$1 } from 'rxjs';
|
|
4
|
+
import { Observable, fromEvent, BehaviorSubject, Subject, of, map as map$1 } from 'rxjs';
|
|
5
5
|
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
|
|
6
6
|
import { filter, distinctUntilChanged, map } from 'rxjs/operators';
|
|
7
7
|
import { Router } from '@angular/router';
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
isSupported() {
|
|
23
|
-
return typeof navigator !== 'undefined' && 'permissions' in navigator;
|
|
24
|
-
}
|
|
25
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PermissionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
26
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PermissionsService });
|
|
27
|
-
}
|
|
28
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PermissionsService, decorators: [{
|
|
29
|
-
type: Injectable
|
|
30
|
-
}] });
|
|
9
|
+
const BROWSER_API_LOGGER = new InjectionToken('BROWSER_API_LOGGER', {
|
|
10
|
+
providedIn: 'root',
|
|
11
|
+
factory: () => ({
|
|
12
|
+
// oxlint-disable-next-line no-console
|
|
13
|
+
info: (message) => console.info(message),
|
|
14
|
+
// oxlint-disable-next-line no-console
|
|
15
|
+
warn: (message) => console.warn(message),
|
|
16
|
+
// oxlint-disable-next-line no-console
|
|
17
|
+
error: (message, error) => console.error(message, error),
|
|
18
|
+
}),
|
|
19
|
+
});
|
|
31
20
|
|
|
32
21
|
/**
|
|
33
|
-
* Base class for all Browser Web API services
|
|
22
|
+
* Base class for all Browser Web API services.
|
|
34
23
|
* Provides common functionality for:
|
|
35
|
-
* -
|
|
36
|
-
* -
|
|
37
|
-
* - Error
|
|
24
|
+
* - Platform detection (browser vs server)
|
|
25
|
+
* - Support assertion via Template Method
|
|
26
|
+
* - Error creation with cause chaining
|
|
27
|
+
* - Structured logging via injectable BROWSER_API_LOGGER token
|
|
38
28
|
* - Lifecycle management with destroyRef
|
|
39
|
-
*
|
|
29
|
+
*
|
|
30
|
+
* Services that also need permission querying should extend
|
|
31
|
+
* `PermissionAwareBrowserApiBaseService` instead.
|
|
40
32
|
*/
|
|
41
33
|
class BrowserApiBaseService {
|
|
42
|
-
permissionsService = inject(PermissionsService);
|
|
43
34
|
destroyRef = inject(DestroyRef);
|
|
44
35
|
platformId = inject(PLATFORM_ID);
|
|
36
|
+
logger = inject(BROWSER_API_LOGGER);
|
|
45
37
|
/**
|
|
46
|
-
* Check if running in browser environment using Angular's platform detection
|
|
38
|
+
* Check if running in browser environment using Angular's platform detection.
|
|
47
39
|
*/
|
|
48
40
|
isBrowserEnvironment() {
|
|
49
41
|
return isPlatformBrowser(this.platformId);
|
|
50
42
|
}
|
|
51
43
|
/**
|
|
52
|
-
* Check if running in server environment using Angular's platform detection
|
|
44
|
+
* Check if running in server environment using Angular's platform detection.
|
|
53
45
|
*/
|
|
54
46
|
isServerEnvironment() {
|
|
55
47
|
return isPlatformServer(this.platformId);
|
|
56
48
|
}
|
|
57
49
|
/**
|
|
58
|
-
*
|
|
50
|
+
* Template Method: asserts the service can run in the current environment.
|
|
51
|
+
* Subclasses must call super.ensureSupported() and then add their own API check.
|
|
59
52
|
*/
|
|
60
|
-
|
|
61
|
-
if (this.
|
|
53
|
+
ensureSupported() {
|
|
54
|
+
if (!this.isBrowserEnvironment()) {
|
|
62
55
|
throw new Error(`${this.getApiName()} API not available in server environment`);
|
|
63
56
|
}
|
|
64
|
-
try {
|
|
65
|
-
const status = await this.permissionsService.query({ name: permission });
|
|
66
|
-
return status.state === 'granted';
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
console.error(`[${this.getApiName()}] Error requesting permission for ${permission}:`, error);
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
57
|
}
|
|
73
58
|
/**
|
|
74
|
-
* Create an error with proper cause chaining
|
|
59
|
+
* Create an error with proper cause chaining.
|
|
75
60
|
*/
|
|
76
61
|
createError(message, cause) {
|
|
77
62
|
const error = new Error(message);
|
|
@@ -80,6 +65,24 @@ class BrowserApiBaseService {
|
|
|
80
65
|
}
|
|
81
66
|
return error;
|
|
82
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Log an error through the injected BROWSER_API_LOGGER (default: console).
|
|
70
|
+
*/
|
|
71
|
+
logError(message, error) {
|
|
72
|
+
this.logger.error(`[${this.getApiName()}] ${message}`, error);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Log a warning through the injected BROWSER_API_LOGGER (default: console).
|
|
76
|
+
*/
|
|
77
|
+
logWarn(message) {
|
|
78
|
+
this.logger.warn(`[${this.getApiName()}] ${message}`);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Log an informational message through the injected BROWSER_API_LOGGER (default: console).
|
|
82
|
+
*/
|
|
83
|
+
logInfo(message) {
|
|
84
|
+
this.logger.info(`[${this.getApiName()}] ${message}`);
|
|
85
|
+
}
|
|
83
86
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BrowserApiBaseService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
84
87
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BrowserApiBaseService });
|
|
85
88
|
}
|
|
@@ -87,25 +90,54 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
87
90
|
type: Injectable
|
|
88
91
|
}] });
|
|
89
92
|
|
|
93
|
+
class PermissionsService extends BrowserApiBaseService {
|
|
94
|
+
getApiName() {
|
|
95
|
+
return 'permissions';
|
|
96
|
+
}
|
|
97
|
+
async query(descriptor) {
|
|
98
|
+
if (!this.isSupported()) {
|
|
99
|
+
throw new Error('Permissions API not supported in this environment');
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
return await navigator.permissions.query(descriptor);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
// Firefox does not support querying 'camera', 'microphone', or 'speaker' via
|
|
106
|
+
// the Permissions API and throws a TypeError. Return a synthetic 'prompt' status
|
|
107
|
+
// so callers fall through to the native getUserMedia / requestPermission flow.
|
|
108
|
+
if (error instanceof TypeError) {
|
|
109
|
+
return { state: 'prompt', onchange: null };
|
|
110
|
+
}
|
|
111
|
+
this.logError(`Error querying permission for ${descriptor.name}:`, error);
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
isSupported() {
|
|
116
|
+
return this.isBrowserEnvironment() && 'permissions' in navigator;
|
|
117
|
+
}
|
|
118
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PermissionsService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
119
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PermissionsService });
|
|
120
|
+
}
|
|
121
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PermissionsService, decorators: [{
|
|
122
|
+
type: Injectable
|
|
123
|
+
}] });
|
|
124
|
+
|
|
90
125
|
class CameraService extends BrowserApiBaseService {
|
|
91
126
|
currentStream = null;
|
|
92
127
|
getApiName() {
|
|
93
128
|
return 'camera';
|
|
94
129
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
130
|
+
ensureSupported() {
|
|
131
|
+
super.ensureSupported();
|
|
132
|
+
if (!navigator.mediaDevices?.getUserMedia) {
|
|
133
|
+
throw new Error('Camera API not supported — a secure context (HTTPS) is required');
|
|
98
134
|
}
|
|
99
135
|
}
|
|
100
136
|
async startCamera(constraints) {
|
|
101
|
-
this.
|
|
137
|
+
this.ensureSupported();
|
|
102
138
|
if (this.currentStream) {
|
|
103
139
|
this.stopCamera();
|
|
104
140
|
}
|
|
105
|
-
const permissionStatus = await this.permissionsService.query({ name: 'camera' });
|
|
106
|
-
if (permissionStatus.state !== 'granted') {
|
|
107
|
-
throw new Error('Camera permission required. Please grant camera access and try again.');
|
|
108
|
-
}
|
|
109
141
|
try {
|
|
110
142
|
const streamConstraints = constraints || {
|
|
111
143
|
video: {
|
|
@@ -118,7 +150,7 @@ class CameraService extends BrowserApiBaseService {
|
|
|
118
150
|
return this.currentStream;
|
|
119
151
|
}
|
|
120
152
|
catch (error) {
|
|
121
|
-
|
|
153
|
+
this.logError('Error starting camera:', error);
|
|
122
154
|
if (error instanceof Error && error.name === 'NotAllowedError') {
|
|
123
155
|
throw this.createError('Camera permission denied by user. Please allow camera access in your browser settings and refresh the page.', error);
|
|
124
156
|
}
|
|
@@ -160,19 +192,24 @@ class CameraService extends BrowserApiBaseService {
|
|
|
160
192
|
return this.startCamera(finalConstraints);
|
|
161
193
|
}
|
|
162
194
|
async getCameraCapabilities(deviceId) {
|
|
163
|
-
this.
|
|
195
|
+
this.ensureSupported();
|
|
164
196
|
try {
|
|
197
|
+
const activeTrack = this.currentStream
|
|
198
|
+
?.getVideoTracks()
|
|
199
|
+
.find((t) => t.getSettings().deviceId === deviceId);
|
|
200
|
+
if (activeTrack) {
|
|
201
|
+
return activeTrack.getCapabilities() ?? null;
|
|
202
|
+
}
|
|
165
203
|
const stream = await navigator.mediaDevices.getUserMedia({
|
|
166
204
|
video: { deviceId: { exact: deviceId } },
|
|
167
205
|
});
|
|
168
206
|
const videoTrack = stream.getVideoTracks()[0];
|
|
169
207
|
const capabilities = videoTrack.getCapabilities();
|
|
170
|
-
// Clean up the stream
|
|
171
208
|
stream.getTracks().forEach((track) => track.stop());
|
|
172
|
-
return capabilities
|
|
209
|
+
return capabilities ?? null;
|
|
173
210
|
}
|
|
174
211
|
catch (error) {
|
|
175
|
-
|
|
212
|
+
this.logError('Error getting camera capabilities:', error);
|
|
176
213
|
return null;
|
|
177
214
|
}
|
|
178
215
|
}
|
|
@@ -183,19 +220,19 @@ class CameraService extends BrowserApiBaseService {
|
|
|
183
220
|
return this.currentStream !== null;
|
|
184
221
|
}
|
|
185
222
|
async getVideoInputDevices() {
|
|
186
|
-
this.
|
|
223
|
+
this.ensureSupported();
|
|
187
224
|
try {
|
|
188
225
|
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
189
226
|
return devices.filter((device) => device.kind === 'videoinput');
|
|
190
227
|
}
|
|
191
228
|
catch (error) {
|
|
192
|
-
|
|
229
|
+
this.logError('Error enumerating video devices:', error);
|
|
193
230
|
throw this.createError('Failed to enumerate video devices', error);
|
|
194
231
|
}
|
|
195
232
|
}
|
|
196
233
|
// Direct access to native camera API
|
|
197
234
|
getNativeMediaDevices() {
|
|
198
|
-
this.
|
|
235
|
+
this.ensureSupported();
|
|
199
236
|
return navigator.mediaDevices;
|
|
200
237
|
}
|
|
201
238
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CameraService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -209,25 +246,26 @@ class GeolocationService extends BrowserApiBaseService {
|
|
|
209
246
|
getApiName() {
|
|
210
247
|
return 'geolocation';
|
|
211
248
|
}
|
|
212
|
-
|
|
249
|
+
ensureSupported() {
|
|
250
|
+
super.ensureSupported();
|
|
213
251
|
if (!('geolocation' in navigator)) {
|
|
214
|
-
throw new Error('Geolocation API not supported
|
|
252
|
+
throw new Error('Geolocation API not supported — a secure context (HTTPS) is required');
|
|
215
253
|
}
|
|
216
254
|
}
|
|
217
255
|
getCurrentPosition(options) {
|
|
218
|
-
this.
|
|
256
|
+
this.ensureSupported();
|
|
219
257
|
return new Promise((resolve, reject) => {
|
|
220
258
|
navigator.geolocation.getCurrentPosition((position) => resolve(position), (error) => {
|
|
221
|
-
|
|
259
|
+
this.logError('Error getting position:', error);
|
|
222
260
|
reject(error);
|
|
223
261
|
}, options);
|
|
224
262
|
});
|
|
225
263
|
}
|
|
226
264
|
watchPosition(options) {
|
|
227
|
-
this.
|
|
265
|
+
this.ensureSupported();
|
|
228
266
|
return new Observable((observer) => {
|
|
229
267
|
const watchId = navigator.geolocation.watchPosition((position) => observer.next(position), (error) => {
|
|
230
|
-
|
|
268
|
+
this.logError('Error watching position:', error);
|
|
231
269
|
observer.error(error);
|
|
232
270
|
}, options);
|
|
233
271
|
return () => {
|
|
@@ -240,7 +278,7 @@ class GeolocationService extends BrowserApiBaseService {
|
|
|
240
278
|
}
|
|
241
279
|
// Direct access to native geolocation API
|
|
242
280
|
getNativeGeolocation() {
|
|
243
|
-
this.
|
|
281
|
+
this.ensureSupported();
|
|
244
282
|
return navigator.geolocation;
|
|
245
283
|
}
|
|
246
284
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: GeolocationService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -254,24 +292,25 @@ class MediaDevicesService extends BrowserApiBaseService {
|
|
|
254
292
|
getApiName() {
|
|
255
293
|
return 'media-devices';
|
|
256
294
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
295
|
+
ensureSupported() {
|
|
296
|
+
super.ensureSupported();
|
|
297
|
+
if (!navigator.mediaDevices) {
|
|
298
|
+
throw new Error('MediaDevices API not supported — a secure context (HTTPS) is required');
|
|
260
299
|
}
|
|
261
300
|
}
|
|
262
301
|
async getDevices() {
|
|
263
|
-
this.
|
|
302
|
+
this.ensureSupported();
|
|
264
303
|
try {
|
|
265
304
|
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
266
305
|
return devices;
|
|
267
306
|
}
|
|
268
307
|
catch (error) {
|
|
269
|
-
|
|
308
|
+
this.logError('Error enumerating devices:', error);
|
|
270
309
|
throw this.createError('Failed to enumerate media devices', error);
|
|
271
310
|
}
|
|
272
311
|
}
|
|
273
312
|
async getUserMedia(constraints) {
|
|
274
|
-
this.
|
|
313
|
+
this.ensureSupported();
|
|
275
314
|
try {
|
|
276
315
|
const defaultConstraints = {
|
|
277
316
|
video: true,
|
|
@@ -281,12 +320,12 @@ class MediaDevicesService extends BrowserApiBaseService {
|
|
|
281
320
|
return await navigator.mediaDevices.getUserMedia(finalConstraints);
|
|
282
321
|
}
|
|
283
322
|
catch (error) {
|
|
284
|
-
|
|
323
|
+
this.logError('Error getting user media:', error);
|
|
285
324
|
throw this.handleMediaError(error);
|
|
286
325
|
}
|
|
287
326
|
}
|
|
288
327
|
async getDisplayMedia(constraints) {
|
|
289
|
-
this.
|
|
328
|
+
this.ensureSupported();
|
|
290
329
|
if (!('getDisplayMedia' in navigator.mediaDevices)) {
|
|
291
330
|
throw new Error('Display media API not supported in this browser');
|
|
292
331
|
}
|
|
@@ -299,12 +338,12 @@ class MediaDevicesService extends BrowserApiBaseService {
|
|
|
299
338
|
return await navigator.mediaDevices.getDisplayMedia(finalConstraints);
|
|
300
339
|
}
|
|
301
340
|
catch (error) {
|
|
302
|
-
|
|
341
|
+
this.logError('Error getting display media:', error);
|
|
303
342
|
throw this.createError('Failed to get display media', error);
|
|
304
343
|
}
|
|
305
344
|
}
|
|
306
345
|
watchDeviceChanges() {
|
|
307
|
-
this.
|
|
346
|
+
this.ensureSupported();
|
|
308
347
|
return new Observable((observer) => {
|
|
309
348
|
const handleDeviceChange = async () => {
|
|
310
349
|
try {
|
|
@@ -312,7 +351,7 @@ class MediaDevicesService extends BrowserApiBaseService {
|
|
|
312
351
|
observer.next(devices);
|
|
313
352
|
}
|
|
314
353
|
catch (error) {
|
|
315
|
-
|
|
354
|
+
this.logError('Error handling device change:', error);
|
|
316
355
|
}
|
|
317
356
|
};
|
|
318
357
|
// Listen for device changes
|
|
@@ -367,7 +406,7 @@ class MediaDevicesService extends BrowserApiBaseService {
|
|
|
367
406
|
}
|
|
368
407
|
// Direct access to native media devices API
|
|
369
408
|
getNativeMediaDevices() {
|
|
370
|
-
this.
|
|
409
|
+
this.ensureSupported();
|
|
371
410
|
return navigator.mediaDevices;
|
|
372
411
|
}
|
|
373
412
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MediaDevicesService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -381,22 +420,24 @@ class NotificationService extends BrowserApiBaseService {
|
|
|
381
420
|
getApiName() {
|
|
382
421
|
return 'notifications';
|
|
383
422
|
}
|
|
423
|
+
ensureSupported() {
|
|
424
|
+
super.ensureSupported();
|
|
425
|
+
if (!('Notification' in window)) {
|
|
426
|
+
throw new Error('Notifications API not supported in this browser');
|
|
427
|
+
}
|
|
428
|
+
}
|
|
384
429
|
get permission() {
|
|
430
|
+
if (!this.isBrowserEnvironment() || !('Notification' in window)) {
|
|
431
|
+
return 'default';
|
|
432
|
+
}
|
|
385
433
|
return Notification.permission;
|
|
386
434
|
}
|
|
387
|
-
isSupported() {
|
|
388
|
-
return 'Notification' in window;
|
|
389
|
-
}
|
|
390
435
|
async requestNotificationPermission() {
|
|
391
|
-
|
|
392
|
-
throw new Error('Notification API not supported in this browser');
|
|
393
|
-
}
|
|
436
|
+
this.ensureSupported();
|
|
394
437
|
return Notification.requestPermission();
|
|
395
438
|
}
|
|
396
439
|
async showNotification(title, options) {
|
|
397
|
-
|
|
398
|
-
throw new Error('Notification API not supported in this browser');
|
|
399
|
-
}
|
|
440
|
+
this.ensureSupported();
|
|
400
441
|
if (Notification.permission !== 'granted') {
|
|
401
442
|
throw new Error('Notification permission required. Please grant notification access and try again.');
|
|
402
443
|
}
|
|
@@ -404,7 +445,7 @@ class NotificationService extends BrowserApiBaseService {
|
|
|
404
445
|
return new Notification(title, options);
|
|
405
446
|
}
|
|
406
447
|
catch (error) {
|
|
407
|
-
|
|
448
|
+
this.logError('Error showing notification:', error);
|
|
408
449
|
throw error;
|
|
409
450
|
}
|
|
410
451
|
}
|
|
@@ -419,44 +460,29 @@ class ClipboardService extends BrowserApiBaseService {
|
|
|
419
460
|
getApiName() {
|
|
420
461
|
return 'clipboard';
|
|
421
462
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
const permissionStatus = await this.permissionsService.query({
|
|
427
|
-
name: `clipboard-${action}`,
|
|
428
|
-
});
|
|
429
|
-
if (permissionStatus.state !== 'granted') {
|
|
430
|
-
throw new Error(`Clipboard ${action} permission required. Please grant clipboard access and try again.`);
|
|
463
|
+
ensureSupported() {
|
|
464
|
+
super.ensureSupported();
|
|
465
|
+
if (!navigator.clipboard) {
|
|
466
|
+
throw new Error('Clipboard API not supported \u2014 a secure context (HTTPS) is required');
|
|
431
467
|
}
|
|
432
468
|
}
|
|
433
469
|
async writeText(text) {
|
|
434
|
-
|
|
470
|
+
this.ensureSupported();
|
|
435
471
|
try {
|
|
436
472
|
await navigator.clipboard.writeText(text);
|
|
437
473
|
}
|
|
438
474
|
catch (error) {
|
|
439
|
-
|
|
475
|
+
this.logError('Error writing to clipboard:', error);
|
|
440
476
|
throw error;
|
|
441
477
|
}
|
|
442
478
|
}
|
|
443
479
|
async readText() {
|
|
444
|
-
|
|
480
|
+
this.ensureSupported();
|
|
445
481
|
try {
|
|
446
482
|
return await navigator.clipboard.readText();
|
|
447
483
|
}
|
|
448
484
|
catch (error) {
|
|
449
|
-
|
|
450
|
-
throw error;
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
async writeTextSecure(text) {
|
|
454
|
-
await this.ensureClipboardPermission('write');
|
|
455
|
-
try {
|
|
456
|
-
await navigator.clipboard.writeText(text);
|
|
457
|
-
}
|
|
458
|
-
catch (error) {
|
|
459
|
-
console.error('[ClipboardService] Error writing to clipboard:', error);
|
|
485
|
+
this.logError('Error reading from clipboard:', error);
|
|
460
486
|
throw error;
|
|
461
487
|
}
|
|
462
488
|
}
|
|
@@ -628,23 +654,23 @@ class BatteryService extends BrowserApiBaseService {
|
|
|
628
654
|
getApiName() {
|
|
629
655
|
return 'battery';
|
|
630
656
|
}
|
|
631
|
-
|
|
657
|
+
ensureSupported() {
|
|
658
|
+
super.ensureSupported();
|
|
632
659
|
const nav = navigator;
|
|
633
660
|
if (!('getBattery' in nav)) {
|
|
634
|
-
throw new Error('Battery API not supported in this browser');
|
|
661
|
+
throw new Error('Battery Status API not supported in this browser');
|
|
635
662
|
}
|
|
636
663
|
}
|
|
637
664
|
async initialize() {
|
|
638
|
-
this.
|
|
665
|
+
this.ensureSupported();
|
|
639
666
|
try {
|
|
640
667
|
const nav = navigator;
|
|
641
668
|
this.batteryManager = await nav.getBattery();
|
|
642
669
|
const batteryInfo = this.getBatteryInfo();
|
|
643
|
-
this.setupEventListeners();
|
|
644
670
|
return batteryInfo;
|
|
645
671
|
}
|
|
646
672
|
catch (error) {
|
|
647
|
-
|
|
673
|
+
this.logError('Error initializing battery API:', error);
|
|
648
674
|
throw this.createError('Failed to initialize battery API', error);
|
|
649
675
|
}
|
|
650
676
|
}
|
|
@@ -683,16 +709,6 @@ class BatteryService extends BrowserApiBaseService {
|
|
|
683
709
|
};
|
|
684
710
|
});
|
|
685
711
|
}
|
|
686
|
-
setupEventListeners() {
|
|
687
|
-
if (!this.batteryManager)
|
|
688
|
-
return;
|
|
689
|
-
this.batteryManager.addEventListener('chargingchange', () => {
|
|
690
|
-
console.log('[BatteryService] Charging status changed:', this.batteryManager.charging);
|
|
691
|
-
});
|
|
692
|
-
this.batteryManager.addEventListener('levelchange', () => {
|
|
693
|
-
console.log('[BatteryService] Battery level changed:', this.batteryManager.level);
|
|
694
|
-
});
|
|
695
|
-
}
|
|
696
712
|
// Direct access to native battery API
|
|
697
713
|
getNativeBatteryManager() {
|
|
698
714
|
if (!this.batteryManager) {
|
|
@@ -723,19 +739,20 @@ class WebShareService extends BrowserApiBaseService {
|
|
|
723
739
|
getApiName() {
|
|
724
740
|
return 'web-share';
|
|
725
741
|
}
|
|
726
|
-
|
|
742
|
+
ensureSupported() {
|
|
743
|
+
super.ensureSupported();
|
|
727
744
|
if (!('share' in navigator)) {
|
|
728
745
|
throw new Error('Web Share API not supported in this browser');
|
|
729
746
|
}
|
|
730
747
|
}
|
|
731
748
|
async share(data) {
|
|
732
|
-
this.
|
|
749
|
+
this.ensureSupported();
|
|
733
750
|
try {
|
|
734
751
|
await navigator.share(data);
|
|
735
752
|
return { shared: true };
|
|
736
753
|
}
|
|
737
754
|
catch (error) {
|
|
738
|
-
|
|
755
|
+
this.logError('Error sharing:', error);
|
|
739
756
|
const errorMessage = error instanceof Error ? error.message : 'Share failed';
|
|
740
757
|
return { shared: false, error: errorMessage };
|
|
741
758
|
}
|
|
@@ -752,7 +769,7 @@ class WebShareService extends BrowserApiBaseService {
|
|
|
752
769
|
}
|
|
753
770
|
// Direct access to native share API
|
|
754
771
|
getNativeShare() {
|
|
755
|
-
this.
|
|
772
|
+
this.ensureSupported();
|
|
756
773
|
return navigator.share;
|
|
757
774
|
}
|
|
758
775
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebShareService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -764,7 +781,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
764
781
|
|
|
765
782
|
class WebStorageService extends BrowserApiBaseService {
|
|
766
783
|
storageEvents = signal(null, ...(ngDevMode ? [{ debugName: "storageEvents" }] : /* istanbul ignore next */ []));
|
|
767
|
-
destroyRef = inject(DestroyRef);
|
|
768
784
|
constructor() {
|
|
769
785
|
super();
|
|
770
786
|
this.setupEventListeners();
|
|
@@ -772,8 +788,9 @@ class WebStorageService extends BrowserApiBaseService {
|
|
|
772
788
|
getApiName() {
|
|
773
789
|
return 'storage';
|
|
774
790
|
}
|
|
775
|
-
|
|
776
|
-
|
|
791
|
+
ensureSupported() {
|
|
792
|
+
super.ensureSupported();
|
|
793
|
+
if (typeof Storage === 'undefined') {
|
|
777
794
|
throw new Error('Storage API not supported in this browser');
|
|
778
795
|
}
|
|
779
796
|
}
|
|
@@ -783,14 +800,13 @@ class WebStorageService extends BrowserApiBaseService {
|
|
|
783
800
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
784
801
|
.subscribe((event) => {
|
|
785
802
|
const storageEvent = event;
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
}
|
|
803
|
+
const area = storageEvent.storageArea === localStorage ? 'localStorage' : 'sessionStorage';
|
|
804
|
+
this.storageEvents.set({
|
|
805
|
+
key: storageEvent.key,
|
|
806
|
+
newValue: storageEvent.newValue ? this.deserializeValue(storageEvent.newValue) : null,
|
|
807
|
+
oldValue: storageEvent.oldValue ? this.deserializeValue(storageEvent.oldValue) : null,
|
|
808
|
+
storageArea: area,
|
|
809
|
+
});
|
|
794
810
|
});
|
|
795
811
|
}
|
|
796
812
|
}
|
|
@@ -817,50 +833,58 @@ class WebStorageService extends BrowserApiBaseService {
|
|
|
817
833
|
const prefix = options?.prefix || '';
|
|
818
834
|
return prefix ? `${prefix}:${key}` : key;
|
|
819
835
|
}
|
|
836
|
+
emitStorageChange(fullKey, newValue, oldValue, area) {
|
|
837
|
+
this.storageEvents.set({ key: fullKey, newValue, oldValue, storageArea: area });
|
|
838
|
+
}
|
|
820
839
|
// Local Storage Methods
|
|
821
840
|
setLocalStorage(key, value, options = {}) {
|
|
822
|
-
this.
|
|
841
|
+
this.ensureSupported();
|
|
823
842
|
try {
|
|
824
843
|
const serializedValue = this.serializeValue(value, options);
|
|
825
844
|
const fullKey = this.getKey(key, options);
|
|
845
|
+
const oldRaw = localStorage.getItem(fullKey);
|
|
846
|
+
const oldValue = oldRaw !== null ? this.deserializeValue(oldRaw, options) : null;
|
|
826
847
|
localStorage.setItem(fullKey, serializedValue);
|
|
848
|
+
this.emitStorageChange(fullKey, value, oldValue, 'localStorage');
|
|
827
849
|
return true;
|
|
828
850
|
}
|
|
829
851
|
catch (error) {
|
|
830
|
-
|
|
852
|
+
this.logError('Error setting localStorage:', error);
|
|
831
853
|
return false;
|
|
832
854
|
}
|
|
833
855
|
}
|
|
834
856
|
getLocalStorage(key, defaultValue = null, options = {}) {
|
|
835
|
-
this.
|
|
857
|
+
this.ensureSupported();
|
|
836
858
|
try {
|
|
837
859
|
const fullKey = this.getKey(key, options);
|
|
838
860
|
const value = localStorage.getItem(fullKey);
|
|
839
861
|
return value !== null ? this.deserializeValue(value, options) : defaultValue;
|
|
840
862
|
}
|
|
841
863
|
catch (error) {
|
|
842
|
-
|
|
864
|
+
this.logError('Error getting localStorage:', error);
|
|
843
865
|
return defaultValue;
|
|
844
866
|
}
|
|
845
867
|
}
|
|
846
868
|
removeLocalStorage(key, options = {}) {
|
|
847
|
-
this.
|
|
869
|
+
this.ensureSupported();
|
|
848
870
|
try {
|
|
849
871
|
const fullKey = this.getKey(key, options);
|
|
872
|
+
const oldRaw = localStorage.getItem(fullKey);
|
|
873
|
+
const oldValue = oldRaw !== null ? this.deserializeValue(oldRaw, options) : null;
|
|
850
874
|
localStorage.removeItem(fullKey);
|
|
875
|
+
this.emitStorageChange(fullKey, null, oldValue, 'localStorage');
|
|
851
876
|
return true;
|
|
852
877
|
}
|
|
853
878
|
catch (error) {
|
|
854
|
-
|
|
879
|
+
this.logError('Error removing localStorage:', error);
|
|
855
880
|
return false;
|
|
856
881
|
}
|
|
857
882
|
}
|
|
858
883
|
clearLocalStorage(options = {}) {
|
|
859
|
-
this.
|
|
884
|
+
this.ensureSupported();
|
|
860
885
|
try {
|
|
861
886
|
const prefix = options?.prefix;
|
|
862
887
|
if (prefix) {
|
|
863
|
-
// Only remove keys with the specified prefix
|
|
864
888
|
const keysToRemove = [];
|
|
865
889
|
for (let i = 0; i < localStorage.length; i++) {
|
|
866
890
|
const key = localStorage.key(i);
|
|
@@ -868,62 +892,72 @@ class WebStorageService extends BrowserApiBaseService {
|
|
|
868
892
|
keysToRemove.push(key);
|
|
869
893
|
}
|
|
870
894
|
}
|
|
871
|
-
keysToRemove.forEach((key) =>
|
|
895
|
+
keysToRemove.forEach((key) => {
|
|
896
|
+
const oldRaw = localStorage.getItem(key);
|
|
897
|
+
localStorage.removeItem(key);
|
|
898
|
+
this.emitStorageChange(key, null, oldRaw, 'localStorage');
|
|
899
|
+
});
|
|
872
900
|
}
|
|
873
901
|
else {
|
|
874
902
|
localStorage.clear();
|
|
903
|
+
this.emitStorageChange(null, null, null, 'localStorage');
|
|
875
904
|
}
|
|
876
905
|
return true;
|
|
877
906
|
}
|
|
878
907
|
catch (error) {
|
|
879
|
-
|
|
908
|
+
this.logError('Error clearing localStorage:', error);
|
|
880
909
|
return false;
|
|
881
910
|
}
|
|
882
911
|
}
|
|
883
912
|
// Session Storage Methods
|
|
884
913
|
setSessionStorage(key, value, options = {}) {
|
|
885
|
-
this.
|
|
914
|
+
this.ensureSupported();
|
|
886
915
|
try {
|
|
887
916
|
const serializedValue = this.serializeValue(value, options);
|
|
888
917
|
const fullKey = this.getKey(key, options);
|
|
918
|
+
const oldRaw = sessionStorage.getItem(fullKey);
|
|
919
|
+
const oldValue = oldRaw !== null ? this.deserializeValue(oldRaw, options) : null;
|
|
889
920
|
sessionStorage.setItem(fullKey, serializedValue);
|
|
921
|
+
this.emitStorageChange(fullKey, value, oldValue, 'sessionStorage');
|
|
890
922
|
return true;
|
|
891
923
|
}
|
|
892
924
|
catch (error) {
|
|
893
|
-
|
|
925
|
+
this.logError('Error setting sessionStorage:', error);
|
|
894
926
|
return false;
|
|
895
927
|
}
|
|
896
928
|
}
|
|
897
929
|
getSessionStorage(key, defaultValue = null, options = {}) {
|
|
898
|
-
this.
|
|
930
|
+
this.ensureSupported();
|
|
899
931
|
try {
|
|
900
932
|
const fullKey = this.getKey(key, options);
|
|
901
933
|
const value = sessionStorage.getItem(fullKey);
|
|
902
934
|
return value !== null ? this.deserializeValue(value, options) : defaultValue;
|
|
903
935
|
}
|
|
904
936
|
catch (error) {
|
|
905
|
-
|
|
937
|
+
this.logError('Error getting sessionStorage:', error);
|
|
906
938
|
return defaultValue;
|
|
907
939
|
}
|
|
908
940
|
}
|
|
909
941
|
removeSessionStorage(key, options = {}) {
|
|
910
|
-
this.
|
|
942
|
+
this.ensureSupported();
|
|
911
943
|
try {
|
|
912
944
|
const fullKey = this.getKey(key, options);
|
|
945
|
+
const oldRaw = sessionStorage.getItem(fullKey);
|
|
946
|
+
const oldValue = oldRaw !== null ? this.deserializeValue(oldRaw, options) : null;
|
|
913
947
|
sessionStorage.removeItem(fullKey);
|
|
948
|
+
this.emitStorageChange(fullKey, null, oldValue, 'sessionStorage');
|
|
914
949
|
return true;
|
|
915
950
|
}
|
|
916
951
|
catch (error) {
|
|
917
|
-
|
|
952
|
+
this.logError('Error removing sessionStorage:', error);
|
|
918
953
|
return false;
|
|
919
954
|
}
|
|
920
955
|
}
|
|
921
956
|
clearSessionStorage(options = {}) {
|
|
922
|
-
this.
|
|
957
|
+
this.ensureSupported();
|
|
923
958
|
try {
|
|
924
959
|
const prefix = options?.prefix;
|
|
925
960
|
if (prefix) {
|
|
926
|
-
// Only remove keys with the specified prefix
|
|
927
961
|
const keysToRemove = [];
|
|
928
962
|
for (let i = 0; i < sessionStorage.length; i++) {
|
|
929
963
|
const key = sessionStorage.key(i);
|
|
@@ -931,21 +965,26 @@ class WebStorageService extends BrowserApiBaseService {
|
|
|
931
965
|
keysToRemove.push(key);
|
|
932
966
|
}
|
|
933
967
|
}
|
|
934
|
-
keysToRemove.forEach((key) =>
|
|
968
|
+
keysToRemove.forEach((key) => {
|
|
969
|
+
const oldRaw = sessionStorage.getItem(key);
|
|
970
|
+
sessionStorage.removeItem(key);
|
|
971
|
+
this.emitStorageChange(key, null, oldRaw, 'sessionStorage');
|
|
972
|
+
});
|
|
935
973
|
}
|
|
936
974
|
else {
|
|
937
975
|
sessionStorage.clear();
|
|
976
|
+
this.emitStorageChange(null, null, null, 'sessionStorage');
|
|
938
977
|
}
|
|
939
978
|
return true;
|
|
940
979
|
}
|
|
941
980
|
catch (error) {
|
|
942
|
-
|
|
981
|
+
this.logError('Error clearing sessionStorage:', error);
|
|
943
982
|
return false;
|
|
944
983
|
}
|
|
945
984
|
}
|
|
946
985
|
// Utility Methods
|
|
947
986
|
getLocalStorageSize(options = {}) {
|
|
948
|
-
this.
|
|
987
|
+
this.ensureSupported();
|
|
949
988
|
let totalSize = 0;
|
|
950
989
|
const prefix = options?.prefix;
|
|
951
990
|
for (let i = 0; i < localStorage.length; i++) {
|
|
@@ -957,7 +996,7 @@ class WebStorageService extends BrowserApiBaseService {
|
|
|
957
996
|
return totalSize;
|
|
958
997
|
}
|
|
959
998
|
getSessionStorageSize(options = {}) {
|
|
960
|
-
this.
|
|
999
|
+
this.ensureSupported();
|
|
961
1000
|
let totalSize = 0;
|
|
962
1001
|
const prefix = options?.prefix;
|
|
963
1002
|
for (let i = 0; i < sessionStorage.length; i++) {
|
|
@@ -974,30 +1013,20 @@ class WebStorageService extends BrowserApiBaseService {
|
|
|
974
1013
|
prev.oldValue === curr.oldValue));
|
|
975
1014
|
}
|
|
976
1015
|
watchLocalStorage(key, options = {}) {
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
if (event.key === fullKey && event.storageArea === 'localStorage') {
|
|
980
|
-
return event.newValue;
|
|
981
|
-
}
|
|
982
|
-
return this.getLocalStorage(key, null, options);
|
|
983
|
-
}));
|
|
1016
|
+
const fullKey = this.getKey(key, options);
|
|
1017
|
+
return this.getStorageEvents().pipe(filter((event) => event.storageArea === 'localStorage' && (event.key === null || event.key === fullKey)), map((event) => event.newValue));
|
|
984
1018
|
}
|
|
985
1019
|
watchSessionStorage(key, options = {}) {
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
if (event.key === fullKey && event.storageArea === 'sessionStorage') {
|
|
989
|
-
return event.newValue;
|
|
990
|
-
}
|
|
991
|
-
return this.getSessionStorage(key, null, options);
|
|
992
|
-
}));
|
|
1020
|
+
const fullKey = this.getKey(key, options);
|
|
1021
|
+
return this.getStorageEvents().pipe(filter((event) => event.storageArea === 'sessionStorage' && (event.key === null || event.key === fullKey)), map((event) => event.newValue));
|
|
993
1022
|
}
|
|
994
1023
|
// Direct access to native storage APIs
|
|
995
1024
|
getNativeLocalStorage() {
|
|
996
|
-
this.
|
|
1025
|
+
this.ensureSupported();
|
|
997
1026
|
return localStorage;
|
|
998
1027
|
}
|
|
999
1028
|
getNativeSessionStorage() {
|
|
1000
|
-
this.
|
|
1029
|
+
this.ensureSupported();
|
|
1001
1030
|
return sessionStorage;
|
|
1002
1031
|
}
|
|
1003
1032
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -1009,21 +1038,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
1009
1038
|
|
|
1010
1039
|
class WebSocketService extends BrowserApiBaseService {
|
|
1011
1040
|
webSocket = null;
|
|
1012
|
-
statusSubject = new
|
|
1041
|
+
statusSubject = new BehaviorSubject({
|
|
1042
|
+
connected: false,
|
|
1043
|
+
connecting: false,
|
|
1044
|
+
reconnecting: false,
|
|
1045
|
+
reconnectAttempts: 0,
|
|
1046
|
+
});
|
|
1013
1047
|
messageSubject = new Subject();
|
|
1014
1048
|
reconnectAttempts = 0;
|
|
1015
1049
|
reconnectTimer = null;
|
|
1016
1050
|
heartbeatTimer = null;
|
|
1051
|
+
_cleanup = this.destroyRef.onDestroy(() => this.disconnect());
|
|
1017
1052
|
getApiName() {
|
|
1018
1053
|
return 'websocket';
|
|
1019
1054
|
}
|
|
1020
|
-
|
|
1055
|
+
ensureSupported() {
|
|
1056
|
+
super.ensureSupported();
|
|
1021
1057
|
if (typeof WebSocket === 'undefined') {
|
|
1022
1058
|
throw new Error('WebSocket API not supported in this browser');
|
|
1023
1059
|
}
|
|
1024
1060
|
}
|
|
1025
1061
|
connect(config) {
|
|
1026
|
-
this.
|
|
1062
|
+
this.ensureSupported();
|
|
1027
1063
|
return new Observable((observer) => {
|
|
1028
1064
|
this.disconnect(); // Disconnect existing connection if any
|
|
1029
1065
|
this.updateStatus({
|
|
@@ -1035,10 +1071,10 @@ class WebSocketService extends BrowserApiBaseService {
|
|
|
1035
1071
|
try {
|
|
1036
1072
|
this.webSocket = new WebSocket(config.url, config.protocols);
|
|
1037
1073
|
this.setupWebSocketHandlers(config);
|
|
1038
|
-
observer.next(this.
|
|
1074
|
+
observer.next(this.statusSubject.getValue());
|
|
1039
1075
|
}
|
|
1040
1076
|
catch (error) {
|
|
1041
|
-
|
|
1077
|
+
this.logError('Error creating WebSocket:', error);
|
|
1042
1078
|
this.updateStatus({
|
|
1043
1079
|
connected: false,
|
|
1044
1080
|
connecting: false,
|
|
@@ -1046,7 +1082,7 @@ class WebSocketService extends BrowserApiBaseService {
|
|
|
1046
1082
|
error: error instanceof Error ? error.message : 'Connection failed',
|
|
1047
1083
|
reconnectAttempts: 0,
|
|
1048
1084
|
});
|
|
1049
|
-
observer.next(this.
|
|
1085
|
+
observer.next(this.statusSubject.getValue());
|
|
1050
1086
|
}
|
|
1051
1087
|
return () => {
|
|
1052
1088
|
this.disconnect();
|
|
@@ -1093,15 +1129,18 @@ class WebSocketService extends BrowserApiBaseService {
|
|
|
1093
1129
|
return this.statusSubject.asObservable();
|
|
1094
1130
|
}
|
|
1095
1131
|
getMessages() {
|
|
1132
|
+
return this.messageSubject.asObservable();
|
|
1133
|
+
}
|
|
1134
|
+
getMessagesByType(type) {
|
|
1096
1135
|
return this.messageSubject
|
|
1097
1136
|
.asObservable()
|
|
1098
|
-
.pipe(filter((msg) =>
|
|
1137
|
+
.pipe(filter((msg) => msg.type === type));
|
|
1099
1138
|
}
|
|
1100
1139
|
setupWebSocketHandlers(config) {
|
|
1101
1140
|
if (!this.webSocket)
|
|
1102
1141
|
return;
|
|
1103
1142
|
this.webSocket.onopen = () => {
|
|
1104
|
-
|
|
1143
|
+
this.logInfo(`Connected to: ${config.url}`);
|
|
1105
1144
|
this.reconnectAttempts = 0;
|
|
1106
1145
|
this.updateStatus({
|
|
1107
1146
|
connected: true,
|
|
@@ -1115,7 +1154,7 @@ class WebSocketService extends BrowserApiBaseService {
|
|
|
1115
1154
|
}
|
|
1116
1155
|
};
|
|
1117
1156
|
this.webSocket.onclose = (event) => {
|
|
1118
|
-
|
|
1157
|
+
this.logInfo(`Connection closed: ${event.code} ${event.reason}`);
|
|
1119
1158
|
this.updateStatus({
|
|
1120
1159
|
connected: false,
|
|
1121
1160
|
connecting: false,
|
|
@@ -1128,7 +1167,7 @@ class WebSocketService extends BrowserApiBaseService {
|
|
|
1128
1167
|
}
|
|
1129
1168
|
};
|
|
1130
1169
|
this.webSocket.onerror = (error) => {
|
|
1131
|
-
|
|
1170
|
+
this.logError('WebSocket error:', error);
|
|
1132
1171
|
this.updateStatus({
|
|
1133
1172
|
connected: false,
|
|
1134
1173
|
connecting: false,
|
|
@@ -1143,7 +1182,7 @@ class WebSocketService extends BrowserApiBaseService {
|
|
|
1143
1182
|
this.messageSubject.next(message);
|
|
1144
1183
|
}
|
|
1145
1184
|
catch (error) {
|
|
1146
|
-
|
|
1185
|
+
this.logError('Error parsing message:', error);
|
|
1147
1186
|
}
|
|
1148
1187
|
};
|
|
1149
1188
|
}
|
|
@@ -1159,7 +1198,7 @@ class WebSocketService extends BrowserApiBaseService {
|
|
|
1159
1198
|
}
|
|
1160
1199
|
attemptReconnect(config) {
|
|
1161
1200
|
if (this.reconnectAttempts >= (config.maxReconnectAttempts || 5)) {
|
|
1162
|
-
|
|
1201
|
+
this.logInfo('Max reconnect attempts reached');
|
|
1163
1202
|
return;
|
|
1164
1203
|
}
|
|
1165
1204
|
this.reconnectAttempts++;
|
|
@@ -1170,23 +1209,14 @@ class WebSocketService extends BrowserApiBaseService {
|
|
|
1170
1209
|
reconnectAttempts: this.reconnectAttempts,
|
|
1171
1210
|
});
|
|
1172
1211
|
this.reconnectTimer = setTimeout(() => {
|
|
1173
|
-
|
|
1212
|
+
this.logInfo(`Reconnect attempt ${this.reconnectAttempts}`);
|
|
1174
1213
|
this.connect(config);
|
|
1175
1214
|
}, config.reconnectInterval || 3000);
|
|
1176
1215
|
}
|
|
1177
1216
|
updateStatus(status) {
|
|
1178
|
-
const
|
|
1179
|
-
const newStatus = { ...currentStatus, ...status };
|
|
1217
|
+
const newStatus = { ...this.statusSubject.getValue(), ...status };
|
|
1180
1218
|
this.statusSubject.next(newStatus);
|
|
1181
1219
|
}
|
|
1182
|
-
getCurrentStatus() {
|
|
1183
|
-
return {
|
|
1184
|
-
connected: this.webSocket?.readyState === WebSocket.OPEN,
|
|
1185
|
-
connecting: false,
|
|
1186
|
-
reconnecting: false,
|
|
1187
|
-
reconnectAttempts: this.reconnectAttempts,
|
|
1188
|
-
};
|
|
1189
|
-
}
|
|
1190
1220
|
// Direct access to native WebSocket
|
|
1191
1221
|
getNativeWebSocket() {
|
|
1192
1222
|
return this.webSocket;
|
|
@@ -1205,21 +1235,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
1205
1235
|
}] });
|
|
1206
1236
|
|
|
1207
1237
|
class WebWorkerService extends BrowserApiBaseService {
|
|
1208
|
-
destroyRef = inject(DestroyRef);
|
|
1209
1238
|
workers = new Map();
|
|
1210
1239
|
workerStatuses = new Map();
|
|
1211
1240
|
workerMessages = new Map();
|
|
1212
1241
|
currentWorkerStatuses = new Map();
|
|
1242
|
+
_cleanup = this.destroyRef.onDestroy(() => this.terminateAllWorkers());
|
|
1213
1243
|
getApiName() {
|
|
1214
1244
|
return 'webworker';
|
|
1215
1245
|
}
|
|
1216
|
-
|
|
1246
|
+
ensureSupported() {
|
|
1247
|
+
super.ensureSupported();
|
|
1217
1248
|
if (typeof Worker === 'undefined') {
|
|
1218
1249
|
throw new Error('Web Workers not supported in this browser');
|
|
1219
1250
|
}
|
|
1220
1251
|
}
|
|
1221
1252
|
createWorker(name, scriptUrl) {
|
|
1222
|
-
this.
|
|
1253
|
+
this.ensureSupported();
|
|
1223
1254
|
return new Observable((observer) => {
|
|
1224
1255
|
if (this.workers.has(name)) {
|
|
1225
1256
|
observer.next(this.currentWorkerStatuses.get(name));
|
|
@@ -1241,7 +1272,7 @@ class WebWorkerService extends BrowserApiBaseService {
|
|
|
1241
1272
|
observer.next(status);
|
|
1242
1273
|
}
|
|
1243
1274
|
catch (error) {
|
|
1244
|
-
|
|
1275
|
+
this.logError(`Failed to create worker ${name}:`, error);
|
|
1245
1276
|
const status = {
|
|
1246
1277
|
initialized: false,
|
|
1247
1278
|
running: false,
|
|
@@ -1275,7 +1306,7 @@ class WebWorkerService extends BrowserApiBaseService {
|
|
|
1275
1306
|
postMessage(workerName, task) {
|
|
1276
1307
|
const worker = this.workers.get(workerName);
|
|
1277
1308
|
if (!worker) {
|
|
1278
|
-
|
|
1309
|
+
this.logError(`Worker ${workerName} not found`);
|
|
1279
1310
|
return;
|
|
1280
1311
|
}
|
|
1281
1312
|
try {
|
|
@@ -1293,7 +1324,7 @@ class WebWorkerService extends BrowserApiBaseService {
|
|
|
1293
1324
|
}
|
|
1294
1325
|
}
|
|
1295
1326
|
catch (error) {
|
|
1296
|
-
|
|
1327
|
+
this.logError(`Failed to post message to worker ${workerName}:`, error);
|
|
1297
1328
|
}
|
|
1298
1329
|
}
|
|
1299
1330
|
getMessages(workerName) {
|
|
@@ -1332,7 +1363,7 @@ class WebWorkerService extends BrowserApiBaseService {
|
|
|
1332
1363
|
this.workerMessages.get(name).next(message);
|
|
1333
1364
|
};
|
|
1334
1365
|
worker.onerror = (error) => {
|
|
1335
|
-
|
|
1366
|
+
this.logError(`Worker ${name} error:`, error);
|
|
1336
1367
|
const status = {
|
|
1337
1368
|
initialized: true,
|
|
1338
1369
|
running: false,
|
|
@@ -1394,10 +1425,12 @@ function intersectionObserverEntriesStream(element, options = {}) {
|
|
|
1394
1425
|
});
|
|
1395
1426
|
}
|
|
1396
1427
|
|
|
1397
|
-
class IntersectionObserverService {
|
|
1398
|
-
|
|
1428
|
+
class IntersectionObserverService extends BrowserApiBaseService {
|
|
1429
|
+
getApiName() {
|
|
1430
|
+
return 'intersection-observer';
|
|
1431
|
+
}
|
|
1399
1432
|
isSupported() {
|
|
1400
|
-
return
|
|
1433
|
+
return this.isBrowserEnvironment() && 'IntersectionObserver' in window;
|
|
1401
1434
|
}
|
|
1402
1435
|
observe(element, options = {}) {
|
|
1403
1436
|
if (!this.isSupported()) {
|
|
@@ -1411,7 +1444,7 @@ class IntersectionObserverService {
|
|
|
1411
1444
|
}
|
|
1412
1445
|
return intersectionObserverStream(element, options);
|
|
1413
1446
|
}
|
|
1414
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: IntersectionObserverService, deps:
|
|
1447
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: IntersectionObserverService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
1415
1448
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: IntersectionObserverService });
|
|
1416
1449
|
}
|
|
1417
1450
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: IntersectionObserverService, decorators: [{
|
|
@@ -1452,10 +1485,12 @@ function resizeObserverEntriesStream(element, options = {}) {
|
|
|
1452
1485
|
});
|
|
1453
1486
|
}
|
|
1454
1487
|
|
|
1455
|
-
class ResizeObserverService {
|
|
1456
|
-
|
|
1488
|
+
class ResizeObserverService extends BrowserApiBaseService {
|
|
1489
|
+
getApiName() {
|
|
1490
|
+
return 'resize-observer';
|
|
1491
|
+
}
|
|
1457
1492
|
isSupported() {
|
|
1458
|
-
return
|
|
1493
|
+
return this.isBrowserEnvironment() && 'ResizeObserver' in window;
|
|
1459
1494
|
}
|
|
1460
1495
|
observe(element, options = {}) {
|
|
1461
1496
|
if (!this.isSupported()) {
|
|
@@ -1469,7 +1504,7 @@ class ResizeObserverService {
|
|
|
1469
1504
|
}
|
|
1470
1505
|
return resizeObserverStream(element, options);
|
|
1471
1506
|
}
|
|
1472
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ResizeObserverService, deps:
|
|
1507
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ResizeObserverService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
1473
1508
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ResizeObserverService });
|
|
1474
1509
|
}
|
|
1475
1510
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ResizeObserverService, decorators: [{
|
|
@@ -1491,10 +1526,12 @@ function pageVisibilityStream() {
|
|
|
1491
1526
|
});
|
|
1492
1527
|
}
|
|
1493
1528
|
|
|
1494
|
-
class PageVisibilityService {
|
|
1495
|
-
|
|
1529
|
+
class PageVisibilityService extends BrowserApiBaseService {
|
|
1530
|
+
getApiName() {
|
|
1531
|
+
return 'page-visibility';
|
|
1532
|
+
}
|
|
1496
1533
|
isSupported() {
|
|
1497
|
-
return
|
|
1534
|
+
return this.isBrowserEnvironment() && 'hidden' in document;
|
|
1498
1535
|
}
|
|
1499
1536
|
get isHidden() {
|
|
1500
1537
|
if (!this.isSupported())
|
|
@@ -1512,32 +1549,79 @@ class PageVisibilityService {
|
|
|
1512
1549
|
watchVisibility() {
|
|
1513
1550
|
return pageVisibilityStream().pipe(map$1((s) => s === 'visible'));
|
|
1514
1551
|
}
|
|
1515
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PageVisibilityService, deps:
|
|
1552
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PageVisibilityService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
1516
1553
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PageVisibilityService });
|
|
1517
1554
|
}
|
|
1518
1555
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PageVisibilityService, decorators: [{
|
|
1519
1556
|
type: Injectable
|
|
1520
1557
|
}] });
|
|
1521
1558
|
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1559
|
+
/**
|
|
1560
|
+
* Base class for services that manage a named registry of persistent
|
|
1561
|
+
* connections (e.g. BroadcastChannel, EventSource, WebSocket pools).
|
|
1562
|
+
*
|
|
1563
|
+
* Implements the Template Method pattern: subclasses define how a single
|
|
1564
|
+
* native connection is closed via `closeNativeConnection()`, while this
|
|
1565
|
+
* class handles the Map lifecycle (remove, closeAll, getActiveKeys).
|
|
1566
|
+
*
|
|
1567
|
+
* Public-facing method names (`close`, `disconnect`, `getOpenChannels`, etc.)
|
|
1568
|
+
* remain the responsibility of the concrete service to preserve the public API.
|
|
1569
|
+
*/
|
|
1570
|
+
class ConnectionRegistryBaseService extends BrowserApiBaseService {
|
|
1571
|
+
connections = new Map();
|
|
1572
|
+
/**
|
|
1573
|
+
* Remove and close the connection registered under `key`.
|
|
1574
|
+
* Safe to call even if the key does not exist.
|
|
1575
|
+
*/
|
|
1576
|
+
removeConnection(key) {
|
|
1577
|
+
const connection = this.connections.get(key);
|
|
1578
|
+
if (connection) {
|
|
1579
|
+
this.closeNativeConnection(connection);
|
|
1580
|
+
this.connections.delete(key);
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
/**
|
|
1584
|
+
* Close all registered connections and clear the registry.
|
|
1585
|
+
*/
|
|
1586
|
+
closeAllConnections() {
|
|
1587
|
+
this.connections.forEach((connection) => this.closeNativeConnection(connection));
|
|
1588
|
+
this.connections.clear();
|
|
1589
|
+
}
|
|
1590
|
+
/**
|
|
1591
|
+
* Return the keys of all currently open connections.
|
|
1592
|
+
*/
|
|
1593
|
+
getConnectionKeys() {
|
|
1594
|
+
return Array.from(this.connections.keys());
|
|
1595
|
+
}
|
|
1596
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ConnectionRegistryBaseService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
1597
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ConnectionRegistryBaseService });
|
|
1598
|
+
}
|
|
1599
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ConnectionRegistryBaseService, decorators: [{
|
|
1600
|
+
type: Injectable
|
|
1601
|
+
}] });
|
|
1602
|
+
|
|
1603
|
+
class BroadcastChannelService extends ConnectionRegistryBaseService {
|
|
1604
|
+
getApiName() {
|
|
1605
|
+
return 'broadcast-channel';
|
|
1606
|
+
}
|
|
1607
|
+
closeNativeConnection(channel) {
|
|
1608
|
+
channel.close();
|
|
1609
|
+
}
|
|
1526
1610
|
isSupported() {
|
|
1527
|
-
return
|
|
1611
|
+
return this.isBrowserEnvironment() && 'BroadcastChannel' in window;
|
|
1528
1612
|
}
|
|
1529
|
-
|
|
1613
|
+
ensureBroadcastChannelSupported() {
|
|
1530
1614
|
if (!this.isSupported()) {
|
|
1531
1615
|
throw new Error('BroadcastChannel API not supported in this environment');
|
|
1532
1616
|
}
|
|
1533
1617
|
}
|
|
1534
1618
|
open(name) {
|
|
1535
|
-
this.
|
|
1619
|
+
this.ensureBroadcastChannelSupported();
|
|
1536
1620
|
return new Observable((observer) => {
|
|
1537
|
-
let channel = this.
|
|
1621
|
+
let channel = this.connections.get(name);
|
|
1538
1622
|
if (!channel) {
|
|
1539
1623
|
channel = new BroadcastChannel(name);
|
|
1540
|
-
this.
|
|
1624
|
+
this.connections.set(name, channel);
|
|
1541
1625
|
}
|
|
1542
1626
|
const handler = (event) => observer.next(event.data);
|
|
1543
1627
|
const errorHandler = () => observer.error(new Error(`BroadcastChannel "${name}" error`));
|
|
@@ -1552,30 +1636,25 @@ class BroadcastChannelService {
|
|
|
1552
1636
|
});
|
|
1553
1637
|
}
|
|
1554
1638
|
post(name, data) {
|
|
1555
|
-
this.
|
|
1556
|
-
let channel = this.
|
|
1639
|
+
this.ensureBroadcastChannelSupported();
|
|
1640
|
+
let channel = this.connections.get(name);
|
|
1557
1641
|
if (!channel) {
|
|
1558
1642
|
channel = new BroadcastChannel(name);
|
|
1559
|
-
this.
|
|
1643
|
+
this.connections.set(name, channel);
|
|
1560
1644
|
this.destroyRef.onDestroy(() => this.close(name));
|
|
1561
1645
|
}
|
|
1562
1646
|
channel.postMessage(data);
|
|
1563
1647
|
}
|
|
1564
1648
|
close(name) {
|
|
1565
|
-
|
|
1566
|
-
if (channel) {
|
|
1567
|
-
channel.close();
|
|
1568
|
-
this.channels.delete(name);
|
|
1569
|
-
}
|
|
1649
|
+
this.removeConnection(name);
|
|
1570
1650
|
}
|
|
1571
1651
|
closeAll() {
|
|
1572
|
-
this.
|
|
1573
|
-
this.channels.clear();
|
|
1652
|
+
this.closeAllConnections();
|
|
1574
1653
|
}
|
|
1575
1654
|
getOpenChannels() {
|
|
1576
|
-
return
|
|
1655
|
+
return this.getConnectionKeys();
|
|
1577
1656
|
}
|
|
1578
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BroadcastChannelService, deps:
|
|
1657
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BroadcastChannelService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
1579
1658
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BroadcastChannelService });
|
|
1580
1659
|
}
|
|
1581
1660
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BroadcastChannelService, decorators: [{
|
|
@@ -1627,21 +1706,23 @@ function networkInformationStream() {
|
|
|
1627
1706
|
});
|
|
1628
1707
|
}
|
|
1629
1708
|
|
|
1630
|
-
class NetworkInformationService {
|
|
1631
|
-
|
|
1709
|
+
class NetworkInformationService extends BrowserApiBaseService {
|
|
1710
|
+
getApiName() {
|
|
1711
|
+
return 'network-information';
|
|
1712
|
+
}
|
|
1632
1713
|
isSupported() {
|
|
1633
|
-
return
|
|
1714
|
+
return this.isBrowserEnvironment() && isNetworkInformationSupported();
|
|
1634
1715
|
}
|
|
1635
1716
|
getSnapshot() {
|
|
1636
|
-
return
|
|
1717
|
+
return this.isBrowserEnvironment() ? getNetworkSnapshot() : { online: true };
|
|
1637
1718
|
}
|
|
1638
1719
|
watch() {
|
|
1639
1720
|
return networkInformationStream();
|
|
1640
1721
|
}
|
|
1641
1722
|
get isOnline() {
|
|
1642
|
-
return
|
|
1723
|
+
return this.isBrowserEnvironment() ? navigator.onLine : true;
|
|
1643
1724
|
}
|
|
1644
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: NetworkInformationService, deps:
|
|
1725
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: NetworkInformationService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
1645
1726
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: NetworkInformationService });
|
|
1646
1727
|
}
|
|
1647
1728
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: NetworkInformationService, decorators: [{
|
|
@@ -1654,7 +1735,7 @@ class ScreenWakeLockService extends BrowserApiBaseService {
|
|
|
1654
1735
|
return 'screen-wake-lock';
|
|
1655
1736
|
}
|
|
1656
1737
|
isSupported() {
|
|
1657
|
-
return
|
|
1738
|
+
return this.isBrowserEnvironment() && 'wakeLock' in navigator;
|
|
1658
1739
|
}
|
|
1659
1740
|
get isActive() {
|
|
1660
1741
|
return this.sentinel !== null && !this.sentinel.released;
|
|
@@ -1675,7 +1756,7 @@ class ScreenWakeLockService extends BrowserApiBaseService {
|
|
|
1675
1756
|
return { active: true, type, released: false };
|
|
1676
1757
|
}
|
|
1677
1758
|
catch (error) {
|
|
1678
|
-
|
|
1759
|
+
this.logError('Failed to acquire wake lock:', error);
|
|
1679
1760
|
throw this.createError('Failed to acquire wake lock', error);
|
|
1680
1761
|
}
|
|
1681
1762
|
}
|
|
@@ -1744,13 +1825,15 @@ function screenOrientationStream() {
|
|
|
1744
1825
|
});
|
|
1745
1826
|
}
|
|
1746
1827
|
|
|
1747
|
-
class ScreenOrientationService {
|
|
1748
|
-
|
|
1828
|
+
class ScreenOrientationService extends BrowserApiBaseService {
|
|
1829
|
+
getApiName() {
|
|
1830
|
+
return 'screen-orientation';
|
|
1831
|
+
}
|
|
1749
1832
|
isSupported() {
|
|
1750
|
-
return
|
|
1833
|
+
return this.isBrowserEnvironment() && 'screen' in window && 'orientation' in screen;
|
|
1751
1834
|
}
|
|
1752
1835
|
getSnapshot() {
|
|
1753
|
-
return
|
|
1836
|
+
return this.isBrowserEnvironment()
|
|
1754
1837
|
? getOrientationSnapshot()
|
|
1755
1838
|
: { type: 'portrait-primary', angle: 0 };
|
|
1756
1839
|
}
|
|
@@ -1771,7 +1854,7 @@ class ScreenOrientationService {
|
|
|
1771
1854
|
await screen.orientation.lock(orientation);
|
|
1772
1855
|
}
|
|
1773
1856
|
catch (error) {
|
|
1774
|
-
|
|
1857
|
+
this.logError('Failed to lock orientation:', error);
|
|
1775
1858
|
throw error;
|
|
1776
1859
|
}
|
|
1777
1860
|
}
|
|
@@ -1780,30 +1863,31 @@ class ScreenOrientationService {
|
|
|
1780
1863
|
screen.orientation.unlock();
|
|
1781
1864
|
}
|
|
1782
1865
|
}
|
|
1783
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ScreenOrientationService, deps:
|
|
1866
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ScreenOrientationService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
1784
1867
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ScreenOrientationService });
|
|
1785
1868
|
}
|
|
1786
1869
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ScreenOrientationService, decorators: [{
|
|
1787
1870
|
type: Injectable
|
|
1788
1871
|
}] });
|
|
1789
1872
|
|
|
1790
|
-
class FullscreenService {
|
|
1791
|
-
|
|
1792
|
-
|
|
1873
|
+
class FullscreenService extends BrowserApiBaseService {
|
|
1874
|
+
getApiName() {
|
|
1875
|
+
return 'fullscreen';
|
|
1876
|
+
}
|
|
1793
1877
|
isSupported() {
|
|
1794
|
-
if (!
|
|
1878
|
+
if (!this.isBrowserEnvironment())
|
|
1795
1879
|
return false;
|
|
1796
1880
|
return !!(document.fullscreenEnabled ??
|
|
1797
1881
|
document.webkitFullscreenEnabled);
|
|
1798
1882
|
}
|
|
1799
1883
|
get isFullscreen() {
|
|
1800
|
-
if (!
|
|
1884
|
+
if (!this.isBrowserEnvironment())
|
|
1801
1885
|
return false;
|
|
1802
1886
|
return !!(document.fullscreenElement ??
|
|
1803
1887
|
document.webkitFullscreenElement);
|
|
1804
1888
|
}
|
|
1805
1889
|
get fullscreenElement() {
|
|
1806
|
-
if (!
|
|
1890
|
+
if (!this.isBrowserEnvironment())
|
|
1807
1891
|
return null;
|
|
1808
1892
|
return (document.fullscreenElement ??
|
|
1809
1893
|
document.webkitFullscreenElement ??
|
|
@@ -1823,7 +1907,7 @@ class FullscreenService {
|
|
|
1823
1907
|
}
|
|
1824
1908
|
}
|
|
1825
1909
|
catch (error) {
|
|
1826
|
-
|
|
1910
|
+
this.logError('Failed to enter fullscreen:', error);
|
|
1827
1911
|
throw error;
|
|
1828
1912
|
}
|
|
1829
1913
|
}
|
|
@@ -1840,7 +1924,7 @@ class FullscreenService {
|
|
|
1840
1924
|
}
|
|
1841
1925
|
}
|
|
1842
1926
|
catch (error) {
|
|
1843
|
-
|
|
1927
|
+
this.logError('Failed to exit fullscreen:', error);
|
|
1844
1928
|
throw error;
|
|
1845
1929
|
}
|
|
1846
1930
|
}
|
|
@@ -1854,7 +1938,7 @@ class FullscreenService {
|
|
|
1854
1938
|
}
|
|
1855
1939
|
watch() {
|
|
1856
1940
|
return new Observable((observer) => {
|
|
1857
|
-
if (!
|
|
1941
|
+
if (!this.isBrowserEnvironment()) {
|
|
1858
1942
|
observer.next(false);
|
|
1859
1943
|
observer.complete();
|
|
1860
1944
|
return undefined;
|
|
@@ -1871,7 +1955,7 @@ class FullscreenService {
|
|
|
1871
1955
|
return cleanup;
|
|
1872
1956
|
});
|
|
1873
1957
|
}
|
|
1874
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FullscreenService, deps:
|
|
1958
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FullscreenService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
1875
1959
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FullscreenService });
|
|
1876
1960
|
}
|
|
1877
1961
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FullscreenService, decorators: [{
|
|
@@ -1888,10 +1972,8 @@ class FileSystemAccessService extends BrowserApiBaseService {
|
|
|
1888
1972
|
get win() {
|
|
1889
1973
|
return window;
|
|
1890
1974
|
}
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
throw new Error('File System Access API not available in server environment');
|
|
1894
|
-
}
|
|
1975
|
+
ensureSupported() {
|
|
1976
|
+
super.ensureSupported();
|
|
1895
1977
|
if (!('showOpenFilePicker' in window)) {
|
|
1896
1978
|
throw new Error('File System Access API not supported in this browser');
|
|
1897
1979
|
}
|
|
@@ -1900,7 +1982,7 @@ class FileSystemAccessService extends BrowserApiBaseService {
|
|
|
1900
1982
|
}
|
|
1901
1983
|
}
|
|
1902
1984
|
async openFile(options = {}) {
|
|
1903
|
-
this.
|
|
1985
|
+
this.ensureSupported();
|
|
1904
1986
|
try {
|
|
1905
1987
|
const handles = await this.win.showOpenFilePicker(options);
|
|
1906
1988
|
return Promise.all(handles.map((h) => h.getFile()));
|
|
@@ -1909,12 +1991,12 @@ class FileSystemAccessService extends BrowserApiBaseService {
|
|
|
1909
1991
|
if (error instanceof DOMException && error.name === 'AbortError') {
|
|
1910
1992
|
return [];
|
|
1911
1993
|
}
|
|
1912
|
-
|
|
1994
|
+
this.logError('Error opening file:', error);
|
|
1913
1995
|
throw error;
|
|
1914
1996
|
}
|
|
1915
1997
|
}
|
|
1916
1998
|
async saveFile(content, options = {}) {
|
|
1917
|
-
this.
|
|
1999
|
+
this.ensureSupported();
|
|
1918
2000
|
if (!this.win.showSaveFilePicker) {
|
|
1919
2001
|
throw new Error('showSaveFilePicker not supported');
|
|
1920
2002
|
}
|
|
@@ -1928,12 +2010,12 @@ class FileSystemAccessService extends BrowserApiBaseService {
|
|
|
1928
2010
|
if (error instanceof DOMException && error.name === 'AbortError') {
|
|
1929
2011
|
return;
|
|
1930
2012
|
}
|
|
1931
|
-
|
|
2013
|
+
this.logError('Error saving file:', error);
|
|
1932
2014
|
throw error;
|
|
1933
2015
|
}
|
|
1934
2016
|
}
|
|
1935
2017
|
async openDirectory(options = {}) {
|
|
1936
|
-
this.
|
|
2018
|
+
this.ensureSupported();
|
|
1937
2019
|
if (!this.win.showDirectoryPicker) {
|
|
1938
2020
|
throw new Error('showDirectoryPicker not supported');
|
|
1939
2021
|
}
|
|
@@ -1944,7 +2026,7 @@ class FileSystemAccessService extends BrowserApiBaseService {
|
|
|
1944
2026
|
if (error instanceof DOMException && error.name === 'AbortError') {
|
|
1945
2027
|
return null;
|
|
1946
2028
|
}
|
|
1947
|
-
|
|
2029
|
+
this.logError('Error opening directory:', error);
|
|
1948
2030
|
throw error;
|
|
1949
2031
|
}
|
|
1950
2032
|
}
|
|
@@ -2011,7 +2093,7 @@ class MediaRecorderService extends BrowserApiBaseService {
|
|
|
2011
2093
|
this.recorder.start(timeslice);
|
|
2012
2094
|
}
|
|
2013
2095
|
catch (error) {
|
|
2014
|
-
|
|
2096
|
+
this.logError('Failed to start recording:', error);
|
|
2015
2097
|
throw this.createError('Failed to start recording', error);
|
|
2016
2098
|
}
|
|
2017
2099
|
}
|
|
@@ -2054,23 +2136,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
2054
2136
|
type: Injectable
|
|
2055
2137
|
}] });
|
|
2056
2138
|
|
|
2057
|
-
class ServerSentEventsService {
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2139
|
+
class ServerSentEventsService extends ConnectionRegistryBaseService {
|
|
2140
|
+
getApiName() {
|
|
2141
|
+
return 'server-sent-events';
|
|
2142
|
+
}
|
|
2143
|
+
closeNativeConnection(source) {
|
|
2144
|
+
source.close();
|
|
2145
|
+
}
|
|
2061
2146
|
isSupported() {
|
|
2062
|
-
return
|
|
2147
|
+
return this.isBrowserEnvironment() && 'EventSource' in window;
|
|
2063
2148
|
}
|
|
2064
|
-
|
|
2149
|
+
ensureSSESupported() {
|
|
2065
2150
|
if (!this.isSupported()) {
|
|
2066
2151
|
throw new Error('Server-Sent Events (EventSource) not supported in this environment');
|
|
2067
2152
|
}
|
|
2068
2153
|
}
|
|
2069
2154
|
connect(url, config = {}) {
|
|
2070
|
-
this.
|
|
2155
|
+
this.ensureSSESupported();
|
|
2071
2156
|
return new Observable((observer) => {
|
|
2072
2157
|
const source = new EventSource(url, { withCredentials: config.withCredentials ?? false });
|
|
2073
|
-
this.
|
|
2158
|
+
this.connections.set(url, source);
|
|
2074
2159
|
const messageHandler = (event) => {
|
|
2075
2160
|
try {
|
|
2076
2161
|
observer.next({
|
|
@@ -2094,7 +2179,7 @@ class ServerSentEventsService {
|
|
|
2094
2179
|
observer.error(new Error('SSE connection closed unexpectedly'));
|
|
2095
2180
|
}
|
|
2096
2181
|
else {
|
|
2097
|
-
|
|
2182
|
+
this.logWarn('SSE connection error, reconnecting...');
|
|
2098
2183
|
}
|
|
2099
2184
|
};
|
|
2100
2185
|
source.addEventListener('message', messageHandler);
|
|
@@ -2112,35 +2197,32 @@ class ServerSentEventsService {
|
|
|
2112
2197
|
});
|
|
2113
2198
|
}
|
|
2114
2199
|
disconnect(url) {
|
|
2115
|
-
|
|
2116
|
-
if (source) {
|
|
2117
|
-
source.close();
|
|
2118
|
-
this.sources.delete(url);
|
|
2119
|
-
}
|
|
2200
|
+
this.removeConnection(url);
|
|
2120
2201
|
}
|
|
2121
2202
|
disconnectAll() {
|
|
2122
|
-
this.
|
|
2123
|
-
this.sources.clear();
|
|
2203
|
+
this.closeAllConnections();
|
|
2124
2204
|
}
|
|
2125
2205
|
getState(url) {
|
|
2126
|
-
const source = this.
|
|
2206
|
+
const source = this.connections.get(url);
|
|
2127
2207
|
if (!source)
|
|
2128
2208
|
return 'closed';
|
|
2129
2209
|
const states = ['connecting', 'open', 'closed'];
|
|
2130
2210
|
return states[source.readyState] ?? 'closed';
|
|
2131
2211
|
}
|
|
2132
2212
|
getActiveConnections() {
|
|
2133
|
-
return
|
|
2213
|
+
return this.getConnectionKeys();
|
|
2134
2214
|
}
|
|
2135
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ServerSentEventsService, deps:
|
|
2215
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ServerSentEventsService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2136
2216
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ServerSentEventsService });
|
|
2137
2217
|
}
|
|
2138
2218
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ServerSentEventsService, decorators: [{
|
|
2139
2219
|
type: Injectable
|
|
2140
2220
|
}] });
|
|
2141
2221
|
|
|
2142
|
-
class VibrationService {
|
|
2143
|
-
|
|
2222
|
+
class VibrationService extends BrowserApiBaseService {
|
|
2223
|
+
getApiName() {
|
|
2224
|
+
return 'vibration';
|
|
2225
|
+
}
|
|
2144
2226
|
presets = {
|
|
2145
2227
|
success: [50, 30, 50],
|
|
2146
2228
|
error: [100, 50, 100, 50, 100],
|
|
@@ -2148,7 +2230,7 @@ class VibrationService {
|
|
|
2148
2230
|
doubleTap: [50, 100, 50],
|
|
2149
2231
|
};
|
|
2150
2232
|
isSupported() {
|
|
2151
|
-
return
|
|
2233
|
+
return this.isBrowserEnvironment() && 'vibrate' in navigator;
|
|
2152
2234
|
}
|
|
2153
2235
|
vibrate(pattern = 200) {
|
|
2154
2236
|
if (!this.isSupported())
|
|
@@ -2170,20 +2252,21 @@ class VibrationService {
|
|
|
2170
2252
|
stop() {
|
|
2171
2253
|
return this.vibrate(0);
|
|
2172
2254
|
}
|
|
2173
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: VibrationService, deps:
|
|
2255
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: VibrationService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2174
2256
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: VibrationService });
|
|
2175
2257
|
}
|
|
2176
2258
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: VibrationService, decorators: [{
|
|
2177
2259
|
type: Injectable
|
|
2178
2260
|
}] });
|
|
2179
2261
|
|
|
2180
|
-
class SpeechSynthesisService {
|
|
2181
|
-
|
|
2182
|
-
|
|
2262
|
+
class SpeechSynthesisService extends BrowserApiBaseService {
|
|
2263
|
+
getApiName() {
|
|
2264
|
+
return 'speech-synthesis';
|
|
2265
|
+
}
|
|
2183
2266
|
isSupported() {
|
|
2184
|
-
return
|
|
2267
|
+
return this.isBrowserEnvironment() && 'speechSynthesis' in window;
|
|
2185
2268
|
}
|
|
2186
|
-
|
|
2269
|
+
ensureSpeechSynthesisSupported() {
|
|
2187
2270
|
if (!this.isSupported()) {
|
|
2188
2271
|
throw new Error('Speech Synthesis API not supported in this browser');
|
|
2189
2272
|
}
|
|
@@ -2222,7 +2305,7 @@ class SpeechSynthesisService {
|
|
|
2222
2305
|
}
|
|
2223
2306
|
speak(text, options = {}) {
|
|
2224
2307
|
return new Observable((observer) => {
|
|
2225
|
-
this.
|
|
2308
|
+
this.ensureSpeechSynthesisSupported();
|
|
2226
2309
|
const utterance = new SpeechSynthesisUtterance(text);
|
|
2227
2310
|
if (options.lang)
|
|
2228
2311
|
utterance.lang = options.lang;
|
|
@@ -2266,7 +2349,7 @@ class SpeechSynthesisService {
|
|
|
2266
2349
|
if (this.isSupported())
|
|
2267
2350
|
speechSynthesis.cancel();
|
|
2268
2351
|
}
|
|
2269
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SpeechSynthesisService, deps:
|
|
2352
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SpeechSynthesisService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2270
2353
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SpeechSynthesisService });
|
|
2271
2354
|
}
|
|
2272
2355
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SpeechSynthesisService, decorators: [{
|
|
@@ -2292,10 +2375,12 @@ function mutationObserverStream(element, options = DEFAULT_OPTIONS) {
|
|
|
2292
2375
|
});
|
|
2293
2376
|
}
|
|
2294
2377
|
|
|
2295
|
-
class MutationObserverService {
|
|
2296
|
-
|
|
2378
|
+
class MutationObserverService extends BrowserApiBaseService {
|
|
2379
|
+
getApiName() {
|
|
2380
|
+
return 'mutation-observer';
|
|
2381
|
+
}
|
|
2297
2382
|
isSupported() {
|
|
2298
|
-
return
|
|
2383
|
+
return this.isBrowserEnvironment() && isMutationObserverSupported();
|
|
2299
2384
|
}
|
|
2300
2385
|
observe(target, options) {
|
|
2301
2386
|
if (!this.isSupported()) {
|
|
@@ -2303,7 +2388,7 @@ class MutationObserverService {
|
|
|
2303
2388
|
}
|
|
2304
2389
|
return mutationObserverStream(target, options);
|
|
2305
2390
|
}
|
|
2306
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MutationObserverService, deps:
|
|
2391
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MutationObserverService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2307
2392
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MutationObserverService });
|
|
2308
2393
|
}
|
|
2309
2394
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MutationObserverService, decorators: [{
|
|
@@ -2328,10 +2413,12 @@ function performanceObserverStream(config) {
|
|
|
2328
2413
|
});
|
|
2329
2414
|
}
|
|
2330
2415
|
|
|
2331
|
-
class PerformanceObserverService {
|
|
2332
|
-
|
|
2416
|
+
class PerformanceObserverService extends BrowserApiBaseService {
|
|
2417
|
+
getApiName() {
|
|
2418
|
+
return 'performance-observer';
|
|
2419
|
+
}
|
|
2333
2420
|
isSupported() {
|
|
2334
|
-
return
|
|
2421
|
+
return this.isBrowserEnvironment() && isPerformanceObserverSupported();
|
|
2335
2422
|
}
|
|
2336
2423
|
observe(config) {
|
|
2337
2424
|
if (!this.isSupported()) {
|
|
@@ -2347,7 +2434,7 @@ class PerformanceObserverService {
|
|
|
2347
2434
|
return [];
|
|
2348
2435
|
return (PerformanceObserver.supportedEntryTypes ?? []);
|
|
2349
2436
|
}
|
|
2350
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PerformanceObserverService, deps:
|
|
2437
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PerformanceObserverService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2351
2438
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PerformanceObserverService });
|
|
2352
2439
|
}
|
|
2353
2440
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PerformanceObserverService, decorators: [{
|
|
@@ -2357,10 +2444,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
2357
2444
|
function getIdleDetectorClass$1() {
|
|
2358
2445
|
return window.IdleDetector;
|
|
2359
2446
|
}
|
|
2360
|
-
class IdleDetectorService {
|
|
2361
|
-
|
|
2447
|
+
class IdleDetectorService extends BrowserApiBaseService {
|
|
2448
|
+
getApiName() {
|
|
2449
|
+
return 'idle-detector';
|
|
2450
|
+
}
|
|
2362
2451
|
isSupported() {
|
|
2363
|
-
return
|
|
2452
|
+
return this.isBrowserEnvironment() && 'IdleDetector' in window;
|
|
2364
2453
|
}
|
|
2365
2454
|
async requestPermission() {
|
|
2366
2455
|
if (!this.isSupported()) {
|
|
@@ -2390,7 +2479,7 @@ class IdleDetectorService {
|
|
|
2390
2479
|
return () => abortController.abort();
|
|
2391
2480
|
});
|
|
2392
2481
|
}
|
|
2393
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: IdleDetectorService, deps:
|
|
2482
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: IdleDetectorService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2394
2483
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: IdleDetectorService });
|
|
2395
2484
|
}
|
|
2396
2485
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: IdleDetectorService, decorators: [{
|
|
@@ -2400,10 +2489,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
2400
2489
|
function getEyeDropperClass() {
|
|
2401
2490
|
return window.EyeDropper;
|
|
2402
2491
|
}
|
|
2403
|
-
class EyeDropperService {
|
|
2404
|
-
|
|
2492
|
+
class EyeDropperService extends BrowserApiBaseService {
|
|
2493
|
+
getApiName() {
|
|
2494
|
+
return 'eye-dropper';
|
|
2495
|
+
}
|
|
2405
2496
|
isSupported() {
|
|
2406
|
-
return
|
|
2497
|
+
return this.isBrowserEnvironment() && 'EyeDropper' in window;
|
|
2407
2498
|
}
|
|
2408
2499
|
async open(signal) {
|
|
2409
2500
|
if (!this.isSupported()) {
|
|
@@ -2412,7 +2503,7 @@ class EyeDropperService {
|
|
|
2412
2503
|
const dropper = new (getEyeDropperClass())();
|
|
2413
2504
|
return dropper.open(signal ? { signal } : undefined);
|
|
2414
2505
|
}
|
|
2415
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: EyeDropperService, deps:
|
|
2506
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: EyeDropperService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2416
2507
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: EyeDropperService });
|
|
2417
2508
|
}
|
|
2418
2509
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: EyeDropperService, decorators: [{
|
|
@@ -2422,10 +2513,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
2422
2513
|
function getBarcodeDetectorClass() {
|
|
2423
2514
|
return window.BarcodeDetector;
|
|
2424
2515
|
}
|
|
2425
|
-
class BarcodeDetectorService {
|
|
2426
|
-
|
|
2516
|
+
class BarcodeDetectorService extends BrowserApiBaseService {
|
|
2517
|
+
getApiName() {
|
|
2518
|
+
return 'barcode-detector';
|
|
2519
|
+
}
|
|
2427
2520
|
isSupported() {
|
|
2428
|
-
return
|
|
2521
|
+
return this.isBrowserEnvironment() && 'BarcodeDetector' in window;
|
|
2429
2522
|
}
|
|
2430
2523
|
async getSupportedFormats() {
|
|
2431
2524
|
if (!this.isSupported())
|
|
@@ -2441,19 +2534,20 @@ class BarcodeDetectorService {
|
|
|
2441
2534
|
: new (getBarcodeDetectorClass())();
|
|
2442
2535
|
return detector.detect(image);
|
|
2443
2536
|
}
|
|
2444
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BarcodeDetectorService, deps:
|
|
2537
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BarcodeDetectorService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2445
2538
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BarcodeDetectorService });
|
|
2446
2539
|
}
|
|
2447
2540
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BarcodeDetectorService, decorators: [{
|
|
2448
2541
|
type: Injectable
|
|
2449
2542
|
}] });
|
|
2450
2543
|
|
|
2451
|
-
class WebAudioService {
|
|
2452
|
-
|
|
2453
|
-
|
|
2544
|
+
class WebAudioService extends BrowserApiBaseService {
|
|
2545
|
+
getApiName() {
|
|
2546
|
+
return 'web-audio';
|
|
2547
|
+
}
|
|
2454
2548
|
context = null;
|
|
2455
2549
|
isSupported() {
|
|
2456
|
-
return
|
|
2550
|
+
return this.isBrowserEnvironment() && 'AudioContext' in window;
|
|
2457
2551
|
}
|
|
2458
2552
|
getContext() {
|
|
2459
2553
|
if (!this.isSupported()) {
|
|
@@ -2527,7 +2621,7 @@ class WebAudioService {
|
|
|
2527
2621
|
source.start(0);
|
|
2528
2622
|
return source;
|
|
2529
2623
|
}
|
|
2530
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebAudioService, deps:
|
|
2624
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebAudioService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2531
2625
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebAudioService });
|
|
2532
2626
|
}
|
|
2533
2627
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebAudioService, decorators: [{
|
|
@@ -2610,10 +2704,12 @@ function gamepadPollStream(index, intervalMs = 16) {
|
|
|
2610
2704
|
});
|
|
2611
2705
|
}
|
|
2612
2706
|
|
|
2613
|
-
class GamepadService {
|
|
2614
|
-
|
|
2707
|
+
class GamepadService extends BrowserApiBaseService {
|
|
2708
|
+
getApiName() {
|
|
2709
|
+
return 'gamepad';
|
|
2710
|
+
}
|
|
2615
2711
|
isSupported() {
|
|
2616
|
-
return
|
|
2712
|
+
return this.isBrowserEnvironment() && isGamepadSupported();
|
|
2617
2713
|
}
|
|
2618
2714
|
getSnapshot(index) {
|
|
2619
2715
|
if (!this.isSupported())
|
|
@@ -2647,7 +2743,7 @@ class GamepadService {
|
|
|
2647
2743
|
}
|
|
2648
2744
|
return gamepadPollStream(index, intervalMs);
|
|
2649
2745
|
}
|
|
2650
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: GamepadService, deps:
|
|
2746
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: GamepadService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2651
2747
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: GamepadService });
|
|
2652
2748
|
}
|
|
2653
2749
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: GamepadService, decorators: [{
|
|
@@ -2657,10 +2753,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
2657
2753
|
function getBluetooth() {
|
|
2658
2754
|
return navigator.bluetooth;
|
|
2659
2755
|
}
|
|
2660
|
-
class WebBluetoothService {
|
|
2661
|
-
|
|
2756
|
+
class WebBluetoothService extends BrowserApiBaseService {
|
|
2757
|
+
getApiName() {
|
|
2758
|
+
return 'web-bluetooth';
|
|
2759
|
+
}
|
|
2662
2760
|
isSupported() {
|
|
2663
|
-
return
|
|
2761
|
+
return this.isBrowserEnvironment() && !!getBluetooth();
|
|
2664
2762
|
}
|
|
2665
2763
|
async requestDevice(options = { acceptAllDevices: true }) {
|
|
2666
2764
|
if (!this.isSupported()) {
|
|
@@ -2716,7 +2814,7 @@ class WebBluetoothService {
|
|
|
2716
2814
|
};
|
|
2717
2815
|
});
|
|
2718
2816
|
}
|
|
2719
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebBluetoothService, deps:
|
|
2817
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebBluetoothService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2720
2818
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebBluetoothService });
|
|
2721
2819
|
}
|
|
2722
2820
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebBluetoothService, decorators: [{
|
|
@@ -2726,10 +2824,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
2726
2824
|
function getUsb() {
|
|
2727
2825
|
return navigator.usb;
|
|
2728
2826
|
}
|
|
2729
|
-
class WebUsbService {
|
|
2730
|
-
|
|
2827
|
+
class WebUsbService extends BrowserApiBaseService {
|
|
2828
|
+
getApiName() {
|
|
2829
|
+
return 'web-usb';
|
|
2830
|
+
}
|
|
2731
2831
|
isSupported() {
|
|
2732
|
-
return
|
|
2832
|
+
return this.isBrowserEnvironment() && !!getUsb();
|
|
2733
2833
|
}
|
|
2734
2834
|
async requestDevice(filters = []) {
|
|
2735
2835
|
if (!this.isSupported()) {
|
|
@@ -2789,7 +2889,7 @@ class WebUsbService {
|
|
|
2789
2889
|
opened: device.opened,
|
|
2790
2890
|
};
|
|
2791
2891
|
}
|
|
2792
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebUsbService, deps:
|
|
2892
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebUsbService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2793
2893
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebUsbService });
|
|
2794
2894
|
}
|
|
2795
2895
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebUsbService, decorators: [{
|
|
@@ -2799,10 +2899,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
2799
2899
|
function getNdefReaderClass() {
|
|
2800
2900
|
return window.NDEFReader;
|
|
2801
2901
|
}
|
|
2802
|
-
class WebNfcService {
|
|
2803
|
-
|
|
2902
|
+
class WebNfcService extends BrowserApiBaseService {
|
|
2903
|
+
getApiName() {
|
|
2904
|
+
return 'web-nfc';
|
|
2905
|
+
}
|
|
2804
2906
|
isSupported() {
|
|
2805
|
-
return
|
|
2907
|
+
return this.isBrowserEnvironment() && 'NDEFReader' in window;
|
|
2806
2908
|
}
|
|
2807
2909
|
scan() {
|
|
2808
2910
|
if (!this.isSupported()) {
|
|
@@ -2836,17 +2938,19 @@ class WebNfcService {
|
|
|
2836
2938
|
const reader = new (getNdefReaderClass())();
|
|
2837
2939
|
await reader.write(message, options);
|
|
2838
2940
|
}
|
|
2839
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebNfcService, deps:
|
|
2941
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebNfcService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2840
2942
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebNfcService });
|
|
2841
2943
|
}
|
|
2842
2944
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebNfcService, decorators: [{
|
|
2843
2945
|
type: Injectable
|
|
2844
2946
|
}] });
|
|
2845
2947
|
|
|
2846
|
-
class PaymentRequestService {
|
|
2847
|
-
|
|
2948
|
+
class PaymentRequestService extends BrowserApiBaseService {
|
|
2949
|
+
getApiName() {
|
|
2950
|
+
return 'payment-request';
|
|
2951
|
+
}
|
|
2848
2952
|
isSupported() {
|
|
2849
|
-
return
|
|
2953
|
+
return this.isBrowserEnvironment() && 'PaymentRequest' in window;
|
|
2850
2954
|
}
|
|
2851
2955
|
async canMakePayment(methods, details) {
|
|
2852
2956
|
if (!this.isSupported())
|
|
@@ -2876,17 +2980,19 @@ class PaymentRequestService {
|
|
|
2876
2980
|
const request = new PaymentRequest(methods, details);
|
|
2877
2981
|
await request.abort();
|
|
2878
2982
|
}
|
|
2879
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PaymentRequestService, deps:
|
|
2983
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PaymentRequestService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2880
2984
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PaymentRequestService });
|
|
2881
2985
|
}
|
|
2882
2986
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PaymentRequestService, decorators: [{
|
|
2883
2987
|
type: Injectable
|
|
2884
2988
|
}] });
|
|
2885
2989
|
|
|
2886
|
-
class CredentialManagementService {
|
|
2887
|
-
|
|
2990
|
+
class CredentialManagementService extends BrowserApiBaseService {
|
|
2991
|
+
getApiName() {
|
|
2992
|
+
return 'credential-management';
|
|
2993
|
+
}
|
|
2888
2994
|
isSupported() {
|
|
2889
|
-
return
|
|
2995
|
+
return this.isBrowserEnvironment() && 'credentials' in navigator;
|
|
2890
2996
|
}
|
|
2891
2997
|
isPublicKeySupported() {
|
|
2892
2998
|
return this.isSupported() && 'PublicKeyCredential' in window;
|
|
@@ -2932,7 +3038,7 @@ class CredentialManagementService {
|
|
|
2932
3038
|
}
|
|
2933
3039
|
return false;
|
|
2934
3040
|
}
|
|
2935
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CredentialManagementService, deps:
|
|
3041
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CredentialManagementService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2936
3042
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CredentialManagementService });
|
|
2937
3043
|
}
|
|
2938
3044
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CredentialManagementService, decorators: [{
|
|
@@ -3268,218 +3374,253 @@ const permissionGuard = (permission) => {
|
|
|
3268
3374
|
};
|
|
3269
3375
|
};
|
|
3270
3376
|
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
enableGeolocation: true,
|
|
3274
|
-
enableNotifications: true,
|
|
3275
|
-
enableClipboard: true,
|
|
3276
|
-
enableBattery: false,
|
|
3277
|
-
enableMediaDevices: true,
|
|
3278
|
-
enableWebShare: false,
|
|
3279
|
-
enableWebStorage: false,
|
|
3280
|
-
enableWebSocket: false,
|
|
3281
|
-
enableWebWorker: false,
|
|
3282
|
-
enableIntersectionObserver: false,
|
|
3283
|
-
enableResizeObserver: false,
|
|
3284
|
-
enablePageVisibility: false,
|
|
3285
|
-
enableBroadcastChannel: false,
|
|
3286
|
-
enableNetworkInformation: false,
|
|
3287
|
-
enableScreenWakeLock: false,
|
|
3288
|
-
enableScreenOrientation: false,
|
|
3289
|
-
enableFullscreen: false,
|
|
3290
|
-
enableFileSystemAccess: false,
|
|
3291
|
-
enableMediaRecorder: false,
|
|
3292
|
-
enableServerSentEvents: false,
|
|
3293
|
-
enableVibration: false,
|
|
3294
|
-
enableSpeechSynthesis: false,
|
|
3295
|
-
enableMutationObserver: false,
|
|
3296
|
-
enablePerformanceObserver: false,
|
|
3297
|
-
enableIdleDetector: false,
|
|
3298
|
-
enableEyeDropper: false,
|
|
3299
|
-
enableBarcodeDetector: false,
|
|
3300
|
-
enableWebAudio: false,
|
|
3301
|
-
enableGamepad: false,
|
|
3302
|
-
enableWebBluetooth: false,
|
|
3303
|
-
enableWebUsb: false,
|
|
3304
|
-
enableWebNfc: false,
|
|
3305
|
-
enablePaymentRequest: false,
|
|
3306
|
-
enableCredentialManagement: false,
|
|
3307
|
-
};
|
|
3308
|
-
function provideBrowserWebApis(config = {}) {
|
|
3309
|
-
const mergedConfig = { ...defaultBrowserWebApisConfig, ...config };
|
|
3310
|
-
const providers = [PermissionsService];
|
|
3311
|
-
const conditionalProviders = [
|
|
3312
|
-
[mergedConfig.enableCamera, CameraService],
|
|
3313
|
-
[mergedConfig.enableGeolocation, GeolocationService],
|
|
3314
|
-
[mergedConfig.enableNotifications, NotificationService],
|
|
3315
|
-
[mergedConfig.enableClipboard, ClipboardService],
|
|
3316
|
-
[mergedConfig.enableMediaDevices, MediaDevicesService],
|
|
3317
|
-
[mergedConfig.enableBattery, BatteryService],
|
|
3318
|
-
[mergedConfig.enableWebShare, WebShareService],
|
|
3319
|
-
[mergedConfig.enableWebStorage, WebStorageService],
|
|
3320
|
-
[mergedConfig.enableWebSocket, WebSocketService],
|
|
3321
|
-
[mergedConfig.enableWebWorker, WebWorkerService],
|
|
3322
|
-
[mergedConfig.enableIntersectionObserver, IntersectionObserverService],
|
|
3323
|
-
[mergedConfig.enableResizeObserver, ResizeObserverService],
|
|
3324
|
-
[mergedConfig.enablePageVisibility, PageVisibilityService],
|
|
3325
|
-
[mergedConfig.enableBroadcastChannel, BroadcastChannelService],
|
|
3326
|
-
[mergedConfig.enableNetworkInformation, NetworkInformationService],
|
|
3327
|
-
[mergedConfig.enableScreenWakeLock, ScreenWakeLockService],
|
|
3328
|
-
[mergedConfig.enableScreenOrientation, ScreenOrientationService],
|
|
3329
|
-
[mergedConfig.enableFullscreen, FullscreenService],
|
|
3330
|
-
[mergedConfig.enableFileSystemAccess, FileSystemAccessService],
|
|
3331
|
-
[mergedConfig.enableMediaRecorder, MediaRecorderService],
|
|
3332
|
-
[mergedConfig.enableServerSentEvents, ServerSentEventsService],
|
|
3333
|
-
[mergedConfig.enableVibration, VibrationService],
|
|
3334
|
-
[mergedConfig.enableSpeechSynthesis, SpeechSynthesisService],
|
|
3335
|
-
[mergedConfig.enableMutationObserver, MutationObserverService],
|
|
3336
|
-
[mergedConfig.enablePerformanceObserver, PerformanceObserverService],
|
|
3337
|
-
[mergedConfig.enableIdleDetector, IdleDetectorService],
|
|
3338
|
-
[mergedConfig.enableEyeDropper, EyeDropperService],
|
|
3339
|
-
[mergedConfig.enableBarcodeDetector, BarcodeDetectorService],
|
|
3340
|
-
[mergedConfig.enableWebAudio, WebAudioService],
|
|
3341
|
-
[mergedConfig.enableGamepad, GamepadService],
|
|
3342
|
-
[mergedConfig.enableWebBluetooth, WebBluetoothService],
|
|
3343
|
-
[mergedConfig.enableWebUsb, WebUsbService],
|
|
3344
|
-
[mergedConfig.enableWebNfc, WebNfcService],
|
|
3345
|
-
[mergedConfig.enablePaymentRequest, PaymentRequestService],
|
|
3346
|
-
[mergedConfig.enableCredentialManagement, CredentialManagementService],
|
|
3347
|
-
];
|
|
3348
|
-
for (const [enabled, provider] of conditionalProviders) {
|
|
3349
|
-
if (enabled) {
|
|
3350
|
-
providers.push(provider);
|
|
3351
|
-
}
|
|
3352
|
-
}
|
|
3353
|
-
return makeEnvironmentProviders(providers);
|
|
3377
|
+
function providePermissions() {
|
|
3378
|
+
return makeEnvironmentProviders([PermissionsService]);
|
|
3354
3379
|
}
|
|
3355
|
-
|
|
3380
|
+
|
|
3356
3381
|
function provideCamera() {
|
|
3357
|
-
return makeEnvironmentProviders([
|
|
3382
|
+
return makeEnvironmentProviders([CameraService]);
|
|
3358
3383
|
}
|
|
3384
|
+
|
|
3359
3385
|
function provideGeolocation() {
|
|
3360
3386
|
return makeEnvironmentProviders([PermissionsService, GeolocationService]);
|
|
3361
3387
|
}
|
|
3388
|
+
|
|
3362
3389
|
function provideNotifications() {
|
|
3363
3390
|
return makeEnvironmentProviders([PermissionsService, NotificationService]);
|
|
3364
3391
|
}
|
|
3392
|
+
|
|
3365
3393
|
function provideClipboard() {
|
|
3366
|
-
return makeEnvironmentProviders([
|
|
3394
|
+
return makeEnvironmentProviders([ClipboardService]);
|
|
3367
3395
|
}
|
|
3396
|
+
|
|
3368
3397
|
function provideMediaDevices() {
|
|
3369
3398
|
return makeEnvironmentProviders([PermissionsService, MediaDevicesService]);
|
|
3370
3399
|
}
|
|
3400
|
+
|
|
3401
|
+
function provideScreenWakeLock() {
|
|
3402
|
+
return makeEnvironmentProviders([PermissionsService, ScreenWakeLockService]);
|
|
3403
|
+
}
|
|
3404
|
+
|
|
3405
|
+
function provideFileSystemAccess() {
|
|
3406
|
+
return makeEnvironmentProviders([PermissionsService, FileSystemAccessService]);
|
|
3407
|
+
}
|
|
3408
|
+
|
|
3409
|
+
function provideMediaRecorder() {
|
|
3410
|
+
return makeEnvironmentProviders([PermissionsService, MediaRecorderService]);
|
|
3411
|
+
}
|
|
3412
|
+
|
|
3413
|
+
function provideIdleDetector() {
|
|
3414
|
+
return makeEnvironmentProviders([PermissionsService, IdleDetectorService]);
|
|
3415
|
+
}
|
|
3416
|
+
|
|
3371
3417
|
function provideBattery() {
|
|
3372
3418
|
return makeEnvironmentProviders([BatteryService]);
|
|
3373
3419
|
}
|
|
3420
|
+
|
|
3374
3421
|
function provideWebShare() {
|
|
3375
3422
|
return makeEnvironmentProviders([WebShareService]);
|
|
3376
3423
|
}
|
|
3424
|
+
|
|
3377
3425
|
function provideWebStorage() {
|
|
3378
3426
|
return makeEnvironmentProviders([WebStorageService]);
|
|
3379
3427
|
}
|
|
3428
|
+
|
|
3380
3429
|
function provideWebSocket() {
|
|
3381
3430
|
return makeEnvironmentProviders([WebSocketService]);
|
|
3382
3431
|
}
|
|
3432
|
+
|
|
3383
3433
|
function provideWebWorker() {
|
|
3384
3434
|
return makeEnvironmentProviders([WebWorkerService]);
|
|
3385
3435
|
}
|
|
3386
|
-
|
|
3387
|
-
return makeEnvironmentProviders([PermissionsService]);
|
|
3388
|
-
}
|
|
3389
|
-
// Combined providers for common use cases
|
|
3390
|
-
function provideMediaApis() {
|
|
3391
|
-
return makeEnvironmentProviders([PermissionsService, CameraService, MediaDevicesService]);
|
|
3392
|
-
}
|
|
3393
|
-
function provideLocationApis() {
|
|
3394
|
-
return makeEnvironmentProviders([PermissionsService, GeolocationService]);
|
|
3395
|
-
}
|
|
3396
|
-
function provideStorageApis() {
|
|
3397
|
-
return makeEnvironmentProviders([PermissionsService, ClipboardService, WebStorageService]);
|
|
3398
|
-
}
|
|
3399
|
-
function provideCommunicationApis() {
|
|
3400
|
-
return makeEnvironmentProviders([
|
|
3401
|
-
PermissionsService,
|
|
3402
|
-
NotificationService,
|
|
3403
|
-
WebShareService,
|
|
3404
|
-
WebSocketService,
|
|
3405
|
-
]);
|
|
3406
|
-
}
|
|
3436
|
+
|
|
3407
3437
|
function provideIntersectionObserver() {
|
|
3408
3438
|
return makeEnvironmentProviders([IntersectionObserverService]);
|
|
3409
3439
|
}
|
|
3440
|
+
|
|
3410
3441
|
function provideResizeObserver() {
|
|
3411
3442
|
return makeEnvironmentProviders([ResizeObserverService]);
|
|
3412
3443
|
}
|
|
3444
|
+
|
|
3413
3445
|
function providePageVisibility() {
|
|
3414
3446
|
return makeEnvironmentProviders([PageVisibilityService]);
|
|
3415
3447
|
}
|
|
3448
|
+
|
|
3416
3449
|
function provideBroadcastChannel() {
|
|
3417
3450
|
return makeEnvironmentProviders([BroadcastChannelService]);
|
|
3418
3451
|
}
|
|
3452
|
+
|
|
3419
3453
|
function provideNetworkInformation() {
|
|
3420
3454
|
return makeEnvironmentProviders([NetworkInformationService]);
|
|
3421
3455
|
}
|
|
3422
|
-
|
|
3423
|
-
return makeEnvironmentProviders([PermissionsService, ScreenWakeLockService]);
|
|
3424
|
-
}
|
|
3456
|
+
|
|
3425
3457
|
function provideScreenOrientation() {
|
|
3426
3458
|
return makeEnvironmentProviders([ScreenOrientationService]);
|
|
3427
3459
|
}
|
|
3460
|
+
|
|
3428
3461
|
function provideFullscreen() {
|
|
3429
3462
|
return makeEnvironmentProviders([FullscreenService]);
|
|
3430
3463
|
}
|
|
3431
|
-
|
|
3432
|
-
return makeEnvironmentProviders([PermissionsService, FileSystemAccessService]);
|
|
3433
|
-
}
|
|
3434
|
-
function provideMediaRecorder() {
|
|
3435
|
-
return makeEnvironmentProviders([PermissionsService, MediaRecorderService]);
|
|
3436
|
-
}
|
|
3464
|
+
|
|
3437
3465
|
function provideServerSentEvents() {
|
|
3438
3466
|
return makeEnvironmentProviders([ServerSentEventsService]);
|
|
3439
3467
|
}
|
|
3468
|
+
|
|
3440
3469
|
function provideVibration() {
|
|
3441
3470
|
return makeEnvironmentProviders([VibrationService]);
|
|
3442
3471
|
}
|
|
3472
|
+
|
|
3443
3473
|
function provideSpeechSynthesis() {
|
|
3444
3474
|
return makeEnvironmentProviders([SpeechSynthesisService]);
|
|
3445
3475
|
}
|
|
3476
|
+
|
|
3446
3477
|
function provideMutationObserver() {
|
|
3447
3478
|
return makeEnvironmentProviders([MutationObserverService]);
|
|
3448
3479
|
}
|
|
3480
|
+
|
|
3449
3481
|
function providePerformanceObserver() {
|
|
3450
3482
|
return makeEnvironmentProviders([PerformanceObserverService]);
|
|
3451
3483
|
}
|
|
3452
|
-
|
|
3453
|
-
return makeEnvironmentProviders([PermissionsService, IdleDetectorService]);
|
|
3454
|
-
}
|
|
3484
|
+
|
|
3455
3485
|
function provideEyeDropper() {
|
|
3456
3486
|
return makeEnvironmentProviders([EyeDropperService]);
|
|
3457
3487
|
}
|
|
3488
|
+
|
|
3458
3489
|
function provideBarcodeDetector() {
|
|
3459
3490
|
return makeEnvironmentProviders([BarcodeDetectorService]);
|
|
3460
3491
|
}
|
|
3492
|
+
|
|
3461
3493
|
function provideWebAudio() {
|
|
3462
3494
|
return makeEnvironmentProviders([WebAudioService]);
|
|
3463
3495
|
}
|
|
3496
|
+
|
|
3464
3497
|
function provideGamepad() {
|
|
3465
3498
|
return makeEnvironmentProviders([GamepadService]);
|
|
3466
3499
|
}
|
|
3500
|
+
|
|
3467
3501
|
function provideWebBluetooth() {
|
|
3468
3502
|
return makeEnvironmentProviders([WebBluetoothService]);
|
|
3469
3503
|
}
|
|
3504
|
+
|
|
3470
3505
|
function provideWebUsb() {
|
|
3471
3506
|
return makeEnvironmentProviders([WebUsbService]);
|
|
3472
3507
|
}
|
|
3508
|
+
|
|
3473
3509
|
function provideWebNfc() {
|
|
3474
3510
|
return makeEnvironmentProviders([WebNfcService]);
|
|
3475
3511
|
}
|
|
3512
|
+
|
|
3476
3513
|
function providePaymentRequest() {
|
|
3477
3514
|
return makeEnvironmentProviders([PaymentRequestService]);
|
|
3478
3515
|
}
|
|
3516
|
+
|
|
3479
3517
|
function provideCredentialManagement() {
|
|
3480
3518
|
return makeEnvironmentProviders([CredentialManagementService]);
|
|
3481
3519
|
}
|
|
3482
3520
|
|
|
3521
|
+
function provideMediaApis() {
|
|
3522
|
+
return makeEnvironmentProviders([PermissionsService, CameraService, MediaDevicesService]);
|
|
3523
|
+
}
|
|
3524
|
+
function provideLocationApis() {
|
|
3525
|
+
return makeEnvironmentProviders([PermissionsService, GeolocationService]);
|
|
3526
|
+
}
|
|
3527
|
+
function provideStorageApis() {
|
|
3528
|
+
return makeEnvironmentProviders([PermissionsService, ClipboardService, WebStorageService]);
|
|
3529
|
+
}
|
|
3530
|
+
function provideCommunicationApis() {
|
|
3531
|
+
return makeEnvironmentProviders([
|
|
3532
|
+
PermissionsService,
|
|
3533
|
+
NotificationService,
|
|
3534
|
+
WebShareService,
|
|
3535
|
+
WebSocketService,
|
|
3536
|
+
]);
|
|
3537
|
+
}
|
|
3538
|
+
|
|
3539
|
+
const defaultBrowserWebApisConfig = {
|
|
3540
|
+
enableCamera: true,
|
|
3541
|
+
enableGeolocation: true,
|
|
3542
|
+
enableNotifications: true,
|
|
3543
|
+
enableClipboard: true,
|
|
3544
|
+
enableBattery: false,
|
|
3545
|
+
enableMediaDevices: true,
|
|
3546
|
+
enableWebShare: false,
|
|
3547
|
+
enableWebStorage: false,
|
|
3548
|
+
enableWebSocket: false,
|
|
3549
|
+
enableWebWorker: false,
|
|
3550
|
+
enableIntersectionObserver: false,
|
|
3551
|
+
enableResizeObserver: false,
|
|
3552
|
+
enablePageVisibility: false,
|
|
3553
|
+
enableBroadcastChannel: false,
|
|
3554
|
+
enableNetworkInformation: false,
|
|
3555
|
+
enableScreenWakeLock: false,
|
|
3556
|
+
enableScreenOrientation: false,
|
|
3557
|
+
enableFullscreen: false,
|
|
3558
|
+
enableFileSystemAccess: false,
|
|
3559
|
+
enableMediaRecorder: false,
|
|
3560
|
+
enableServerSentEvents: false,
|
|
3561
|
+
enableVibration: false,
|
|
3562
|
+
enableSpeechSynthesis: false,
|
|
3563
|
+
enableMutationObserver: false,
|
|
3564
|
+
enablePerformanceObserver: false,
|
|
3565
|
+
enableIdleDetector: false,
|
|
3566
|
+
enableEyeDropper: false,
|
|
3567
|
+
enableBarcodeDetector: false,
|
|
3568
|
+
enableWebAudio: false,
|
|
3569
|
+
enableGamepad: false,
|
|
3570
|
+
enableWebBluetooth: false,
|
|
3571
|
+
enableWebUsb: false,
|
|
3572
|
+
enableWebNfc: false,
|
|
3573
|
+
enablePaymentRequest: false,
|
|
3574
|
+
enableCredentialManagement: false,
|
|
3575
|
+
};
|
|
3576
|
+
function provideBrowserWebApis(config = {}) {
|
|
3577
|
+
const mergedConfig = { ...defaultBrowserWebApisConfig, ...config };
|
|
3578
|
+
const providers = [PermissionsService];
|
|
3579
|
+
const conditionalProviders = [
|
|
3580
|
+
[mergedConfig.enableCamera, CameraService],
|
|
3581
|
+
[mergedConfig.enableGeolocation, GeolocationService],
|
|
3582
|
+
[mergedConfig.enableNotifications, NotificationService],
|
|
3583
|
+
[mergedConfig.enableClipboard, ClipboardService],
|
|
3584
|
+
[mergedConfig.enableMediaDevices, MediaDevicesService],
|
|
3585
|
+
[mergedConfig.enableBattery, BatteryService],
|
|
3586
|
+
[mergedConfig.enableWebShare, WebShareService],
|
|
3587
|
+
[mergedConfig.enableWebStorage, WebStorageService],
|
|
3588
|
+
[mergedConfig.enableWebSocket, WebSocketService],
|
|
3589
|
+
[mergedConfig.enableWebWorker, WebWorkerService],
|
|
3590
|
+
[mergedConfig.enableIntersectionObserver, IntersectionObserverService],
|
|
3591
|
+
[mergedConfig.enableResizeObserver, ResizeObserverService],
|
|
3592
|
+
[mergedConfig.enablePageVisibility, PageVisibilityService],
|
|
3593
|
+
[mergedConfig.enableBroadcastChannel, BroadcastChannelService],
|
|
3594
|
+
[mergedConfig.enableNetworkInformation, NetworkInformationService],
|
|
3595
|
+
[mergedConfig.enableScreenWakeLock, ScreenWakeLockService],
|
|
3596
|
+
[mergedConfig.enableScreenOrientation, ScreenOrientationService],
|
|
3597
|
+
[mergedConfig.enableFullscreen, FullscreenService],
|
|
3598
|
+
[mergedConfig.enableFileSystemAccess, FileSystemAccessService],
|
|
3599
|
+
[mergedConfig.enableMediaRecorder, MediaRecorderService],
|
|
3600
|
+
[mergedConfig.enableServerSentEvents, ServerSentEventsService],
|
|
3601
|
+
[mergedConfig.enableVibration, VibrationService],
|
|
3602
|
+
[mergedConfig.enableSpeechSynthesis, SpeechSynthesisService],
|
|
3603
|
+
[mergedConfig.enableMutationObserver, MutationObserverService],
|
|
3604
|
+
[mergedConfig.enablePerformanceObserver, PerformanceObserverService],
|
|
3605
|
+
[mergedConfig.enableIdleDetector, IdleDetectorService],
|
|
3606
|
+
[mergedConfig.enableEyeDropper, EyeDropperService],
|
|
3607
|
+
[mergedConfig.enableBarcodeDetector, BarcodeDetectorService],
|
|
3608
|
+
[mergedConfig.enableWebAudio, WebAudioService],
|
|
3609
|
+
[mergedConfig.enableGamepad, GamepadService],
|
|
3610
|
+
[mergedConfig.enableWebBluetooth, WebBluetoothService],
|
|
3611
|
+
[mergedConfig.enableWebUsb, WebUsbService],
|
|
3612
|
+
[mergedConfig.enableWebNfc, WebNfcService],
|
|
3613
|
+
[mergedConfig.enablePaymentRequest, PaymentRequestService],
|
|
3614
|
+
[mergedConfig.enableCredentialManagement, CredentialManagementService],
|
|
3615
|
+
];
|
|
3616
|
+
for (const [enabled, provider] of conditionalProviders) {
|
|
3617
|
+
if (enabled) {
|
|
3618
|
+
providers.push(provider);
|
|
3619
|
+
}
|
|
3620
|
+
}
|
|
3621
|
+
return makeEnvironmentProviders(providers);
|
|
3622
|
+
}
|
|
3623
|
+
|
|
3483
3624
|
// Browser Web APIs Services
|
|
3484
3625
|
// Version
|
|
3485
3626
|
const version = '0.1.0';
|
|
@@ -3488,4 +3629,4 @@ const version = '0.1.0';
|
|
|
3488
3629
|
* Generated bundle index. Do not edit.
|
|
3489
3630
|
*/
|
|
3490
3631
|
|
|
3491
|
-
export { BarcodeDetectorService, BatteryService, BroadcastChannelService, BrowserApiBaseService, BrowserCapabilityService, BrowserSupportUtil, CameraService, ClipboardService, CredentialManagementService, EyeDropperService, FileSystemAccessService, FullscreenService, GamepadService, GeolocationService, IdleDetectorService, IntersectionObserverService, MediaDevicesService, MediaRecorderService, MutationObserverService, NetworkInformationService, NotificationService, PageVisibilityService, PaymentRequestService, PerformanceObserverService, PermissionsService, ResizeObserverService, ScreenOrientationService, ScreenWakeLockService, ServerSentEventsService, SpeechSynthesisService, VibrationService, WebAudioService, WebBluetoothService, WebNfcService, WebShareService, WebSocketService, WebStorageService, WebUsbService, WebWorkerService, permissionGuard as createPermissionGuard, defaultBrowserWebApisConfig, injectGamepad, injectIdleDetector, injectIntersectionObserver, injectMutationObserver, injectNetworkInformation, injectPageVisibility, injectPerformanceObserver, injectResizeObserver, injectScreenOrientation, permissionGuard, provideBarcodeDetector, provideBattery, provideBroadcastChannel, provideBrowserWebApis, provideCamera, provideClipboard, provideCommunicationApis, provideCredentialManagement, provideEyeDropper, provideFileSystemAccess, provideFullscreen, provideGamepad, provideGeolocation, provideIdleDetector, provideIntersectionObserver, provideLocationApis, provideMediaApis, provideMediaDevices, provideMediaRecorder, provideMutationObserver, provideNetworkInformation, provideNotifications, providePageVisibility, providePaymentRequest, providePerformanceObserver, providePermissions, provideResizeObserver, provideScreenOrientation, provideScreenWakeLock, provideServerSentEvents, provideSpeechSynthesis, provideStorageApis, provideVibration, provideWebAudio, provideWebBluetooth, provideWebNfc, provideWebShare, provideWebSocket, provideWebStorage, provideWebUsb, provideWebWorker, version };
|
|
3632
|
+
export { BROWSER_API_LOGGER, BarcodeDetectorService, BatteryService, BroadcastChannelService, BrowserApiBaseService, BrowserCapabilityService, BrowserSupportUtil, CameraService, ClipboardService, ConnectionRegistryBaseService, CredentialManagementService, EyeDropperService, FileSystemAccessService, FullscreenService, GamepadService, GeolocationService, IdleDetectorService, IntersectionObserverService, MediaDevicesService, MediaRecorderService, MutationObserverService, NetworkInformationService, NotificationService, PageVisibilityService, PaymentRequestService, PerformanceObserverService, PermissionsService, ResizeObserverService, ScreenOrientationService, ScreenWakeLockService, ServerSentEventsService, SpeechSynthesisService, VibrationService, WebAudioService, WebBluetoothService, WebNfcService, WebShareService, WebSocketService, WebStorageService, WebUsbService, WebWorkerService, permissionGuard as createPermissionGuard, defaultBrowserWebApisConfig, injectGamepad, injectIdleDetector, injectIntersectionObserver, injectMutationObserver, injectNetworkInformation, injectPageVisibility, injectPerformanceObserver, injectResizeObserver, injectScreenOrientation, permissionGuard, provideBarcodeDetector, provideBattery, provideBroadcastChannel, provideBrowserWebApis, provideCamera, provideClipboard, provideCommunicationApis, provideCredentialManagement, provideEyeDropper, provideFileSystemAccess, provideFullscreen, provideGamepad, provideGeolocation, provideIdleDetector, provideIntersectionObserver, provideLocationApis, provideMediaApis, provideMediaDevices, provideMediaRecorder, provideMutationObserver, provideNetworkInformation, provideNotifications, providePageVisibility, providePaymentRequest, providePerformanceObserver, providePermissions, provideResizeObserver, provideScreenOrientation, provideScreenWakeLock, provideServerSentEvents, provideSpeechSynthesis, provideStorageApis, provideVibration, provideWebAudio, provideWebBluetooth, provideWebNfc, provideWebShare, provideWebSocket, provideWebStorage, provideWebUsb, provideWebWorker, version };
|