@angular-helpers/browser-web-apis 21.0.2 → 21.2.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
ADDED
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
# @angular-helpers/browser-web-apis
|
|
2
|
+
|
|
3
|
+
Paquete de servicios Angular para acceder de forma estructurada y segura a Browser Web APIs.
|
|
4
|
+
|
|
5
|
+
🌐 **Documentación y Demo**: https://gaspar1992.github.io/angular-helpers/
|
|
6
|
+
|
|
7
|
+
[Read in English](./README.md)
|
|
8
|
+
|
|
9
|
+
## Caracteristicas
|
|
10
|
+
|
|
11
|
+
- Seguridad integrada con prevencion de ReDoS usando Web Workers
|
|
12
|
+
- Acceso unificado a APIs del navegador mediante servicios tipados
|
|
13
|
+
- Arquitectura tree-shakable
|
|
14
|
+
- Configuracion modular para habilitar solo lo necesario
|
|
15
|
+
- APIs reactivas con signals y observables
|
|
16
|
+
- Integracion segura con el ciclo de vida usando `destroyRef`
|
|
17
|
+
|
|
18
|
+
## Servicios disponibles
|
|
19
|
+
|
|
20
|
+
### APIs de medios y dispositivo
|
|
21
|
+
|
|
22
|
+
- `CameraService` - Acceso a camara con gestion de permisos
|
|
23
|
+
- `MediaDevicesService` - Enumeracion y gestion de dispositivos multimedia
|
|
24
|
+
- `GeolocationService` - Acceso a la API de geolocalizacion
|
|
25
|
+
- `NotificationService` - API de notificaciones del navegador
|
|
26
|
+
- `MediaRecorderService` - Grabar audio/video desde MediaStream
|
|
27
|
+
|
|
28
|
+
### APIs de observadores
|
|
29
|
+
|
|
30
|
+
- `IntersectionObserverService` - Detectar cuando elementos entran/salen del viewport
|
|
31
|
+
- `ResizeObserverService` - Observar cambios de tamano de elementos
|
|
32
|
+
|
|
33
|
+
### APIs de sistema
|
|
34
|
+
|
|
35
|
+
- `BatteryService` - Monitorear estado de bateria y carga
|
|
36
|
+
- `PageVisibilityService` - Rastrear cambios de visibilidad del documento
|
|
37
|
+
- `ScreenWakeLockService` - Evitar que la pantalla se atenue o bloquee
|
|
38
|
+
- `ScreenOrientationService` - Leer y bloquear orientacion de pantalla
|
|
39
|
+
- `FullscreenService` - Alternar modo pantalla completa para elementos
|
|
40
|
+
- `VibrationService` - Activar patrones de retroalimentacion tactil
|
|
41
|
+
- `SpeechSynthesisService` - Texto a voz con seleccion de voz
|
|
42
|
+
|
|
43
|
+
### APIs de red
|
|
44
|
+
|
|
45
|
+
- `WebSocketService` - Gestion de conexiones WebSocket
|
|
46
|
+
- `ServerSentEventsService` - Cliente de Server-Sent Events
|
|
47
|
+
- `BroadcastChannelService` - Comunicacion entre pestanas
|
|
48
|
+
- `NetworkInformationService` - Informacion de conexion y estado online
|
|
49
|
+
|
|
50
|
+
### APIs de almacenamiento y E/S
|
|
51
|
+
|
|
52
|
+
- `WebStorageService` - Helpers para LocalStorage y SessionStorage
|
|
53
|
+
- `WebShareService` - Soporte para Web Share API nativa
|
|
54
|
+
- `ClipboardService` - Acceso al portapapeles del sistema
|
|
55
|
+
- `FileSystemAccessService` - Abrir/guardar archivos via selector nativo
|
|
56
|
+
|
|
57
|
+
### Web APIs
|
|
58
|
+
|
|
59
|
+
- `WebWorkerService` - Gestion de Web Workers
|
|
60
|
+
|
|
61
|
+
### Seguridad y capacidades
|
|
62
|
+
|
|
63
|
+
- `PermissionsService` - Gestion centralizada de permisos del navegador
|
|
64
|
+
- `BrowserCapabilityService` - Deteccion de soporte de APIs del navegador
|
|
65
|
+
|
|
66
|
+
### Utilidades
|
|
67
|
+
|
|
68
|
+
- `BrowserApiBaseService` - Clase base compartida para servicios de Browser APIs
|
|
69
|
+
|
|
70
|
+
## Instalacion
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm install @angular-helpers/browser-web-apis
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Configuracion rapida
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { provideBrowserWebApis } from '@angular-helpers/browser-web-apis';
|
|
80
|
+
|
|
81
|
+
bootstrapApplication(AppComponent, {
|
|
82
|
+
providers: [
|
|
83
|
+
provideBrowserWebApis({
|
|
84
|
+
enableCamera: true,
|
|
85
|
+
enableGeolocation: true,
|
|
86
|
+
enableNotifications: true,
|
|
87
|
+
}),
|
|
88
|
+
],
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Uso por servicio
|
|
93
|
+
|
|
94
|
+
### CameraService
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { CameraService } from '@angular-helpers/browser-web-apis';
|
|
98
|
+
|
|
99
|
+
export class PhotoComponent {
|
|
100
|
+
private cameraService = inject(CameraService);
|
|
101
|
+
|
|
102
|
+
async takePhoto() {
|
|
103
|
+
try {
|
|
104
|
+
const stream = await this.cameraService.startCamera({
|
|
105
|
+
video: true,
|
|
106
|
+
audio: false,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Usa el stream para captura de foto o video
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error('Error accessing camera:', error);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async stopCamera() {
|
|
116
|
+
await this.cameraService.stopCamera();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### BrowserCapabilityService
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import { BrowserCapabilityService } from '@angular-helpers/browser-web-apis';
|
|
125
|
+
|
|
126
|
+
export class MyComponent {
|
|
127
|
+
private capability = inject(BrowserCapabilityService);
|
|
128
|
+
|
|
129
|
+
ngOnInit() {
|
|
130
|
+
if (this.capability.isSupported('geolocation')) {
|
|
131
|
+
console.log('La geolocalizacion esta disponible');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
> Para prevención de ReDoS, usa el paquete `@angular-helpers/security`.
|
|
138
|
+
|
|
139
|
+
### GeolocationService
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { GeolocationService } from '@angular-helpers/browser-web-apis';
|
|
143
|
+
|
|
144
|
+
export class LocationComponent {
|
|
145
|
+
private geolocation = inject(GeolocationService);
|
|
146
|
+
|
|
147
|
+
async getCurrentLocation() {
|
|
148
|
+
try {
|
|
149
|
+
const position = await this.geolocation.getCurrentPosition({
|
|
150
|
+
enableHighAccuracy: true,
|
|
151
|
+
timeout: 10000,
|
|
152
|
+
maximumAge: 60000,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
console.log('Position:', position.coords);
|
|
156
|
+
} catch (error) {
|
|
157
|
+
console.error('Error getting location:', error);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### IntersectionObserverService
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { IntersectionObserverService } from '@angular-helpers/browser-web-apis';
|
|
167
|
+
|
|
168
|
+
export class LazyImageComponent {
|
|
169
|
+
private intersectionService = inject(IntersectionObserverService);
|
|
170
|
+
private elementRef = inject(ElementRef);
|
|
171
|
+
|
|
172
|
+
isVisible = signal(false);
|
|
173
|
+
|
|
174
|
+
ngAfterViewInit() {
|
|
175
|
+
this.intersectionService
|
|
176
|
+
.observeVisibility(this.elementRef.nativeElement, { threshold: 0.5 })
|
|
177
|
+
.subscribe((visible) => this.isVisible.set(visible));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### ResizeObserverService
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
import { ResizeObserverService } from '@angular-helpers/browser-web-apis';
|
|
186
|
+
|
|
187
|
+
export class ResponsiveComponent {
|
|
188
|
+
private resizeService = inject(ResizeObserverService);
|
|
189
|
+
private elementRef = inject(ElementRef);
|
|
190
|
+
|
|
191
|
+
elementSize = signal<ElementSize | null>(null);
|
|
192
|
+
|
|
193
|
+
ngAfterViewInit() {
|
|
194
|
+
this.resizeService
|
|
195
|
+
.observeSize(this.elementRef.nativeElement)
|
|
196
|
+
.subscribe((size) => this.elementSize.set(size));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### PageVisibilityService
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
import { PageVisibilityService } from '@angular-helpers/browser-web-apis';
|
|
205
|
+
|
|
206
|
+
export class AnalyticsComponent {
|
|
207
|
+
private visibilityService = inject(PageVisibilityService);
|
|
208
|
+
|
|
209
|
+
ngOnInit() {
|
|
210
|
+
this.visibilityService.watch().subscribe((state) => {
|
|
211
|
+
console.log('La pagina ahora esta:', state);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### FullscreenService
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
import { FullscreenService } from '@angular-helpers/browser-web-apis';
|
|
221
|
+
|
|
222
|
+
export class VideoPlayerComponent {
|
|
223
|
+
private fullscreenService = inject(FullscreenService);
|
|
224
|
+
|
|
225
|
+
async toggleFullscreen() {
|
|
226
|
+
await this.fullscreenService.toggle();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### ScreenWakeLockService
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
import { ScreenWakeLockService } from '@angular-helpers/browser-web-apis';
|
|
235
|
+
|
|
236
|
+
export class PresentationComponent {
|
|
237
|
+
private wakeLockService = inject(ScreenWakeLockService);
|
|
238
|
+
|
|
239
|
+
async keepScreenOn() {
|
|
240
|
+
await this.wakeLockService.request();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async releaseScreen() {
|
|
244
|
+
await this.wakeLockService.release();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### BroadcastChannelService
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
import { BroadcastChannelService } from '@angular-helpers/browser-web-apis';
|
|
253
|
+
|
|
254
|
+
export class SyncComponent {
|
|
255
|
+
private broadcastService = inject(BroadcastChannelService);
|
|
256
|
+
|
|
257
|
+
ngOnInit() {
|
|
258
|
+
// Escuchar mensajes de otras pestanas
|
|
259
|
+
this.broadcastService.open<string>('app-sync').subscribe((msg) => {
|
|
260
|
+
console.log('Recibido:', msg);
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
sendMessage(data: string) {
|
|
265
|
+
this.broadcastService.post('app-sync', data);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### ServerSentEventsService
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
import { ServerSentEventsService } from '@angular-helpers/browser-web-apis';
|
|
274
|
+
|
|
275
|
+
export class LiveFeedComponent {
|
|
276
|
+
private sseService = inject(ServerSentEventsService);
|
|
277
|
+
|
|
278
|
+
connectToEvents() {
|
|
279
|
+
this.sseService.connect('https://api.example.com/events').subscribe({
|
|
280
|
+
next: (message) => console.log('Evento:', message),
|
|
281
|
+
error: (err) => console.error('Error SSE:', err),
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### VibrationService
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
import { VibrationService } from '@angular-helpers/browser-web-apis';
|
|
291
|
+
|
|
292
|
+
export class FeedbackComponent {
|
|
293
|
+
private vibrationService = inject(VibrationService);
|
|
294
|
+
|
|
295
|
+
onSuccess() {
|
|
296
|
+
this.vibrationService.success();
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
onError() {
|
|
300
|
+
this.vibrationService.error();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### SpeechSynthesisService
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
import { SpeechSynthesisService } from '@angular-helpers/browser-web-apis';
|
|
309
|
+
|
|
310
|
+
export class VoiceComponent {
|
|
311
|
+
private speechService = inject(SpeechSynthesisService);
|
|
312
|
+
|
|
313
|
+
speakText(text: string) {
|
|
314
|
+
this.speechService.speak(text).subscribe((state) => {
|
|
315
|
+
console.log('Estado de voz:', state);
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### ScreenOrientationService
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
import { ScreenOrientationService } from '@angular-helpers/browser-web-apis';
|
|
325
|
+
|
|
326
|
+
export class MobileComponent {
|
|
327
|
+
private orientationService = inject(ScreenOrientationService);
|
|
328
|
+
|
|
329
|
+
ngOnInit() {
|
|
330
|
+
// Observar cambios de orientacion
|
|
331
|
+
this.orientationService.watch().subscribe((orientation) => {
|
|
332
|
+
console.log('Orientacion:', orientation.type, 'Angulo:', orientation.angle);
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
async lockPortrait() {
|
|
337
|
+
try {
|
|
338
|
+
await this.orientationService.lock('portrait');
|
|
339
|
+
} catch (error) {
|
|
340
|
+
console.error('No se pudo bloquear la orientacion:', error);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
unlockOrientation() {
|
|
345
|
+
this.orientationService.unlock();
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### BatteryService
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
import { BatteryService } from '@angular-helpers/browser-web-apis';
|
|
354
|
+
|
|
355
|
+
export class PowerComponent {
|
|
356
|
+
private batteryService = inject(BatteryService);
|
|
357
|
+
|
|
358
|
+
async ngOnInit() {
|
|
359
|
+
try {
|
|
360
|
+
// Inicializar y obtener informacion inicial de la bateria
|
|
361
|
+
const batteryInfo = await this.batteryService.initialize();
|
|
362
|
+
console.log('Nivel de bateria:', batteryInfo.level);
|
|
363
|
+
console.log('Esta cargando:', batteryInfo.charging);
|
|
364
|
+
|
|
365
|
+
// Observar cambios de bateria
|
|
366
|
+
this.batteryService.watchBatteryInfo().subscribe((info) => {
|
|
367
|
+
console.log('Bateria actualizada:', info);
|
|
368
|
+
});
|
|
369
|
+
} catch (error) {
|
|
370
|
+
console.error('Battery API no soportada:', error);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### ClipboardService
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
import { ClipboardService } from '@angular-helpers/browser-web-apis';
|
|
380
|
+
|
|
381
|
+
export class CopyComponent {
|
|
382
|
+
private clipboardService = inject(ClipboardService);
|
|
383
|
+
|
|
384
|
+
async copyToClipboard(text: string) {
|
|
385
|
+
try {
|
|
386
|
+
await this.clipboardService.writeText(text);
|
|
387
|
+
console.log('Copiado exitosamente');
|
|
388
|
+
} catch (error) {
|
|
389
|
+
console.error('Error al copiar:', error);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
async pasteFromClipboard(): Promise<string> {
|
|
394
|
+
try {
|
|
395
|
+
const text = await this.clipboardService.readText();
|
|
396
|
+
return text;
|
|
397
|
+
} catch (error) {
|
|
398
|
+
console.error('Error al leer el portapapeles:', error);
|
|
399
|
+
return '';
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### FileSystemAccessService
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
import { FileSystemAccessService } from '@angular-helpers/browser-web-apis';
|
|
409
|
+
|
|
410
|
+
export class FileManagerComponent {
|
|
411
|
+
private fileService = inject(FileSystemAccessService);
|
|
412
|
+
|
|
413
|
+
async openFiles() {
|
|
414
|
+
try {
|
|
415
|
+
const files = await this.fileService.openFile({
|
|
416
|
+
multiple: true,
|
|
417
|
+
types: [
|
|
418
|
+
{
|
|
419
|
+
description: 'Archivos de texto',
|
|
420
|
+
accept: { 'text/plain': ['.txt'] },
|
|
421
|
+
},
|
|
422
|
+
],
|
|
423
|
+
});
|
|
424
|
+
console.log('Archivos seleccionados:', files);
|
|
425
|
+
} catch (error) {
|
|
426
|
+
console.error('Error al abrir archivos:', error);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
async saveContent(content: string) {
|
|
431
|
+
try {
|
|
432
|
+
await this.fileService.saveFile(content, {
|
|
433
|
+
suggestedName: 'documento.txt',
|
|
434
|
+
});
|
|
435
|
+
} catch (error) {
|
|
436
|
+
console.error('Error al guardar archivo:', error);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### MediaRecorderService
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
import { MediaRecorderService } from '@angular-helpers/browser-web-apis';
|
|
446
|
+
|
|
447
|
+
export class RecorderComponent {
|
|
448
|
+
private recorderService = inject(MediaRecorderService);
|
|
449
|
+
private stream: MediaStream | null = null;
|
|
450
|
+
|
|
451
|
+
async startRecording() {
|
|
452
|
+
try {
|
|
453
|
+
this.stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
|
|
454
|
+
await this.recorderService.start(this.stream, { mimeType: 'video/webm' });
|
|
455
|
+
} catch (error) {
|
|
456
|
+
console.error('Error al iniciar la grabacion:', error);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
stopRecording() {
|
|
461
|
+
const result = this.recorderService.stop();
|
|
462
|
+
if (result) {
|
|
463
|
+
console.log('Grabacion guardada, URL del blob:', result.url);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### WebSocketService
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
import { WebSocketService } from '@angular-helpers/browser-web-apis';
|
|
473
|
+
|
|
474
|
+
export class LiveComponent {
|
|
475
|
+
private wsService = inject(WebSocketService);
|
|
476
|
+
|
|
477
|
+
connect() {
|
|
478
|
+
this.wsService
|
|
479
|
+
.connect({
|
|
480
|
+
url: 'wss://example.com/socket',
|
|
481
|
+
reconnectInterval: 3000,
|
|
482
|
+
maxReconnectAttempts: 5,
|
|
483
|
+
})
|
|
484
|
+
.subscribe((status) => {
|
|
485
|
+
console.log('Estado de conexion:', status);
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
this.wsService.getMessages().subscribe((message) => {
|
|
489
|
+
console.log('Recibido:', message);
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
sendMessage(data: unknown) {
|
|
494
|
+
this.wsService.send({ type: 'message', data });
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### WebStorageService
|
|
500
|
+
|
|
501
|
+
```typescript
|
|
502
|
+
import { WebStorageService } from '@angular-helpers/browser-web-apis';
|
|
503
|
+
|
|
504
|
+
export class SettingsComponent {
|
|
505
|
+
private storageService = inject(WebStorageService);
|
|
506
|
+
|
|
507
|
+
saveSetting(key: string, value: unknown) {
|
|
508
|
+
this.storageService.setLocalStorage(key, value);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
getSetting<T>(key: string): T | null {
|
|
512
|
+
return this.storageService.getLocalStorage<T>(key);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
watchSetting<T>(key: string) {
|
|
516
|
+
return this.storageService.watchLocalStorage<T>(key).subscribe((value) => {
|
|
517
|
+
console.log('Configuracion cambiada:', value);
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### WebWorkerService
|
|
524
|
+
|
|
525
|
+
```typescript
|
|
526
|
+
import { WebWorkerService } from '@angular-helpers/browser-web-apis';
|
|
527
|
+
|
|
528
|
+
export class WorkerComponent {
|
|
529
|
+
private workerService = inject(WebWorkerService);
|
|
530
|
+
|
|
531
|
+
async createWorker() {
|
|
532
|
+
this.workerService
|
|
533
|
+
.createWorker('calc-worker', '/assets/workers/calc.worker.js')
|
|
534
|
+
.subscribe((status) => {
|
|
535
|
+
console.log('Estado del worker:', status);
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
this.workerService.getMessages('calc-worker').subscribe((message) => {
|
|
539
|
+
console.log('Respuesta del worker:', message);
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
sendTask(data: unknown) {
|
|
544
|
+
this.workerService.postMessage('calc-worker', {
|
|
545
|
+
id: 'task-1',
|
|
546
|
+
type: 'CALCULATE',
|
|
547
|
+
data,
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
## Soporte de navegadores
|
|
554
|
+
|
|
555
|
+
Los servicios validan automaticamente el soporte del navegador y el manejo de rutas no soportadas:
|
|
556
|
+
|
|
557
|
+
- Chrome: soporte completo
|
|
558
|
+
- Firefox: soporte completo
|
|
559
|
+
- Safari: soporte parcial
|
|
560
|
+
- Edge: soporte completo
|
|
561
|
+
- Navegadores moviles: depende de plataforma y API
|
|
562
|
+
|
|
563
|
+
## Notas
|
|
564
|
+
|
|
565
|
+
- Varias APIs requieren contexto seguro (HTTPS)
|
|
566
|
+
- Algunas APIs requieren interaccion explicita del usuario
|
|
567
|
+
- El comportamiento de permisos varia segun el navegador
|
|
568
|
+
- Implementa siempre manejo de errores y fallback
|
|
569
|
+
|
|
570
|
+
## Licencia
|
|
571
|
+
|
|
572
|
+
MIT
|