ngx-opalbytes-services 1.1.0 → 1.3.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.md CHANGED
@@ -1,9 +1,7 @@
1
- # 📦 ngx-opalbytes-services
1
+ # ngx-opalbytes-services
2
2
 
3
3
  Esta biblioteca destina-se a abrigar serviços (`services`) Angular reutilizáveis que encapsulam lógica de negócios, chamadas de API e outras funcionalidades compartilhadas.
4
4
 
5
- **Nota:** Atualmente, esta biblioteca contém apenas um componente de placeholder e ainda não possui serviços implementados.
6
-
7
5
  ---
8
6
  ## Compatibilidade
9
7
  |Tecnologia | Versão | Descrição |
@@ -39,24 +37,24 @@ Esta biblioteca possui as seguintes dependências:
39
37
  ---
40
38
  ## Como Usar
41
39
 
42
- Quando serviços forem adicionados, eles poderão ser injetados nos seus componentes ou outros serviços via injeção de dependência do Angular.
40
+ Os serviços podem ser injetados nos seus componentes ou outros serviços via injeção de dependência do Angular.
43
41
 
44
42
  **Exemplo de como um serviço seria utilizado:**
45
43
 
46
44
  ```typescript
47
45
  import { Component, OnInit } from '@angular/core';
48
- // Supondo a existência de um 'UserService'
49
- import { UserService } from 'ngx-opalbytes-services';
46
+ import { WebsocketService } from 'ngx-opalbytes-services';
50
47
 
51
48
  @Component({
52
49
  selector: 'app-user-profile',
53
50
  })
54
51
  export class UserProfileComponent implements OnInit {
55
52
 
56
- constructor(private userService: UserService) {}
53
+ private websocketService = inject(WebsocketService)
54
+ constructor() {}
57
55
 
58
56
  ngOnInit() {
59
- // this.userService.getUsers().subscribe(...);
57
+ // this.websocketService.connect('ws://localhost:8080');
60
58
  }
61
59
  }
62
60
  ```
@@ -65,35 +63,152 @@ export class UserProfileComponent implements OnInit {
65
63
 
66
64
  ## Organização de Pastas
67
65
 
68
- Dentro da pasta `src/lib/`, os serviços devem ser organizados em subpastas, se necessário, ou diretamente sob `lib/`. Por exemplo:
66
+ Dentro da pasta `src/lib/`, os serviços são organizados na pasta `services/`.
69
67
 
70
68
  ```
71
69
  src/
72
70
  └── lib/
73
- ├── services/
74
- │ └── user.service.ts
75
- └── auth.service.ts
71
+ └── services/
72
+ ├── date-pipe.service.ts
73
+ ├── installer.service.ts
74
+ └── websocket.service.ts
75
+ ```
76
+
77
+ ---
78
+
79
+ ---
80
+
81
+ ## Detalhes dos Serviços
82
+
83
+ ### `CaoDatePipeService`
84
+ Um serviço simples que atua como um wrapper para o `DatePipe` do Angular, facilitando a formatação de datas.
85
+
86
+ **Métodos**
87
+
88
+ | Método | Parâmetros | Retorno | Descrição |
89
+ | --- | --- | --- | --- |
90
+ | `getConvertedDatePipe` | `value: Date`, `transform: string` | `string` | Formata uma data de acordo com a string de formato fornecida. |
91
+
92
+ **Exemplo de Uso**
93
+ ```typescript
94
+ import { CaoDatePipeService } from 'ngx-opalbytes-services';
95
+
96
+ // ...
97
+
98
+ constructor(private datePipeService: CaoDatePipeService) {}
99
+
100
+ formatarData() {
101
+ const dataFormatada = this.datePipeService.getConvertedDatePipe(new Date(), 'dd/MM/yyyy');
102
+ console.log(dataFormatada); // Ex: 22/12/2025
103
+ }
76
104
  ```
77
105
 
78
106
  ---
79
107
 
80
- ## Serviços Disponíveis
108
+ ### `CaoInstallationService`
109
+ Este serviço gerencia o download e a instalação de executáveis ou a abertura de arquivos, comumente usado em cenários de instalação de aplicações desktop a partir de uma aplicação web.
110
+
111
+ **Propriedades**
112
+
113
+ | Propriedade | Tipo | Descrição |
114
+ | --- | --- | --- |
115
+ | `status$` | `Observable<IStatusInstallation>` | Emite o status atual da instalação. |
81
116
 
82
- Atualmente, não há serviços disponíveis nesta biblioteca.
117
+ **Interfaces**
118
+ ```typescript
119
+ interface IStatusInstallation {
120
+ isInstalled: boolean;
121
+ version?: string;
122
+ lastChecked: Date;
123
+ installationPath?: string;
124
+ }
125
+
126
+ interface IConfigInstallation {
127
+ executableName: string;
128
+ assetPath: string; // URL para o arquivo
129
+ }
130
+
131
+ interface IBlobConfigInstallation {
132
+ executableName: string;
133
+ assetPath: Blob; // Arquivo em formato Blob
134
+ }
135
+ ```
136
+
137
+ **Métodos**
138
+
139
+ | Método | Parâmetros | Retorno | Descrição |
140
+ | --- | --- | --- | --- |
141
+ | `downloadAndInstall` | `config: IConfigInstallation` | `Observable<boolean>` | Inicia o download e a instalação de um executável. |
142
+ | `downloadAndOpenFile` | `config: IConfigInstallation`, `isTargetBlank?: boolean` | `Observable<boolean>` | Faz o download e abre um arquivo em uma nova aba. |
143
+ | `downloadBlobFile` | `configBlob: IBlobConfigInstallation` | `void` | Inicia o download de um arquivo a partir de um objeto Blob. |
144
+ | `reinstall` | `config: IConfigInstallation` | `Observable<boolean>` | Atalho para o método `downloadAndInstall`. |
145
+
146
+ ---
147
+
148
+ ### `CaoWebSocketService`
149
+ Gerencia uma conexão WebSocket com um servidor, incluindo lógica de reconexão automática.
150
+
151
+ **Propriedades (Emitters)**
152
+
153
+ | Propriedade | Tipo | Descrição |
154
+ | --- | --- | --- |
155
+ | `isConnectionEvent` | `EventEmitter<boolean>` | Emite `true` em sucesso e `false` em falha de conexão. |
156
+ | `onErrorConnection` | `EventEmitter<string>` | Emite mensagens de erro durante as tentativas de conexão. |
157
+ | `onSuccessConnection`| `EventEmitter<boolean>`| Emite `true` quando a conexão é estabelecida com sucesso. |
158
+
159
+ **Métodos**
160
+
161
+ | Método | Parâmetros | Retorno | Descrição |
162
+ | --- | --- | --- | --- |
163
+ | `startConnection` | `webSocketServer: string` | `void` | Inicia o processo de conexão com o servidor WebSocket. |
164
+ | `connect` | `webSocketServer: string` | `void` | Lógica principal de conexão, com tentativas de reconexão. |
165
+ | `sendMessage` | `msg: any` | `void` | Envia uma mensagem para o servidor. |
166
+ | `getMessages` | - | `Observable<any>` | Retorna um Observable que emite as mensagens recebidas do servidor. |
167
+ | `close` | - | `void` | Fecha a conexão com o WebSocket. |
168
+
169
+ **Exemplo de Uso**
170
+ ```typescript
171
+ import { CaoWebSocketService } from 'ngx-opalbytes-services';
172
+
173
+ // ...
174
+ private wsService = inject(CaoWebSocketService)
175
+
176
+ constructor() {}
177
+
178
+ ngOnInit() {
179
+ this.wsService.startConnection('wss://meu-servidor.com');
180
+
181
+ this.wsService.isConnectionEvent.subscribe(isSuccess => {
182
+ console.log('Status da conexão:', isSuccess);
183
+ });
184
+
185
+ this.wsService.getMessages().subscribe(message => {
186
+ console.log('Nova mensagem:', message);
187
+ });
188
+ }
189
+
190
+ enviar() {
191
+ this.wsService.sendMessage({ data: 'Olá, servidor!' });
192
+ }
193
+
194
+ ngOnDestroy() {
195
+ this.wsService.close();
196
+ }
197
+ ```
83
198
 
84
199
  ---
85
200
 
86
- ## 📜 Como Contribuir
201
+ ## Como Contribuir
87
202
 
88
203
  Para adicionar um novo serviço a esta biblioteca, siga os passos abaixo:
89
204
 
90
- 1. **Crie o arquivo** do seu serviço dentro da pasta `src/lib/`. Por exemplo: `src/lib/user.service.ts`.
205
+ 1. **Crie o arquivo** do seu serviço dentro da pasta `src/lib/services/`. Por exemplo: `src/lib/services/user.service.ts`.
91
206
  2. **Implemente seu serviço**, lembrando de marcá-lo com `@Injectable({ providedIn: 'root' })` para que ele seja "tree-shakable".
92
207
  3. **Exponha o serviço** na API pública da biblioteca, adicionando uma linha de exportação no arquivo `src/public-api.ts`.
93
208
 
94
209
  ```typescript
95
210
  // projects/ngx-opalbytes-services/src/public-api.ts
96
- export * from './lib/user.service';
211
+ export * from './lib/services/user.service';
97
212
  ```
98
213
  4. **Adicione testes unitários** para garantir a qualidade e o funcionamento esperado do seu serviço.
99
214
  5. **Faça o commit** seguindo as [regras de commit do projeto](/README.md#룰-regras-de-commit-com-escopo-obrigatório), usando o escopo `services`.
@@ -1,15 +1,19 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component } from '@angular/core';
2
+ import { Component, inject, Injectable, EventEmitter } from '@angular/core';
3
+ import { DatePipe } from '@angular/common';
4
+ import { BehaviorSubject, Observable, Subject } from 'rxjs';
5
+ import { catchError, retry } from 'rxjs/operators';
6
+ import { webSocket } from 'rxjs/webSocket';
3
7
 
4
8
  class NgxOpalbytesServices {
5
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: NgxOpalbytesServices, deps: [], target: i0.ɵɵFactoryTarget.Component });
6
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.2", type: NgxOpalbytesServices, isStandalone: true, selector: "cao-ngx-opalbytes-services", ngImport: i0, template: `
9
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxOpalbytesServices, deps: [], target: i0.ɵɵFactoryTarget.Component });
10
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: NgxOpalbytesServices, isStandalone: true, selector: "cao-ngx-opalbytes-services", ngImport: i0, template: `
7
11
  <p>
8
12
  ngx-opalbytes-services works!
9
13
  </p>
10
14
  `, isInline: true, styles: [""] });
11
15
  }
12
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: NgxOpalbytesServices, decorators: [{
16
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxOpalbytesServices, decorators: [{
13
17
  type: Component,
14
18
  args: [{ selector: 'cao-ngx-opalbytes-services', imports: [], template: `
15
19
  <p>
@@ -18,6 +22,197 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImpor
18
22
  ` }]
19
23
  }] });
20
24
 
25
+ class CaoDatePipeService {
26
+ datePipe = inject(DatePipe);
27
+ constructor() { }
28
+ getConvertedDatePipe(value, transform) {
29
+ const result = this.datePipe.transform(value, transform);
30
+ return result ?? "";
31
+ }
32
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CaoDatePipeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
33
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CaoDatePipeService, providedIn: "root" });
34
+ }
35
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CaoDatePipeService, decorators: [{
36
+ type: Injectable,
37
+ args: [{
38
+ providedIn: "root",
39
+ }]
40
+ }], ctorParameters: () => [] });
41
+
42
+ class CaoInstallationService {
43
+ installationStatus$ = new BehaviorSubject({
44
+ isInstalled: false,
45
+ lastChecked: new Date(),
46
+ });
47
+ status$ = this.installationStatus$.asObservable();
48
+ downloadAndInstall(config) {
49
+ return new Observable((observer) => {
50
+ try {
51
+ const url = config.assetPath;
52
+ const link = document.createElement("a");
53
+ link.target = "_blank";
54
+ link.href = url;
55
+ link.download = config.executableName || "download";
56
+ link.style.display = "none";
57
+ document.body.appendChild(link);
58
+ link.click();
59
+ document.body.removeChild(link);
60
+ setTimeout(() => {
61
+ observer.next(true);
62
+ observer.complete();
63
+ }, 100);
64
+ }
65
+ catch (error) {
66
+ console.error("Erro no download:", error);
67
+ observer.error(error);
68
+ }
69
+ });
70
+ }
71
+ downloadAndOpenFile(config, isTargetBlank = true) {
72
+ return new Observable((observer) => {
73
+ try {
74
+ const link = document.createElement("a");
75
+ link.href = config.assetPath;
76
+ link.target = isTargetBlank ? "_blank" : "";
77
+ link.rel = "noopener noreferrer";
78
+ document.body.appendChild(link);
79
+ link.click();
80
+ document.body.removeChild(link);
81
+ observer.next(true);
82
+ observer.complete();
83
+ }
84
+ catch (error) {
85
+ observer.error(error);
86
+ }
87
+ });
88
+ }
89
+ downloadBlobFile(configBlob) {
90
+ const url = window.URL.createObjectURL(configBlob.assetPath);
91
+ const a = document.createElement("a");
92
+ a.href = url;
93
+ a.download = configBlob.executableName;
94
+ document.body.appendChild(a);
95
+ a.click();
96
+ window.URL.revokeObjectURL(url);
97
+ document.body.removeChild(a);
98
+ }
99
+ reinstall(config) {
100
+ return this.downloadAndInstall(config);
101
+ }
102
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CaoInstallationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
103
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CaoInstallationService, providedIn: "root" });
104
+ }
105
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CaoInstallationService, decorators: [{
106
+ type: Injectable,
107
+ args: [{
108
+ providedIn: "root",
109
+ }]
110
+ }] });
111
+
112
+ class CaoWebSocketService {
113
+ socket$ = null;
114
+ reconnectAttempts = 0;
115
+ maxReconnectAttempts = 5;
116
+ isConnectionSuccess = false;
117
+ isSocketClosed = false;
118
+ isConnectionEvent = new EventEmitter();
119
+ onErrorConnection = new EventEmitter();
120
+ onSuccessConnection = new EventEmitter();
121
+ startConnection(webSocketServer) {
122
+ this.reconnectAttempts = 0;
123
+ this.isSocketClosed = false;
124
+ this.connect(webSocketServer);
125
+ }
126
+ connect(webSocketServer) {
127
+ this.socket$ = webSocket({
128
+ url: webSocketServer,
129
+ deserializer: (e) => {
130
+ try {
131
+ return JSON.parse(e.data);
132
+ }
133
+ catch {
134
+ return e.data;
135
+ }
136
+ },
137
+ });
138
+ this.socket$
139
+ .pipe(catchError((error) => {
140
+ if (this.isSocketClosed) {
141
+ return new Subject();
142
+ }
143
+ this.onErrorConnection.emit(error);
144
+ this.reconnectAttempts++;
145
+ if (this.reconnectAttempts <= this.maxReconnectAttempts) {
146
+ this.onErrorConnection.emit(`Tentando reconectar (${this.reconnectAttempts})...`);
147
+ this.isConnectionSuccess = false;
148
+ this.emitStatusConnection();
149
+ setTimeout(() => {
150
+ this.connect(webSocketServer);
151
+ }, 3000);
152
+ return new Subject();
153
+ }
154
+ else {
155
+ this.onErrorConnection.emit("Máximo de tentativas de reconexão atingido.");
156
+ this.isConnectionSuccess = false;
157
+ this.emitStatusConnection();
158
+ return new Subject();
159
+ }
160
+ }), retry(this.maxReconnectAttempts))
161
+ .subscribe();
162
+ this.register();
163
+ }
164
+ emitStatusConnection() {
165
+ this.isConnectionEvent.emit(this.isConnectionSuccess);
166
+ }
167
+ register() {
168
+ if (this.socket$ && !this.socket$.closed) {
169
+ this.isConnectionSuccess = true;
170
+ this.emitStatusConnection();
171
+ this.onSuccessConnection.emit(true);
172
+ this.socket$.next("register:web_client");
173
+ }
174
+ }
175
+ /**
176
+ *
177
+ * @returns {void}
178
+ * Este método permite enviar mensagem para o servidor websocket.
179
+ */
180
+ sendMessage(msg) {
181
+ if (this.socket$ && !this.socket$.closed) {
182
+ this.socket$.next(msg);
183
+ }
184
+ }
185
+ /**
186
+ *
187
+ * @returns {Observable<any>} Observável que emite mensagens da conexão WebSocket..
188
+ * Este método permite que outros componentes assinem as mensagens recebidas do servidor WebSocket.
189
+ */
190
+ getMessages() {
191
+ return this.socket$.asObservable();
192
+ }
193
+ /**
194
+ *
195
+ * @returns {void}
196
+ * Este método fecha a conexão WebSocket.
197
+ * É importante chamar este método quando a aplicação não precisar mais da conexão WebSocket,
198
+ */
199
+ close() {
200
+ if (this.socket$) {
201
+ this.isSocketClosed = true;
202
+ this.socket$.complete();
203
+ this.socket$ = null;
204
+ }
205
+ }
206
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CaoWebSocketService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
207
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CaoWebSocketService, providedIn: "root" });
208
+ }
209
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CaoWebSocketService, decorators: [{
210
+ type: Injectable,
211
+ args: [{
212
+ providedIn: "root",
213
+ }]
214
+ }] });
215
+
21
216
  /*
22
217
  * Public API Surface of ngx-opalbytes-services
23
218
  */
@@ -26,5 +221,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImpor
26
221
  * Generated bundle index. Do not edit.
27
222
  */
28
223
 
29
- export { NgxOpalbytesServices };
224
+ export { CaoDatePipeService, CaoInstallationService, CaoWebSocketService, NgxOpalbytesServices };
30
225
  //# sourceMappingURL=ngx-opalbytes-services.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-opalbytes-services.mjs","sources":["../../../projects/ngx-opalbytes-services/src/lib/ngx-opalbytes-services.ts","../../../projects/ngx-opalbytes-services/src/public-api.ts","../../../projects/ngx-opalbytes-services/src/ngx-opalbytes-services.ts"],"sourcesContent":["import { Component } from '@angular/core';\n\n@Component({\n selector: 'cao-ngx-opalbytes-services',\n imports: [],\n template: `\n <p>\n ngx-opalbytes-services works!\n </p>\n `,\n styles: ``,\n})\nexport class NgxOpalbytesServices {\n\n}\n","/*\n * Public API Surface of ngx-opalbytes-services\n */\n\nexport * from './lib/ngx-opalbytes-services';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;MAYa,oBAAoB,CAAA;uGAApB,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAApB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,4BAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAPrB;;;;AAIT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAGU,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAVhC,SAAS;+BACE,4BAA4B,EAAA,OAAA,EAC7B,EAAE,EAAA,QAAA,EACD;;;;AAIT,EAAA,CAAA,EAAA;;;ACTH;;AAEG;;ACFH;;AAEG;;;;"}
1
+ {"version":3,"file":"ngx-opalbytes-services.mjs","sources":["../../../projects/ngx-opalbytes-services/src/lib/ngx-opalbytes-services.ts","../../../projects/ngx-opalbytes-services/src/lib/services/date-pipe.service.ts","../../../projects/ngx-opalbytes-services/src/lib/services/installer.service.ts","../../../projects/ngx-opalbytes-services/src/lib/services/websocket.service.ts","../../../projects/ngx-opalbytes-services/src/public-api.ts","../../../projects/ngx-opalbytes-services/src/ngx-opalbytes-services.ts"],"sourcesContent":["import { Component } from '@angular/core';\n\n@Component({\n selector: 'cao-ngx-opalbytes-services',\n imports: [],\n template: `\n <p>\n ngx-opalbytes-services works!\n </p>\n `,\n styles: ``,\n})\nexport class NgxOpalbytesServices {\n\n}\n","import { DatePipe } from \"@angular/common\";\nimport { inject, Injectable } from \"@angular/core\";\n\n@Injectable({\n providedIn: \"root\",\n})\nexport class CaoDatePipeService {\n readonly datePipe = inject(DatePipe);\n\n constructor() {}\n\n getConvertedDatePipe(value: Date, transform: string): string {\n const result = this.datePipe.transform(value, transform);\n\n return result ?? \"\";\n }\n}\n","import { Injectable } from \"@angular/core\";\n\nimport { Observable, BehaviorSubject } from \"rxjs\";\n\nexport interface IStatusInstallation {\n isInstalled: boolean;\n version?: string;\n lastChecked: Date;\n installationPath?: string;\n}\n\nexport interface IConfigInstallation {\n executableName: string;\n assetPath: string;\n registryPath?: string;\n expectedVersion?: string;\n}\n\nexport interface IBlobConfigInstallation {\n executableName: string;\n assetPath: Blob;\n}\n\n@Injectable({\n providedIn: \"root\",\n})\nexport class CaoInstallationService {\n private readonly installationStatus$ = new BehaviorSubject<IStatusInstallation>({\n isInstalled: false,\n lastChecked: new Date(),\n });\n\n readonly status$ = this.installationStatus$.asObservable();\n\n downloadAndInstall(config: IConfigInstallation): Observable<boolean> {\n return new Observable((observer) => {\n try {\n const url = config.assetPath;\n const link = document.createElement(\"a\");\n\n link.target = \"_blank\";\n link.href = url;\n link.download = config.executableName || \"download\";\n\n link.style.display = \"none\";\n\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n\n setTimeout(() => {\n observer.next(true);\n observer.complete();\n }, 100);\n } catch (error) {\n console.error(\"Erro no download:\", error);\n observer.error(error);\n }\n });\n }\n\n downloadAndOpenFile(\n config: IConfigInstallation,\n isTargetBlank = true\n ): Observable<boolean> {\n return new Observable((observer) => {\n try {\n const link = document.createElement(\"a\");\n link.href = config.assetPath;\n link.target = isTargetBlank ? \"_blank\" : \"\";\n link.rel = \"noopener noreferrer\";\n\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n\n observer.next(true);\n observer.complete();\n } catch (error) {\n observer.error(error);\n }\n });\n }\n\n downloadBlobFile(configBlob: IBlobConfigInstallation): void {\n const url = window.URL.createObjectURL(configBlob.assetPath);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = configBlob.executableName;\n document.body.appendChild(a);\n a.click();\n window.URL.revokeObjectURL(url);\n document.body.removeChild(a);\n }\n\n reinstall(config: IConfigInstallation): Observable<boolean> {\n return this.downloadAndInstall(config);\n }\n}","import { EventEmitter, Injectable } from \"@angular/core\";\n\nimport { Observable, Subject } from \"rxjs\";\nimport { catchError, retry } from \"rxjs/operators\";\nimport { webSocket, WebSocketSubject } from \"rxjs/webSocket\";\n\n@Injectable({\n providedIn: \"root\",\n})\nexport class CaoWebSocketService {\n protected socket$: WebSocketSubject<unknown> | null = null;\n protected reconnectAttempts = 0;\n protected maxReconnectAttempts = 5;\n\n private isConnectionSuccess = false;\n private isSocketClosed = false;\n\n isConnectionEvent: EventEmitter<boolean> = new EventEmitter<boolean>();\n onErrorConnection: EventEmitter<string> = new EventEmitter<string>()\n onSuccessConnection: EventEmitter<boolean> = new EventEmitter<boolean>()\n\n public startConnection(webSocketServer: string) {\n this.reconnectAttempts = 0;\n this.isSocketClosed = false;\n this.connect(webSocketServer);\n }\n \n public connect(webSocketServer: string) {\n this.socket$ = webSocket({\n url: webSocketServer,\n deserializer: (e) => {\n try {\n return JSON.parse(e.data);\n } catch {\n return e.data;\n }\n },\n });\n\n this.socket$\n .pipe(\n catchError((error) => {\n if (this.isSocketClosed) {\n return new Subject();\n }\n this.onErrorConnection.emit(error);\n this.reconnectAttempts++;\n if (this.reconnectAttempts <= this.maxReconnectAttempts) {\n this.onErrorConnection.emit(`Tentando reconectar (${this.reconnectAttempts})...`);\n this.isConnectionSuccess = false;\n this.emitStatusConnection();\n setTimeout(() => {\n this.connect(webSocketServer);\n }, 3000);\n return new Subject();\n } else {\n this.onErrorConnection.emit(\"Máximo de tentativas de reconexão atingido.\");\n this.isConnectionSuccess = false;\n this.emitStatusConnection();\n return new Subject();\n }\n }),\n retry(this.maxReconnectAttempts)\n )\n .subscribe();\n this.register();\n }\n\n emitStatusConnection() {\n this.isConnectionEvent.emit(this.isConnectionSuccess);\n }\n\n register() {\n if (this.socket$ && !this.socket$.closed) {\n this.isConnectionSuccess = true;\n this.emitStatusConnection();\n this.onSuccessConnection.emit(true)\n this.socket$.next(\"register:web_client\");\n }\n }\n\n /**\n *\n * @returns {void}\n * Este método permite enviar mensagem para o servidor websocket.\n */\n sendMessage(msg: any) {\n if (this.socket$ && !this.socket$.closed) {\n this.socket$.next(msg);\n }\n }\n\n /**\n *\n * @returns {Observable<any>} Observável que emite mensagens da conexão WebSocket..\n * Este método permite que outros componentes assinem as mensagens recebidas do servidor WebSocket.\n */\n getMessages(): Observable<any> {\n return this.socket$!.asObservable();\n }\n\n /**\n *\n * @returns {void}\n * Este método fecha a conexão WebSocket.\n * É importante chamar este método quando a aplicação não precisar mais da conexão WebSocket,\n */\n close() {\n if (this.socket$) {\n this.isSocketClosed = true;\n this.socket$.complete();\n this.socket$ = null;\n }\n }\n}\n","/*\n * Public API Surface of ngx-opalbytes-services\n */\n\nexport * from './lib/ngx-opalbytes-services';\nexport * from './lib/services/date-pipe.service';\nexport * from './lib/services/installer.service';\nexport * from './lib/services/websocket.service';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-opalbytes-services",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^21.0.0",
6
6
  "@angular/core": "^21.0.0"
@@ -20,4 +20,4 @@
20
20
  "default": "./fesm2022/ngx-opalbytes-services.mjs"
21
21
  }
22
22
  }
23
- }
23
+ }
@@ -1,8 +1,84 @@
1
1
  import * as i0 from '@angular/core';
2
+ import { EventEmitter } from '@angular/core';
3
+ import { DatePipe } from '@angular/common';
4
+ import { Observable } from 'rxjs';
5
+ import { WebSocketSubject } from 'rxjs/webSocket';
2
6
 
3
7
  declare class NgxOpalbytesServices {
4
8
  static ɵfac: i0.ɵɵFactoryDeclaration<NgxOpalbytesServices, never>;
5
9
  static ɵcmp: i0.ɵɵComponentDeclaration<NgxOpalbytesServices, "cao-ngx-opalbytes-services", never, {}, {}, never, never, true, never>;
6
10
  }
7
11
 
8
- export { NgxOpalbytesServices };
12
+ declare class CaoDatePipeService {
13
+ readonly datePipe: DatePipe;
14
+ constructor();
15
+ getConvertedDatePipe(value: Date, transform: string): string;
16
+ static ɵfac: i0.ɵɵFactoryDeclaration<CaoDatePipeService, never>;
17
+ static ɵprov: i0.ɵɵInjectableDeclaration<CaoDatePipeService>;
18
+ }
19
+
20
+ interface IStatusInstallation {
21
+ isInstalled: boolean;
22
+ version?: string;
23
+ lastChecked: Date;
24
+ installationPath?: string;
25
+ }
26
+ interface IConfigInstallation {
27
+ executableName: string;
28
+ assetPath: string;
29
+ registryPath?: string;
30
+ expectedVersion?: string;
31
+ }
32
+ interface IBlobConfigInstallation {
33
+ executableName: string;
34
+ assetPath: Blob;
35
+ }
36
+ declare class CaoInstallationService {
37
+ private readonly installationStatus$;
38
+ readonly status$: Observable<IStatusInstallation>;
39
+ downloadAndInstall(config: IConfigInstallation): Observable<boolean>;
40
+ downloadAndOpenFile(config: IConfigInstallation, isTargetBlank?: boolean): Observable<boolean>;
41
+ downloadBlobFile(configBlob: IBlobConfigInstallation): void;
42
+ reinstall(config: IConfigInstallation): Observable<boolean>;
43
+ static ɵfac: i0.ɵɵFactoryDeclaration<CaoInstallationService, never>;
44
+ static ɵprov: i0.ɵɵInjectableDeclaration<CaoInstallationService>;
45
+ }
46
+
47
+ declare class CaoWebSocketService {
48
+ protected socket$: WebSocketSubject<unknown> | null;
49
+ protected reconnectAttempts: number;
50
+ protected maxReconnectAttempts: number;
51
+ private isConnectionSuccess;
52
+ private isSocketClosed;
53
+ isConnectionEvent: EventEmitter<boolean>;
54
+ onErrorConnection: EventEmitter<string>;
55
+ onSuccessConnection: EventEmitter<boolean>;
56
+ startConnection(webSocketServer: string): void;
57
+ connect(webSocketServer: string): void;
58
+ emitStatusConnection(): void;
59
+ register(): void;
60
+ /**
61
+ *
62
+ * @returns {void}
63
+ * Este método permite enviar mensagem para o servidor websocket.
64
+ */
65
+ sendMessage(msg: any): void;
66
+ /**
67
+ *
68
+ * @returns {Observable<any>} Observável que emite mensagens da conexão WebSocket..
69
+ * Este método permite que outros componentes assinem as mensagens recebidas do servidor WebSocket.
70
+ */
71
+ getMessages(): Observable<any>;
72
+ /**
73
+ *
74
+ * @returns {void}
75
+ * Este método fecha a conexão WebSocket.
76
+ * É importante chamar este método quando a aplicação não precisar mais da conexão WebSocket,
77
+ */
78
+ close(): void;
79
+ static ɵfac: i0.ɵɵFactoryDeclaration<CaoWebSocketService, never>;
80
+ static ɵprov: i0.ɵɵInjectableDeclaration<CaoWebSocketService>;
81
+ }
82
+
83
+ export { CaoDatePipeService, CaoInstallationService, CaoWebSocketService, NgxOpalbytesServices };
84
+ export type { IBlobConfigInstallation, IConfigInstallation, IStatusInstallation };