@firebase/data-connect 0.5.0 → 0.6.0-20260408221811
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/dist/index.cjs.js +1165 -143
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +1164 -144
- package/dist/index.esm.js.map +1 -1
- package/dist/index.node.cjs.js +1231 -190
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/internal.d.ts +133 -12
- package/dist/node-esm/index.node.esm.js +1230 -191
- package/dist/node-esm/index.node.esm.js.map +1 -1
- package/dist/node-esm/src/api/Mutation.d.ts +2 -2
- package/dist/node-esm/src/api/query.d.ts +1 -1
- package/dist/node-esm/src/core/query/QueryManager.d.ts +22 -3
- package/dist/node-esm/src/network/index.d.ts +1 -1
- package/dist/node-esm/src/network/manager.d.ts +61 -0
- package/dist/node-esm/src/network/{fetch.d.ts → rest/fetch.d.ts} +9 -4
- package/dist/node-esm/src/network/rest/index.d.ts +18 -0
- package/dist/node-esm/src/network/rest/restTransport.d.ts +33 -0
- package/dist/node-esm/src/network/stream/streamTransport.d.ts +241 -0
- package/dist/node-esm/src/network/stream/websocket.d.ts +90 -0
- package/dist/node-esm/src/network/stream/wire.d.ts +138 -0
- package/dist/node-esm/src/network/transport.d.ts +179 -0
- package/dist/node-esm/src/util/url.d.ts +3 -1
- package/dist/private.d.ts +29 -7
- package/dist/public.d.ts +3 -1
- package/dist/src/api/Mutation.d.ts +2 -2
- package/dist/src/api/query.d.ts +1 -1
- package/dist/src/core/query/QueryManager.d.ts +22 -3
- package/dist/src/network/index.d.ts +1 -1
- package/dist/src/network/manager.d.ts +61 -0
- package/dist/src/network/{fetch.d.ts → rest/fetch.d.ts} +9 -4
- package/dist/src/network/rest/index.d.ts +18 -0
- package/dist/src/network/rest/restTransport.d.ts +33 -0
- package/dist/src/network/stream/streamTransport.d.ts +241 -0
- package/dist/src/network/stream/websocket.d.ts +90 -0
- package/dist/src/network/stream/wire.d.ts +138 -0
- package/dist/src/network/transport.d.ts +179 -0
- package/dist/src/util/url.d.ts +3 -1
- package/package.json +1 -1
- package/dist/node-esm/src/network/transport/index.d.ts +0 -81
- package/dist/node-esm/src/network/transport/rest.d.ts +0 -49
- package/dist/src/network/transport/index.d.ts +0 -81
- package/dist/src/network/transport/rest.d.ts +0 -49
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { AbstractDataConnectTransport, DataConnectResponse, SubscribeObserver } from '../transport';
|
|
18
|
+
import { DataConnectStreamRequest } from './wire';
|
|
19
|
+
/**
|
|
20
|
+
* The base class for all {@link DataConnectStreamTransport | Stream Transport} implementations.
|
|
21
|
+
* Handles management of logical streams (requests), authentication, data routing to query layer, etc.
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
export declare abstract class AbstractDataConnectStreamTransport extends AbstractDataConnectTransport {
|
|
25
|
+
/** Optional callback invoked when the stream closes gracefully. */
|
|
26
|
+
onGracefulStreamClose?: () => void;
|
|
27
|
+
/** True if the physical stream connection is fully open and ready to transmit data. */
|
|
28
|
+
abstract get streamIsReady(): boolean;
|
|
29
|
+
/** Is the stream currently waiting to close connection? */
|
|
30
|
+
get isPendingClose(): boolean;
|
|
31
|
+
private pendingClose;
|
|
32
|
+
/** True if the transport is unable to connect to the server */
|
|
33
|
+
isUnableToConnect: boolean;
|
|
34
|
+
/** True if there are active subscriptions on the stream */
|
|
35
|
+
get hasActiveSubscriptions(): boolean;
|
|
36
|
+
/** True if there are active execute or mutation requests on the stream */
|
|
37
|
+
get hasActiveExecuteRequests(): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Open a physical connection to the server.
|
|
40
|
+
* @returns a promise which resolves when the connection is ready, or rejects if it fails to open.
|
|
41
|
+
*/
|
|
42
|
+
protected abstract openConnection(): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Close the physical connection with the server. Handles no cleanup - simply closes the
|
|
45
|
+
* implementation-specific connection.
|
|
46
|
+
* @returns a promise which resolves when the connection is closed, or rejects if it fails to close.
|
|
47
|
+
* On failure to close, the connection is still considered closed.
|
|
48
|
+
*/
|
|
49
|
+
protected abstract closeConnection(): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Queue a message to be sent over the stream.
|
|
52
|
+
* @param requestBody The body of the message to be sent.
|
|
53
|
+
* @throws DataConnectError if sending fails.
|
|
54
|
+
*/
|
|
55
|
+
protected abstract sendMessage<Variables>(requestBody: DataConnectStreamRequest<Variables>): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Ensures that that there is an open connection. If there is none, it initiates a new one.
|
|
58
|
+
* If a connection attempt is already in progress, it returns the existing connection promise.
|
|
59
|
+
* @returns A promise that resolves when the stream is open and ready.
|
|
60
|
+
*/
|
|
61
|
+
protected abstract ensureConnection(): Promise<void>;
|
|
62
|
+
/** The request ID of the next message to be sent. Monotonically increasing sequence number. */
|
|
63
|
+
private requestNumber;
|
|
64
|
+
/**
|
|
65
|
+
* Generates and returns the next request ID.
|
|
66
|
+
*/
|
|
67
|
+
private nextRequestId;
|
|
68
|
+
/**
|
|
69
|
+
* Map of query/variables to their active execute/resume request bodies.
|
|
70
|
+
*/
|
|
71
|
+
private activeQueryExecuteRequests;
|
|
72
|
+
/**
|
|
73
|
+
* Map of mutation/variables to their active execute request bodies.
|
|
74
|
+
*/
|
|
75
|
+
private activeMutationExecuteRequests;
|
|
76
|
+
/**
|
|
77
|
+
* Map of query/variables to their active subscribe request bodies.
|
|
78
|
+
*/
|
|
79
|
+
private activeSubscribeRequests;
|
|
80
|
+
/**
|
|
81
|
+
* Map of active execution RequestIds and their corresponding Promises and resolvers.
|
|
82
|
+
*/
|
|
83
|
+
private executeRequestPromises;
|
|
84
|
+
/**
|
|
85
|
+
* Map of active subscription RequestIds and their corresponding observers.
|
|
86
|
+
*/
|
|
87
|
+
private subscribeObservers;
|
|
88
|
+
/** current close timeout from setTimeout(), if any */
|
|
89
|
+
private closeTimeout;
|
|
90
|
+
/** has the close timeout finished? */
|
|
91
|
+
private closeTimeoutFinished;
|
|
92
|
+
/** current auth uid. used to detect if a different user logs in */
|
|
93
|
+
private authUid;
|
|
94
|
+
/**
|
|
95
|
+
* Tracks a query execution request, storing the request body and creating and storing a promise that
|
|
96
|
+
* will be resolved when the response is received.
|
|
97
|
+
* @returns The reject function and the response promise.
|
|
98
|
+
*
|
|
99
|
+
* @remarks
|
|
100
|
+
* This method returns a promise, but is synchronous.
|
|
101
|
+
*/
|
|
102
|
+
private trackQueryExecuteRequest;
|
|
103
|
+
/**
|
|
104
|
+
* Tracks a mutation execution request, storing the request body and creating and storing a promise
|
|
105
|
+
* that will be resolved when the response is received.
|
|
106
|
+
* @returns The reject function and the response promise.
|
|
107
|
+
*
|
|
108
|
+
* @remarks
|
|
109
|
+
* This method returns a promise, but is synchronous.
|
|
110
|
+
*/
|
|
111
|
+
private trackMutationExecuteRequest;
|
|
112
|
+
/**
|
|
113
|
+
* Tracks a subscribe request, storing the request body and the notification observer.
|
|
114
|
+
* @remarks
|
|
115
|
+
* This method is synchronous.
|
|
116
|
+
*/
|
|
117
|
+
private trackSubscribeRequest;
|
|
118
|
+
/**
|
|
119
|
+
* Cleans up the query execute request tracking data structures, deleting the tracked request and
|
|
120
|
+
* it's associated promise.
|
|
121
|
+
*/
|
|
122
|
+
private cleanupQueryExecuteRequest;
|
|
123
|
+
/**
|
|
124
|
+
* Cleans up the mutation execute request tracking data structures, deleting the tracked request and
|
|
125
|
+
* it's associated promise.
|
|
126
|
+
*/
|
|
127
|
+
private cleanupMutationExecuteRequest;
|
|
128
|
+
/**
|
|
129
|
+
* Cleans up the subscribe request tracking data structures, deleting the tracked request and
|
|
130
|
+
* it's associated promise.
|
|
131
|
+
*/
|
|
132
|
+
private cleanupSubscribeRequest;
|
|
133
|
+
/**
|
|
134
|
+
* Tracks if the next message to be sent is the first message of the stream.
|
|
135
|
+
*/
|
|
136
|
+
private isFirstStreamMessage;
|
|
137
|
+
/**
|
|
138
|
+
* Tracks the last auth token sent to the server.
|
|
139
|
+
* Used to detect if the token has changed and needs to be resent.
|
|
140
|
+
*/
|
|
141
|
+
private lastSentAuthToken;
|
|
142
|
+
/**
|
|
143
|
+
* Indicates whether we should include the auth token in the next message.
|
|
144
|
+
* Only true if there is an auth token and it is different from the last sent auth token, or this
|
|
145
|
+
* is the first message.
|
|
146
|
+
*/
|
|
147
|
+
private get shouldIncludeAuth();
|
|
148
|
+
/**
|
|
149
|
+
* Called by the concrete transport implementation when the physical connection is ready.
|
|
150
|
+
*/
|
|
151
|
+
protected onConnectionReady(): void;
|
|
152
|
+
/**
|
|
153
|
+
* Attempt to close the connection. Will only close if there are no active requests preventing it
|
|
154
|
+
* from doing so.
|
|
155
|
+
*/
|
|
156
|
+
private attemptClose;
|
|
157
|
+
/**
|
|
158
|
+
* Begin closing the connection. Waits for and cleans up all active requests, and waits for
|
|
159
|
+
* {@link IDLE_CONNECTION_TIMEOUT_MS}. This is a graceful close - it will be called when there are
|
|
160
|
+
* no more active subscriptions, so there's no need to cleanup.
|
|
161
|
+
*/
|
|
162
|
+
private prepareToCloseGracefully;
|
|
163
|
+
/**
|
|
164
|
+
* Cancel closing the connection.
|
|
165
|
+
*/
|
|
166
|
+
private cancelClose;
|
|
167
|
+
/**
|
|
168
|
+
* Reject all active execute promises and notify all subscribe observers with the given error.
|
|
169
|
+
* Clear active request tracking maps without cancelling or re-invoking any requests.
|
|
170
|
+
*/
|
|
171
|
+
private rejectAllActiveRequests;
|
|
172
|
+
/**
|
|
173
|
+
* Called by concrete implementations when the stream is successfully closed, gracefully or otherwise.
|
|
174
|
+
*/
|
|
175
|
+
protected onStreamClose(code: number, reason: string): void;
|
|
176
|
+
/**
|
|
177
|
+
* Prepares a stream request message by adding necessary headers and metadata.
|
|
178
|
+
* If this is the first message on the stream, it includes the resource name, auth token, and App Check token.
|
|
179
|
+
* If the auth token has refreshed since the last message, it includes the new auth token.
|
|
180
|
+
*
|
|
181
|
+
* This method is called by the concrete transport implementation before sending a message.
|
|
182
|
+
*
|
|
183
|
+
* @returns the requestBody, with attached headers and initial request fields
|
|
184
|
+
*/
|
|
185
|
+
protected prepareMessage<Variables, StreamBody extends DataConnectStreamRequest<Variables>>(requestBody: StreamBody): StreamBody;
|
|
186
|
+
/**
|
|
187
|
+
* Sends a request message to the server via the concrete implementation.
|
|
188
|
+
* Ensures the connection is ready and prepares the message before sending.
|
|
189
|
+
* @returns A promise that resolves when the request message has been sent.
|
|
190
|
+
*/
|
|
191
|
+
private sendRequestMessage;
|
|
192
|
+
/**
|
|
193
|
+
* Helper to generate a consistent string key for the tracking maps.
|
|
194
|
+
*/
|
|
195
|
+
private getMapKey;
|
|
196
|
+
/**
|
|
197
|
+
* Recursively sorts the keys of an object.
|
|
198
|
+
*/
|
|
199
|
+
private sortObjectKeys;
|
|
200
|
+
/**
|
|
201
|
+
* @inheritdoc
|
|
202
|
+
* @remarks
|
|
203
|
+
* This method synchronously updates the request tracking data structures before sending any message.
|
|
204
|
+
* If any asynchronous functionality is added to this function, it MUST be done in a way that
|
|
205
|
+
* preserves the synchronous update of the tracking data structures before the method returns.
|
|
206
|
+
*/
|
|
207
|
+
invokeQuery<Data, Variables>(queryName: string, variables?: Variables): Promise<DataConnectResponse<Data>>;
|
|
208
|
+
/**
|
|
209
|
+
* @inheritdoc
|
|
210
|
+
* @remarks
|
|
211
|
+
* This method synchronously updates the request tracking data structures before sending any message.
|
|
212
|
+
* If any asynchronous functionality is added to this function, it MUST be done in a way that
|
|
213
|
+
* preserves the synchronous update of the tracking data structures before the method returns.
|
|
214
|
+
*/
|
|
215
|
+
invokeMutation<Data, Variables>(mutationName: string, variables?: Variables): Promise<DataConnectResponse<Data>>;
|
|
216
|
+
/**
|
|
217
|
+
* @inheritdoc
|
|
218
|
+
* @remarks
|
|
219
|
+
* This method synchronously updates the request tracking data structures before sending any message
|
|
220
|
+
* or cancelling the closing of the stream. If any asynchronous functionality is added to this function,
|
|
221
|
+
* it MUST be done in a way that preserves the synchronous update of the tracking data structures
|
|
222
|
+
* before the method returns.
|
|
223
|
+
*/
|
|
224
|
+
invokeSubscribe<Data, Variables>(observer: SubscribeObserver<Data>, queryName: string, variables: Variables): void;
|
|
225
|
+
/**
|
|
226
|
+
* @inheritdoc
|
|
227
|
+
* @remarks
|
|
228
|
+
* This method synchronously updates the request tracking data structures before sending any message.
|
|
229
|
+
* If any asynchronous functionality is added to this function, it MUST be done in a way that
|
|
230
|
+
* preserves the synchronous update of the tracking data structures before the method returns.
|
|
231
|
+
*/
|
|
232
|
+
invokeUnsubscribe<Variables>(queryName: string, variables: Variables): void;
|
|
233
|
+
onAuthTokenChanged(newToken: string | null): void;
|
|
234
|
+
/**
|
|
235
|
+
* Handle a response message from the server. Called by the connection-specific implementation after
|
|
236
|
+
* it's transformed a message from the server into a {@link DataConnectResponse}.
|
|
237
|
+
* @param requestId the requestId associated with this response.
|
|
238
|
+
* @param response the response from the server.
|
|
239
|
+
*/
|
|
240
|
+
protected handleResponse<Data>(requestId: string, response: DataConnectResponse<Data>): Promise<void>;
|
|
241
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { DataConnectOptions, TransportOptions } from '../../api/DataConnect';
|
|
18
|
+
import { AppCheckTokenProvider } from '../../core/AppCheckTokenProvider';
|
|
19
|
+
import { AuthTokenProvider } from '../../core/FirebaseAuthProvider';
|
|
20
|
+
import { CallerSdkType } from '../transport';
|
|
21
|
+
import { AbstractDataConnectStreamTransport } from './streamTransport';
|
|
22
|
+
import { DataConnectStreamRequest } from './wire';
|
|
23
|
+
/**
|
|
24
|
+
* This function is ONLY used for testing and for ensuring compatability in environments which may
|
|
25
|
+
* be using a poyfill and/or bundlers. It should not be called by users of the Firebase JS SDK.
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export declare function initializeWebSocket(webSocketImpl: typeof WebSocket): void;
|
|
29
|
+
/**
|
|
30
|
+
* The code used to close the WebSocket connection.
|
|
31
|
+
* This is a protocol-level code, and is not the same as the {@link Code | DataConnect error code}.
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
export declare const WEBSOCKET_CLOSE_CODE = 1000;
|
|
35
|
+
/**
|
|
36
|
+
* An {@link AbstractDataConnectStreamTransport | Stream Transport} implementation that uses {@link WebSocket | WebSockets} to stream requests and responses.
|
|
37
|
+
* This class handles the lifecycle of the WebSocket connection, including automatic
|
|
38
|
+
* reconnection and request correlation.
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
export declare class WebSocketTransport extends AbstractDataConnectStreamTransport {
|
|
42
|
+
protected apiKey?: string | undefined;
|
|
43
|
+
protected appId?: (string | null) | undefined;
|
|
44
|
+
protected authProvider?: AuthTokenProvider | undefined;
|
|
45
|
+
protected appCheckProvider?: AppCheckTokenProvider | undefined;
|
|
46
|
+
protected _isUsingGen: boolean;
|
|
47
|
+
protected _callerSdkType: CallerSdkType;
|
|
48
|
+
get endpointUrl(): string;
|
|
49
|
+
/** Decodes binary WebSocket responses to strings */
|
|
50
|
+
private decoder;
|
|
51
|
+
/**
|
|
52
|
+
* Decodes a WebSocket response from a Uint8Array to a JSON object.
|
|
53
|
+
* Emulator does not send messages as Uint8Arrays, but prod does.
|
|
54
|
+
*/
|
|
55
|
+
private decodeBinaryResponse;
|
|
56
|
+
/** The current connection to the server. Undefined if disconnected. */
|
|
57
|
+
private connection;
|
|
58
|
+
get streamIsReady(): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Current connection attempt. If null, we are not currently attemping to connect (not connected,
|
|
61
|
+
* or already connected). Will be resolved or rejected when the connection is opened or fails to open.
|
|
62
|
+
*/
|
|
63
|
+
private connectionAttempt;
|
|
64
|
+
constructor(options: DataConnectOptions, apiKey?: string | undefined, appId?: (string | null) | undefined, authProvider?: AuthTokenProvider | undefined, appCheckProvider?: AppCheckTokenProvider | undefined, transportOptions?: TransportOptions | undefined, _isUsingGen?: boolean, _callerSdkType?: CallerSdkType);
|
|
65
|
+
protected ensureConnection(): Promise<void>;
|
|
66
|
+
protected openConnection(): Promise<void>;
|
|
67
|
+
protected closeConnection(code?: number, reason?: string): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Handle a disconnection from the server. Initiates graceful clean up and reconnection attempts.
|
|
70
|
+
* @param ev the {@link CloseEvent} that closed the WebSocket.
|
|
71
|
+
*/
|
|
72
|
+
private handleWebsocketDisconnect;
|
|
73
|
+
/**
|
|
74
|
+
* Handle an error that occurred on the WebSocket. Close the connection and reject all active requests.
|
|
75
|
+
*/
|
|
76
|
+
private handleError;
|
|
77
|
+
protected sendMessage<Variables>(requestBody: DataConnectStreamRequest<Variables>): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Handles incoming WebSocket messages.
|
|
80
|
+
* @param ev The {@link MessageEvent} from the WebSocket.
|
|
81
|
+
*/
|
|
82
|
+
private handleWebSocketMessage;
|
|
83
|
+
/**
|
|
84
|
+
* Parse a response from the server. Assert that it has a {@link DataConnectStreamResponse.requestId | requestId}.
|
|
85
|
+
* @param data the message from the server to be parsed
|
|
86
|
+
* @returns the parsed message as a {@link DataConnectStreamResponse}
|
|
87
|
+
* @throws {DataConnectError} if parsing fails or message is malformed.
|
|
88
|
+
*/
|
|
89
|
+
private parseWebSocketData;
|
|
90
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { Extensions } from '../index';
|
|
18
|
+
/**
|
|
19
|
+
* Shape of response from the server.
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
export interface DataConnectStreamResponse<Data> {
|
|
23
|
+
requestId: string;
|
|
24
|
+
data: Data;
|
|
25
|
+
extensions: Extensions;
|
|
26
|
+
dataEtag: string;
|
|
27
|
+
errors: Error[];
|
|
28
|
+
cancelled: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Base interface for stream request payloads sent over the stream to the server.
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
export interface StreamRequest {
|
|
35
|
+
/** monotonically increasing request ID */
|
|
36
|
+
requestId: string;
|
|
37
|
+
/** connectorResourcePath - only required on initial connection */
|
|
38
|
+
name?: string;
|
|
39
|
+
/** optional headers for this request, for authentication + telemetry */
|
|
40
|
+
headers?: StreamRequestHeaders;
|
|
41
|
+
/** received from server on previous response, included to optimize bandwidth */
|
|
42
|
+
dataEtag?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Optional headers for a stream request, for authentication + telemetry
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
export interface StreamRequestHeaders {
|
|
49
|
+
/** used to initially authenticate or re-authenticate */
|
|
50
|
+
authToken?: string;
|
|
51
|
+
/** used to initially authenticate or re-authenticate */
|
|
52
|
+
appCheckToken?: string;
|
|
53
|
+
/** SDK telemetry header */
|
|
54
|
+
'X-Goog-Api-Client'?: string;
|
|
55
|
+
/** firebase appid */
|
|
56
|
+
'x-firebase-gmpid'?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Fields for an execute request payload.
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
interface ExecuteRequestKind<Variables> {
|
|
63
|
+
operationName: string;
|
|
64
|
+
variables?: Variables;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Fields for a subscribe request payload.
|
|
68
|
+
* @internal
|
|
69
|
+
*/
|
|
70
|
+
interface SubscribeRequestKind<Variables> {
|
|
71
|
+
operationName: string;
|
|
72
|
+
variables?: Variables;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Fields for a resume request payload.
|
|
76
|
+
* @internal
|
|
77
|
+
*/
|
|
78
|
+
interface ResumeRequestKind {
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Fields for a cancel request payload.
|
|
82
|
+
* @internal
|
|
83
|
+
*/
|
|
84
|
+
interface CancelRequestKind {
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Fields for a subscribe request payload.
|
|
88
|
+
* @internal
|
|
89
|
+
*/
|
|
90
|
+
export interface SubscribeStreamRequest<Variables> extends StreamRequest {
|
|
91
|
+
subscribe: SubscribeRequestKind<Variables>;
|
|
92
|
+
execute?: never;
|
|
93
|
+
resume?: never;
|
|
94
|
+
cancel?: never;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Fields for an execute request payload.
|
|
98
|
+
* @internal
|
|
99
|
+
*/
|
|
100
|
+
export interface ExecuteStreamRequest<Variables> extends StreamRequest {
|
|
101
|
+
execute: ExecuteRequestKind<Variables>;
|
|
102
|
+
subscribe?: never;
|
|
103
|
+
resume?: never;
|
|
104
|
+
cancel?: never;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Fields for a resume (subscribe) request payload.
|
|
108
|
+
* @internal
|
|
109
|
+
*/
|
|
110
|
+
export interface ResumeStreamRequest extends StreamRequest {
|
|
111
|
+
resume: ResumeRequestKind;
|
|
112
|
+
subscribe?: never;
|
|
113
|
+
execute?: never;
|
|
114
|
+
cancel?: never;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Fields for a cancel (unsubscribe) request payload.
|
|
118
|
+
* @internal
|
|
119
|
+
*/
|
|
120
|
+
export interface CancelStreamRequest extends StreamRequest {
|
|
121
|
+
cancel: CancelRequestKind;
|
|
122
|
+
subscribe?: never;
|
|
123
|
+
execute?: never;
|
|
124
|
+
resume?: never;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Shape of the request body to be sent over the stream to the server.
|
|
128
|
+
* @internal
|
|
129
|
+
*/
|
|
130
|
+
export type DataConnectStreamRequest<Variables> = ExecuteStreamRequest<Variables> | SubscribeStreamRequest<Variables> | ResumeStreamRequest | CancelStreamRequest;
|
|
131
|
+
/**
|
|
132
|
+
* Determines whether the provided request to execute a query is an execution request or a resume
|
|
133
|
+
* request
|
|
134
|
+
* @returns true if the requestBody is a resume request
|
|
135
|
+
* @internal
|
|
136
|
+
*/
|
|
137
|
+
export declare function queryRequestIsResume<Variables>(requestBody: ExecuteStreamRequest<Variables> | ResumeStreamRequest): requestBody is ResumeStreamRequest;
|
|
138
|
+
export {};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2024 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { DataConnectOptions, TransportOptions } from '../api/DataConnect';
|
|
18
|
+
import { AppCheckTokenProvider } from '../core/AppCheckTokenProvider';
|
|
19
|
+
import { AuthTokenProvider } from '../core/FirebaseAuthProvider';
|
|
20
|
+
/**
|
|
21
|
+
* enum representing different flavors of the SDK used by developers
|
|
22
|
+
* use the CallerSdkType for type-checking, and the CallerSdkTypeEnum for value-checking/assigning
|
|
23
|
+
*/
|
|
24
|
+
export type CallerSdkType = 'Base' | 'Generated' | 'TanstackReactCore' | 'GeneratedReact' | 'TanstackAngularCore' | 'GeneratedAngular';
|
|
25
|
+
export declare const CallerSdkTypeEnum: {
|
|
26
|
+
readonly Base: "Base";
|
|
27
|
+
readonly Generated: "Generated";
|
|
28
|
+
readonly TanstackReactCore: "TanstackReactCore";
|
|
29
|
+
readonly GeneratedReact: "GeneratedReact";
|
|
30
|
+
readonly TanstackAngularCore: "TanstackAngularCore";
|
|
31
|
+
readonly GeneratedAngular: "GeneratedAngular";
|
|
32
|
+
};
|
|
33
|
+
export interface DataConnectEntityArray {
|
|
34
|
+
entityIds: string[];
|
|
35
|
+
}
|
|
36
|
+
export interface DataConnectSingleEntity {
|
|
37
|
+
entityId: string;
|
|
38
|
+
}
|
|
39
|
+
export type DataConnectExtension = {
|
|
40
|
+
path: Array<string | number>;
|
|
41
|
+
} & (DataConnectEntityArray | DataConnectSingleEntity);
|
|
42
|
+
/** @internal */
|
|
43
|
+
export interface DataConnectMaxAge {
|
|
44
|
+
maxAge: string;
|
|
45
|
+
}
|
|
46
|
+
/** @internal */
|
|
47
|
+
export type DataConnectExtensionWithMaxAge = {
|
|
48
|
+
path: Array<string | number>;
|
|
49
|
+
} & (DataConnectEntityArray | DataConnectSingleEntity | DataConnectMaxAge);
|
|
50
|
+
export interface Extensions {
|
|
51
|
+
dataConnect?: DataConnectExtension[];
|
|
52
|
+
}
|
|
53
|
+
/** @internal */
|
|
54
|
+
export interface ExtensionsWithMaxAge {
|
|
55
|
+
dataConnect?: DataConnectExtensionWithMaxAge[];
|
|
56
|
+
}
|
|
57
|
+
/** @internal */
|
|
58
|
+
export interface DataConnectResponse<T> {
|
|
59
|
+
data: T;
|
|
60
|
+
errors: Error[];
|
|
61
|
+
extensions: Extensions;
|
|
62
|
+
}
|
|
63
|
+
/** @internal */
|
|
64
|
+
export interface DataConnectResponseWithMaxAge<T> {
|
|
65
|
+
data: T;
|
|
66
|
+
errors: Error[];
|
|
67
|
+
extensions: ExtensionsWithMaxAge;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Observer defined by the Query Layer for receiving notifications from the Transport Layer.
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
73
|
+
export interface SubscribeObserver<Data> {
|
|
74
|
+
onData(response: DataConnectResponse<Data>): Promise<void> | void;
|
|
75
|
+
onDisconnect(code: string, reason: string): void;
|
|
76
|
+
onError(error: Error): void;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Interface defining the external API of the transport layer.
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
82
|
+
export interface DataConnectTransportInterface {
|
|
83
|
+
/**
|
|
84
|
+
* Invoke a query execution request.
|
|
85
|
+
* @param queryName The name of the query to execute.
|
|
86
|
+
* @param body The variables associated with the query.
|
|
87
|
+
* @returns A promise resolving to the DataConnectResponse.
|
|
88
|
+
*/
|
|
89
|
+
invokeQuery<Data, Variables>(queryName: string, body?: Variables): Promise<DataConnectResponseWithMaxAge<Data>>;
|
|
90
|
+
/**
|
|
91
|
+
* Invoke a mutation execution request.
|
|
92
|
+
* @param queryName The name of the mutation to execute.
|
|
93
|
+
* @param body The variables associated with the mutation.
|
|
94
|
+
* @returns A promise resolving to the DataConnectResponse.
|
|
95
|
+
*/
|
|
96
|
+
invokeMutation<Data, Variables>(queryName: string, body?: Variables): Promise<DataConnectResponse<Data>>;
|
|
97
|
+
/**
|
|
98
|
+
* Subscribes to a query to receive push notifications of updates.
|
|
99
|
+
* @param observer the observer passed to the transport layer to notify the query layer of events.
|
|
100
|
+
* @param queryName The name of the query to subscribe to.
|
|
101
|
+
* @param body The variables associated with the subscription.
|
|
102
|
+
*/
|
|
103
|
+
invokeSubscribe<Data, Variables>(observer: SubscribeObserver<Data>, queryName: string, body?: Variables): void;
|
|
104
|
+
/**
|
|
105
|
+
* Unsubscribes from an active subscription.
|
|
106
|
+
* @param queryName The name of the query to unsubscribe from.
|
|
107
|
+
* @param body The variables associated with the subscription.
|
|
108
|
+
*/
|
|
109
|
+
invokeUnsubscribe<Variables>(queryName: string, body?: Variables): void;
|
|
110
|
+
/**
|
|
111
|
+
* Configures the transport to use a local Data Connect emulator.
|
|
112
|
+
* @param host The host address of the emulator (e.g., '127.0.0.1').
|
|
113
|
+
* @param port The port number the emulator is listening on.
|
|
114
|
+
* @param sslEnabled Whether to use SSL (HTTPS/WSS) for the emulator connection.
|
|
115
|
+
*/
|
|
116
|
+
useEmulator(host: string, port?: number, sslEnabled?: boolean): void;
|
|
117
|
+
/**
|
|
118
|
+
* Callback invoked when the Firebase Auth token is refreshed or changed. Note that this callback
|
|
119
|
+
* is called immediately asynchronously when the Auth Provider is initialized to provide
|
|
120
|
+
* the initial auth state.
|
|
121
|
+
* @param token The new access token or null if signed out.
|
|
122
|
+
*/
|
|
123
|
+
onAuthTokenChanged: (token: string | null) => void;
|
|
124
|
+
/**
|
|
125
|
+
* Internal method to set the SDK type for metrics and logging purposes.
|
|
126
|
+
* @param callerSdkType The type of SDK making the call (e.g., generated vs base).
|
|
127
|
+
*/
|
|
128
|
+
_setCallerSdkType(callerSdkType: CallerSdkType): void;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Type signature of a transport class constructor.
|
|
132
|
+
* @internal
|
|
133
|
+
*/
|
|
134
|
+
export type TransportClass = new (options: DataConnectOptions, apiKey?: string, appId?: string, authProvider?: AuthTokenProvider, appCheckProvider?: AppCheckTokenProvider, transportOptions?: TransportOptions, _isUsingGen?: boolean, _callerSdkType?: CallerSdkType) => DataConnectTransportInterface;
|
|
135
|
+
/**
|
|
136
|
+
* Constructs the value for the X-Goog-Api-Client header
|
|
137
|
+
* @internal
|
|
138
|
+
*/
|
|
139
|
+
export declare function getGoogApiClientValue(isUsingGen: boolean, callerSdkType: CallerSdkType): string;
|
|
140
|
+
/**
|
|
141
|
+
* The base class for all DataConnectTransportInterface implementations. Handles common logic such as
|
|
142
|
+
* URL construction, auth token management, and emulator usage. Concrete transport implementations
|
|
143
|
+
* should extend this class and implement the abstract {@link DataConnectTransportInterface} methods.
|
|
144
|
+
* @internal
|
|
145
|
+
*/
|
|
146
|
+
export declare abstract class AbstractDataConnectTransport implements DataConnectTransportInterface {
|
|
147
|
+
protected apiKey?: string | undefined;
|
|
148
|
+
protected appId?: (string | null) | undefined;
|
|
149
|
+
protected authProvider?: AuthTokenProvider | undefined;
|
|
150
|
+
protected appCheckProvider?: AppCheckTokenProvider | undefined;
|
|
151
|
+
protected _isUsingGen: boolean;
|
|
152
|
+
protected _callerSdkType: CallerSdkType;
|
|
153
|
+
protected _host: string;
|
|
154
|
+
protected _port: number | undefined;
|
|
155
|
+
protected _location: string;
|
|
156
|
+
protected _connectorName: string;
|
|
157
|
+
/** The resource path for requests from this Data Connect instance. */
|
|
158
|
+
protected _connectorResourcePath: string;
|
|
159
|
+
protected _secure: boolean;
|
|
160
|
+
protected _project: string;
|
|
161
|
+
protected _serviceName: string;
|
|
162
|
+
protected _authToken: string | null;
|
|
163
|
+
protected _appCheckToken: string | null | undefined;
|
|
164
|
+
protected _lastToken: string | null;
|
|
165
|
+
protected _isUsingEmulator: boolean;
|
|
166
|
+
constructor(options: DataConnectOptions, apiKey?: string | undefined, appId?: (string | null) | undefined, authProvider?: AuthTokenProvider | undefined, appCheckProvider?: AppCheckTokenProvider | undefined, transportOptions?: TransportOptions | undefined, _isUsingGen?: boolean, _callerSdkType?: CallerSdkType);
|
|
167
|
+
/** Get the endpoint URL this transport should use to communicate with the backend. */
|
|
168
|
+
abstract get endpointUrl(): string;
|
|
169
|
+
useEmulator(host: string, port?: number, isSecure?: boolean): void;
|
|
170
|
+
getWithAuth(forceToken?: boolean): Promise<string | null>;
|
|
171
|
+
withRetry<T>(promiseFactory: () => Promise<DataConnectResponse<T>>, retry?: boolean): Promise<DataConnectResponse<T>>;
|
|
172
|
+
_setLastToken(lastToken: string | null): void;
|
|
173
|
+
abstract invokeQuery<Data, Variables>(queryName: string, body?: Variables): Promise<DataConnectResponseWithMaxAge<Data>>;
|
|
174
|
+
abstract invokeMutation<Data, Variables>(queryName: string, body?: Variables): Promise<DataConnectResponse<Data>>;
|
|
175
|
+
abstract invokeSubscribe<Data, Variables>(observer: SubscribeObserver<Data>, queryName: string, body?: Variables): void;
|
|
176
|
+
abstract invokeUnsubscribe<Variables>(queryName: string, variables: Variables): void;
|
|
177
|
+
abstract onAuthTokenChanged(newToken: string | null): void;
|
|
178
|
+
_setCallerSdkType(callerSdkType: CallerSdkType): void;
|
|
179
|
+
}
|
package/dist/src/util/url.d.ts
CHANGED
|
@@ -16,5 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { DataConnectOptions, TransportOptions } from '../api/DataConnect';
|
|
18
18
|
export declare const PROD_HOST = "firebasedataconnect.googleapis.com";
|
|
19
|
-
export declare
|
|
19
|
+
export declare const WEBSOCKET_PATH = "ws/google.firebase.dataconnect.v1.ConnectorStreamService";
|
|
20
|
+
export declare function restUrlBuilder(projectConfig: DataConnectOptions, transportOptions: TransportOptions): string;
|
|
21
|
+
export declare function websocketUrlBuilder(projectConfig: DataConnectOptions, transportOptions: TransportOptions): string;
|
|
20
22
|
export declare function addToken(url: string, apiKey?: string): string;
|