@aeres/farol-web 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,168 @@
1
- # Temporary Holding Version
1
+ # @aeres/farol-web
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ SDK de observabilidade **somente para desenvolvimento** de aplicações React, Next.js e outros portais web. A instalação isolada não ativa nenhum interceptor. `enabled: true`, ambiente de navegador e token do coletor local são obrigatórios.
4
+
5
+ ## Instalação
6
+
7
+ O nome reservado para distribuição no npm é `@aeres/farol-web`, versão `0.2.0`.
8
+ Use o modo **npm** em **Conectar projeto** somente quando o Studio indicar que
9
+ essa versão foi verificada no registro. Nesse caso:
10
+
11
+ ```sh
12
+ npm install --save-dev --save-exact @aeres/farol-web@0.2.0
13
+ ```
14
+
15
+ Enquanto a publicação não estiver confirmada, exporte o SDK pelo Studio e instale
16
+ o arquivo local. A geração do `.tgz` não publica o pacote:
17
+
18
+ ```bash
19
+ npm install --save-dev /caminho/aeres-farol-web-0.2.0.tgz
20
+ ```
21
+
22
+ ## Integração Vite / React
23
+
24
+ Crie `.env.local` com `VITE_FAROL_TOKEN` igual ao token exibido pelo coletor local. Inicialize antes de montar a aplicação:
25
+
26
+ ```ts
27
+ if (import.meta.env.DEV) {
28
+ const { initFarol } = await import('@aeres/farol-web');
29
+ const farol = initFarol({
30
+ appName: 'Meu portal',
31
+ enabled: true,
32
+ token: import.meta.env.VITE_FAROL_TOKEN,
33
+ endpoint: 'ws://127.0.0.1:43218/ws',
34
+ captureBodies: false,
35
+ });
36
+ import.meta.hot?.dispose(() => farol.destroy());
37
+ }
38
+ ```
39
+
40
+ O token de pareamento é uma credencial do ambiente local. Não publique o arquivo `.env.local`. Mantenha a importação e os componentes de diagnóstico sob o guard de desenvolvimento; isso permite ao bundler remover o SDK do build de produção.
41
+
42
+ O exemplo usa a porta padrão do aplicativo macOS. Copie o endpoint efetivamente
43
+ exibido em **Conectar projeto**; o broker separado normalmente usa a porta `4318`.
44
+
45
+ ## Next.js
46
+
47
+ No arquivo client de bootstrap, use um efeito de desenvolvimento e encerre no cleanup. O SDK não instrumenta SSR nem código de servidor.
48
+
49
+ ```tsx
50
+ 'use client';
51
+ import { useEffect } from 'react';
52
+
53
+ export function FarolBootstrap() {
54
+ useEffect(() => {
55
+ if (process.env.NODE_ENV !== 'development') return;
56
+ let disposed = false;
57
+ let cleanup: (() => void) | undefined;
58
+ void import('@aeres/farol-web').then(({ initFarol }) => {
59
+ if (disposed) return;
60
+ const farol = initFarol({
61
+ appName: 'Portal Next', enabled: true,
62
+ token: process.env.NEXT_PUBLIC_FAROL_TOKEN,
63
+ endpoint: 'ws://127.0.0.1:43218/ws',
64
+ });
65
+ cleanup = () => farol.destroy();
66
+ });
67
+ return () => { disposed = true; cleanup?.(); };
68
+ }, []);
69
+ return null;
70
+ }
71
+ ```
72
+
73
+ ## React Profiler e Error Boundary
74
+
75
+ O entrypoint React é separado para manter o SDK principal sem dependência de React em runtime.
76
+
77
+ ```tsx
78
+ import { FarolProfiler, FarolErrorBoundary } from '@aeres/farol-web/react';
79
+
80
+ <FarolErrorBoundary client={farol} fallback={(error, reset) => (
81
+ <div role="alert">Falha no exemplo. <button onClick={reset}>Tentar novamente</button></div>
82
+ )}>
83
+ <FarolProfiler client={farol} id="Checkout">
84
+ <Checkout />
85
+ </FarolProfiler>
86
+ </FarolErrorBoundary>
87
+ ```
88
+
89
+ `createProfilerCallback(farol)` também funciona como `onRender` de um `<Profiler>` existente. React pode não emitir medições de Profiler em builds de produção. Error boundaries capturam falhas de renderização em descendentes; erros globais e rejeições não tratadas são capturados pelos listeners do SDK.
90
+
91
+ ## Zustand, Redux e TanStack Query
92
+
93
+ ```ts
94
+ // Zustand: getState / subscribe / setState do store vanilla ou store hook.
95
+ const stop = farol.watchStore('cart', {
96
+ getState: cartStore.getState,
97
+ subscribe: cartStore.subscribe,
98
+ setState: (value) => cartStore.setState(value),
99
+ });
100
+
101
+ // Redux: inspeção e assinatura. Não existe mutação arbitrária sem adapter explícito.
102
+ farol.watchStore('redux', {
103
+ getState: store.getState,
104
+ subscribe: store.subscribe,
105
+ });
106
+
107
+ const stopQueries = farol.observeQueryClient(queryClient);
108
+ farol.track('checkout.completed', { orderId: 'demo-123', items: 3 });
109
+ stop();
110
+ stopQueries();
111
+ ```
112
+
113
+ Adapters são estruturais e não exigem dependências Zustand/Redux/TanStack no SDK. `state.set` só funciona quando você fornece `setState`. Invalidação usa a API `invalidateQueries({queryKey})` do cliente registrado.
114
+
115
+ ## Capturas e controles
116
+
117
+ - Console, erros globais, rejeições e erros React com contexto e stack disponível.
118
+ - Fetch e XMLHttpRequest: método, URL, status, duração, headers e falhas. Bodies ficam desativados por padrão, são limitados a 8 KiB quando ativados e excluem streams/binários/multipart.
119
+ - Local/session storage: snapshot inicial, alterações e comandos de edição/remoção.
120
+ - Histórico de navegação, `popstate`, `hashchange` e navegação restrita à mesma origem.
121
+ - PerformanceObserver: navegação, paint, long tasks, LCP e CLS quando suportados pelo navegador. As medições não substituem um tracing completo do Chrome.
122
+ - Snapshots de stores, cache de queries, renders e eventos personalizados.
123
+ - Mocks por URL completa ou pathname, wildcard `*`, método, status, corpo e atraso; simulação de offline e latência em fetch/XHR.
124
+ - Snapshot DOM limitado a 150 elementos com tags, ids, texto direto e retângulos; nenhum valor de campo é coletado. Marque blocos sensíveis com `data-farol-private`. Highlight temporário de seletor CSS.
125
+
126
+ Mocks interceptam somente chamadas da página instrumentada. Não afetam WebSockets, service workers, iframes, workers ou tráfego nativo React Native. XHR simulado reproduz status/corpo/eventos finais; não pretende simular streaming, progress de upload ou cada transição intermediária do navegador. SDK/browser não oferecem inspeção de heap, debugger de breakpoints ou árvore Fiber; continue usando DevTools para essas tarefas.
127
+
128
+ ## Segurança e ciclo de vida
129
+
130
+ - Sem `enabled: true` explícito, sem token, em SSR, ou com endpoint externo: retorna client inativo sem abrir conexão nem instalar patches.
131
+ - Conecta somente a `localhost`, `127.0.0.1` ou `[::1]`. O coletor recebe autenticação antes de sessão/eventos, e comandos exigem conexão pareada e o id da sessão atual.
132
+ - Páginas HTTPS podem exigir endpoint local `wss://` com certificado confiável e permissão CSP `connect-src`; configure isso no ambiente de desenvolvimento.
133
+ - Redige profundamente campos de tokens, senhas, cookies, Authorization, chaves de API, URLs com credenciais/query sensível e strings JSON reconhecidas. Getters não são executados. Protege contra ciclos, profundidade excessiva e volume ilimitado.
134
+ - A redação é heurística: dados pessoais em chaves genéricas e segredos sem contexto podem permanecer visíveis. Use dados de teste; habilite bodies apenas quando necessário.
135
+ - Eventos são redigidos antes de entrar na fila. Fila padrão: 400 eventos; máximo configurável: 2.000. Payloads excessivos são substituídos por um aviso. A captura não garante entrega durante fechamento da página/desconexões prolongadas.
136
+ - Reconexão com backoff limitado; erro de autenticação encerra tentativas. Inicialização repetida encerra o client anterior (HMR).
137
+ - `farol.destroy()` remove subscriptions/listeners/observers, fecha transporte e restaura wrappers que ainda pertencem ao SDK. Não desfaz alterações deliberadas feitas no estado/storage por comandos.
138
+ - Não existe execução de JavaScript remoto nem comando `eval`.
139
+ - `state.set` e `storage.set` recusam valores com marcadores de redação/serialização (por exemplo `[REDACTED]`, `[Max depth]`, `[Circular]`, `[Function …]`, `[truncated]`, omissão de entradas e descrições de dados binários). A recusa ocorre antes de chamar setters. O helper público `containsSerializationMarkers(value)` permite ao painel bloquear a edição/restauração de snapshots incompletos com o mesmo critério.
140
+ - Resultados de comandos acima de 64 KiB retornam `ok: false` com erro explícito de limite. Escritas em storage retornam confirmação curta; consulte `storage.list` separadamente para atualizar o painel.
141
+ - `network.get` retorna `{ offline, latency, mocks }` da sessão atual, permitindo recuperar simulações existentes ao reconectar ou trocar de sessão.
142
+
143
+ O comando de reload não pode preservar o estado em memória. Valores completos continuam no app original; redação afeta a cópia enviada ao painel.
144
+
145
+ ## API resumida
146
+
147
+ ```ts
148
+ initFarol({ appName, enabled?, endpoint?, token?, captureBodies?, maxBodyBytes?, maxQueueSize? })
149
+ // => enabled, connected, session, getSession(), track(), record(),
150
+ // watchStore(), observeQueryClient(), destroy()
151
+ ```
152
+
153
+ Protocolo de comandos: `storage.list`, `storage.set`, `storage.remove`, `state.set`, `query.invalidate`, `network.get`, `network.configure`, `mock.set`, `mock.remove`, `dom.snapshot`, `dom.highlight`, `page.reload`, `nav.go`. Respostas usam `command.result`, id original, sessionId, `ok` e `data` ou `error`.
154
+
155
+ ## Desenvolvimento do pacote
156
+
157
+ ```bash
158
+ npm run build -w @aeres/farol-web
159
+ npm run test -w @aeres/farol-web
160
+ npm pack -w @aeres/farol-web
161
+ ```
162
+
163
+ O pacote distribui ESM, CommonJS, sourcemaps e declarações TypeScript. O protocolo de tipos é autocontido, sem import runtime de pacotes internos do workspace.
164
+
165
+ `prepublishOnly` executa build e testes antes de uma publicação a partir do
166
+ checkout. Os consumidores não executam esse hook ao instalar o pacote. O pacote
167
+ mantém a declaração **UNLICENSED**; acesso público no npm não concede uma licença
168
+ de código aberto nem altera os direitos de uso.