@apollion-dsi/relay 0.25.10 → 0.26.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/lib/commitMutation/commitMutation.d.ts +42 -0
- package/lib/commitMutation/index.d.ts +8 -0
- package/lib/index.d.ts +18 -0
- package/lib/mutationUtils/index.d.ts +9 -0
- package/lib/mutationUtils/mutationUtils.d.ts +133 -0
- package/lib/relayArgsInterface/index.d.ts +7 -0
- package/lib/relayArgsInterface/relayArgsInterface.d.ts +163 -0
- package/lib/setupRelayEnvironment/executeEnvironment.d.ts +27 -0
- package/lib/setupRelayEnvironment/fetchQuery.d.ts +28 -0
- package/lib/setupRelayEnvironment/fetchWithRetries.d.ts +41 -0
- package/lib/setupRelayEnvironment/setupRelayEnvironment.d.ts +128 -0
- package/lib/setupRelayEnvironment/setupRelayEnvironment.helpers.d.ts +78 -0
- package/lib/setupRelayEnvironment/storage.d.ts +59 -0
- package/lib/setupRelayEnvironment/subscriptionHandler.d.ts +29 -0
- package/lib/useEnvironment/index.d.ts +9 -0
- package/lib/useEnvironment/useEnvironment.d.ts +73 -0
- package/package.json +11 -12
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { MutationConfig, MutationParameters } from 'relay-runtime';
|
|
2
|
+
import { Environment } from 'relay-runtime/lib/store/RelayStoreTypes';
|
|
3
|
+
/**
|
|
4
|
+
* Wrapper Promise-based em torno do `commitMutation` do `relay-runtime`.
|
|
5
|
+
*
|
|
6
|
+
* O `commitMutation` original do Relay expõe a conclusão da mutação via os
|
|
7
|
+
* callbacks `onCompleted` e `onError`. Esta função encapsula esses callbacks
|
|
8
|
+
* em uma `Promise`, permitindo o uso natural de `async/await` no consumidor —
|
|
9
|
+
* o que tipicamente cobre 95% dos casos. Para fluxos que precisam de
|
|
10
|
+
* `optimisticResponse`, `updater`, `cacheConfig` etc., todas as demais opções
|
|
11
|
+
* de `MutationConfig` continuam sendo aceitas via `config`.
|
|
12
|
+
*
|
|
13
|
+
* Os campos `onCompleted` e `onError` são omitidos do `config` de propósito:
|
|
14
|
+
* eles são gerenciados internamente para alimentar o resolve/reject da Promise.
|
|
15
|
+
*
|
|
16
|
+
* @typeParam T - Tipo gerado pelo Relay Compiler para a mutação (`graphql`
|
|
17
|
+
* tagged) — fornece o shape de `variables` e `response`.
|
|
18
|
+
*
|
|
19
|
+
* @param environment - Ambiente Relay (geralmente o exposto por
|
|
20
|
+
* `CreateRelayEnvironment`).
|
|
21
|
+
* @param config - Configuração da mutação, sem `onCompleted` e `onError`.
|
|
22
|
+
*
|
|
23
|
+
* @returns Promise que resolve com `T['response']` ou rejeita com o erro
|
|
24
|
+
* retornado pelo Relay.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* import { commitMutation } from '@apollion-dsi/relay/commitMutation';
|
|
29
|
+
* import { Environment } from './environment';
|
|
30
|
+
* import { MyMutation } from './__generated__/MyMutation.graphql';
|
|
31
|
+
*
|
|
32
|
+
* const response = await commitMutation<MyMutation>(Environment, {
|
|
33
|
+
* mutation: graphql`
|
|
34
|
+
* mutation MyMutation($input: MyInput!) {
|
|
35
|
+
* myMutation(input: $input) { ok }
|
|
36
|
+
* }
|
|
37
|
+
* `,
|
|
38
|
+
* variables: { input: { ... } },
|
|
39
|
+
* });
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare const commitMutation: <T extends MutationParameters = MutationParameters>(environment: Environment, config: Omit<MutationConfig<T>, "onCompleted" | "onError">) => Promise<T["response"]>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Barrel público do módulo `commitMutation`.
|
|
3
|
+
*
|
|
4
|
+
* Reexporta a função `commitMutation` para que consumidores possam importar
|
|
5
|
+
* via `@apollion-dsi/relay/commitMutation` (importação granular, evitando
|
|
6
|
+
* carregar o resto do pacote) ou via `@apollion-dsi/relay` (barrel raiz).
|
|
7
|
+
*/
|
|
8
|
+
export * from './commitMutation';
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Barrel público do package `@apollion-dsi/relay`.
|
|
3
|
+
*
|
|
4
|
+
* Reexporta a superfície pública do package: a fábrica de Environment
|
|
5
|
+
* (`CreateRelayEnvironment`), o Context/hook (`EnvironmentProvider` /
|
|
6
|
+
* `useEnvironment`), os tipos de configuração (`RelayArgsInterface`,
|
|
7
|
+
* `Sink`), os utilitários de updater de mutations e o wrapper
|
|
8
|
+
* Promise-based `commitMutation`.
|
|
9
|
+
*
|
|
10
|
+
* Cada módulo também pode ser importado de forma granular via
|
|
11
|
+
* `@apollion-dsi/relay/<nome>` quando o consumidor quiser carregar
|
|
12
|
+
* menos código.
|
|
13
|
+
*/
|
|
14
|
+
export { default as CreateRelayEnvironment } from './setupRelayEnvironment/setupRelayEnvironment';
|
|
15
|
+
export * from './useEnvironment';
|
|
16
|
+
export * from './relayArgsInterface';
|
|
17
|
+
export * from './mutationUtils';
|
|
18
|
+
export * from './commitMutation';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Barrel público do módulo `mutationUtils`.
|
|
3
|
+
*
|
|
4
|
+
* Reexporta os helpers para escrever `updater`s de mutations Relay
|
|
5
|
+
* (listas, connections, optimistic responses). Importável via
|
|
6
|
+
* `@apollion-dsi/relay/mutationUtils` (granular) ou via
|
|
7
|
+
* `@apollion-dsi/relay` (barrel raiz).
|
|
8
|
+
*/
|
|
9
|
+
export * from './mutationUtils';
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Utilitários para escrever `updater`s de mutations Relay
|
|
3
|
+
* de forma declarativa, sem precisar manipular `RecordProxy` /
|
|
4
|
+
* `ConnectionHandler` à mão em cada caso comum.
|
|
5
|
+
*
|
|
6
|
+
* Cobre os cenários mais frequentes:
|
|
7
|
+
* - inserir/remover itens em listas (`linked records`);
|
|
8
|
+
* - inserir/remover edges em connections (paginação Relay);
|
|
9
|
+
* - copiar campos escalares de um objeto JS para um `RecordProxy`
|
|
10
|
+
* (útil em respostas otimistas).
|
|
11
|
+
*/
|
|
12
|
+
import { RecordProxy, RecordSourceSelectorProxy } from 'relay-runtime';
|
|
13
|
+
/**
|
|
14
|
+
* Verifica se um valor é um objeto não-nulo (para detectar campos
|
|
15
|
+
* escalares vs. linked records em `copyObjScalarsToProxy`).
|
|
16
|
+
*/
|
|
17
|
+
export declare function isObject(obj: any): boolean;
|
|
18
|
+
/** Argumentos de `listRecordRemoveUpdater`. */
|
|
19
|
+
type ListRecordRemoveUpdaterOptions = {
|
|
20
|
+
parentId: string;
|
|
21
|
+
itemId: string;
|
|
22
|
+
parentFieldName: string;
|
|
23
|
+
store: RecordSourceSelectorProxy;
|
|
24
|
+
};
|
|
25
|
+
/** Argumentos de `listRecordAddUpdater`. */
|
|
26
|
+
type ListRecordAddUpdaterOptions = {
|
|
27
|
+
parentId: string;
|
|
28
|
+
item: Record<string, any>;
|
|
29
|
+
type: string;
|
|
30
|
+
parentFieldName: string;
|
|
31
|
+
store: RecordSourceSelectorProxy;
|
|
32
|
+
};
|
|
33
|
+
/** Argumentos de `optimisticConnectionUpdater`. */
|
|
34
|
+
type OptimisticConnectionUpdaterOptions = {
|
|
35
|
+
parentId: string;
|
|
36
|
+
store: RecordSourceSelectorProxy;
|
|
37
|
+
connectionName: string;
|
|
38
|
+
item: Record<string, any>;
|
|
39
|
+
customNode: RecordProxy;
|
|
40
|
+
itemType: string;
|
|
41
|
+
};
|
|
42
|
+
/** Argumentos de `connectionDeleteEdgeUpdater`. */
|
|
43
|
+
type ConnectionDeleteEdgeUpdaterOptions = {
|
|
44
|
+
parentId: string;
|
|
45
|
+
connectionName: string;
|
|
46
|
+
nodeId: string;
|
|
47
|
+
store: RecordSourceSelectorProxy;
|
|
48
|
+
};
|
|
49
|
+
/** Argumentos de `copyObjScalarsToProxy`. */
|
|
50
|
+
type CopyObjScalarsToProxyOptions = {
|
|
51
|
+
object: Record<string, any>;
|
|
52
|
+
proxy: RecordProxy;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Identificador único gerado uma vez por carregamento do módulo,
|
|
56
|
+
* destinado ao campo `clientMutationId` esperado pelo padrão Relay
|
|
57
|
+
* Modern.
|
|
58
|
+
*/
|
|
59
|
+
export declare const ClientMutationID: string;
|
|
60
|
+
/**
|
|
61
|
+
* Remove um item de uma lista de `linked records` num parent.
|
|
62
|
+
*
|
|
63
|
+
* Usa `getLinkedRecords` + `setLinkedRecords` com filtro por `dataID`.
|
|
64
|
+
* Para connections paginadas, prefira `connectionDeleteEdgeUpdater`.
|
|
65
|
+
*
|
|
66
|
+
* @param options.parentId - DataID do parent que possui o linked field.
|
|
67
|
+
* @param options.itemId - DataID do item a remover.
|
|
68
|
+
* @param options.parentFieldName - Nome do field linked no parent.
|
|
69
|
+
* @param options.store - `RecordSourceSelectorProxy` recebido no updater.
|
|
70
|
+
*/
|
|
71
|
+
export declare function listRecordRemoveUpdater({ parentId, itemId, parentFieldName, store, }: ListRecordRemoveUpdaterOptions): void;
|
|
72
|
+
/**
|
|
73
|
+
* Adiciona um item ao final de uma lista de `linked records`.
|
|
74
|
+
*
|
|
75
|
+
* Cria um novo `RecordProxy` usando `item.id` como dataID e copia todos
|
|
76
|
+
* os campos de `item` para o novo record (sem validar tipos — escalares
|
|
77
|
+
* e linked refs viram `setValue`).
|
|
78
|
+
*
|
|
79
|
+
* @param options.parentId - DataID do parent.
|
|
80
|
+
* @param options.item - Objeto com os campos do novo record (precisa ter `id`).
|
|
81
|
+
* @param options.type - Tipo GraphQL do record (ex: `'Todo'`).
|
|
82
|
+
* @param options.parentFieldName - Nome do field linked no parent.
|
|
83
|
+
* @param options.store - `RecordSourceSelectorProxy` do updater.
|
|
84
|
+
*/
|
|
85
|
+
export declare function listRecordAddUpdater({ parentId, item, type, parentFieldName, store, }: ListRecordAddUpdaterOptions): void;
|
|
86
|
+
/**
|
|
87
|
+
* Insere um edge em uma connection paginada (Relay Connections spec).
|
|
88
|
+
*
|
|
89
|
+
* @param store - `RecordSourceSelectorProxy` do updater.
|
|
90
|
+
* @param parentId - DataID do parent que possui a connection.
|
|
91
|
+
* @param connectionName - Nome da connection no schema (`@connection(key: ...)`).
|
|
92
|
+
* @param edge - O `RecordProxy` do edge já criado pelo chamador.
|
|
93
|
+
* @param before - Se `true`, insere antes do primeiro edge (default `false`).
|
|
94
|
+
*/
|
|
95
|
+
export declare function connectionUpdater(store: RecordSourceSelectorProxy, parentId: string, connectionName: string, edge: RecordProxy, before?: boolean): void;
|
|
96
|
+
/**
|
|
97
|
+
* Variante de `connectionUpdater` usada em respostas otimistas: cria o
|
|
98
|
+
* node e o edge "do zero" a partir de um objeto JS, simulando o que o
|
|
99
|
+
* servidor retornaria.
|
|
100
|
+
*
|
|
101
|
+
* @param options.parentId - DataID do parent.
|
|
102
|
+
* @param options.store - `RecordSourceSelectorProxy`.
|
|
103
|
+
* @param options.connectionName - Nome da connection.
|
|
104
|
+
* @param options.item - Objeto com os campos do novo node (precisa ter `id`).
|
|
105
|
+
* @param options.customNode - `RecordProxy` pré-criado (opcional, evita criar via `item`).
|
|
106
|
+
* @param options.itemType - Tipo GraphQL do node (ex: `'Todo'`); o edge
|
|
107
|
+
* será criado como `<itemType>Edge`.
|
|
108
|
+
*/
|
|
109
|
+
export declare function optimisticConnectionUpdater({ parentId, store, connectionName, item, customNode, itemType, }: OptimisticConnectionUpdaterOptions): void;
|
|
110
|
+
/**
|
|
111
|
+
* Remove um node de uma connection paginada pelo seu `dataID`.
|
|
112
|
+
*
|
|
113
|
+
* Loga `console.warn` se a connection não for encontrada (geralmente
|
|
114
|
+
* significa que o `connectionName` está errado).
|
|
115
|
+
*
|
|
116
|
+
* @param options.parentId - DataID do parent.
|
|
117
|
+
* @param options.connectionName - Nome da connection.
|
|
118
|
+
* @param options.nodeId - DataID do node a remover.
|
|
119
|
+
* @param options.store - `RecordSourceSelectorProxy`.
|
|
120
|
+
*/
|
|
121
|
+
export declare function connectionDeleteEdgeUpdater({ parentId, connectionName, nodeId, store, }: ConnectionDeleteEdgeUpdaterOptions): void;
|
|
122
|
+
/**
|
|
123
|
+
* Copia os campos escalares de um objeto JS para um `RecordProxy`.
|
|
124
|
+
*
|
|
125
|
+
* Ignora campos que são objetos ou arrays (linked records / linked
|
|
126
|
+
* record lists) — esses precisam ser manipulados com
|
|
127
|
+
* `setLinkedRecord`/`setLinkedRecords`.
|
|
128
|
+
*
|
|
129
|
+
* @param options.object - Objeto JS de origem.
|
|
130
|
+
* @param options.proxy - `RecordProxy` de destino.
|
|
131
|
+
*/
|
|
132
|
+
export declare function copyObjScalarsToProxy({ object, proxy }: CopyObjScalarsToProxyOptions): void;
|
|
133
|
+
export {};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tipos públicos consumidos pelo `setupRelayEnvironment`
|
|
3
|
+
* (`RelayArgsInterface`) e pelos seus internals (`Sink`).
|
|
4
|
+
*
|
|
5
|
+
* `RelayArgsInterface` é o contrato de configuração de
|
|
6
|
+
* `CreateRelayEnvironment` — qualquer mudança aqui é parte da API
|
|
7
|
+
* pública do package.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Sink do `Observable` Relay. Implementado pelo runtime do Relay e
|
|
11
|
+
* passado para o callback de `Observable.create`. Os internals de
|
|
12
|
+
* fetch/subscription usam essa interface para propagar dados, erros
|
|
13
|
+
* e completação para a stream.
|
|
14
|
+
*/
|
|
15
|
+
export interface Sink {
|
|
16
|
+
/** Empurra o próximo valor para a stream. */
|
|
17
|
+
next(value: any): void;
|
|
18
|
+
/** Reporta um erro e fecha a stream. */
|
|
19
|
+
error(error: Error, isUncaughtThrownError?: boolean): void;
|
|
20
|
+
/** Sinaliza completação normal da stream. */
|
|
21
|
+
complete(): void;
|
|
22
|
+
/** `true` quando a stream já foi fechada (sink complete/error). */
|
|
23
|
+
readonly closed: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Configuração aceita pelo construtor de `CreateRelayEnvironment`.
|
|
27
|
+
*
|
|
28
|
+
* Apenas `url` é obrigatório. Todos os demais campos têm defaults
|
|
29
|
+
* sensatos definidos no construtor.
|
|
30
|
+
*
|
|
31
|
+
* @see {@link "../setupRelayEnvironment/setupRelayEnvironment"} para os defaults.
|
|
32
|
+
*/
|
|
33
|
+
export interface RelayArgsInterface {
|
|
34
|
+
/**
|
|
35
|
+
* Endpoint HTTP do servidor GraphQL. Obrigatório.
|
|
36
|
+
*/
|
|
37
|
+
url: string;
|
|
38
|
+
/**
|
|
39
|
+
* Endpoint do servidor de autenticação. Usado pelo fluxo de
|
|
40
|
+
* verificação de sessão (`${authUrl}user/me`). Obrigatório quando
|
|
41
|
+
* `useAuthorization` é `true`.
|
|
42
|
+
*/
|
|
43
|
+
authUrl?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Endpoint WebSocket para subscriptions GraphQL. Obrigatório quando
|
|
46
|
+
* `useSubscription` é `true`.
|
|
47
|
+
*/
|
|
48
|
+
socket?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Lista de delays (ms) entre tentativas de retry, com backoff.
|
|
51
|
+
*
|
|
52
|
+
* @defaultValue `[1s, 2s, 3s, 5s, 8s, 13s, 21s, 34s]` (fibonacci-like)
|
|
53
|
+
*/
|
|
54
|
+
retries?: number[];
|
|
55
|
+
/**
|
|
56
|
+
* Timeout por requisição em ms.
|
|
57
|
+
*
|
|
58
|
+
* @defaultValue 15 minutos
|
|
59
|
+
*/
|
|
60
|
+
timeout?: number;
|
|
61
|
+
/**
|
|
62
|
+
* Habilita o handler de subscriptions GraphQL via WebSocket.
|
|
63
|
+
*
|
|
64
|
+
* @defaultValue false
|
|
65
|
+
*/
|
|
66
|
+
useSubscription?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Habilita autenticação via JWT — injeta `Authorization: Bearer <token>`
|
|
69
|
+
* em cada request usando o `sessionToken` armazenado.
|
|
70
|
+
*
|
|
71
|
+
* @defaultValue false
|
|
72
|
+
*/
|
|
73
|
+
useAuthorization?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Habilita cache de respostas via `QueryResponseCache` do Relay.
|
|
76
|
+
* Por recomendação do time do Relay, vem desligado por padrão.
|
|
77
|
+
*
|
|
78
|
+
* @defaultValue false
|
|
79
|
+
*/
|
|
80
|
+
useCache?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* TTL (ms) das entradas do cache de queries.
|
|
83
|
+
*
|
|
84
|
+
* @defaultValue 8 minutos
|
|
85
|
+
*/
|
|
86
|
+
cacheTime?: number;
|
|
87
|
+
/**
|
|
88
|
+
* Tamanho máximo do cache (número de queries distintas mantidas).
|
|
89
|
+
*
|
|
90
|
+
* @defaultValue 250
|
|
91
|
+
*/
|
|
92
|
+
cacheSize?: number;
|
|
93
|
+
/**
|
|
94
|
+
* Nome da chave usada em storage para o token de sessão (JWT).
|
|
95
|
+
*
|
|
96
|
+
* @defaultValue `'USER_SESSION_TOKEN'`
|
|
97
|
+
*/
|
|
98
|
+
sessionStorageProp?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Nome da chave usada em storage para o refresh token.
|
|
101
|
+
*
|
|
102
|
+
* @defaultValue `'USER_REFRESH_TOKEN'`
|
|
103
|
+
*/
|
|
104
|
+
refreshStorageProp?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Rota interna para a qual o usuário será redirecionado quando a
|
|
107
|
+
* sessão expirar (ou em erros de auth, se `redirectOnError` estiver
|
|
108
|
+
* ligado).
|
|
109
|
+
*
|
|
110
|
+
* @defaultValue `'/'`
|
|
111
|
+
*/
|
|
112
|
+
loginRoute?: string;
|
|
113
|
+
/**
|
|
114
|
+
* Liga logs verbosos (útil em desenvolvimento). Não habilite em
|
|
115
|
+
* produção.
|
|
116
|
+
*
|
|
117
|
+
* @defaultValue false
|
|
118
|
+
*/
|
|
119
|
+
useDebug?: boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Habilita retries em caso de erro/timeout, usando os delays de
|
|
122
|
+
* `retries`.
|
|
123
|
+
*
|
|
124
|
+
* @defaultValue false
|
|
125
|
+
*/
|
|
126
|
+
useRetries?: boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Redireciona o usuário para `loginRoute` quando um erro com status
|
|
129
|
+
* em `authenticationErrors` é detectado e a sessão é considerada
|
|
130
|
+
* inválida.
|
|
131
|
+
*
|
|
132
|
+
* @defaultValue false
|
|
133
|
+
*/
|
|
134
|
+
redirectOnError?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Lista de status HTTP que disparam retry (quando `useRetries` é
|
|
137
|
+
* `true`). Defaults cobrem erros típicos de Cloudflare.
|
|
138
|
+
*
|
|
139
|
+
* @defaultValue `[503, 504, 521, 522, 524]`
|
|
140
|
+
* @see https://support.cloudflare.com/hc/pt-br/articles/115003011431-Solu%C3%A7%C3%A3o-de-problemas-de-erros-5XX-da-Cloudflare
|
|
141
|
+
*/
|
|
142
|
+
retryWhen?: number[];
|
|
143
|
+
/**
|
|
144
|
+
* Status considerados como erro de autenticação para o fluxo de
|
|
145
|
+
* `redirectOnError`.
|
|
146
|
+
*
|
|
147
|
+
* @defaultValue `[401, 403]`
|
|
148
|
+
*/
|
|
149
|
+
authenticationErrors?: number[];
|
|
150
|
+
/**
|
|
151
|
+
* Estratégia de storage no browser para tokens.
|
|
152
|
+
*
|
|
153
|
+
* @defaultValue `'localStorage'`
|
|
154
|
+
*/
|
|
155
|
+
storageType?: 'cookie' | 'localStorage';
|
|
156
|
+
/**
|
|
157
|
+
* Identificador de parceiro enviado em todas as requests via
|
|
158
|
+
* header `X-Partner`. Útil para tenants/whitelabels.
|
|
159
|
+
*
|
|
160
|
+
* @defaultValue undefined
|
|
161
|
+
*/
|
|
162
|
+
partner?: string;
|
|
163
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Detecção de ambiente de execução (browser/DOM,
|
|
3
|
+
* Worker, viewport) usada por `setupRelayEnvironment` para alternar
|
|
4
|
+
* comportamento entre browser e SSR.
|
|
5
|
+
*
|
|
6
|
+
* Não exposto pelo barrel raiz — implementação interna de
|
|
7
|
+
* `CreateRelayEnvironment`.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Conjunto de flags booleanas indicando capacidades do ambiente atual.
|
|
11
|
+
* Inspirado no antigo `fbjs/ExecutionEnvironment`. Usado para evitar
|
|
12
|
+
* dependências circulares e permitir que o código reaja a SSR sem
|
|
13
|
+
* importar React diretamente.
|
|
14
|
+
*/
|
|
15
|
+
declare const _default: {
|
|
16
|
+
/** `true` em browsers. */
|
|
17
|
+
canUseDOM: boolean;
|
|
18
|
+
/** `true` se `Worker` está disponível globalmente. */
|
|
19
|
+
canUseWorkers: boolean;
|
|
20
|
+
/** `true` em browsers que suportam `addEventListener` ou IE `attachEvent`. */
|
|
21
|
+
canUseEventListeners: boolean;
|
|
22
|
+
/** `true` em browsers com `window.screen` (viewport mensurável). */
|
|
23
|
+
canUseViewport: boolean;
|
|
24
|
+
/** `true` quando rodando em um Worker (sem DOM). */
|
|
25
|
+
isInWorker: boolean;
|
|
26
|
+
};
|
|
27
|
+
export default _default;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Fábrica da `fetchFn` do Relay usada por
|
|
3
|
+
* `setupRelayEnvironment`. Encapsula cache de respostas, retries via
|
|
4
|
+
* `fetchWithRetries`, tratamento de erros (incluindo redirect em caso
|
|
5
|
+
* de sessão expirada) e adaptação para o modelo `Observable` que o
|
|
6
|
+
* `Network.create` do Relay espera.
|
|
7
|
+
*
|
|
8
|
+
* Não exposto pelo barrel raiz — implementação interna de
|
|
9
|
+
* `CreateRelayEnvironment`.
|
|
10
|
+
*/
|
|
11
|
+
import { CacheConfig, Observable, RequestParameters, UploadableMap, Variables } from 'relay-runtime';
|
|
12
|
+
/**
|
|
13
|
+
* Cria a fetch function que será passada para `Network.create` do Relay.
|
|
14
|
+
*
|
|
15
|
+
* Comportamento:
|
|
16
|
+
* - Para queries com `useCache` ligado, tenta servir do cache
|
|
17
|
+
* (`QueryResponseCache`) antes de fazer a requisição.
|
|
18
|
+
* - Para mutations com `useCache` ligado, limpa o cache (invalidação
|
|
19
|
+
* total — Relay vai re-buscar queries afetadas).
|
|
20
|
+
* - Em caso de erro de autenticação detectado, chama o endpoint
|
|
21
|
+
* `${authUrl}user/me` e, se inválido, limpa storage e redireciona
|
|
22
|
+
* para `loginRoute`.
|
|
23
|
+
* - Erros são propagados via `sink.error()`.
|
|
24
|
+
*
|
|
25
|
+
* @param config - Instância de `CreateRelayEnvironment` configurada.
|
|
26
|
+
* @returns Função compatível com `Network.create(fetchFn, ...)`.
|
|
27
|
+
*/
|
|
28
|
+
export declare const createFetchFunction: (config: any) => (request: RequestParameters, variables: Variables, cacheConfig: CacheConfig, uploadables: UploadableMap) => Observable<unknown>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Implementação de `fetch` com retries e timeout, usada
|
|
3
|
+
* internamente por `fetchQuery` no `setupRelayEnvironment`.
|
|
4
|
+
*
|
|
5
|
+
* Adiciona em cima do `fetch` nativo:
|
|
6
|
+
* - timeout por requisição (`AbortController`);
|
|
7
|
+
* - retry com delays configuráveis (`retries` no config) quando o
|
|
8
|
+
* status HTTP está em `retryWhen` ou houve timeout;
|
|
9
|
+
* - debug logs opcionais via `useDebug`.
|
|
10
|
+
*
|
|
11
|
+
* Não exposto pelo barrel raiz — implementação interna de
|
|
12
|
+
* `CreateRelayEnvironment`.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Subconjunto de `RequestInit` aceito por `fetchWithRetries`. Mantemos
|
|
16
|
+
* apenas os campos efetivamente repassados ao `fetch` nativo.
|
|
17
|
+
*/
|
|
18
|
+
export type InitWithRetries = {
|
|
19
|
+
body?: BodyInit | null;
|
|
20
|
+
cache?: RequestCache;
|
|
21
|
+
credentials?: RequestCredentials;
|
|
22
|
+
headers?: HeadersInit;
|
|
23
|
+
method?: string;
|
|
24
|
+
mode?: RequestMode;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Cria uma função `fetch` configurada com timeout e retries.
|
|
28
|
+
*
|
|
29
|
+
* Comportamento:
|
|
30
|
+
* - Cada tentativa tem timeout de `config.timeout` ms (via `AbortController`).
|
|
31
|
+
* - Se houver timeout ou o status estiver em `config.retryWhen`, agenda
|
|
32
|
+
* a próxima tentativa com o delay correspondente em `config.retries`.
|
|
33
|
+
* - Retries só ocorrem quando há DOM disponível e `config.useRetries`
|
|
34
|
+
* é `true` — no SSR a primeira tentativa é a única.
|
|
35
|
+
* - Erros não relacionados a `AbortError` são rejeitados imediatamente.
|
|
36
|
+
*
|
|
37
|
+
* @param config - Configuração do environment (timeout, retries,
|
|
38
|
+
* retryWhen, useRetries, useDebug, url).
|
|
39
|
+
* @returns Função que recebe `RequestInit` e retorna `Promise<Response>`.
|
|
40
|
+
*/
|
|
41
|
+
export declare function fetchWithRetries(config: any): (init?: InitWithRetries | null) => Promise<any>;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Environment } from 'relay-runtime';
|
|
2
|
+
import { RelayArgsInterface } from '../relayArgsInterface';
|
|
3
|
+
declare const kMountEnvironment: unique symbol;
|
|
4
|
+
declare const kFeetchHandler: unique symbol;
|
|
5
|
+
declare const kSubscriptionHandler: unique symbol;
|
|
6
|
+
/**
|
|
7
|
+
* Fábrica de `Environment` Relay com bateria inclusa: autenticação JWT,
|
|
8
|
+
* retries com backoff, suporte a subscriptions via WebSocket, cache de
|
|
9
|
+
* respostas e estratégia plugável de storage (localStorage ou cookie).
|
|
10
|
+
*
|
|
11
|
+
* Esta classe encapsula a configuração que normalmente precisaria ser
|
|
12
|
+
* escrita à mão para cada projeto que usa Relay: criar `Network`,
|
|
13
|
+
* `RecordSource`, `Store`, configurar `fetch` com retries/timeout,
|
|
14
|
+
* adicionar headers de autenticação, lidar com redirecionamento em caso
|
|
15
|
+
* de sessão expirada e opcionalmente registrar um handler de
|
|
16
|
+
* subscriptions GraphQL.
|
|
17
|
+
*
|
|
18
|
+
* A instância exposta possui a propriedade pública `Environment`, que é
|
|
19
|
+
* o objeto que deve ser passado para `react-relay` (via `RelayEnvironmentProvider`
|
|
20
|
+
* ou `QueryRenderer`).
|
|
21
|
+
*
|
|
22
|
+
* @example Setup mínimo
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { CreateRelayEnvironment } from '@apollion-dsi/relay';
|
|
25
|
+
*
|
|
26
|
+
* const { Environment } = new CreateRelayEnvironment({
|
|
27
|
+
* url: 'https://api.example.com/graphql/',
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @example Com auth JWT e retries
|
|
32
|
+
* ```ts
|
|
33
|
+
* const { Environment } = new CreateRelayEnvironment({
|
|
34
|
+
* url: 'https://api.example.com/graphql/',
|
|
35
|
+
* authUrl: 'https://api.example.com/auth/',
|
|
36
|
+
* useAuthorization: true,
|
|
37
|
+
* useRetries: true,
|
|
38
|
+
* retries: [1000, 2000, 5000],
|
|
39
|
+
* });
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @example Com subscriptions
|
|
43
|
+
* ```ts
|
|
44
|
+
* const { Environment } = new CreateRelayEnvironment({
|
|
45
|
+
* url: 'https://api.example.com/graphql/',
|
|
46
|
+
* socket: 'wss://api.example.com/graphql/',
|
|
47
|
+
* useSubscription: true,
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @see {@link RelayArgsInterface} para a lista completa de opções de configuração.
|
|
52
|
+
*/
|
|
53
|
+
export default class RelayEnvironment implements RelayArgsInterface {
|
|
54
|
+
/** Endpoint HTTP do servidor GraphQL. Obrigatório. */
|
|
55
|
+
url: string;
|
|
56
|
+
/** Endpoint do servidor de autenticação. Obrigatório quando `useAuthorization` é `true`. */
|
|
57
|
+
authUrl?: string;
|
|
58
|
+
/** Endpoint WebSocket para subscriptions. Obrigatório quando `useSubscription` é `true`. */
|
|
59
|
+
socket?: string;
|
|
60
|
+
/** Lista de delays (ms) entre tentativas, quando `useRetries` é `true`. */
|
|
61
|
+
retries?: number[];
|
|
62
|
+
/** Timeout (ms) por requisição. */
|
|
63
|
+
timeout?: number;
|
|
64
|
+
/** Habilita subscriptions GraphQL via WebSocket. */
|
|
65
|
+
useSubscription?: boolean;
|
|
66
|
+
/** Habilita injeção do header `Authorization: Bearer <token>` em cada request. */
|
|
67
|
+
useAuthorization?: boolean;
|
|
68
|
+
/** Habilita cache de respostas (via `QueryResponseCache` do Relay). */
|
|
69
|
+
useCache?: boolean;
|
|
70
|
+
/** TTL (ms) das entradas do cache. */
|
|
71
|
+
cacheTime?: number;
|
|
72
|
+
/** Tamanho máximo do cache (número de queries). */
|
|
73
|
+
cacheSize?: number;
|
|
74
|
+
/** Nome da chave em storage usada para guardar o token de sessão. */
|
|
75
|
+
sessionStorageProp?: string;
|
|
76
|
+
/** Nome da chave em storage usada para guardar o refresh token. */
|
|
77
|
+
refreshStorageProp?: string;
|
|
78
|
+
/** Rota usada para redirecionar o usuário em caso de sessão expirada. */
|
|
79
|
+
loginRoute?: string;
|
|
80
|
+
/** Liga logs de debug (útil em desenvolvimento). */
|
|
81
|
+
useDebug?: boolean;
|
|
82
|
+
/** Habilita o mecanismo de retries em caso de erro/timeout. */
|
|
83
|
+
useRetries?: boolean;
|
|
84
|
+
/** Redireciona automaticamente para `loginRoute` em caso de erro de auth. */
|
|
85
|
+
redirectOnError?: boolean;
|
|
86
|
+
/** Lista de status HTTP que disparam retry (quando `useRetries` é `true`). */
|
|
87
|
+
retryWhen?: number[];
|
|
88
|
+
/** Status HTTP considerados como erros de autenticação (default: 401, 403). */
|
|
89
|
+
authenticationErrors?: number[];
|
|
90
|
+
/** Estratégia de storage no browser. */
|
|
91
|
+
storageType: 'cookie' | 'localStorage';
|
|
92
|
+
/** Identificador opcional do parceiro, enviado no header `X-Partner`. */
|
|
93
|
+
partner?: string;
|
|
94
|
+
/**
|
|
95
|
+
* Função de fetch montada para uso pelo `Network` do Relay. Interno.
|
|
96
|
+
*/
|
|
97
|
+
private [kFeetchHandler]?;
|
|
98
|
+
/**
|
|
99
|
+
* Função de subscription montada para uso pelo `Network` do Relay. Interno.
|
|
100
|
+
*/
|
|
101
|
+
private [kSubscriptionHandler]?;
|
|
102
|
+
/**
|
|
103
|
+
* Handler de storage. Expõe métodos `getTokens`, `setTokens`, `clear`,
|
|
104
|
+
* `hasChangedSession`. Use diretamente quando precisar manipular tokens
|
|
105
|
+
* fora do fluxo padrão (ex: tela de login).
|
|
106
|
+
*/
|
|
107
|
+
StorageHandler: any;
|
|
108
|
+
/**
|
|
109
|
+
* Instância de `Environment` do `relay-runtime` pronta para uso com
|
|
110
|
+
* `RelayEnvironmentProvider` (`react-relay`).
|
|
111
|
+
*/
|
|
112
|
+
Environment: Environment;
|
|
113
|
+
/**
|
|
114
|
+
* @param config - Configuração da instância. Veja {@link RelayArgsInterface}.
|
|
115
|
+
* Apenas `url` é obrigatório; demais opções têm defaults sensatos.
|
|
116
|
+
*
|
|
117
|
+
* @throws {Error} Se `url` não for informado.
|
|
118
|
+
* @throws {Error} Se `useAuthorization` for `true` e `authUrl` não for informado.
|
|
119
|
+
* @throws {Error} Se `useSubscription` for `true` e `socket` não for informado.
|
|
120
|
+
*/
|
|
121
|
+
constructor(config: RelayArgsInterface);
|
|
122
|
+
/**
|
|
123
|
+
* Monta o `Environment` Relay a partir da fetch function e subscription
|
|
124
|
+
* handler configurados. Chamado uma única vez pelo construtor.
|
|
125
|
+
*/
|
|
126
|
+
private [kMountEnvironment];
|
|
127
|
+
}
|
|
128
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Helpers internos usados por `setupRelayEnvironment` para
|
|
3
|
+
* montar a Network do Relay: detecção do tipo de operação, construção do
|
|
4
|
+
* body/headers da requisição, parse de respostas (incluindo
|
|
5
|
+
* `multipart/mixed` para `@defer`/`@stream`), redirecionamento em erro
|
|
6
|
+
* de auth e constantes de tempo.
|
|
7
|
+
*
|
|
8
|
+
* Não exposto pelo barrel raiz — faz parte da implementação interna de
|
|
9
|
+
* `CreateRelayEnvironment`.
|
|
10
|
+
*/
|
|
11
|
+
import { CacheConfig, RequestParameters, UploadableMap, Variables } from 'relay-runtime';
|
|
12
|
+
import { RelayArgsInterface, Sink } from '../relayArgsInterface';
|
|
13
|
+
/** Verdadeiro se a operação Relay é uma mutation. */
|
|
14
|
+
export declare const isMutation: (request: RequestParameters) => boolean;
|
|
15
|
+
/** Verdadeiro se a operação Relay é uma query. */
|
|
16
|
+
export declare const isQuery: (request: RequestParameters) => boolean;
|
|
17
|
+
/** Verdadeiro quando o consumidor pediu `force: true` no `CacheConfig` (bypass do cache). */
|
|
18
|
+
export declare const forceFetch: (cacheConfig: CacheConfig) => boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Retorna o delimitador (`?` ou `&`) apropriado para anexar query params
|
|
21
|
+
* à URL atual do browser. Retorna string vazia em ambientes sem DOM (SSR).
|
|
22
|
+
*/
|
|
23
|
+
export declare const getParamsDelimiter: () => string;
|
|
24
|
+
/**
|
|
25
|
+
* Retorna o `pathname` atual do browser, ou string vazia em ambientes
|
|
26
|
+
* sem DOM (SSR).
|
|
27
|
+
*/
|
|
28
|
+
export declare const getBrowserLocation: () => string;
|
|
29
|
+
/**
|
|
30
|
+
* Redireciona o usuário para `redirectTo`, preservando a URL atual em
|
|
31
|
+
* `?redirect=` (para o fluxo de login redirecionar de volta).
|
|
32
|
+
*
|
|
33
|
+
* Não adiciona o parâmetro `redirect` quando a URL atual já é igual ao
|
|
34
|
+
* destino ou quando o destino é a própria `loginRoute`.
|
|
35
|
+
*
|
|
36
|
+
* @param url - URL atual (origem do redirect).
|
|
37
|
+
* @param redirectTo - Destino do redirect.
|
|
38
|
+
* @param config - Configuração do environment (usada para checar `loginRoute`).
|
|
39
|
+
*/
|
|
40
|
+
export declare const redirectUser: (url: string, redirectTo: string, config?: RelayArgsInterface) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Constrói o body da requisição GraphQL — multipart se há uploadables,
|
|
43
|
+
* JSON caso contrário.
|
|
44
|
+
*
|
|
45
|
+
* @param request - Parâmetros da requisição Relay.
|
|
46
|
+
* @param variables - Variáveis da operação.
|
|
47
|
+
* @param uploadables - Arquivos para upload (opcional).
|
|
48
|
+
*/
|
|
49
|
+
export declare function getRequestBody(request: RequestParameters, variables: Variables, uploadables?: UploadableMap): string | FormData;
|
|
50
|
+
/**
|
|
51
|
+
* Monta os headers HTTP da requisição. Para uploads, usa `Accept: *\/*`
|
|
52
|
+
* e deixa o browser definir o `Content-Type` com boundary. Para JSON,
|
|
53
|
+
* usa `application/json` em ambos.
|
|
54
|
+
*
|
|
55
|
+
* Quando `useAuthorization` está ligado e existe um `sessionToken` em
|
|
56
|
+
* storage, anexa `Authorization: Bearer <token>` — exceto quando o
|
|
57
|
+
* usuário está na própria rota de login (para evitar loops).
|
|
58
|
+
*
|
|
59
|
+
* Se um `partner` está configurado, adiciona o header `X-Partner`.
|
|
60
|
+
*/
|
|
61
|
+
export declare const getHeaders: (args: any, uploadables?: UploadableMap) => HeadersInit;
|
|
62
|
+
/**
|
|
63
|
+
* Lê o `Response` do fetch e empurra os dados para o `Sink` do Relay.
|
|
64
|
+
*
|
|
65
|
+
* Suporta três modos:
|
|
66
|
+
* - `multipart/mixed` (usado por `@defer` e `@stream`): lê o stream
|
|
67
|
+
* chunk a chunk e usa `PatchResolver` para repassar cada patch.
|
|
68
|
+
* - `application/json`: parseia o JSON inteiro e chama `callback`.
|
|
69
|
+
* - Outros: lê como texto e empurra como array de strings.
|
|
70
|
+
*
|
|
71
|
+
* Copiado da biblioteca `fetch-multipart-graphql` com adaptações para o
|
|
72
|
+
* `Sink` Relay.
|
|
73
|
+
*/
|
|
74
|
+
export declare const handleData: (response: Response, sink: Sink, callback: (data: any) => void) => void;
|
|
75
|
+
/** Constante de tempo: 1 segundo em milissegundos. */
|
|
76
|
+
export declare const ONE_SECOND = 1000;
|
|
77
|
+
/** Constante de tempo: 1 minuto em milissegundos. */
|
|
78
|
+
export declare const ONE_MINUTE: number;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { RelayArgsInterface } from '../relayArgsInterface';
|
|
2
|
+
/** Par de tokens armazenado. */
|
|
3
|
+
type TokenTypes = {
|
|
4
|
+
sessionToken?: string;
|
|
5
|
+
refreshToken?: string;
|
|
6
|
+
};
|
|
7
|
+
declare const kStorageHandler: unique symbol;
|
|
8
|
+
declare const kPropSession: unique symbol;
|
|
9
|
+
declare const kPropRefresh: unique symbol;
|
|
10
|
+
/**
|
|
11
|
+
* Handler de storage usado por `CreateRelayEnvironment`. Encapsula a
|
|
12
|
+
* estratégia escolhida (`storageType`) e padroniza a manipulação de
|
|
13
|
+
* `sessionToken` e `refreshToken` por trás de uma API estável.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const { StorageHandler } = new CreateRelayEnvironment({ ... });
|
|
18
|
+
* StorageHandler.setTokens({ sessionToken: 't', refreshToken: 'r' });
|
|
19
|
+
* const { sessionToken } = StorageHandler.getTokens();
|
|
20
|
+
* StorageHandler.clear();
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export default class StorageClass {
|
|
24
|
+
private [kStorageHandler];
|
|
25
|
+
private [kPropSession];
|
|
26
|
+
private [kPropRefresh];
|
|
27
|
+
/**
|
|
28
|
+
* @param strategy - Instância de `CreateRelayEnvironment` (que
|
|
29
|
+
* implementa `RelayArgsInterface`). Os campos lidos são
|
|
30
|
+
* `storageType`, `sessionStorageProp`, `refreshStorageProp`.
|
|
31
|
+
*/
|
|
32
|
+
constructor(strategy: RelayArgsInterface);
|
|
33
|
+
/**
|
|
34
|
+
* Lê os tokens atualmente armazenados.
|
|
35
|
+
*
|
|
36
|
+
* @returns Objeto com `sessionToken` e `refreshToken` (podem ser
|
|
37
|
+
* `undefined` quando ausentes).
|
|
38
|
+
*/
|
|
39
|
+
getTokens(): TokenTypes;
|
|
40
|
+
/**
|
|
41
|
+
* Grava ambos os tokens em storage. Use após receber resposta de
|
|
42
|
+
* login/refresh.
|
|
43
|
+
*/
|
|
44
|
+
setTokens(tokens: TokenTypes): void;
|
|
45
|
+
/**
|
|
46
|
+
* Remove ambos os tokens do storage. Usado em logout ou ao detectar
|
|
47
|
+
* sessão expirada.
|
|
48
|
+
*/
|
|
49
|
+
clear(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Compara um novo `sessionToken` com o atualmente armazenado.
|
|
52
|
+
*
|
|
53
|
+
* @param tokens - Objeto contendo o novo `sessionToken` (vindo, por
|
|
54
|
+
* exemplo, de um header de resposta).
|
|
55
|
+
* @returns `true` se o token mudou.
|
|
56
|
+
*/
|
|
57
|
+
hasChangedSession({ sessionToken: newSessionToken }: TokenTypes): boolean;
|
|
58
|
+
}
|
|
59
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Fábrica do subscription handler GraphQL via WebSocket,
|
|
3
|
+
* usada por `setupRelayEnvironment` quando `useSubscription` está
|
|
4
|
+
* habilitado.
|
|
5
|
+
*
|
|
6
|
+
* Baseado em `graphql-ws` (protocolo `graphql-transport-ws`).
|
|
7
|
+
*
|
|
8
|
+
* Não exposto pelo barrel raiz — implementação interna de
|
|
9
|
+
* `CreateRelayEnvironment`.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Monta a subscription function para o `Network.create` do Relay.
|
|
13
|
+
*
|
|
14
|
+
* Retorna uma função (a ser chamada uma vez, no setup do Environment)
|
|
15
|
+
* que por sua vez retorna a subscribe function que o Relay vai invocar
|
|
16
|
+
* para cada subscription operation. A adaptação de callbacks
|
|
17
|
+
* `next/error/complete` do `graphql-ws` para o `Sink` do Observable
|
|
18
|
+
* Relay é feita aqui.
|
|
19
|
+
*
|
|
20
|
+
* @param settings - Objeto com a URL do endpoint WebSocket (`socket`).
|
|
21
|
+
* Quando `useSubscription` é `true` mas `socket` não foi configurado,
|
|
22
|
+
* o construtor de `CreateRelayEnvironment` lança erro antes desta
|
|
23
|
+
* função ser chamada.
|
|
24
|
+
* @returns Função que, quando invocada, retorna a subscribe function
|
|
25
|
+
* compatível com `Network.create(fetchFn, subscribeFn)`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function setupSubscription(settings: {
|
|
28
|
+
socket?: string;
|
|
29
|
+
}): () => any;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Barrel público do módulo `useEnvironment`.
|
|
3
|
+
*
|
|
4
|
+
* Reexporta o hook `useEnvironment` e o componente `EnvironmentProvider`,
|
|
5
|
+
* para que consumidores possam importar via
|
|
6
|
+
* `@apollion-dsi/relay/useEnvironment` (granular) ou via
|
|
7
|
+
* `@apollion-dsi/relay` (barrel raiz).
|
|
8
|
+
*/
|
|
9
|
+
export * from './useEnvironment';
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Environment } from 'relay-runtime';
|
|
3
|
+
import { MockEnvironment } from 'relay-test-utils';
|
|
4
|
+
/**
|
|
5
|
+
* Estado interno do Context: contém apenas o `Environment` Relay
|
|
6
|
+
* (real ou mockado em testes).
|
|
7
|
+
*/
|
|
8
|
+
type StateType = {
|
|
9
|
+
environment: Environment | MockEnvironment;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Props do `EnvironmentProvider`.
|
|
13
|
+
*/
|
|
14
|
+
type EnvironmentProviderInterface = {
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
} & StateType;
|
|
17
|
+
/**
|
|
18
|
+
* Provider que injeta o `Environment` Relay na árvore React via Context.
|
|
19
|
+
*
|
|
20
|
+
* Em produção, passe a propriedade `Environment` exposta por
|
|
21
|
+
* `CreateRelayEnvironment`. Em testes, passe um `MockEnvironment` de
|
|
22
|
+
* `relay-test-utils` para facilitar a substituição do backend.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* import { CreateRelayEnvironment, EnvironmentProvider } from '@apollion-dsi/relay';
|
|
27
|
+
*
|
|
28
|
+
* const { Environment } = new CreateRelayEnvironment({ url: '...' });
|
|
29
|
+
*
|
|
30
|
+
* function App() {
|
|
31
|
+
* return (
|
|
32
|
+
* <EnvironmentProvider environment={Environment}>
|
|
33
|
+
* <Routes />
|
|
34
|
+
* </EnvironmentProvider>
|
|
35
|
+
* );
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @example Em testes
|
|
40
|
+
* ```tsx
|
|
41
|
+
* import { createMockEnvironment } from 'relay-test-utils';
|
|
42
|
+
*
|
|
43
|
+
* const mock = createMockEnvironment();
|
|
44
|
+
* render(
|
|
45
|
+
* <EnvironmentProvider environment={mock}>
|
|
46
|
+
* <SubjectUnderTest />
|
|
47
|
+
* </EnvironmentProvider>
|
|
48
|
+
* );
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
declare function EnvironmentProvider({ children, environment }: EnvironmentProviderInterface): React.JSX.Element;
|
|
52
|
+
/**
|
|
53
|
+
* Hook para acessar o `Environment` Relay corrente.
|
|
54
|
+
*
|
|
55
|
+
* Deve ser usado dentro de um `EnvironmentProvider`. Lança erro
|
|
56
|
+
* descritivo caso seja chamado fora dele ou se nenhum environment
|
|
57
|
+
* tenha sido fornecido — falhas silenciosas aqui geralmente viram
|
|
58
|
+
* "loading infinito" no Relay, então preferimos falhar cedo.
|
|
59
|
+
*
|
|
60
|
+
* @returns Objeto com a propriedade `environment`.
|
|
61
|
+
* @throws {Error} Quando usado fora de `EnvironmentProvider` ou quando
|
|
62
|
+
* o environment fornecido é `null`/`undefined`.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```tsx
|
|
66
|
+
* function MyComponent() {
|
|
67
|
+
* const { environment } = useEnvironment();
|
|
68
|
+
* // ...
|
|
69
|
+
* }
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
declare function useEnvironment(): StateType;
|
|
73
|
+
export { EnvironmentProvider, useEnvironment };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apollion-dsi/relay",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Frontend services regarding Relay Environment",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/index.esm.js",
|
|
@@ -22,8 +22,7 @@
|
|
|
22
22
|
"format": "yarn prettier --write",
|
|
23
23
|
"validate": "./scripts/validate.sh",
|
|
24
24
|
"validate:tests": "jest --coverage",
|
|
25
|
-
"build": "node ./esbuild",
|
|
26
|
-
"postbuild": "tsc --emitDeclarationOnly",
|
|
25
|
+
"build": "node -e \"require('fs').rmSync('./lib',{recursive:true,force:true})\" && node ./esbuild && tsc --emitDeclarationOnly",
|
|
27
26
|
"test": "yarn validate",
|
|
28
27
|
"code:check": "yarn lint && yarn coverage"
|
|
29
28
|
},
|
|
@@ -32,16 +31,16 @@
|
|
|
32
31
|
},
|
|
33
32
|
"dependencies": {
|
|
34
33
|
"fetch-multipart-graphql": "2.3.1",
|
|
35
|
-
"graphql": "
|
|
34
|
+
"graphql": "16.14.2",
|
|
36
35
|
"graphql-ws": "6.0.8",
|
|
37
36
|
"js-cookie": "3.0.7",
|
|
38
37
|
"nanoid": "5.1.11",
|
|
39
|
-
"react-relay": "
|
|
40
|
-
"relay-runtime": "
|
|
41
|
-
"relay-test-utils": "
|
|
38
|
+
"react-relay": "21.0.1",
|
|
39
|
+
"relay-runtime": "21.0.1",
|
|
40
|
+
"relay-test-utils": "21.0.1"
|
|
42
41
|
},
|
|
43
42
|
"devDependencies": {
|
|
44
|
-
"@apollion-dsi/eslint-config": "0.
|
|
43
|
+
"@apollion-dsi/eslint-config": "0.8.0",
|
|
45
44
|
"@babel/core": "7.29.0",
|
|
46
45
|
"@babel/plugin-transform-class-properties": "7.27.1",
|
|
47
46
|
"@babel/plugin-transform-runtime": "7.29.0",
|
|
@@ -59,12 +58,12 @@
|
|
|
59
58
|
"@types/relay-runtime": "20.1.1",
|
|
60
59
|
"@types/relay-test-utils": "19.0.0",
|
|
61
60
|
"babel-jest": "30.4.1",
|
|
62
|
-
"babel-plugin-relay": "
|
|
61
|
+
"babel-plugin-relay": "21.0.1",
|
|
63
62
|
"esbuild": "0.28.0",
|
|
64
63
|
"eslint": "9.29.0",
|
|
65
64
|
"express": "4.22.2",
|
|
66
|
-
"
|
|
67
|
-
"graphql-relay": "0.
|
|
65
|
+
"graphql-http": "1.22.4",
|
|
66
|
+
"graphql-relay": "0.10.2",
|
|
68
67
|
"isomorphic-fetch": "3.0.0",
|
|
69
68
|
"jest": "30.4.2",
|
|
70
69
|
"jest-environment-jsdom": "30.4.1",
|
|
@@ -72,7 +71,7 @@
|
|
|
72
71
|
"prettier": "3.8.3",
|
|
73
72
|
"react": "19.2.6",
|
|
74
73
|
"react-dom": "19.2.6",
|
|
75
|
-
"relay-compiler": "
|
|
74
|
+
"relay-compiler": "21.0.1",
|
|
76
75
|
"typescript": "6.0.3"
|
|
77
76
|
}
|
|
78
77
|
}
|