uni-manager 0.0.5 → 0.0.7

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.
@@ -1,52 +1,496 @@
1
- import { BehaviorSubject } from 'rxjs';
1
+ import { BehaviorSubject, switchMap, mergeMap, concatMap, exhaustMap, throwError, of, EMPTY, defer, from, tap, catchError, finalize, timer, distinctUntilChanged } from 'rxjs';
2
+ import { isHttpErrorBody, UniHttpError } from 'uni-error';
3
+ import { isEqual } from 'lodash-es';
2
4
 
3
- class ErrorManager {
4
- // Store privato (Subject)
5
+ class UniErrorManager {
6
+ /** Store privato (Subject) */
5
7
  static { this.store = new BehaviorSubject(new Map()); }
6
- // Store pubblico (Observable)
7
- static { this.store$ = ErrorManager.store.asObservable(); }
8
- /**
9
- * Ottiene lo stato attuale della Map senza dover sottoscrivere l'observable
10
- */
8
+ /** Store pubblico (Observable) */
9
+ static { this.store$ = UniErrorManager.store.asObservable(); }
10
+ /** Ottiene lo stato attuale della Map senza dover sottoscrivere l'observable */
11
11
  static get currentErrors() {
12
- return ErrorManager.store.getValue();
12
+ return UniErrorManager.store.getValue();
13
13
  }
14
14
  /* ------------------------------ Methods ------------------------------ */
15
15
  /**
16
- * Aggiunge o aggiorna un errore (HTTP o FE) nello store.
17
- * Se l'errore esiste già (stesso ID), incrementa il contatore.
16
+ * Aggiunge o aggiorna un errore nello store.
17
+ * Se l'errore esiste già (stesso ID), incrementa il contatore 'count'.
18
18
  */
19
- static addError(error) {
20
- // Recupera lo stato attuale (la "foto" istantanea)
21
- const oldMap = ErrorManager.currentErrors;
22
- const oldError = oldMap.get(error.id);
23
- // Crea il nuovo oggetto errore con il conteggio aggiornato
24
- const newError = {
19
+ static addError(id, error) {
20
+ // Recupera l'ultimo stato (Map)
21
+ const oldMap = UniErrorManager.currentErrors;
22
+ // Tenta di recuperare l'oggetto corrente
23
+ const oldItem = oldMap.get(id);
24
+ // Crea il nuovo oggetto aggiornato (in base al recupero o meno di uno con lo stesso id)
25
+ const newItemMap = {
25
26
  ...error,
26
- count: oldError ? oldError.count + 1 : 1,
27
+ count: oldItem ? oldItem.count + 1 : 1,
27
28
  };
28
- // Aggiorna store
29
+ // Crea una nuova istanza della Map
29
30
  const newMap = new Map(oldMap);
30
- newMap.set(error.type === 'fe' ? (error.exception.functionName ?? '/') : error.id, newError);
31
- ErrorManager.store.next(newMap);
31
+ newMap.set(id, newItemMap);
32
+ // Aggiorna il nuovo stato notificando l'observer
33
+ UniErrorManager.store.next(newMap);
32
34
  }
33
35
  /**
34
36
  * Rimuove un errore tramite ID
35
37
  */
36
38
  static removeError(id) {
37
- const oldMap = ErrorManager.currentErrors;
39
+ // Recupera l'ultimo stato (Map)
40
+ const oldMap = UniErrorManager.currentErrors;
41
+ // Controllo: se non è presente l'item allora termina
38
42
  if (!oldMap.has(id))
39
43
  return;
40
44
  // Aggiorna store
41
45
  const newMap = new Map(oldMap);
42
46
  newMap.delete(id);
43
- ErrorManager.store.next(newMap);
47
+ UniErrorManager.store.next(newMap);
44
48
  }
45
49
  /**
46
50
  * Svuota completamente la lista degli errori
47
51
  */
48
52
  static clearAll() {
49
- ErrorManager.store.next(new Map());
53
+ UniErrorManager.store.next(new Map());
54
+ }
55
+ }
56
+
57
+ var MapOperator;
58
+ (function (MapOperator) {
59
+ /** Cancella la precedente richiesta, mantiene solo l’ultima */
60
+ MapOperator[MapOperator["SWITCH_MAP"] = 0] = "SWITCH_MAP";
61
+ /** Ignora nuovi valori finché la corrente non finisce */
62
+ MapOperator[MapOperator["EXHAUST_MAP"] = 1] = "EXHAUST_MAP";
63
+ /** Mette le richieste in coda, le esegue una alla volta */
64
+ MapOperator[MapOperator["CONCAT_MAP"] = 2] = "CONCAT_MAP";
65
+ /** Esegue tutte le richieste in parallelo, ordine non garantito */
66
+ MapOperator[MapOperator["MERGE_MAP"] = 3] = "MERGE_MAP";
67
+ })(MapOperator || (MapOperator = {}));
68
+ var PollingErrorMode;
69
+ (function (PollingErrorMode) {
70
+ /** Salta questa iterazione emettendo un undefined. Il polling continua al tick successivo. */
71
+ PollingErrorMode[PollingErrorMode["IGNORE"] = 0] = "IGNORE";
72
+ /** Salta questa iterazione senza emettere valori. Il polling continua al tick successivo. */
73
+ PollingErrorMode[PollingErrorMode["SKIP"] = 1] = "SKIP";
74
+ /** Interrompe il polling propagando l'errore. */
75
+ PollingErrorMode[PollingErrorMode["STOP"] = 2] = "STOP";
76
+ /** Ignora l'errore, lo salva (es. per UI), e continua il polling. Emette `undefined`. */
77
+ PollingErrorMode[PollingErrorMode["IGNORE_WITH_ERROR"] = 3] = "IGNORE_WITH_ERROR";
78
+ })(PollingErrorMode || (PollingErrorMode = {}));
79
+ var EmitValueMode;
80
+ (function (EmitValueMode) {
81
+ /** Aggiorna lo stato solo se arrivano dati nuovi (distinct) */
82
+ EmitValueMode[EmitValueMode["ON_NEW_DATA"] = 0] = "ON_NEW_DATA";
83
+ /** Aggiorna lo stato ad ogni chiamata, anche se i dati sono uguali */
84
+ EmitValueMode[EmitValueMode["EVERY_TIME"] = 1] = "EVERY_TIME";
85
+ })(EmitValueMode || (EmitValueMode = {}));
86
+
87
+ async function execute(url, init) {
88
+ try {
89
+ /* Esegue chiamata http */
90
+ const res = await fetch(url, init);
91
+ /* Nessun contenuto */
92
+ if (res.status === 204) {
93
+ return undefined;
94
+ }
95
+ /* Recupero se è un json */
96
+ const contentType = res.headers.get('content-type') ?? '';
97
+ const isJson = contentType.startsWith('application/json');
98
+ const isImage = contentType.startsWith('image/');
99
+ /* Errore HTTP (quindi risposta ricevuta ma non ok) */
100
+ if (!res.ok) {
101
+ let errorBody;
102
+ try {
103
+ const resClone = res.clone();
104
+ errorBody = isJson ? await resClone.json() : await resClone.text();
105
+ }
106
+ catch {
107
+ errorBody = await res.text();
108
+ }
109
+ if (isHttpErrorBody(errorBody)) {
110
+ const type = errorBody.exceptionType.includes('HttpRequestException') ? 'be' : 'ice';
111
+ throw new UniHttpError(type, res.status, url, errorBody);
112
+ }
113
+ else {
114
+ const error = new Error(`HTTP ${res.statusText}`);
115
+ throw new UniHttpError('base', res.status, url, {
116
+ exceptionMessage: error.message,
117
+ exceptionType: 'ErrorBase',
118
+ message: error.message,
119
+ stackTrace: error.stack ?? '',
120
+ });
121
+ }
122
+ }
123
+ return { res, type: isJson ? 'json' : isImage ? 'image' : null };
124
+ }
125
+ catch (error) {
126
+ if (error instanceof TypeError) {
127
+ throw new UniHttpError('network', -1, url, {
128
+ exceptionMessage: `${error.name}: ${error.message}\n${error.stack}`,
129
+ exceptionType: error.name,
130
+ message: error.message,
131
+ stackTrace: error.stack ?? '',
132
+ });
133
+ }
134
+ // Fallback
135
+ throw error;
136
+ }
137
+ }
138
+ async function executeHttp(url, init) {
139
+ /* Esegue chiamata http e vari controlli */
140
+ const executeRes = await execute(url, init);
141
+ if (!executeRes)
142
+ return undefined;
143
+ /* Recupero risposta */
144
+ const { res, type } = executeRes;
145
+ /* Successo JSON */
146
+ if (type === 'json') {
147
+ return (await res.json());
148
+ }
149
+ /* Successo testo */
150
+ const text = await res.text();
151
+ return text ? text : undefined;
152
+ }
153
+ async function executeImage(url, init) {
154
+ /* Esegue chiamata http e vari controlli */
155
+ const executeRes = await execute(url, init);
156
+ if (!executeRes)
157
+ return undefined;
158
+ /* Recupero risposta */
159
+ const { res, type } = executeRes;
160
+ /* Successo immagine */
161
+ if (type !== 'image') {
162
+ throw new Error(`Not image found`);
163
+ }
164
+ /* Successo immagine */
165
+ const blob = await res.blob();
166
+ return URL.createObjectURL(blob);
167
+ }
168
+
169
+ /**
170
+ * Aggiunge una nuova ref nello store solo se non è già presente.
171
+ * Se l'ID esiste già, l'operazione viene interrotta per preservare il dato originale.
172
+ */
173
+ function addRef(id, lineId, url, type) {
174
+ // Recupera l'ultimo stato (Map)
175
+ const oldMap = UniHttpManager.currentRefs;
176
+ // Controllo: se è presente l'item allora termina
177
+ if (oldMap.get(id))
178
+ return;
179
+ // Crea il nuovo oggetto (essendo un nuovo inserimento, i valori sono quelli di default)
180
+ const newItemMap = { type, lineId, url, hasError: false, pendingCount: 0 };
181
+ // Crea una nuova istanza della Map
182
+ const newMap = new Map(oldMap);
183
+ newMap.set(id, newItemMap);
184
+ // Aggiorna il nuovo stato notificando l'observer
185
+ UniHttpManager.store.next(newMap);
186
+ }
187
+ /**
188
+ * Rimuove un http ref tramite ID
189
+ */
190
+ function removeRef(id) {
191
+ // Recupera l'ultimo stato (Map)
192
+ const oldMap = UniHttpManager.currentRefs;
193
+ // Controllo: se non è presente l'item allora termina
194
+ if (!oldMap.has(id))
195
+ return;
196
+ // Aggiorna store
197
+ const newMap = new Map(oldMap);
198
+ newMap.delete(id);
199
+ UniHttpManager.store.next(newMap);
200
+ }
201
+ /**
202
+ * Aggiorna il contatore delle chiamate pendenti per una specifica ref.
203
+ * Incrementa o decrementa 'pendingCount' garantendo che non scenda mai sotto lo zero.
204
+ * Se la ref non esiste, l'operazione viene ignorata.
205
+ */
206
+ function updateRefIsLoading(id, delta) {
207
+ // Recupera l'ultimo stato (Map)
208
+ const oldMap = UniHttpManager.currentRefs;
209
+ // Tenta di recuperare l'oggetto corrente
210
+ const oldItem = oldMap.get(id);
211
+ // Controllo: se non è presente l'item allora termina
212
+ if (!oldItem)
213
+ return;
214
+ // Aggiorna l'oggetto
215
+ const newItemMap = {
216
+ ...oldItem,
217
+ pendingCount: Math.max(0, oldItem.pendingCount + delta),
218
+ };
219
+ // Crea una nuova istanza della Map
220
+ const newMap = new Map(oldMap);
221
+ newMap.set(id, newItemMap);
222
+ // Aggiorna il nuovo stato notificando l'observer
223
+ UniHttpManager.store.next(newMap);
224
+ }
225
+ /**
226
+ * Aggiorna lo stato di errore per una specifica ref.
227
+ * Se il valore di 'hasError' è identico a quello attuale o se la ref non esiste,
228
+ * l'operazione viene interrotta per evitare aggiornamenti inutili.
229
+ */
230
+ function updateRefHasError(id, hasError) {
231
+ // Recupera l'ultimo stato (Map)
232
+ const oldMap = UniHttpManager.currentRefs;
233
+ // Tenta di recuperare l'oggetto corrente
234
+ const oldItem = oldMap.get(id);
235
+ // Controllo: se non è presente l'item allora termina
236
+ if (!oldItem)
237
+ return;
238
+ // Controllo: se con lo stesso valore, salta
239
+ if (oldItem.hasError === hasError)
240
+ return;
241
+ // Aggiorna l'oggetto
242
+ const newItemMap = { ...oldItem, hasError };
243
+ // Crea una nuova istanza della Map
244
+ const newMap = new Map(oldMap);
245
+ newMap.set(id, newItemMap);
246
+ // Aggiorna il nuovo stato notificando l'observer
247
+ UniHttpManager.store.next(newMap);
248
+ }
249
+
250
+ function operatorHandler(operator) {
251
+ // Gestione della concorrenza in base al parametro
252
+ switch (operator) {
253
+ case MapOperator.EXHAUST_MAP:
254
+ return (project) => exhaustMap(project);
255
+ case MapOperator.CONCAT_MAP:
256
+ return (project) => concatMap(project);
257
+ case MapOperator.MERGE_MAP:
258
+ return (project) => mergeMap(project);
259
+ case MapOperator.SWITCH_MAP:
260
+ default:
261
+ return (project) => switchMap(project);
262
+ }
263
+ }
264
+ function errorHandler(err, errorMode, ref) {
265
+ // Controllo: sia effettivamente un errore di tipo 'UniHttpError'
266
+ if (!(err instanceof UniHttpError)) {
267
+ return throwError(() => err);
268
+ }
269
+ // Aggiorna la ref nella map
270
+ updateRefHasError(ref, true);
271
+ // Gestione dell'errore in base al parametro
272
+ switch (errorMode) {
273
+ case PollingErrorMode.IGNORE:
274
+ return of(undefined);
275
+ case PollingErrorMode.SKIP:
276
+ return EMPTY;
277
+ case PollingErrorMode.IGNORE_WITH_ERROR: {
278
+ UniErrorManager.addError(ref, err);
279
+ return of(undefined);
280
+ }
281
+ case PollingErrorMode.STOP:
282
+ default: {
283
+ UniErrorManager.addError(ref, err);
284
+ return throwError(() => err);
285
+ }
286
+ }
287
+ }
288
+
289
+ function http$(url, refType, config, promiseFactory) {
290
+ /* Recupero configurazione */
291
+ const { ref, hasLoader } = config;
292
+ return defer(() => {
293
+ const http$ = from(promiseFactory());
294
+ return http$.pipe(tap({
295
+ subscribe: () => {
296
+ /* Creazione reference */
297
+ addRef(ref, null, url, refType);
298
+ /* Incrementa per il loader */
299
+ if (hasLoader !== false) {
300
+ updateRefIsLoading(ref, 1);
301
+ }
302
+ },
303
+ unsubscribe: () => {
304
+ /* Rimozione reference */
305
+ removeRef(ref);
306
+ },
307
+ // TODO: toast
308
+ // next: (res) => {
309
+ // /* Mostra toast (se presente) */
310
+ // if (toast) {
311
+ // showToast(res, toast);
312
+ // }
313
+ // },
314
+ }), catchError((err) => {
315
+ /* Gestione errore */
316
+ return errorHandler(err, PollingErrorMode.STOP, ref);
317
+ }), finalize(() => {
318
+ /* Decrementa per il loader */
319
+ if (hasLoader !== false) {
320
+ updateRefIsLoading(ref, -1);
321
+ }
322
+ }));
323
+ });
324
+ }
325
+ function httpPolling$(url, config, promiseFactory) {
326
+ /* Recupero configurazione */
327
+ const { interval, ref, operator = MapOperator.SWITCH_MAP, errorMode = PollingErrorMode.STOP, emitValueMode = EmitValueMode.EVERY_TIME, firstIteration, } = config;
328
+ const timer$ = timer(0, interval);
329
+ const source$ = timer$.pipe(tap({
330
+ subscribe: () => {
331
+ /* Creazione reference */
332
+ addRef(ref, null, url, 'polling');
333
+ },
334
+ unsubscribe: () => {
335
+ /* Rimozione reference */
336
+ removeRef(ref);
337
+ },
338
+ }), operatorHandler(operator)((index) => {
339
+ /* Incrementa per il loader */
340
+ if (index === 0 && firstIteration?.hasLoader !== false) {
341
+ updateRefIsLoading(ref, 1);
342
+ }
343
+ return defer(() => {
344
+ const http$ = from(promiseFactory());
345
+ return http$.pipe(tap(() => {
346
+ /* Rimozione popup di errore nel caso di errorMode = 'IGNORE_WITH_ERROR' */
347
+ if (errorMode === PollingErrorMode.IGNORE_WITH_ERROR) {
348
+ updateRefHasError(ref, false);
349
+ UniErrorManager.removeError(ref);
350
+ }
351
+ // /* Prima risposta */
352
+ // if (index === 0 && firstIteration) {
353
+ // showToast(res, firstIteration.toast);
354
+ // }
355
+ }), catchError((err) => {
356
+ /* Gestione errore */
357
+ return errorHandler(err, errorMode, ref);
358
+ }), finalize(() => {
359
+ /* Decrementa per il loader */
360
+ if (index === 0 && firstIteration?.hasLoader !== false) {
361
+ updateRefIsLoading(ref, -1);
362
+ }
363
+ }));
364
+ });
365
+ }));
366
+ return emitValueMode === EmitValueMode.EVERY_TIME
367
+ ? source$
368
+ : source$.pipe(distinctUntilChanged((prev, cur) => isEqual(prev, cur)));
369
+ }
370
+
371
+ function getUrl(hostname, port, path) {
372
+ const base = `http://${hostname}:${port}`;
373
+ return new URL(`/api${path}`, base);
374
+ }
375
+
376
+ /* eslint-disable @typescript-eslint/no-explicit-any */
377
+ class UniHttpManager {
378
+ /** Store privato (Subject) */
379
+ static { this.store = new BehaviorSubject(new Map()); }
380
+ /** Store pubblico (Observable) */
381
+ static { this.store$ = this.store.asObservable(); }
382
+ /** Ottiene lo stato attuale della Map senza dover sottoscrivere l'observable */
383
+ static get currentRefs() {
384
+ return this.store.getValue();
385
+ }
386
+ /* ------------------------------------------------------------------------------- */
387
+ /* -------------------------------- Metodi: setup -------------------------------- */
388
+ /* ------------------------------------------------------------------------------- */
389
+ /**
390
+ * Inizializza la configurazione di rete del manager.
391
+ * Deve essere chiamato prima di effettuare qualsiasi richiesta HTTP.
392
+ */
393
+ static setup(hostname, port) {
394
+ this.hostname = hostname;
395
+ this.port = port;
396
+ }
397
+ /* ------------------------------------------------------------------------------- */
398
+ /* ------------------------------ Metodi: http one ------------------------------- */
399
+ /* ------------------------------------------------------------------------------- */
400
+ /** Esegue una singola richiesta HTTP GET.
401
+ * Utilizza il path configurato per costruire l'URL completo e restituisce un Observable del risultato.
402
+ */
403
+ static get$(config) {
404
+ /* Recupero configurazione */
405
+ const { path, init } = config;
406
+ const initCustom = { ...init, method: 'GET' };
407
+ const url = getUrl(this.hostname, this.port, path);
408
+ return http$(url, 'one', config, () => executeHttp(url, initCustom));
409
+ }
410
+ /**
411
+ * Recupera un'immagine tramite una richiesta GET e la trasforma in un formato gestibile (es. Blob o Base64).
412
+ * Delega la logica di conversione alla funzione executeImage.
413
+ */
414
+ static getImage$(config) {
415
+ /* Recupero configurazione */
416
+ const { path, init } = config;
417
+ const initCustom = { ...init, method: 'GET' };
418
+ const url = getUrl(this.hostname, this.port, path);
419
+ return http$(url, 'one', config, () => executeImage(url, initCustom));
420
+ }
421
+ /**
422
+ * Esegue una singola richiesta HTTP PUT per aggiornare una risorsa esistente.
423
+ */
424
+ static put$(config) {
425
+ /* Recupero configurazione */
426
+ const { path, init } = config;
427
+ const initCustom = { ...init, method: 'PUT' };
428
+ const url = getUrl(this.hostname, this.port, path);
429
+ return http$(url, 'one', config, () => executeHttp(url, initCustom));
430
+ }
431
+ /**
432
+ * Esegue una richiesta HTTP POST inviando un payload JSON nel corpo della richiesta.
433
+ * Imposta automaticamente l'header 'Content-Type' come 'application/json'.
434
+ */
435
+ static post$(config, body) {
436
+ /* Recupero configurazione */
437
+ const { path, init } = config;
438
+ const initCustom = {
439
+ ...init,
440
+ method: 'POST',
441
+ headers: {
442
+ ...init?.headers,
443
+ 'Content-Type': 'application/json',
444
+ },
445
+ body: JSON.stringify(body),
446
+ };
447
+ const url = getUrl(this.hostname, this.port, path);
448
+ return http$(url, 'one', config, () => executeHttp(url, initCustom));
449
+ }
450
+ /* ------------------------------------------------------------------------------- */
451
+ /* ---------------------------- Metodi: http polling ----------------------------- */
452
+ /* ------------------------------------------------------------------------------- */
453
+ /**
454
+ * Avvia un ciclo di polling basato su richieste GET.
455
+ * Continua a emettere valori in base alla configurazione di intervallo definita in HttpConfigPolling.
456
+ */
457
+ static getHttpPolling$(config) {
458
+ /* Recupero configurazione */
459
+ const { path, init } = config;
460
+ const initCustom = { ...init, method: 'GET' };
461
+ const url = getUrl(this.hostname, this.port, path);
462
+ return httpPolling$(url, config, () => executeHttp(url, initCustom));
463
+ }
464
+ /**
465
+ * Avvia un ciclo di polling basato su richieste POST.
466
+ * Invia il body specificato a ogni iterazione del ciclo.
467
+ */
468
+ static postHttpPolling$(config, body) {
469
+ /* Recupero configurazione */
470
+ const { path, init } = config;
471
+ const initCustom = {
472
+ ...init,
473
+ method: 'POST',
474
+ headers: { 'Content-Type': 'application/json' },
475
+ body: JSON.stringify(body),
476
+ };
477
+ const url = getUrl(this.hostname, this.port, path);
478
+ return httpPolling$(url, config, () => executeHttp(url, initCustom));
479
+ }
480
+ /* ------------------------------------------------------------------------------- */
481
+ /* --------------------------------- Metodi: ref --------------------------------- */
482
+ /* ------------------------------------------------------------------------------- */
483
+ /**
484
+ * Aggiorna lo stato di caricamento per una specifica reference.
485
+ */
486
+ static updateRefIsLoading(id, delta) {
487
+ updateRefIsLoading(id, delta);
488
+ }
489
+ /**
490
+ * Imposta o resetta lo stato di errore per una specifica reference.
491
+ */
492
+ static updateRefHasError(id, hasError) {
493
+ updateRefHasError(id, hasError);
50
494
  }
51
495
  }
52
496
 
@@ -58,5 +502,5 @@ class ErrorManager {
58
502
  * Generated bundle index. Do not edit.
59
503
  */
60
504
 
61
- export { ErrorManager };
505
+ export { EmitValueMode, MapOperator, PollingErrorMode, UniErrorManager, UniHttpManager };
62
506
  //# sourceMappingURL=uni-manager.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"uni-manager.mjs","sources":["../../../projects/uni-manager/src/lib/error/manager.ts","../../../projects/uni-manager/src/public-api.ts","../../../projects/uni-manager/src/uni-manager.ts"],"sourcesContent":["import { BehaviorSubject, type Observable } from 'rxjs';\r\nimport type { IUniFeError, IUniHttpError } from 'uni-error';\r\n\r\nexport class ErrorManager {\r\n // Store privato (Subject)\r\n private static store = new BehaviorSubject<Map<string, IUniFeError | IUniHttpError>>(new Map());\r\n\r\n // Store pubblico (Observable)\r\n public static store$: Observable<Map<string, IUniFeError | IUniHttpError>> =\r\n ErrorManager.store.asObservable();\r\n\r\n /**\r\n * Ottiene lo stato attuale della Map senza dover sottoscrivere l'observable\r\n */\r\n public static get currentErrors(): Map<string, IUniFeError | IUniHttpError> {\r\n return ErrorManager.store.getValue();\r\n }\r\n\r\n /* ------------------------------ Methods ------------------------------ */\r\n /**\r\n * Aggiunge o aggiorna un errore (HTTP o FE) nello store.\r\n * Se l'errore esiste già (stesso ID), incrementa il contatore.\r\n */\r\n public static addError(error: IUniHttpError | IUniFeError): void {\r\n // Recupera lo stato attuale (la \"foto\" istantanea)\r\n const oldMap = ErrorManager.currentErrors;\r\n const oldError = oldMap.get(error.id);\r\n\r\n // Crea il nuovo oggetto errore con il conteggio aggiornato\r\n const newError: IUniFeError | IUniHttpError = {\r\n ...error,\r\n count: oldError ? oldError.count + 1 : 1,\r\n };\r\n\r\n // Aggiorna store\r\n const newMap = new Map(oldMap);\r\n newMap.set(error.type === 'fe' ? (error.exception.functionName ?? '/') : error.id, newError);\r\n ErrorManager.store.next(newMap);\r\n }\r\n\r\n /**\r\n * Rimuove un errore tramite ID\r\n */\r\n public static removeError(id: string): void {\r\n const oldMap = ErrorManager.currentErrors;\r\n if (!oldMap.has(id)) return;\r\n\r\n // Aggiorna store\r\n const newMap = new Map(oldMap);\r\n newMap.delete(id);\r\n ErrorManager.store.next(newMap);\r\n }\r\n\r\n /**\r\n * Svuota completamente la lista degli errori\r\n */\r\n public static clearAll(): void {\r\n ErrorManager.store.next(new Map());\r\n }\r\n}\r\n","/*\r\n * Public API Surface of uni-manager\r\n */\r\n\r\nexport * from './lib/error';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;MAGa,YAAY,CAAA;;aAER,IAAK,CAAA,KAAA,GAAG,IAAI,eAAe,CAA2C,IAAI,GAAG,EAAE,CAAC,CAAC;;AAGlF,IAAA,SAAA,IAAA,CAAA,MAAM,GAClB,YAAY,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;AAEpC;;AAEG;AACI,IAAA,WAAW,aAAa,GAAA;AAC7B,QAAA,OAAO,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE;;;AAItC;;;AAGG;IACI,OAAO,QAAQ,CAAC,KAAkC,EAAA;;AAEvD,QAAA,MAAM,MAAM,GAAG,YAAY,CAAC,aAAa;QACzC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;;AAGrC,QAAA,MAAM,QAAQ,GAAgC;AAC5C,YAAA,GAAG,KAAK;AACR,YAAA,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC;SACzC;;AAGD,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;AAC9B,QAAA,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,YAAY,IAAI,GAAG,IAAI,KAAK,CAAC,EAAE,EAAE,QAAQ,CAAC;AAC5F,QAAA,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;;AAGjC;;AAEG;IACI,OAAO,WAAW,CAAC,EAAU,EAAA;AAClC,QAAA,MAAM,MAAM,GAAG,YAAY,CAAC,aAAa;AACzC,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE;;AAGrB,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;AAC9B,QAAA,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;AACjB,QAAA,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;;AAGjC;;AAEG;AACI,IAAA,OAAO,QAAQ,GAAA;QACpB,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;;;;ACzDtC;;AAEG;;ACFH;;AAEG;;;;"}
1
+ {"version":3,"file":"uni-manager.mjs","sources":["../../../projects/uni-manager/src/lib/error/manager.ts","../../../projects/uni-manager/src/lib/http/enum.ts","../../../projects/uni-manager/src/lib/http/execute.ts","../../../projects/uni-manager/src/lib/http/ref.ts","../../../projects/uni-manager/src/lib/http/handler.ts","../../../projects/uni-manager/src/lib/http/http.ts","../../../projects/uni-manager/src/lib/http/util.ts","../../../projects/uni-manager/src/lib/http/manager.ts","../../../projects/uni-manager/src/public-api.ts","../../../projects/uni-manager/src/uni-manager.ts"],"sourcesContent":["import { BehaviorSubject, type Observable } from 'rxjs';\r\nimport type { IUniFeError, IUniHttpError } from 'uni-error';\r\n\r\nexport class UniErrorManager {\r\n /** Store privato (Subject) */\r\n private static store = new BehaviorSubject<Map<string, IUniFeError | IUniHttpError>>(new Map());\r\n\r\n /** Store pubblico (Observable) */\r\n public static store$: Observable<Map<string, IUniFeError | IUniHttpError>> =\r\n UniErrorManager.store.asObservable();\r\n\r\n /** Ottiene lo stato attuale della Map senza dover sottoscrivere l'observable */\r\n public static get currentErrors(): Map<string, IUniFeError | IUniHttpError> {\r\n return UniErrorManager.store.getValue();\r\n }\r\n\r\n /* ------------------------------ Methods ------------------------------ */\r\n /**\r\n * Aggiunge o aggiorna un errore nello store.\r\n * Se l'errore esiste già (stesso ID), incrementa il contatore 'count'.\r\n */\r\n public static addError(id: string, error: IUniHttpError | IUniFeError): void {\r\n // Recupera l'ultimo stato (Map)\r\n const oldMap = UniErrorManager.currentErrors;\r\n\r\n // Tenta di recuperare l'oggetto corrente\r\n const oldItem = oldMap.get(id);\r\n\r\n // Crea il nuovo oggetto aggiornato (in base al recupero o meno di uno con lo stesso id)\r\n const newItemMap: IUniFeError | IUniHttpError = {\r\n ...error,\r\n count: oldItem ? oldItem.count + 1 : 1,\r\n };\r\n\r\n // Crea una nuova istanza della Map\r\n const newMap = new Map(oldMap);\r\n newMap.set(id, newItemMap);\r\n\r\n // Aggiorna il nuovo stato notificando l'observer\r\n UniErrorManager.store.next(newMap);\r\n }\r\n\r\n /**\r\n * Rimuove un errore tramite ID\r\n */\r\n public static removeError(id: string): void {\r\n // Recupera l'ultimo stato (Map)\r\n const oldMap = UniErrorManager.currentErrors;\r\n\r\n // Controllo: se non è presente l'item allora termina\r\n if (!oldMap.has(id)) return;\r\n\r\n // Aggiorna store\r\n const newMap = new Map(oldMap);\r\n newMap.delete(id);\r\n UniErrorManager.store.next(newMap);\r\n }\r\n\r\n /**\r\n * Svuota completamente la lista degli errori\r\n */\r\n public static clearAll(): void {\r\n UniErrorManager.store.next(new Map());\r\n }\r\n}\r\n","export enum MapOperator {\r\n\t/** Cancella la precedente richiesta, mantiene solo l’ultima */\r\n\tSWITCH_MAP,\r\n\r\n\t/** Ignora nuovi valori finché la corrente non finisce */\r\n\tEXHAUST_MAP,\r\n\r\n\t/** Mette le richieste in coda, le esegue una alla volta */\r\n\tCONCAT_MAP,\r\n\r\n\t/** Esegue tutte le richieste in parallelo, ordine non garantito */\r\n\tMERGE_MAP\r\n}\r\n\r\nexport enum PollingErrorMode {\r\n\t/** Salta questa iterazione emettendo un undefined. Il polling continua al tick successivo. */\r\n\tIGNORE,\r\n\r\n\t/** Salta questa iterazione senza emettere valori. Il polling continua al tick successivo. */\r\n\tSKIP,\r\n\r\n\t/** Interrompe il polling propagando l'errore. */\r\n\tSTOP,\r\n\r\n\t/** Ignora l'errore, lo salva (es. per UI), e continua il polling. Emette `undefined`. */\r\n\tIGNORE_WITH_ERROR\r\n}\r\n\r\nexport enum EmitValueMode {\r\n\t/** Aggiorna lo stato solo se arrivano dati nuovi (distinct) */\r\n\tON_NEW_DATA,\r\n\r\n\t/** Aggiorna lo stato ad ogni chiamata, anche se i dati sono uguali */\r\n\tEVERY_TIME\r\n}\r\n","import { isHttpErrorBody, UniHttpError } from 'uni-error';\r\n\r\nasync function execute(\r\n url: URL,\r\n init?: RequestInit,\r\n): Promise<{ res: Response; type: 'json' | 'image' | null } | undefined> {\r\n try {\r\n /* Esegue chiamata http */\r\n const res = await fetch(url, init);\r\n\r\n /* Nessun contenuto */\r\n if (res.status === 204) {\r\n return undefined;\r\n }\r\n\r\n /* Recupero se è un json */\r\n const contentType = res.headers.get('content-type') ?? '';\r\n const isJson = contentType.startsWith('application/json');\r\n const isImage = contentType.startsWith('image/');\r\n\r\n /* Errore HTTP (quindi risposta ricevuta ma non ok) */\r\n if (!res.ok) {\r\n let errorBody: unknown;\r\n\r\n try {\r\n const resClone = res.clone();\r\n errorBody = isJson ? await resClone.json() : await resClone.text();\r\n } catch {\r\n errorBody = await res.text();\r\n }\r\n\r\n if (isHttpErrorBody(errorBody)) {\r\n const type = errorBody.exceptionType.includes('HttpRequestException') ? 'be' : 'ice';\r\n throw new UniHttpError(type, res.status, url, errorBody);\r\n } else {\r\n const error = new Error(`HTTP ${res.statusText}`);\r\n throw new UniHttpError('base', res.status, url, {\r\n exceptionMessage: error.message,\r\n exceptionType: 'ErrorBase',\r\n message: error.message,\r\n stackTrace: error.stack ?? '',\r\n });\r\n }\r\n }\r\n\r\n return { res, type: isJson ? 'json' : isImage ? 'image' : null };\r\n } catch (error: unknown) {\r\n if (error instanceof TypeError) {\r\n throw new UniHttpError('network', -1, url, {\r\n exceptionMessage: `${error.name}: ${error.message}\\n${error.stack}`,\r\n exceptionType: error.name,\r\n message: error.message,\r\n stackTrace: error.stack ?? '',\r\n });\r\n }\r\n\r\n // Fallback\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function executeHttp<T>(url: URL, init?: RequestInit): Promise<T | undefined> {\r\n /* Esegue chiamata http e vari controlli */\r\n const executeRes = await execute(url, init);\r\n if (!executeRes) return undefined;\r\n\r\n /* Recupero risposta */\r\n const { res, type } = executeRes;\r\n\r\n /* Successo JSON */\r\n if (type === 'json') {\r\n return (await res.json()) as T;\r\n }\r\n\r\n /* Successo testo */\r\n const text = await res.text();\r\n return text ? (text as unknown as T) : undefined;\r\n}\r\n\r\nexport async function executeImage(url: URL, init?: RequestInit): Promise<string | undefined> {\r\n /* Esegue chiamata http e vari controlli */\r\n const executeRes = await execute(url, init);\r\n if (!executeRes) return undefined;\r\n\r\n /* Recupero risposta */\r\n const { res, type } = executeRes;\r\n\r\n /* Successo immagine */\r\n if (type !== 'image') {\r\n throw new Error(`Not image found`);\r\n }\r\n\r\n /* Successo immagine */\r\n const blob = await res.blob();\r\n return URL.createObjectURL(blob);\r\n}\r\n","import { UniHttpManager } from './manager';\r\nimport type { HttpRef } from './model';\r\n\r\n/**\r\n * Aggiunge una nuova ref nello store solo se non è già presente.\r\n * Se l'ID esiste già, l'operazione viene interrotta per preservare il dato originale.\r\n */\r\nexport function addRef(id: string, lineId: null, url: URL, type: HttpRef['type']): void {\r\n // Recupera l'ultimo stato (Map)\r\n const oldMap = UniHttpManager.currentRefs;\r\n\r\n // Controllo: se è presente l'item allora termina\r\n if (oldMap.get(id)) return;\r\n\r\n // Crea il nuovo oggetto (essendo un nuovo inserimento, i valori sono quelli di default)\r\n const newItemMap: HttpRef = { type, lineId, url, hasError: false, pendingCount: 0 };\r\n\r\n // Crea una nuova istanza della Map\r\n const newMap = new Map(oldMap);\r\n newMap.set(id, newItemMap);\r\n\r\n // Aggiorna il nuovo stato notificando l'observer\r\n UniHttpManager.store.next(newMap);\r\n}\r\n\r\n/**\r\n * Rimuove un http ref tramite ID\r\n */\r\nexport function removeRef(id: string): void {\r\n // Recupera l'ultimo stato (Map)\r\n const oldMap = UniHttpManager.currentRefs;\r\n\r\n // Controllo: se non è presente l'item allora termina\r\n if (!oldMap.has(id)) return;\r\n\r\n // Aggiorna store\r\n const newMap = new Map(oldMap);\r\n newMap.delete(id);\r\n UniHttpManager.store.next(newMap);\r\n}\r\n\r\n/**\r\n * Aggiorna il contatore delle chiamate pendenti per una specifica ref.\r\n * Incrementa o decrementa 'pendingCount' garantendo che non scenda mai sotto lo zero.\r\n * Se la ref non esiste, l'operazione viene ignorata.\r\n */\r\nexport function updateRefIsLoading(id: string, delta: -1 | 1): void {\r\n // Recupera l'ultimo stato (Map)\r\n const oldMap = UniHttpManager.currentRefs;\r\n\r\n // Tenta di recuperare l'oggetto corrente\r\n const oldItem = oldMap.get(id);\r\n\r\n // Controllo: se non è presente l'item allora termina\r\n if (!oldItem) return;\r\n\r\n // Aggiorna l'oggetto\r\n const newItemMap: HttpRef = {\r\n ...oldItem,\r\n pendingCount: Math.max(0, oldItem.pendingCount + delta),\r\n };\r\n\r\n // Crea una nuova istanza della Map\r\n const newMap = new Map(oldMap);\r\n newMap.set(id, newItemMap);\r\n\r\n // Aggiorna il nuovo stato notificando l'observer\r\n UniHttpManager.store.next(newMap);\r\n}\r\n\r\n/**\r\n * Aggiorna lo stato di errore per una specifica ref.\r\n * Se il valore di 'hasError' è identico a quello attuale o se la ref non esiste,\r\n * l'operazione viene interrotta per evitare aggiornamenti inutili.\r\n */\r\nexport function updateRefHasError(id: string, hasError: boolean): void {\r\n // Recupera l'ultimo stato (Map)\r\n const oldMap = UniHttpManager.currentRefs;\r\n\r\n // Tenta di recuperare l'oggetto corrente\r\n const oldItem = oldMap.get(id);\r\n\r\n // Controllo: se non è presente l'item allora termina\r\n if (!oldItem) return;\r\n\r\n // Controllo: se con lo stesso valore, salta\r\n if (oldItem.hasError === hasError) return;\r\n\r\n // Aggiorna l'oggetto\r\n const newItemMap: HttpRef = { ...oldItem, hasError };\r\n\r\n // Crea una nuova istanza della Map\r\n const newMap = new Map(oldMap);\r\n newMap.set(id, newItemMap);\r\n\r\n // Aggiorna il nuovo stato notificando l'observer\r\n UniHttpManager.store.next(newMap);\r\n}\r\n","import {\r\n concatMap,\r\n EMPTY,\r\n exhaustMap,\r\n mergeMap,\r\n Observable,\r\n of,\r\n type OperatorFunction,\r\n switchMap,\r\n throwError,\r\n} from 'rxjs';\r\nimport { UniHttpError } from 'uni-error';\r\n\r\nimport { UniErrorManager } from '../error';\r\nimport { MapOperator, PollingErrorMode } from './enum';\r\nimport { updateRefHasError } from './ref';\r\n\r\nexport function operatorHandler<T>(\r\n operator: MapOperator,\r\n): (\r\n project: (value: number) => Observable<T | undefined>,\r\n) => OperatorFunction<number, T | undefined> {\r\n // Gestione della concorrenza in base al parametro\r\n switch (operator) {\r\n case MapOperator.EXHAUST_MAP:\r\n return (project) => exhaustMap(project);\r\n case MapOperator.CONCAT_MAP:\r\n return (project) => concatMap(project);\r\n case MapOperator.MERGE_MAP:\r\n return (project) => mergeMap(project);\r\n case MapOperator.SWITCH_MAP:\r\n default:\r\n return (project) => switchMap(project);\r\n }\r\n}\r\n\r\nexport function errorHandler(\r\n err: unknown,\r\n errorMode: PollingErrorMode,\r\n ref: string,\r\n): Observable<undefined> {\r\n // Controllo: sia effettivamente un errore di tipo 'UniHttpError'\r\n if (!(err instanceof UniHttpError)) {\r\n return throwError(() => err);\r\n }\r\n\r\n // Aggiorna la ref nella map\r\n updateRefHasError(ref, true);\r\n\r\n // Gestione dell'errore in base al parametro\r\n switch (errorMode) {\r\n case PollingErrorMode.IGNORE:\r\n return of(undefined);\r\n case PollingErrorMode.SKIP:\r\n return EMPTY;\r\n case PollingErrorMode.IGNORE_WITH_ERROR: {\r\n UniErrorManager.addError(ref, err);\r\n return of(undefined);\r\n }\r\n case PollingErrorMode.STOP:\r\n default: {\r\n UniErrorManager.addError(ref, err);\r\n return throwError(() => err);\r\n }\r\n }\r\n}\r\n","import { isEqual } from 'lodash-es';\r\nimport {\r\n catchError,\r\n defer,\r\n distinctUntilChanged,\r\n finalize,\r\n from,\r\n Observable,\r\n tap,\r\n timer,\r\n} from 'rxjs';\r\n\r\nimport { UniErrorManager } from '../error';\r\nimport { EmitValueMode, MapOperator, PollingErrorMode } from './enum';\r\nimport { errorHandler, operatorHandler } from './handler';\r\nimport type { HttpConfig, HttpConfigPolling, HttpRef } from './model';\r\nimport { addRef, removeRef, updateRefHasError, updateRefIsLoading } from './ref';\r\n\r\nexport function http$<T>(\r\n url: URL,\r\n refType: HttpRef['type'],\r\n config: HttpConfig<T>,\r\n promiseFactory: () => Promise<T | undefined>,\r\n): Observable<T | undefined> {\r\n /* Recupero configurazione */\r\n const { ref, hasLoader } = config;\r\n\r\n return defer(() => {\r\n const http$ = from(promiseFactory());\r\n return http$.pipe(\r\n tap({\r\n subscribe: () => {\r\n /* Creazione reference */\r\n addRef(ref, null, url, refType);\r\n\r\n /* Incrementa per il loader */\r\n if (hasLoader !== false) {\r\n updateRefIsLoading(ref, 1);\r\n }\r\n },\r\n unsubscribe: () => {\r\n /* Rimozione reference */\r\n removeRef(ref);\r\n },\r\n // TODO: toast\r\n // next: (res) => {\r\n // /* Mostra toast (se presente) */\r\n // if (toast) {\r\n // showToast(res, toast);\r\n // }\r\n // },\r\n }),\r\n catchError((err) => {\r\n /* Gestione errore */\r\n return errorHandler(err, PollingErrorMode.STOP, ref);\r\n }),\r\n finalize(() => {\r\n /* Decrementa per il loader */\r\n if (hasLoader !== false) {\r\n updateRefIsLoading(ref, -1);\r\n }\r\n }),\r\n );\r\n });\r\n}\r\n\r\nexport function httpPolling$<T>(\r\n url: URL,\r\n config: HttpConfigPolling<T>,\r\n promiseFactory: () => Promise<T | undefined>,\r\n): Observable<T | undefined> {\r\n /* Recupero configurazione */\r\n const {\r\n interval,\r\n ref,\r\n operator = MapOperator.SWITCH_MAP,\r\n errorMode = PollingErrorMode.STOP,\r\n emitValueMode = EmitValueMode.EVERY_TIME,\r\n firstIteration,\r\n } = config;\r\n\r\n const timer$ = timer(0, interval);\r\n const source$ = timer$.pipe(\r\n tap({\r\n subscribe: () => {\r\n /* Creazione reference */\r\n addRef(ref, null, url, 'polling');\r\n },\r\n unsubscribe: () => {\r\n /* Rimozione reference */\r\n removeRef(ref);\r\n },\r\n }),\r\n operatorHandler<T>(operator)((index) => {\r\n /* Incrementa per il loader */\r\n if (index === 0 && firstIteration?.hasLoader !== false) {\r\n updateRefIsLoading(ref, 1);\r\n }\r\n\r\n return defer(() => {\r\n const http$ = from(promiseFactory());\r\n return http$.pipe(\r\n tap(() => {\r\n /* Rimozione popup di errore nel caso di errorMode = 'IGNORE_WITH_ERROR' */\r\n if (errorMode === PollingErrorMode.IGNORE_WITH_ERROR) {\r\n updateRefHasError(ref, false);\r\n UniErrorManager.removeError(ref);\r\n }\r\n\r\n // /* Prima risposta */\r\n // if (index === 0 && firstIteration) {\r\n // showToast(res, firstIteration.toast);\r\n // }\r\n }),\r\n catchError((err) => {\r\n /* Gestione errore */\r\n return errorHandler(err, errorMode, ref);\r\n }),\r\n finalize(() => {\r\n /* Decrementa per il loader */\r\n if (index === 0 && firstIteration?.hasLoader !== false) {\r\n updateRefIsLoading(ref, -1);\r\n }\r\n }),\r\n );\r\n });\r\n }),\r\n );\r\n\r\n return emitValueMode === EmitValueMode.EVERY_TIME\r\n ? source$\r\n : source$.pipe(distinctUntilChanged((prev, cur) => isEqual(prev, cur)));\r\n}\r\n","export function getUrl(hostname: string, port: number, path: string): URL {\r\n const base = `http://${hostname}:${port}`;\r\n return new URL(`/api${path}`, base);\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\n\r\nimport { executeHttp, executeImage } from './execute';\r\nimport { http$, httpPolling$ } from './http';\r\nimport type { HttpConfig, HttpConfigPolling, HttpRef } from './model';\r\nimport { updateRefHasError, updateRefIsLoading } from './ref';\r\nimport { getUrl } from './util';\r\n\r\nexport class UniHttpManager {\r\n /** Store privato (Subject) */\r\n public static store = new BehaviorSubject<Map<string, HttpRef>>(new Map());\r\n\r\n /** Store pubblico (Observable) */\r\n public static store$: Observable<Map<string, HttpRef>> = this.store.asObservable();\r\n\r\n /** Ottiene lo stato attuale della Map senza dover sottoscrivere l'observable */\r\n public static get currentRefs(): Map<string, HttpRef> {\r\n return this.store.getValue();\r\n }\r\n\r\n /** Hostname del server (es. 'api.example.com' o 'localhost') */\r\n private static hostname: string;\r\n\r\n /** Porta del server su cui effettuare le chiamate (es. 80, 443 o 3000) */\r\n private static port: number;\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* -------------------------------- Metodi: setup -------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Inizializza la configurazione di rete del manager.\r\n * Deve essere chiamato prima di effettuare qualsiasi richiesta HTTP.\r\n */\r\n public static setup(hostname: string, port: number): void {\r\n this.hostname = hostname;\r\n this.port = port;\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* ------------------------------ Metodi: http one ------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /** Esegue una singola richiesta HTTP GET.\r\n * Utilizza il path configurato per costruire l'URL completo e restituisce un Observable del risultato.\r\n */\r\n public static get$<T>(config: HttpConfig<T>): Observable<T | undefined> {\r\n /* Recupero configurazione */\r\n const { path, init } = config;\r\n\r\n const initCustom: RequestInit = { ...init, method: 'GET' };\r\n const url = getUrl(this.hostname, this.port, path);\r\n return http$(url, 'one', config, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /**\r\n * Recupera un'immagine tramite una richiesta GET e la trasforma in un formato gestibile (es. Blob o Base64).\r\n * Delega la logica di conversione alla funzione executeImage.\r\n */\r\n public static getImage$(config: HttpConfig<string>): Observable<string | undefined> {\r\n /* Recupero configurazione */\r\n const { path, init } = config;\r\n\r\n const initCustom: RequestInit = { ...init, method: 'GET' };\r\n const url = getUrl(this.hostname, this.port, path);\r\n return http$(url, 'one', config, () => executeImage(url, initCustom));\r\n }\r\n\r\n /**\r\n * Esegue una singola richiesta HTTP PUT per aggiornare una risorsa esistente.\r\n */\r\n public static put$<T>(config: HttpConfig<T>): Observable<T | undefined> {\r\n /* Recupero configurazione */\r\n const { path, init } = config;\r\n\r\n const initCustom: RequestInit = { ...init, method: 'PUT' };\r\n const url = getUrl(this.hostname, this.port, path);\r\n return http$(url, 'one', config, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /**\r\n * Esegue una richiesta HTTP POST inviando un payload JSON nel corpo della richiesta.\r\n * Imposta automaticamente l'header 'Content-Type' come 'application/json'.\r\n */\r\n public static post$<T>(\r\n config: HttpConfig<T>,\r\n body: Record<string, any>,\r\n ): Observable<T | undefined> {\r\n /* Recupero configurazione */\r\n const { path, init } = config;\r\n\r\n const initCustom: RequestInit = {\r\n ...init,\r\n method: 'POST',\r\n headers: {\r\n ...init?.headers,\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify(body),\r\n };\r\n const url = getUrl(this.hostname, this.port, path);\r\n return http$(url, 'one', config, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* ---------------------------- Metodi: http polling ----------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Avvia un ciclo di polling basato su richieste GET.\r\n * Continua a emettere valori in base alla configurazione di intervallo definita in HttpConfigPolling.\r\n */\r\n public static getHttpPolling$<T>(config: HttpConfigPolling<T>): Observable<T | undefined> {\r\n /* Recupero configurazione */\r\n const { path, init } = config;\r\n\r\n const initCustom: RequestInit = { ...init, method: 'GET' };\r\n const url = getUrl(this.hostname, this.port, path);\r\n return httpPolling$(url, config, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /**\r\n * Avvia un ciclo di polling basato su richieste POST.\r\n * Invia il body specificato a ogni iterazione del ciclo.\r\n */\r\n public static postHttpPolling$<T>(\r\n config: HttpConfigPolling<T>,\r\n body: Record<any, any>,\r\n ): Observable<T | undefined> {\r\n /* Recupero configurazione */\r\n const { path, init } = config;\r\n\r\n const initCustom: RequestInit = {\r\n ...init,\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(body),\r\n };\r\n const url = getUrl(this.hostname, this.port, path);\r\n return httpPolling$(url, config, () => executeHttp<T>(url, initCustom));\r\n }\r\n\r\n /* ------------------------------------------------------------------------------- */\r\n /* --------------------------------- Metodi: ref --------------------------------- */\r\n /* ------------------------------------------------------------------------------- */\r\n /**\r\n * Aggiorna lo stato di caricamento per una specifica reference.\r\n */\r\n public static updateRefIsLoading(id: string, delta: -1 | 1): void {\r\n updateRefIsLoading(id, delta);\r\n }\r\n\r\n /**\r\n * Imposta o resetta lo stato di errore per una specifica reference.\r\n */\r\n public static updateRefHasError(id: string, hasError: boolean): void {\r\n updateRefHasError(id, hasError);\r\n }\r\n}\r\n","/*\r\n * Public API Surface of uni-manager\r\n */\r\n\r\nexport * from './lib/error';\r\nexport * from './lib/http';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;MAGa,eAAe,CAAA;;aAEX,IAAK,CAAA,KAAA,GAAG,IAAI,eAAe,CAA2C,IAAI,GAAG,EAAE,CAAC,CAAC;;AAGlF,IAAA,SAAA,IAAA,CAAA,MAAM,GAClB,eAAe,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;;AAGhC,IAAA,WAAW,aAAa,GAAA;AAC7B,QAAA,OAAO,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE;;;AAIzC;;;AAGG;AACI,IAAA,OAAO,QAAQ,CAAC,EAAU,EAAE,KAAkC,EAAA;;AAEnE,QAAA,MAAM,MAAM,GAAG,eAAe,CAAC,aAAa;;QAG5C,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;;AAG9B,QAAA,MAAM,UAAU,GAAgC;AAC9C,YAAA,GAAG,KAAK;AACR,YAAA,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC;SACvC;;AAGD,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;AAC9B,QAAA,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC;;AAG1B,QAAA,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;;AAGpC;;AAEG;IACI,OAAO,WAAW,CAAC,EAAU,EAAA;;AAElC,QAAA,MAAM,MAAM,GAAG,eAAe,CAAC,aAAa;;AAG5C,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE;;AAGrB,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;AAC9B,QAAA,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;AACjB,QAAA,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;;AAGpC;;AAEG;AACI,IAAA,OAAO,QAAQ,GAAA;QACpB,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;;;;IC9D7B;AAAZ,CAAA,UAAY,WAAW,EAAA;;AAEtB,IAAA,WAAA,CAAA,WAAA,CAAA,YAAA,CAAA,GAAA,CAAA,CAAA,GAAA,YAAU;;AAGV,IAAA,WAAA,CAAA,WAAA,CAAA,aAAA,CAAA,GAAA,CAAA,CAAA,GAAA,aAAW;;AAGX,IAAA,WAAA,CAAA,WAAA,CAAA,YAAA,CAAA,GAAA,CAAA,CAAA,GAAA,YAAU;;AAGV,IAAA,WAAA,CAAA,WAAA,CAAA,WAAA,CAAA,GAAA,CAAA,CAAA,GAAA,WAAS;AACV,CAAC,EAZW,WAAW,KAAX,WAAW,GAYtB,EAAA,CAAA,CAAA;IAEW;AAAZ,CAAA,UAAY,gBAAgB,EAAA;;AAE3B,IAAA,gBAAA,CAAA,gBAAA,CAAA,QAAA,CAAA,GAAA,CAAA,CAAA,GAAA,QAAM;;AAGN,IAAA,gBAAA,CAAA,gBAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAI;;AAGJ,IAAA,gBAAA,CAAA,gBAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAI;;AAGJ,IAAA,gBAAA,CAAA,gBAAA,CAAA,mBAAA,CAAA,GAAA,CAAA,CAAA,GAAA,mBAAiB;AAClB,CAAC,EAZW,gBAAgB,KAAhB,gBAAgB,GAY3B,EAAA,CAAA,CAAA;IAEW;AAAZ,CAAA,UAAY,aAAa,EAAA;;AAExB,IAAA,aAAA,CAAA,aAAA,CAAA,aAAA,CAAA,GAAA,CAAA,CAAA,GAAA,aAAW;;AAGX,IAAA,aAAA,CAAA,aAAA,CAAA,YAAA,CAAA,GAAA,CAAA,CAAA,GAAA,YAAU;AACX,CAAC,EANW,aAAa,KAAb,aAAa,GAMxB,EAAA,CAAA,CAAA;;AChCD,eAAe,OAAO,CACpB,GAAQ,EACR,IAAkB,EAAA;AAElB,IAAA,IAAI;;QAEF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC;;AAGlC,QAAA,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE;AACtB,YAAA,OAAO,SAAS;;;AAIlB,QAAA,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE;QACzD,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,kBAAkB,CAAC;QACzD,MAAM,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC;;AAGhD,QAAA,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE;AACX,YAAA,IAAI,SAAkB;AAEtB,YAAA,IAAI;AACF,gBAAA,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,EAAE;AAC5B,gBAAA,SAAS,GAAG,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE;;AAClE,YAAA,MAAM;AACN,gBAAA,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE;;AAG9B,YAAA,IAAI,eAAe,CAAC,SAAS,CAAC,EAAE;AAC9B,gBAAA,MAAM,IAAI,GAAG,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,sBAAsB,CAAC,GAAG,IAAI,GAAG,KAAK;AACpF,gBAAA,MAAM,IAAI,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,CAAC;;iBACnD;gBACL,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,CAAQ,KAAA,EAAA,GAAG,CAAC,UAAU,CAAE,CAAA,CAAC;gBACjD,MAAM,IAAI,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE;oBAC9C,gBAAgB,EAAE,KAAK,CAAC,OAAO;AAC/B,oBAAA,aAAa,EAAE,WAAW;oBAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;AACtB,oBAAA,UAAU,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;AAC9B,iBAAA,CAAC;;;QAIN,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,IAAI,EAAE;;IAChE,OAAO,KAAc,EAAE;AACvB,QAAA,IAAI,KAAK,YAAY,SAAS,EAAE;YAC9B,MAAM,IAAI,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE;AACzC,gBAAA,gBAAgB,EAAE,CAAA,EAAG,KAAK,CAAC,IAAI,CAAA,EAAA,EAAK,KAAK,CAAC,OAAO,CAAA,EAAA,EAAK,KAAK,CAAC,KAAK,CAAE,CAAA;gBACnE,aAAa,EAAE,KAAK,CAAC,IAAI;gBACzB,OAAO,EAAE,KAAK,CAAC,OAAO;AACtB,gBAAA,UAAU,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;AAC9B,aAAA,CAAC;;;AAIJ,QAAA,MAAM,KAAK;;AAEf;AAEO,eAAe,WAAW,CAAI,GAAQ,EAAE,IAAkB,EAAA;;IAE/D,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC;AAC3C,IAAA,IAAI,CAAC,UAAU;AAAE,QAAA,OAAO,SAAS;;AAGjC,IAAA,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,UAAU;;AAGhC,IAAA,IAAI,IAAI,KAAK,MAAM,EAAE;AACnB,QAAA,QAAQ,MAAM,GAAG,CAAC,IAAI,EAAE;;;AAI1B,IAAA,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE;IAC7B,OAAO,IAAI,GAAI,IAAqB,GAAG,SAAS;AAClD;AAEO,eAAe,YAAY,CAAC,GAAQ,EAAE,IAAkB,EAAA;;IAE7D,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC;AAC3C,IAAA,IAAI,CAAC,UAAU;AAAE,QAAA,OAAO,SAAS;;AAGjC,IAAA,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,UAAU;;AAGhC,IAAA,IAAI,IAAI,KAAK,OAAO,EAAE;AACpB,QAAA,MAAM,IAAI,KAAK,CAAC,CAAA,eAAA,CAAiB,CAAC;;;AAIpC,IAAA,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE;AAC7B,IAAA,OAAO,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC;AAClC;;AC5FA;;;AAGG;AACG,SAAU,MAAM,CAAC,EAAU,EAAE,MAAY,EAAE,GAAQ,EAAE,IAAqB,EAAA;;AAE9E,IAAA,MAAM,MAAM,GAAG,cAAc,CAAC,WAAW;;AAGzC,IAAA,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE;;AAGpB,IAAA,MAAM,UAAU,GAAY,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,EAAE;;AAGnF,IAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;AAC9B,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC;;AAG1B,IAAA,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AACnC;AAEA;;AAEG;AACG,SAAU,SAAS,CAAC,EAAU,EAAA;;AAElC,IAAA,MAAM,MAAM,GAAG,cAAc,CAAC,WAAW;;AAGzC,IAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE;;AAGrB,IAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;AAC9B,IAAA,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;AACjB,IAAA,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AACnC;AAEA;;;;AAIG;AACa,SAAA,kBAAkB,CAAC,EAAU,EAAE,KAAa,EAAA;;AAE1D,IAAA,MAAM,MAAM,GAAG,cAAc,CAAC,WAAW;;IAGzC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;;AAG9B,IAAA,IAAI,CAAC,OAAO;QAAE;;AAGd,IAAA,MAAM,UAAU,GAAY;AAC1B,QAAA,GAAG,OAAO;AACV,QAAA,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,YAAY,GAAG,KAAK,CAAC;KACxD;;AAGD,IAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;AAC9B,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC;;AAG1B,IAAA,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AACnC;AAEA;;;;AAIG;AACa,SAAA,iBAAiB,CAAC,EAAU,EAAE,QAAiB,EAAA;;AAE7D,IAAA,MAAM,MAAM,GAAG,cAAc,CAAC,WAAW;;IAGzC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;;AAG9B,IAAA,IAAI,CAAC,OAAO;QAAE;;AAGd,IAAA,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE;;IAGnC,MAAM,UAAU,GAAY,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE;;AAGpD,IAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;AAC9B,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC;;AAG1B,IAAA,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AACnC;;AChFM,SAAU,eAAe,CAC7B,QAAqB,EAAA;;IAKrB,QAAQ,QAAQ;QACd,KAAK,WAAW,CAAC,WAAW;YAC1B,OAAO,CAAC,OAAO,KAAK,UAAU,CAAC,OAAO,CAAC;QACzC,KAAK,WAAW,CAAC,UAAU;YACzB,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,OAAO,CAAC;QACxC,KAAK,WAAW,CAAC,SAAS;YACxB,OAAO,CAAC,OAAO,KAAK,QAAQ,CAAC,OAAO,CAAC;QACvC,KAAK,WAAW,CAAC,UAAU;AAC3B,QAAA;YACE,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,OAAO,CAAC;;AAE5C;SAEgB,YAAY,CAC1B,GAAY,EACZ,SAA2B,EAC3B,GAAW,EAAA;;AAGX,IAAA,IAAI,EAAE,GAAG,YAAY,YAAY,CAAC,EAAE;AAClC,QAAA,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC;;;AAI9B,IAAA,iBAAiB,CAAC,GAAG,EAAE,IAAI,CAAC;;IAG5B,QAAQ,SAAS;QACf,KAAK,gBAAgB,CAAC,MAAM;AAC1B,YAAA,OAAO,EAAE,CAAC,SAAS,CAAC;QACtB,KAAK,gBAAgB,CAAC,IAAI;AACxB,YAAA,OAAO,KAAK;AACd,QAAA,KAAK,gBAAgB,CAAC,iBAAiB,EAAE;AACvC,YAAA,eAAe,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;AAClC,YAAA,OAAO,EAAE,CAAC,SAAS,CAAC;;QAEtB,KAAK,gBAAgB,CAAC,IAAI;QAC1B,SAAS;AACP,YAAA,eAAe,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;AAClC,YAAA,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC;;;AAGlC;;AC/CM,SAAU,KAAK,CACnB,GAAQ,EACR,OAAwB,EACxB,MAAqB,EACrB,cAA4C,EAAA;;AAG5C,IAAA,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,MAAM;IAEjC,OAAO,KAAK,CAAC,MAAK;AAChB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;AACpC,QAAA,OAAO,KAAK,CAAC,IAAI,CACf,GAAG,CAAC;YACF,SAAS,EAAE,MAAK;;gBAEd,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC;;AAG/B,gBAAA,IAAI,SAAS,KAAK,KAAK,EAAE;AACvB,oBAAA,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC;;aAE7B;YACD,WAAW,EAAE,MAAK;;gBAEhB,SAAS,CAAC,GAAG,CAAC;aACf;;;;;;;;AAQF,SAAA,CAAC,EACF,UAAU,CAAC,CAAC,GAAG,KAAI;;YAEjB,OAAO,YAAY,CAAC,GAAG,EAAE,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC;AACtD,SAAC,CAAC,EACF,QAAQ,CAAC,MAAK;;AAEZ,YAAA,IAAI,SAAS,KAAK,KAAK,EAAE;AACvB,gBAAA,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;;SAE9B,CAAC,CACH;AACH,KAAC,CAAC;AACJ;SAEgB,YAAY,CAC1B,GAAQ,EACR,MAA4B,EAC5B,cAA4C,EAAA;;IAG5C,MAAM,EACJ,QAAQ,EACR,GAAG,EACH,QAAQ,GAAG,WAAW,CAAC,UAAU,EACjC,SAAS,GAAG,gBAAgB,CAAC,IAAI,EACjC,aAAa,GAAG,aAAa,CAAC,UAAU,EACxC,cAAc,GACf,GAAG,MAAM;IAEV,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;AACjC,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CACzB,GAAG,CAAC;QACF,SAAS,EAAE,MAAK;;YAEd,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC;SAClC;QACD,WAAW,EAAE,MAAK;;YAEhB,SAAS,CAAC,GAAG,CAAC;SACf;KACF,CAAC,EACF,eAAe,CAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,KAAI;;QAErC,IAAI,KAAK,KAAK,CAAC,IAAI,cAAc,EAAE,SAAS,KAAK,KAAK,EAAE;AACtD,YAAA,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC;;QAG5B,OAAO,KAAK,CAAC,MAAK;AAChB,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;AACpC,YAAA,OAAO,KAAK,CAAC,IAAI,CACf,GAAG,CAAC,MAAK;;AAEP,gBAAA,IAAI,SAAS,KAAK,gBAAgB,CAAC,iBAAiB,EAAE;AACpD,oBAAA,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC;AAC7B,oBAAA,eAAe,CAAC,WAAW,CAAC,GAAG,CAAC;;;;;;AAOpC,aAAC,CAAC,EACF,UAAU,CAAC,CAAC,GAAG,KAAI;;gBAEjB,OAAO,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC;AAC1C,aAAC,CAAC,EACF,QAAQ,CAAC,MAAK;;gBAEZ,IAAI,KAAK,KAAK,CAAC,IAAI,cAAc,EAAE,SAAS,KAAK,KAAK,EAAE;AACtD,oBAAA,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;;aAE9B,CAAC,CACH;AACH,SAAC,CAAC;KACH,CAAC,CACH;AAED,IAAA,OAAO,aAAa,KAAK,aAAa,CAAC;AACrC,UAAE;UACA,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;AAC3E;;SCpIgB,MAAM,CAAC,QAAgB,EAAE,IAAY,EAAE,IAAY,EAAA;AACjE,IAAA,MAAM,IAAI,GAAG,CAAA,OAAA,EAAU,QAAQ,CAAI,CAAA,EAAA,IAAI,EAAE;IACzC,OAAO,IAAI,GAAG,CAAC,CAAA,IAAA,EAAO,IAAI,CAAE,CAAA,EAAE,IAAI,CAAC;AACrC;;ACHA;MASa,cAAc,CAAA;;aAEX,IAAK,CAAA,KAAA,GAAG,IAAI,eAAe,CAAuB,IAAI,GAAG,EAAE,CAAC,CAAC;;AAG7D,IAAA,SAAA,IAAA,CAAA,MAAM,GAAqC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;;AAG5E,IAAA,WAAW,WAAW,GAAA;AAC3B,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;;;;;AAY9B;;;AAGG;AACI,IAAA,OAAO,KAAK,CAAC,QAAgB,EAAE,IAAY,EAAA;AAChD,QAAA,IAAI,CAAC,QAAQ,GAAG,QAAQ;AACxB,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI;;;;;AAMlB;;AAEG;IACI,OAAO,IAAI,CAAI,MAAqB,EAAA;;AAEzC,QAAA,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM;QAE7B,MAAM,UAAU,GAAgB,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE;AAC1D,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;AAClD,QAAA,OAAO,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAI,GAAG,EAAE,UAAU,CAAC,CAAC;;AAGzE;;;AAGG;IACI,OAAO,SAAS,CAAC,MAA0B,EAAA;;AAEhD,QAAA,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM;QAE7B,MAAM,UAAU,GAAgB,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE;AAC1D,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;AAClD,QAAA,OAAO,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;;AAGvE;;AAEG;IACI,OAAO,IAAI,CAAI,MAAqB,EAAA;;AAEzC,QAAA,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM;QAE7B,MAAM,UAAU,GAAgB,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE;AAC1D,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;AAClD,QAAA,OAAO,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAI,GAAG,EAAE,UAAU,CAAC,CAAC;;AAGzE;;;AAGG;AACI,IAAA,OAAO,KAAK,CACjB,MAAqB,EACrB,IAAyB,EAAA;;AAGzB,QAAA,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM;AAE7B,QAAA,MAAM,UAAU,GAAgB;AAC9B,YAAA,GAAG,IAAI;AACP,YAAA,MAAM,EAAE,MAAM;AACd,YAAA,OAAO,EAAE;gBACP,GAAG,IAAI,EAAE,OAAO;AAChB,gBAAA,cAAc,EAAE,kBAAkB;AACnC,aAAA;AACD,YAAA,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B;AACD,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;AAClD,QAAA,OAAO,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAI,GAAG,EAAE,UAAU,CAAC,CAAC;;;;;AAMzE;;;AAGG;IACI,OAAO,eAAe,CAAI,MAA4B,EAAA;;AAE3D,QAAA,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM;QAE7B,MAAM,UAAU,GAAgB,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE;AAC1D,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;AAClD,QAAA,OAAO,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,WAAW,CAAI,GAAG,EAAE,UAAU,CAAC,CAAC;;AAGzE;;;AAGG;AACI,IAAA,OAAO,gBAAgB,CAC5B,MAA4B,EAC5B,IAAsB,EAAA;;AAGtB,QAAA,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM;AAE7B,QAAA,MAAM,UAAU,GAAgB;AAC9B,YAAA,GAAG,IAAI;AACP,YAAA,MAAM,EAAE,MAAM;AACd,YAAA,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;AAC/C,YAAA,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B;AACD,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;AAClD,QAAA,OAAO,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,WAAW,CAAI,GAAG,EAAE,UAAU,CAAC,CAAC;;;;;AAMzE;;AAEG;AACI,IAAA,OAAO,kBAAkB,CAAC,EAAU,EAAE,KAAa,EAAA;AACxD,QAAA,kBAAkB,CAAC,EAAE,EAAE,KAAK,CAAC;;AAG/B;;AAEG;AACI,IAAA,OAAO,iBAAiB,CAAC,EAAU,EAAE,QAAiB,EAAA;AAC3D,QAAA,iBAAiB,CAAC,EAAE,EAAE,QAAQ,CAAC;;;;AC1JnC;;AAEG;;ACFH;;AAEG;;;;"}
@@ -1,17 +1,17 @@
1
1
  import { type Observable } from 'rxjs';
2
2
  import type { IUniFeError, IUniHttpError } from 'uni-error';
3
- export declare class ErrorManager {
3
+ export declare class UniErrorManager {
4
+ /** Store privato (Subject) */
4
5
  private static store;
6
+ /** Store pubblico (Observable) */
5
7
  static store$: Observable<Map<string, IUniFeError | IUniHttpError>>;
6
- /**
7
- * Ottiene lo stato attuale della Map senza dover sottoscrivere l'observable
8
- */
8
+ /** Ottiene lo stato attuale della Map senza dover sottoscrivere l'observable */
9
9
  static get currentErrors(): Map<string, IUniFeError | IUniHttpError>;
10
10
  /**
11
- * Aggiunge o aggiorna un errore (HTTP o FE) nello store.
12
- * Se l'errore esiste già (stesso ID), incrementa il contatore.
11
+ * Aggiunge o aggiorna un errore nello store.
12
+ * Se l'errore esiste già (stesso ID), incrementa il contatore 'count'.
13
13
  */
14
- static addError(error: IUniHttpError | IUniFeError): void;
14
+ static addError(id: string, error: IUniHttpError | IUniFeError): void;
15
15
  /**
16
16
  * Rimuove un errore tramite ID
17
17
  */
@@ -0,0 +1,26 @@
1
+ export declare enum MapOperator {
2
+ /** Cancella la precedente richiesta, mantiene solo l’ultima */
3
+ SWITCH_MAP = 0,
4
+ /** Ignora nuovi valori finché la corrente non finisce */
5
+ EXHAUST_MAP = 1,
6
+ /** Mette le richieste in coda, le esegue una alla volta */
7
+ CONCAT_MAP = 2,
8
+ /** Esegue tutte le richieste in parallelo, ordine non garantito */
9
+ MERGE_MAP = 3
10
+ }
11
+ export declare enum PollingErrorMode {
12
+ /** Salta questa iterazione emettendo un undefined. Il polling continua al tick successivo. */
13
+ IGNORE = 0,
14
+ /** Salta questa iterazione senza emettere valori. Il polling continua al tick successivo. */
15
+ SKIP = 1,
16
+ /** Interrompe il polling propagando l'errore. */
17
+ STOP = 2,
18
+ /** Ignora l'errore, lo salva (es. per UI), e continua il polling. Emette `undefined`. */
19
+ IGNORE_WITH_ERROR = 3
20
+ }
21
+ export declare enum EmitValueMode {
22
+ /** Aggiorna lo stato solo se arrivano dati nuovi (distinct) */
23
+ ON_NEW_DATA = 0,
24
+ /** Aggiorna lo stato ad ogni chiamata, anche se i dati sono uguali */
25
+ EVERY_TIME = 1
26
+ }
@@ -0,0 +1,2 @@
1
+ export declare function executeHttp<T>(url: URL, init?: RequestInit): Promise<T | undefined>;
2
+ export declare function executeImage(url: URL, init?: RequestInit): Promise<string | undefined>;
@@ -0,0 +1,4 @@
1
+ import { Observable, type OperatorFunction } from 'rxjs';
2
+ import { MapOperator, PollingErrorMode } from './enum';
3
+ export declare function operatorHandler<T>(operator: MapOperator): (project: (value: number) => Observable<T | undefined>) => OperatorFunction<number, T | undefined>;
4
+ export declare function errorHandler(err: unknown, errorMode: PollingErrorMode, ref: string): Observable<undefined>;
@@ -0,0 +1,4 @@
1
+ import { Observable } from 'rxjs';
2
+ import type { HttpConfig, HttpConfigPolling, HttpRef } from './model';
3
+ export declare function http$<T>(url: URL, refType: HttpRef['type'], config: HttpConfig<T>, promiseFactory: () => Promise<T | undefined>): Observable<T | undefined>;
4
+ export declare function httpPolling$<T>(url: URL, config: HttpConfigPolling<T>, promiseFactory: () => Promise<T | undefined>): Observable<T | undefined>;
@@ -0,0 +1,3 @@
1
+ export * from './enum';
2
+ export * from './manager';
3
+ export * from './model';
@@ -0,0 +1,55 @@
1
+ import { BehaviorSubject, Observable } from 'rxjs';
2
+ import type { HttpConfig, HttpConfigPolling, HttpRef } from './model';
3
+ export declare class UniHttpManager {
4
+ /** Store privato (Subject) */
5
+ static store: BehaviorSubject<Map<string, HttpRef>>;
6
+ /** Store pubblico (Observable) */
7
+ static store$: Observable<Map<string, HttpRef>>;
8
+ /** Ottiene lo stato attuale della Map senza dover sottoscrivere l'observable */
9
+ static get currentRefs(): Map<string, HttpRef>;
10
+ /** Hostname del server (es. 'api.example.com' o 'localhost') */
11
+ private static hostname;
12
+ /** Porta del server su cui effettuare le chiamate (es. 80, 443 o 3000) */
13
+ private static port;
14
+ /**
15
+ * Inizializza la configurazione di rete del manager.
16
+ * Deve essere chiamato prima di effettuare qualsiasi richiesta HTTP.
17
+ */
18
+ static setup(hostname: string, port: number): void;
19
+ /** Esegue una singola richiesta HTTP GET.
20
+ * Utilizza il path configurato per costruire l'URL completo e restituisce un Observable del risultato.
21
+ */
22
+ static get$<T>(config: HttpConfig<T>): Observable<T | undefined>;
23
+ /**
24
+ * Recupera un'immagine tramite una richiesta GET e la trasforma in un formato gestibile (es. Blob o Base64).
25
+ * Delega la logica di conversione alla funzione executeImage.
26
+ */
27
+ static getImage$(config: HttpConfig<string>): Observable<string | undefined>;
28
+ /**
29
+ * Esegue una singola richiesta HTTP PUT per aggiornare una risorsa esistente.
30
+ */
31
+ static put$<T>(config: HttpConfig<T>): Observable<T | undefined>;
32
+ /**
33
+ * Esegue una richiesta HTTP POST inviando un payload JSON nel corpo della richiesta.
34
+ * Imposta automaticamente l'header 'Content-Type' come 'application/json'.
35
+ */
36
+ static post$<T>(config: HttpConfig<T>, body: Record<string, any>): Observable<T | undefined>;
37
+ /**
38
+ * Avvia un ciclo di polling basato su richieste GET.
39
+ * Continua a emettere valori in base alla configurazione di intervallo definita in HttpConfigPolling.
40
+ */
41
+ static getHttpPolling$<T>(config: HttpConfigPolling<T>): Observable<T | undefined>;
42
+ /**
43
+ * Avvia un ciclo di polling basato su richieste POST.
44
+ * Invia il body specificato a ogni iterazione del ciclo.
45
+ */
46
+ static postHttpPolling$<T>(config: HttpConfigPolling<T>, body: Record<any, any>): Observable<T | undefined>;
47
+ /**
48
+ * Aggiorna lo stato di caricamento per una specifica reference.
49
+ */
50
+ static updateRefIsLoading(id: string, delta: -1 | 1): void;
51
+ /**
52
+ * Imposta o resetta lo stato di errore per una specifica reference.
53
+ */
54
+ static updateRefHasError(id: string, hasError: boolean): void;
55
+ }
@@ -0,0 +1,34 @@
1
+ import { EmitValueMode, MapOperator, PollingErrorMode } from './enum';
2
+ export interface HttpRef {
3
+ type: 'one' | 'polling' | 'image';
4
+ lineId: number | null;
5
+ url: URL;
6
+ hasError: boolean;
7
+ pendingCount: number;
8
+ }
9
+ export interface HttpConfig<T> {
10
+ path: string;
11
+ ref: string;
12
+ init?: RequestInit;
13
+ toast?: HttpConfigToast<T>;
14
+ hasLoader?: boolean;
15
+ }
16
+ export interface HttpConfigPolling<T> {
17
+ path: string;
18
+ interval: number;
19
+ ref: string;
20
+ init?: RequestInit;
21
+ operator?: MapOperator;
22
+ errorMode?: PollingErrorMode;
23
+ emitValueMode?: EmitValueMode;
24
+ firstIteration?: {
25
+ toast: HttpConfigToast<T>;
26
+ hasLoader?: boolean;
27
+ };
28
+ }
29
+ export interface HttpConfigToast<T> {
30
+ label: string;
31
+ params?: Record<string, string | number | Date>;
32
+ paramKeys?: (keyof T)[];
33
+ paramCount?: string;
34
+ }
@@ -0,0 +1,22 @@
1
+ import type { HttpRef } from './model';
2
+ /**
3
+ * Aggiunge una nuova ref nello store solo se non è già presente.
4
+ * Se l'ID esiste già, l'operazione viene interrotta per preservare il dato originale.
5
+ */
6
+ export declare function addRef(id: string, lineId: null, url: URL, type: HttpRef['type']): void;
7
+ /**
8
+ * Rimuove un http ref tramite ID
9
+ */
10
+ export declare function removeRef(id: string): void;
11
+ /**
12
+ * Aggiorna il contatore delle chiamate pendenti per una specifica ref.
13
+ * Incrementa o decrementa 'pendingCount' garantendo che non scenda mai sotto lo zero.
14
+ * Se la ref non esiste, l'operazione viene ignorata.
15
+ */
16
+ export declare function updateRefIsLoading(id: string, delta: -1 | 1): void;
17
+ /**
18
+ * Aggiorna lo stato di errore per una specifica ref.
19
+ * Se il valore di 'hasError' è identico a quello attuale o se la ref non esiste,
20
+ * l'operazione viene interrotta per evitare aggiornamenti inutili.
21
+ */
22
+ export declare function updateRefHasError(id: string, hasError: boolean): void;
@@ -0,0 +1 @@
1
+ export declare function getUrl(hostname: string, port: number, path: string): URL;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uni-manager",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^19.1.0",
6
6
  "@angular/core": "^19.1.0"
package/public-api.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from './lib/error';
2
+ export * from './lib/http';