convex 1.24.5 → 1.24.7-alpha.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/CHANGELOG.md +6 -4
- package/dist/browser.bundle.js +14 -7
- package/dist/browser.bundle.js.map +2 -2
- package/dist/cjs/browser/sync/web_socket_manager.js +13 -6
- package/dist/cjs/browser/sync/web_socket_manager.js.map +2 -2
- package/dist/cjs/cli/lib/deployApi/types.js +3 -3
- package/dist/cjs/cli/lib/deployApi/types.js.map +2 -2
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs-types/browser/sync/web_socket_manager.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts +33 -33
- package/dist/cjs-types/cli/lib/deployApi/types.d.ts +19 -19
- package/dist/cjs-types/cli/lib/deployApi/types.d.ts.map +1 -1
- package/dist/cjs-types/index.d.ts +1 -1
- package/dist/cjs-types/index.d.ts.map +1 -1
- package/dist/cli.bundle.cjs +18 -10
- package/dist/cli.bundle.cjs.map +3 -3
- package/dist/esm/browser/sync/web_socket_manager.js +13 -6
- package/dist/esm/browser/sync/web_socket_manager.js.map +2 -2
- package/dist/esm/cli/lib/deployApi/types.js +3 -3
- package/dist/esm/cli/lib/deployApi/types.js.map +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm-types/browser/sync/web_socket_manager.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deployApi/startPush.d.ts +33 -33
- package/dist/esm-types/cli/lib/deployApi/types.d.ts +19 -19
- package/dist/esm-types/cli/lib/deployApi/types.d.ts.map +1 -1
- package/dist/esm-types/index.d.ts +1 -1
- package/dist/esm-types/index.d.ts.map +1 -1
- package/dist/react.bundle.js +14 -7
- package/dist/react.bundle.js.map +2 -2
- package/package.json +1 -1
- package/src/browser/sync/web_socket_manager.ts +30 -6
- package/src/cli/lib/deployApi/types.ts +15 -10
- package/src/index.ts +1 -1
|
@@ -121,7 +121,13 @@ export class WebSocketManager {
|
|
|
121
121
|
}
|
|
122
122
|
this.logger.log(msg);
|
|
123
123
|
}
|
|
124
|
-
|
|
124
|
+
if (event.reason?.includes("SubscriptionsWorkerFullError")) {
|
|
125
|
+
this.scheduleReconnect("SubscriptionsWorkerFullError");
|
|
126
|
+
} else if (event.reason?.includes("TooManyConcurrentRequests")) {
|
|
127
|
+
this.scheduleReconnect("TooManyConcurrentRequests");
|
|
128
|
+
} else {
|
|
129
|
+
this.scheduleReconnect("unknown");
|
|
130
|
+
}
|
|
125
131
|
return;
|
|
126
132
|
};
|
|
127
133
|
}
|
|
@@ -179,9 +185,9 @@ export class WebSocketManager {
|
|
|
179
185
|
this.closeAndReconnect("InactiveServer");
|
|
180
186
|
}, this.serverInactivityThreshold);
|
|
181
187
|
}
|
|
182
|
-
scheduleReconnect() {
|
|
188
|
+
scheduleReconnect(reason) {
|
|
183
189
|
this.socket = { state: "disconnected" };
|
|
184
|
-
const backoff = this.nextBackoff();
|
|
190
|
+
const backoff = this.nextBackoff(reason);
|
|
185
191
|
this.logger.log(`Attempting reconnect in ${backoff}ms`);
|
|
186
192
|
setTimeout(() => this.connect(), backoff);
|
|
187
193
|
}
|
|
@@ -201,7 +207,7 @@ export class WebSocketManager {
|
|
|
201
207
|
case "ready": {
|
|
202
208
|
this.lastCloseReason = closeReason;
|
|
203
209
|
void this.close();
|
|
204
|
-
this.scheduleReconnect();
|
|
210
|
+
this.scheduleReconnect("client");
|
|
205
211
|
return;
|
|
206
212
|
}
|
|
207
213
|
default: {
|
|
@@ -374,8 +380,9 @@ export class WebSocketManager {
|
|
|
374
380
|
_logVerbose(message) {
|
|
375
381
|
this.logger.logVerbose(message);
|
|
376
382
|
}
|
|
377
|
-
nextBackoff() {
|
|
378
|
-
const
|
|
383
|
+
nextBackoff(reason) {
|
|
384
|
+
const initialBackoff = reason === "SubscriptionsWorkerFullError" ? 3e3 : reason === "TooManyConcurrentRequests" ? 3e3 : this.initialBackoff;
|
|
385
|
+
const baseBackoff = initialBackoff * Math.pow(2, this.retries);
|
|
379
386
|
this.retries += 1;
|
|
380
387
|
const actualBackoff = Math.min(baseBackoff, this.maxBackoff);
|
|
381
388
|
const jitter = actualBackoff * (Math.random() - 0.5);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/browser/sync/web_socket_manager.ts"],
|
|
4
|
-
"sourcesContent": ["import { Logger } from \"../logging.js\";\nimport {\n ClientMessage,\n encodeClientMessage,\n parseServerMessage,\n ServerMessage,\n} from \"./protocol.js\";\n\nconst CLOSE_NORMAL = 1000;\nconst CLOSE_GOING_AWAY = 1001;\nconst CLOSE_NO_STATUS = 1005;\n/** Convex-specific close code representing a \"404 Not Found\".\n * The edge Onramp accepts websocket upgrades before confirming that the\n * intended destination exists, so this code is sent once we've discovered that\n * the destination does not exist.\n */\nconst CLOSE_NOT_FOUND = 4040;\n\n/**\n * The various states our WebSocket can be in:\n *\n * - \"disconnected\": We don't have a WebSocket, but plan to create one.\n * - \"connecting\": We have created the WebSocket and are waiting for the\n * `onOpen` callback.\n * - \"ready\": We have an open WebSocket.\n * - \"stopped\": The WebSocket was closed and a new one can be created via `.restart()`.\n * - \"terminated\": We have closed the WebSocket and will never create a new one.\n *\n *\n * WebSocket State Machine\n * -----------------------\n * initialState: disconnected\n * validTransitions:\n * disconnected:\n * new WebSocket() -> connecting\n * terminate() -> terminated\n * connecting:\n * onopen -> ready\n * close() -> disconnected\n * terminate() -> terminated\n * ready:\n * close() -> disconnected\n * stop() -> stopped\n * terminate() -> terminated\n * stopped:\n * restart() -> connecting\n * terminate() -> terminated\n * terminalStates:\n * terminated\n *\n *\n *\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u250C\u2500\u2500\u2500\u2500terminate()\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2502 disconnected \u2502\u25C0\u2500\u2510\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n * \u25BC \u2502 \u25B2 \u2502\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 new WebSocket() \u2502 \u2502\n * \u250C\u2500\u25B6\u2502 terminated \u2502\u25C0\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 \u2502 \u2502\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502 \u2502 \u2502 \u2502\n * \u2502 \u25B2 terminate() \u2502 close() close()\n * \u2502 terminate() \u2502 \u2502 \u2502 \u2502\n * \u2502 \u2502 \u2502 \u25BC \u2502 \u2502\n * \u2502 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n * \u2502 \u2502 stopped \u2502\u2500\u2500restart()\u2500\u2500\u2500\u25B6\u2502 connecting \u2502 \u2502\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n * \u2502 \u25B2 \u2502 \u2502\n * \u2502 \u2502 onopen \u2502\n * \u2502 \u2502 \u2502 \u2502\n * \u2502 \u2502 \u25BC \u2502\n * terminate() \u2502 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500stop()\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2502 ready \u2502\u2500\u2500\u2518\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n * \u2502 \u2502\n * \u2502 \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n *\n * The `connecting` and `ready` state have a sub-state-machine for pausing.\n */\n\ntype Socket =\n | { state: \"disconnected\" }\n | { state: \"connecting\"; ws: WebSocket; paused: \"yes\" | \"no\" }\n | { state: \"ready\"; ws: WebSocket; paused: \"yes\" | \"no\" | \"uninitialized\" }\n | { state: \"stopped\" }\n | { state: \"terminated\" };\n\nexport type ReconnectMetadata = {\n connectionCount: number;\n lastCloseReason: string | null;\n};\n\nexport type OnMessageResponse = {\n hasSyncedPastLastReconnect: boolean;\n};\n\n/**\n * A wrapper around a websocket that handles errors, reconnection, and message\n * parsing.\n */\nexport class WebSocketManager {\n private socket: Socket;\n\n private connectionCount: number;\n private _hasEverConnected: boolean = false;\n private lastCloseReason: string | null;\n\n /** Upon HTTPS/WSS failure, the first jittered backoff duration, in ms. */\n private readonly initialBackoff: number;\n\n /** We backoff exponentially, but we need to cap that--this is the jittered max. */\n private readonly maxBackoff: number;\n\n /** How many times have we failed consecutively? */\n private retries: number;\n\n /** How long before lack of server response causes us to initiate a reconnect,\n * in ms */\n private readonly serverInactivityThreshold: number;\n\n private reconnectDueToServerInactivityTimeout: ReturnType<\n typeof setTimeout\n > | null;\n\n private readonly uri: string;\n private readonly onOpen: (reconnectMetadata: ReconnectMetadata) => void;\n private readonly onResume: () => void;\n private readonly onMessage: (message: ServerMessage) => OnMessageResponse;\n private readonly webSocketConstructor: typeof WebSocket;\n private readonly logger: Logger;\n\n constructor(\n uri: string,\n callbacks: {\n onOpen: (reconnectMetadata: ReconnectMetadata) => void;\n onResume: () => void;\n onMessage: (message: ServerMessage) => OnMessageResponse;\n },\n webSocketConstructor: typeof WebSocket,\n logger: Logger,\n ) {\n this.webSocketConstructor = webSocketConstructor;\n this.socket = { state: \"disconnected\" };\n this.connectionCount = 0;\n this.lastCloseReason = \"InitialConnect\";\n\n this.initialBackoff = 100;\n this.maxBackoff = 16000;\n this.retries = 0;\n\n this.serverInactivityThreshold = 30000;\n this.reconnectDueToServerInactivityTimeout = null;\n\n this.uri = uri;\n this.onOpen = callbacks.onOpen;\n this.onResume = callbacks.onResume;\n this.onMessage = callbacks.onMessage;\n this.logger = logger;\n\n this.connect();\n }\n\n private setSocketState(state: Socket) {\n this.socket = state;\n this._logVerbose(\n `socket state changed: ${this.socket.state}, paused: ${\n \"paused\" in this.socket ? this.socket.paused : undefined\n }`,\n );\n }\n\n private connect() {\n if (this.socket.state === \"terminated\") {\n return;\n }\n if (\n this.socket.state !== \"disconnected\" &&\n this.socket.state !== \"stopped\"\n ) {\n throw new Error(\n \"Didn't start connection from disconnected state: \" + this.socket.state,\n );\n }\n\n const ws = new this.webSocketConstructor(this.uri);\n this._logVerbose(\"constructed WebSocket\");\n this.setSocketState({\n state: \"connecting\",\n ws,\n paused: \"no\",\n });\n\n // Kick off server inactivity timer before WebSocket connection is established\n // so we can detect cases where handshake fails.\n // The `onopen` event only fires after the connection is established:\n // Source: https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\n this.resetServerInactivityTimeout();\n\n ws.onopen = () => {\n this.logger.logVerbose(\"begin ws.onopen\");\n if (this.socket.state !== \"connecting\") {\n throw new Error(\"onopen called with socket not in connecting state\");\n }\n this.setSocketState({\n state: \"ready\",\n ws,\n paused: this.socket.paused === \"yes\" ? \"uninitialized\" : \"no\",\n });\n this.resetServerInactivityTimeout();\n if (this.socket.paused === \"no\") {\n this._hasEverConnected = true;\n this.onOpen({\n connectionCount: this.connectionCount,\n lastCloseReason: this.lastCloseReason,\n });\n }\n\n if (this.lastCloseReason !== \"InitialConnect\") {\n this.logger.log(\"WebSocket reconnected\");\n }\n\n this.connectionCount += 1;\n this.lastCloseReason = null;\n };\n // NB: The WebSocket API calls `onclose` even if connection fails, so we can route all error paths through `onclose`.\n ws.onerror = (error) => {\n const message = (error as ErrorEvent).message;\n this.logger.log(`WebSocket error: ${message}`);\n };\n ws.onmessage = (message) => {\n this.resetServerInactivityTimeout();\n const serverMessage = parseServerMessage(JSON.parse(message.data));\n this._logVerbose(`received ws message with type ${serverMessage.type}`);\n const response = this.onMessage(serverMessage);\n if (response.hasSyncedPastLastReconnect) {\n // Reset backoff to 0 once all outstanding requests are complete.\n this.retries = 0;\n }\n };\n ws.onclose = (event) => {\n this._logVerbose(\"begin ws.onclose\");\n if (this.lastCloseReason === null) {\n this.lastCloseReason = event.reason ?? \"OnCloseInvoked\";\n }\n if (\n event.code !== CLOSE_NORMAL &&\n event.code !== CLOSE_GOING_AWAY && // This commonly gets fired on mobile apps when the app is backgrounded\n event.code !== CLOSE_NO_STATUS &&\n event.code !== CLOSE_NOT_FOUND // Note that we want to retry on a 404, as it can be transient during a push.\n ) {\n let msg = `WebSocket closed with code ${event.code}`;\n if (event.reason) {\n msg += `: ${event.reason}`;\n }\n this.logger.log(msg);\n }\n this.scheduleReconnect();\n return;\n };\n }\n\n /**\n * @returns The state of the {@link Socket}.\n */\n socketState(): string {\n return this.socket.state;\n }\n\n /**\n * @param message - A ClientMessage to send.\n * @returns Whether the message (might have been) sent.\n */\n sendMessage(message: ClientMessage) {\n const messageForLog = {\n type: message.type,\n ...(message.type === \"Authenticate\" && message.tokenType === \"User\"\n ? {\n value: `...${message.value.slice(-7)}`,\n }\n : {}),\n };\n if (this.socket.state === \"ready\" && this.socket.paused === \"no\") {\n const encodedMessage = encodeClientMessage(message);\n const request = JSON.stringify(encodedMessage);\n try {\n this.socket.ws.send(request);\n } catch (error: any) {\n this.logger.log(\n `Failed to send message on WebSocket, reconnecting: ${error}`,\n );\n this.closeAndReconnect(\"FailedToSendMessage\");\n }\n // We are not sure if this was sent or not.\n this._logVerbose(\n `sent message with type ${message.type}: ${JSON.stringify(\n messageForLog,\n )}`,\n );\n return true;\n }\n this._logVerbose(\n `message not sent (socket state: ${this.socket.state}, paused: ${\"paused\" in this.socket ? this.socket.paused : undefined}): ${JSON.stringify(\n messageForLog,\n )}`,\n );\n\n return false;\n }\n\n private resetServerInactivityTimeout() {\n if (this.socket.state === \"terminated\") {\n // Don't reset any timers if we were trying to terminate.\n return;\n }\n if (this.reconnectDueToServerInactivityTimeout !== null) {\n clearTimeout(this.reconnectDueToServerInactivityTimeout);\n this.reconnectDueToServerInactivityTimeout = null;\n }\n this.reconnectDueToServerInactivityTimeout = setTimeout(() => {\n this.closeAndReconnect(\"InactiveServer\");\n }, this.serverInactivityThreshold);\n }\n\n private scheduleReconnect() {\n this.socket = { state: \"disconnected\" };\n const backoff = this.nextBackoff();\n this.logger.log(`Attempting reconnect in ${backoff}ms`);\n setTimeout(() => this.connect(), backoff);\n }\n\n /**\n * Close the WebSocket and schedule a reconnect.\n *\n * This should be used when we hit an error and would like to restart the session.\n */\n private closeAndReconnect(closeReason: string) {\n this._logVerbose(`begin closeAndReconnect with reason ${closeReason}`);\n switch (this.socket.state) {\n case \"disconnected\":\n case \"terminated\":\n case \"stopped\":\n // Nothing to do if we don't have a WebSocket.\n return;\n case \"connecting\":\n case \"ready\": {\n this.lastCloseReason = closeReason;\n // Close the old socket asynchronously, we'll open a new socket in reconnect.\n void this.close();\n this.scheduleReconnect();\n return;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n const _: never = this.socket;\n }\n }\n }\n\n /**\n * Close the WebSocket, being careful to clear the onclose handler to avoid re-entrant\n * calls. Use this instead of directly calling `ws.close()`\n *\n * It is the callers responsibility to update the state after this method is called so that the\n * closed socket is not accessible or used again after this method is called\n */\n private close(): Promise<void> {\n switch (this.socket.state) {\n case \"disconnected\":\n case \"terminated\":\n case \"stopped\":\n // Nothing to do if we don't have a WebSocket.\n return Promise.resolve();\n case \"connecting\": {\n const ws = this.socket.ws;\n return new Promise((r) => {\n ws.onclose = () => {\n this._logVerbose(\"Closed after connecting\");\n r();\n };\n ws.onopen = () => {\n this._logVerbose(\"Opened after connecting\");\n ws.close();\n };\n });\n }\n case \"ready\": {\n this._logVerbose(\"ws.close called\");\n const ws = this.socket.ws;\n const result: Promise<void> = new Promise((r) => {\n ws.onclose = () => {\n r();\n };\n });\n ws.close();\n return result;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n const _: never = this.socket;\n return Promise.resolve();\n }\n }\n }\n\n /**\n * Close the WebSocket and do not reconnect.\n * @returns A Promise that resolves when the WebSocket `onClose` callback is called.\n */\n terminate(): Promise<void> {\n if (this.reconnectDueToServerInactivityTimeout) {\n clearTimeout(this.reconnectDueToServerInactivityTimeout);\n }\n switch (this.socket.state) {\n case \"terminated\":\n case \"stopped\":\n case \"disconnected\":\n case \"connecting\":\n case \"ready\": {\n const result = this.close();\n this.setSocketState({ state: \"terminated\" });\n return result;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n const _: never = this.socket;\n throw new Error(\n `Invalid websocket state: ${(this.socket as any).state}`,\n );\n }\n }\n }\n\n stop(): Promise<void> {\n switch (this.socket.state) {\n case \"terminated\":\n // If we're terminating we ignore stop\n return Promise.resolve();\n case \"connecting\":\n case \"stopped\":\n case \"disconnected\":\n case \"ready\": {\n const result = this.close();\n this.socket = { state: \"stopped\" };\n return result;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n const _: never = this.socket;\n return Promise.resolve();\n }\n }\n }\n\n /**\n * Create a new WebSocket after a previous `stop()`, unless `terminate()` was\n * called before.\n */\n tryRestart(): void {\n switch (this.socket.state) {\n case \"stopped\":\n break;\n case \"terminated\":\n case \"connecting\":\n case \"ready\":\n case \"disconnected\":\n this.logger.logVerbose(\"Restart called without stopping first\");\n return;\n default: {\n // Enforce that the switch-case is exhaustive.\n const _: never = this.socket;\n }\n }\n this.connect();\n }\n\n pause(): void {\n switch (this.socket.state) {\n case \"disconnected\":\n case \"stopped\":\n case \"terminated\":\n // If already stopped or stopping ignore.\n return;\n case \"connecting\":\n case \"ready\": {\n this.socket = { ...this.socket, paused: \"yes\" };\n return;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n const _: never = this.socket;\n return;\n }\n }\n }\n\n /**\n * Resume the state machine if previously paused.\n */\n resume(): void {\n switch (this.socket.state) {\n case \"connecting\":\n this.socket = { ...this.socket, paused: \"no\" };\n return;\n case \"ready\":\n if (this.socket.paused === \"uninitialized\") {\n this.socket = { ...this.socket, paused: \"no\" };\n this.onOpen({\n connectionCount: this.connectionCount,\n lastCloseReason: this.lastCloseReason,\n });\n } else if (this.socket.paused === \"yes\") {\n this.socket = { ...this.socket, paused: \"no\" };\n this.onResume();\n }\n return;\n case \"terminated\":\n case \"stopped\":\n case \"disconnected\":\n // Ignore resume if not paused, perhaps we already resumed.\n return;\n default: {\n // Enforce that the switch-case is exhaustive.\n const _: never = this.socket;\n }\n }\n this.connect();\n }\n\n connectionState(): {\n isConnected: boolean;\n hasEverConnected: boolean;\n connectionCount: number;\n connectionRetries: number;\n } {\n return {\n isConnected: this.socket.state === \"ready\",\n hasEverConnected: this._hasEverConnected,\n connectionCount: this.connectionCount,\n connectionRetries: this.retries,\n };\n }\n\n private _logVerbose(message: string) {\n this.logger.logVerbose(message);\n }\n\n private nextBackoff(): number {\n const baseBackoff = this.initialBackoff * Math.pow(2, this.retries);\n this.retries += 1;\n const actualBackoff = Math.min(baseBackoff, this.maxBackoff);\n const jitter = actualBackoff * (Math.random() - 0.5);\n return actualBackoff + jitter;\n }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { Logger } from \"../logging.js\";\nimport {\n ClientMessage,\n encodeClientMessage,\n parseServerMessage,\n ServerMessage,\n} from \"./protocol.js\";\n\nconst CLOSE_NORMAL = 1000;\nconst CLOSE_GOING_AWAY = 1001;\nconst CLOSE_NO_STATUS = 1005;\n/** Convex-specific close code representing a \"404 Not Found\".\n * The edge Onramp accepts websocket upgrades before confirming that the\n * intended destination exists, so this code is sent once we've discovered that\n * the destination does not exist.\n */\nconst CLOSE_NOT_FOUND = 4040;\n\n/**\n * The various states our WebSocket can be in:\n *\n * - \"disconnected\": We don't have a WebSocket, but plan to create one.\n * - \"connecting\": We have created the WebSocket and are waiting for the\n * `onOpen` callback.\n * - \"ready\": We have an open WebSocket.\n * - \"stopped\": The WebSocket was closed and a new one can be created via `.restart()`.\n * - \"terminated\": We have closed the WebSocket and will never create a new one.\n *\n *\n * WebSocket State Machine\n * -----------------------\n * initialState: disconnected\n * validTransitions:\n * disconnected:\n * new WebSocket() -> connecting\n * terminate() -> terminated\n * connecting:\n * onopen -> ready\n * close() -> disconnected\n * terminate() -> terminated\n * ready:\n * close() -> disconnected\n * stop() -> stopped\n * terminate() -> terminated\n * stopped:\n * restart() -> connecting\n * terminate() -> terminated\n * terminalStates:\n * terminated\n *\n *\n *\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u250C\u2500\u2500\u2500\u2500terminate()\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2502 disconnected \u2502\u25C0\u2500\u2510\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n * \u25BC \u2502 \u25B2 \u2502\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 new WebSocket() \u2502 \u2502\n * \u250C\u2500\u25B6\u2502 terminated \u2502\u25C0\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 \u2502 \u2502\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502 \u2502 \u2502 \u2502\n * \u2502 \u25B2 terminate() \u2502 close() close()\n * \u2502 terminate() \u2502 \u2502 \u2502 \u2502\n * \u2502 \u2502 \u2502 \u25BC \u2502 \u2502\n * \u2502 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n * \u2502 \u2502 stopped \u2502\u2500\u2500restart()\u2500\u2500\u2500\u25B6\u2502 connecting \u2502 \u2502\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n * \u2502 \u25B2 \u2502 \u2502\n * \u2502 \u2502 onopen \u2502\n * \u2502 \u2502 \u2502 \u2502\n * \u2502 \u2502 \u25BC \u2502\n * terminate() \u2502 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500stop()\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2502 ready \u2502\u2500\u2500\u2518\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n * \u2502 \u2502\n * \u2502 \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n *\n * The `connecting` and `ready` state have a sub-state-machine for pausing.\n */\n\ntype Socket =\n | { state: \"disconnected\" }\n | { state: \"connecting\"; ws: WebSocket; paused: \"yes\" | \"no\" }\n | { state: \"ready\"; ws: WebSocket; paused: \"yes\" | \"no\" | \"uninitialized\" }\n | { state: \"stopped\" }\n | { state: \"terminated\" };\n\nexport type ReconnectMetadata = {\n connectionCount: number;\n lastCloseReason: string | null;\n};\n\nexport type OnMessageResponse = {\n hasSyncedPastLastReconnect: boolean;\n};\n\n/**\n * A wrapper around a websocket that handles errors, reconnection, and message\n * parsing.\n */\nexport class WebSocketManager {\n private socket: Socket;\n\n private connectionCount: number;\n private _hasEverConnected: boolean = false;\n private lastCloseReason: string | null;\n\n /** Upon HTTPS/WSS failure, the first jittered backoff duration, in ms. */\n private readonly initialBackoff: number;\n\n /** We backoff exponentially, but we need to cap that--this is the jittered max. */\n private readonly maxBackoff: number;\n\n /** How many times have we failed consecutively? */\n private retries: number;\n\n /** How long before lack of server response causes us to initiate a reconnect,\n * in ms */\n private readonly serverInactivityThreshold: number;\n\n private reconnectDueToServerInactivityTimeout: ReturnType<\n typeof setTimeout\n > | null;\n\n private readonly uri: string;\n private readonly onOpen: (reconnectMetadata: ReconnectMetadata) => void;\n private readonly onResume: () => void;\n private readonly onMessage: (message: ServerMessage) => OnMessageResponse;\n private readonly webSocketConstructor: typeof WebSocket;\n private readonly logger: Logger;\n\n constructor(\n uri: string,\n callbacks: {\n onOpen: (reconnectMetadata: ReconnectMetadata) => void;\n onResume: () => void;\n onMessage: (message: ServerMessage) => OnMessageResponse;\n },\n webSocketConstructor: typeof WebSocket,\n logger: Logger,\n ) {\n this.webSocketConstructor = webSocketConstructor;\n this.socket = { state: \"disconnected\" };\n this.connectionCount = 0;\n this.lastCloseReason = \"InitialConnect\";\n\n this.initialBackoff = 100;\n this.maxBackoff = 16000;\n this.retries = 0;\n\n this.serverInactivityThreshold = 30000;\n this.reconnectDueToServerInactivityTimeout = null;\n\n this.uri = uri;\n this.onOpen = callbacks.onOpen;\n this.onResume = callbacks.onResume;\n this.onMessage = callbacks.onMessage;\n this.logger = logger;\n\n this.connect();\n }\n\n private setSocketState(state: Socket) {\n this.socket = state;\n this._logVerbose(\n `socket state changed: ${this.socket.state}, paused: ${\n \"paused\" in this.socket ? this.socket.paused : undefined\n }`,\n );\n }\n\n private connect() {\n if (this.socket.state === \"terminated\") {\n return;\n }\n if (\n this.socket.state !== \"disconnected\" &&\n this.socket.state !== \"stopped\"\n ) {\n throw new Error(\n \"Didn't start connection from disconnected state: \" + this.socket.state,\n );\n }\n\n const ws = new this.webSocketConstructor(this.uri);\n this._logVerbose(\"constructed WebSocket\");\n this.setSocketState({\n state: \"connecting\",\n ws,\n paused: \"no\",\n });\n\n // Kick off server inactivity timer before WebSocket connection is established\n // so we can detect cases where handshake fails.\n // The `onopen` event only fires after the connection is established:\n // Source: https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\n this.resetServerInactivityTimeout();\n\n ws.onopen = () => {\n this.logger.logVerbose(\"begin ws.onopen\");\n if (this.socket.state !== \"connecting\") {\n throw new Error(\"onopen called with socket not in connecting state\");\n }\n this.setSocketState({\n state: \"ready\",\n ws,\n paused: this.socket.paused === \"yes\" ? \"uninitialized\" : \"no\",\n });\n this.resetServerInactivityTimeout();\n if (this.socket.paused === \"no\") {\n this._hasEverConnected = true;\n this.onOpen({\n connectionCount: this.connectionCount,\n lastCloseReason: this.lastCloseReason,\n });\n }\n\n if (this.lastCloseReason !== \"InitialConnect\") {\n this.logger.log(\"WebSocket reconnected\");\n }\n\n this.connectionCount += 1;\n this.lastCloseReason = null;\n };\n // NB: The WebSocket API calls `onclose` even if connection fails, so we can route all error paths through `onclose`.\n ws.onerror = (error) => {\n const message = (error as ErrorEvent).message;\n this.logger.log(`WebSocket error: ${message}`);\n };\n ws.onmessage = (message) => {\n this.resetServerInactivityTimeout();\n const serverMessage = parseServerMessage(JSON.parse(message.data));\n this._logVerbose(`received ws message with type ${serverMessage.type}`);\n const response = this.onMessage(serverMessage);\n if (response.hasSyncedPastLastReconnect) {\n // Reset backoff to 0 once all outstanding requests are complete.\n this.retries = 0;\n }\n };\n ws.onclose = (event) => {\n this._logVerbose(\"begin ws.onclose\");\n if (this.lastCloseReason === null) {\n this.lastCloseReason = event.reason ?? \"OnCloseInvoked\";\n }\n if (\n event.code !== CLOSE_NORMAL &&\n event.code !== CLOSE_GOING_AWAY && // This commonly gets fired on mobile apps when the app is backgrounded\n event.code !== CLOSE_NO_STATUS &&\n event.code !== CLOSE_NOT_FOUND // Note that we want to retry on a 404, as it can be transient during a push.\n ) {\n let msg = `WebSocket closed with code ${event.code}`;\n if (event.reason) {\n msg += `: ${event.reason}`;\n }\n this.logger.log(msg);\n }\n if (event.reason?.includes(\"SubscriptionsWorkerFullError\")) {\n this.scheduleReconnect(\"SubscriptionsWorkerFullError\");\n } else if (event.reason?.includes(\"TooManyConcurrentRequests\")) {\n this.scheduleReconnect(\"TooManyConcurrentRequests\");\n } else {\n this.scheduleReconnect(\"unknown\");\n }\n return;\n };\n }\n\n /**\n * @returns The state of the {@link Socket}.\n */\n socketState(): string {\n return this.socket.state;\n }\n\n /**\n * @param message - A ClientMessage to send.\n * @returns Whether the message (might have been) sent.\n */\n sendMessage(message: ClientMessage) {\n const messageForLog = {\n type: message.type,\n ...(message.type === \"Authenticate\" && message.tokenType === \"User\"\n ? {\n value: `...${message.value.slice(-7)}`,\n }\n : {}),\n };\n if (this.socket.state === \"ready\" && this.socket.paused === \"no\") {\n const encodedMessage = encodeClientMessage(message);\n const request = JSON.stringify(encodedMessage);\n try {\n this.socket.ws.send(request);\n } catch (error: any) {\n this.logger.log(\n `Failed to send message on WebSocket, reconnecting: ${error}`,\n );\n this.closeAndReconnect(\"FailedToSendMessage\");\n }\n // We are not sure if this was sent or not.\n this._logVerbose(\n `sent message with type ${message.type}: ${JSON.stringify(\n messageForLog,\n )}`,\n );\n return true;\n }\n this._logVerbose(\n `message not sent (socket state: ${this.socket.state}, paused: ${\"paused\" in this.socket ? this.socket.paused : undefined}): ${JSON.stringify(\n messageForLog,\n )}`,\n );\n\n return false;\n }\n\n private resetServerInactivityTimeout() {\n if (this.socket.state === \"terminated\") {\n // Don't reset any timers if we were trying to terminate.\n return;\n }\n if (this.reconnectDueToServerInactivityTimeout !== null) {\n clearTimeout(this.reconnectDueToServerInactivityTimeout);\n this.reconnectDueToServerInactivityTimeout = null;\n }\n this.reconnectDueToServerInactivityTimeout = setTimeout(() => {\n this.closeAndReconnect(\"InactiveServer\");\n }, this.serverInactivityThreshold);\n }\n\n private scheduleReconnect(\n reason:\n | \"client\"\n | \"unknown\"\n | \"SubscriptionsWorkerFullError\"\n | \"TooManyConcurrentRequests\",\n ) {\n this.socket = { state: \"disconnected\" };\n const backoff = this.nextBackoff(reason);\n this.logger.log(`Attempting reconnect in ${backoff}ms`);\n setTimeout(() => this.connect(), backoff);\n }\n\n /**\n * Close the WebSocket and schedule a reconnect.\n *\n * This should be used when we hit an error and would like to restart the session.\n */\n private closeAndReconnect(closeReason: string) {\n this._logVerbose(`begin closeAndReconnect with reason ${closeReason}`);\n switch (this.socket.state) {\n case \"disconnected\":\n case \"terminated\":\n case \"stopped\":\n // Nothing to do if we don't have a WebSocket.\n return;\n case \"connecting\":\n case \"ready\": {\n this.lastCloseReason = closeReason;\n // Close the old socket asynchronously, we'll open a new socket in reconnect.\n void this.close();\n this.scheduleReconnect(\"client\");\n return;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n const _: never = this.socket;\n }\n }\n }\n\n /**\n * Close the WebSocket, being careful to clear the onclose handler to avoid re-entrant\n * calls. Use this instead of directly calling `ws.close()`\n *\n * It is the callers responsibility to update the state after this method is called so that the\n * closed socket is not accessible or used again after this method is called\n */\n private close(): Promise<void> {\n switch (this.socket.state) {\n case \"disconnected\":\n case \"terminated\":\n case \"stopped\":\n // Nothing to do if we don't have a WebSocket.\n return Promise.resolve();\n case \"connecting\": {\n const ws = this.socket.ws;\n return new Promise((r) => {\n ws.onclose = () => {\n this._logVerbose(\"Closed after connecting\");\n r();\n };\n ws.onopen = () => {\n this._logVerbose(\"Opened after connecting\");\n ws.close();\n };\n });\n }\n case \"ready\": {\n this._logVerbose(\"ws.close called\");\n const ws = this.socket.ws;\n const result: Promise<void> = new Promise((r) => {\n ws.onclose = () => {\n r();\n };\n });\n ws.close();\n return result;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n const _: never = this.socket;\n return Promise.resolve();\n }\n }\n }\n\n /**\n * Close the WebSocket and do not reconnect.\n * @returns A Promise that resolves when the WebSocket `onClose` callback is called.\n */\n terminate(): Promise<void> {\n if (this.reconnectDueToServerInactivityTimeout) {\n clearTimeout(this.reconnectDueToServerInactivityTimeout);\n }\n switch (this.socket.state) {\n case \"terminated\":\n case \"stopped\":\n case \"disconnected\":\n case \"connecting\":\n case \"ready\": {\n const result = this.close();\n this.setSocketState({ state: \"terminated\" });\n return result;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n const _: never = this.socket;\n throw new Error(\n `Invalid websocket state: ${(this.socket as any).state}`,\n );\n }\n }\n }\n\n stop(): Promise<void> {\n switch (this.socket.state) {\n case \"terminated\":\n // If we're terminating we ignore stop\n return Promise.resolve();\n case \"connecting\":\n case \"stopped\":\n case \"disconnected\":\n case \"ready\": {\n const result = this.close();\n this.socket = { state: \"stopped\" };\n return result;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n const _: never = this.socket;\n return Promise.resolve();\n }\n }\n }\n\n /**\n * Create a new WebSocket after a previous `stop()`, unless `terminate()` was\n * called before.\n */\n tryRestart(): void {\n switch (this.socket.state) {\n case \"stopped\":\n break;\n case \"terminated\":\n case \"connecting\":\n case \"ready\":\n case \"disconnected\":\n this.logger.logVerbose(\"Restart called without stopping first\");\n return;\n default: {\n // Enforce that the switch-case is exhaustive.\n const _: never = this.socket;\n }\n }\n this.connect();\n }\n\n pause(): void {\n switch (this.socket.state) {\n case \"disconnected\":\n case \"stopped\":\n case \"terminated\":\n // If already stopped or stopping ignore.\n return;\n case \"connecting\":\n case \"ready\": {\n this.socket = { ...this.socket, paused: \"yes\" };\n return;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n const _: never = this.socket;\n return;\n }\n }\n }\n\n /**\n * Resume the state machine if previously paused.\n */\n resume(): void {\n switch (this.socket.state) {\n case \"connecting\":\n this.socket = { ...this.socket, paused: \"no\" };\n return;\n case \"ready\":\n if (this.socket.paused === \"uninitialized\") {\n this.socket = { ...this.socket, paused: \"no\" };\n this.onOpen({\n connectionCount: this.connectionCount,\n lastCloseReason: this.lastCloseReason,\n });\n } else if (this.socket.paused === \"yes\") {\n this.socket = { ...this.socket, paused: \"no\" };\n this.onResume();\n }\n return;\n case \"terminated\":\n case \"stopped\":\n case \"disconnected\":\n // Ignore resume if not paused, perhaps we already resumed.\n return;\n default: {\n // Enforce that the switch-case is exhaustive.\n const _: never = this.socket;\n }\n }\n this.connect();\n }\n\n connectionState(): {\n isConnected: boolean;\n hasEverConnected: boolean;\n connectionCount: number;\n connectionRetries: number;\n } {\n return {\n isConnected: this.socket.state === \"ready\",\n hasEverConnected: this._hasEverConnected,\n connectionCount: this.connectionCount,\n connectionRetries: this.retries,\n };\n }\n\n private _logVerbose(message: string) {\n this.logger.logVerbose(message);\n }\n\n private nextBackoff(\n reason:\n | \"client\"\n | \"unknown\"\n | \"SubscriptionsWorkerFullError\"\n | \"TooManyConcurrentRequests\",\n ): number {\n const initialBackoff =\n reason === \"SubscriptionsWorkerFullError\"\n ? 3000\n : reason === \"TooManyConcurrentRequests\"\n ? 3000\n : this.initialBackoff;\n const baseBackoff = initialBackoff * Math.pow(2, this.retries);\n this.retries += 1;\n const actualBackoff = Math.min(baseBackoff, this.maxBackoff);\n const jitter = actualBackoff * (Math.random() - 0.5);\n return actualBackoff + jitter;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -7,11 +7,11 @@ const Oidc = z.object({
|
|
|
7
7
|
}).passthrough();
|
|
8
8
|
const CustomJwt = z.object({
|
|
9
9
|
type: z.literal("customJwt"),
|
|
10
|
-
applicationID: z.
|
|
10
|
+
applicationID: z.string().nullable(),
|
|
11
11
|
issuer: z.string(),
|
|
12
12
|
jwks: z.string(),
|
|
13
13
|
algorithm: z.string()
|
|
14
|
-
});
|
|
15
|
-
export const authInfo = z.union([
|
|
14
|
+
}).passthrough();
|
|
15
|
+
export const authInfo = z.union([CustomJwt, Oidc]);
|
|
16
16
|
export const identifier = z.string();
|
|
17
17
|
//# sourceMappingURL=types.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/cli/lib/deployApi/types.ts"],
|
|
4
|
-
"sourcesContent": ["import { z } from \"zod\";\n\nexport const reference = z.string();\nexport type Reference = z.infer<typeof reference>;\n\n//
|
|
5
|
-
"mappings": ";AAAA,SAAS,SAAS;AAEX,aAAM,YAAY,EAAE,OAAO;
|
|
4
|
+
"sourcesContent": ["import { z } from \"zod\";\n\nexport const reference = z.string();\nexport type Reference = z.infer<typeof reference>;\n\n// These validators parse the response from the backend so although\n// they roughly correspond with convex/auth.config.ts providers they\n// have been processed.\n\n// Passthrough so old CLIs can operate on new backend formats.\nconst Oidc = z\n .object({\n applicationID: z.string(),\n domain: z.string(),\n })\n .passthrough();\nconst CustomJwt = z\n .object({\n type: z.literal(\"customJwt\"),\n applicationID: z.string().nullable(),\n issuer: z.string(),\n jwks: z.string(),\n algorithm: z.string(),\n })\n .passthrough();\n\nexport const authInfo = z.union([CustomJwt, Oidc]);\n\nexport type AuthInfo = z.infer<typeof authInfo>;\n\nexport const identifier = z.string();\nexport type Identifier = z.infer<typeof identifier>;\n"],
|
|
5
|
+
"mappings": ";AAAA,SAAS,SAAS;AAEX,aAAM,YAAY,EAAE,OAAO;AAQlC,MAAM,OAAO,EACV,OAAO;AAAA,EACN,eAAe,EAAE,OAAO;AAAA,EACxB,QAAQ,EAAE,OAAO;AACnB,CAAC,EACA,YAAY;AACf,MAAM,YAAY,EACf,OAAO;AAAA,EACN,MAAM,EAAE,QAAQ,WAAW;AAAA,EAC3B,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,EACnC,QAAQ,EAAE,OAAO;AAAA,EACjB,MAAM,EAAE,OAAO;AAAA,EACf,WAAW,EAAE,OAAO;AACtB,CAAC,EACA,YAAY;AAER,aAAM,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,CAAC;AAI1C,aAAM,aAAa,EAAE,OAAO;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/esm/index.js
CHANGED
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web_socket_manager.d.ts","sourceRoot":"","sources":["../../../../src/browser/sync/web_socket_manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EACL,aAAa,EAGb,aAAa,EACd,MAAM,eAAe,CAAC;AAgFvB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,0BAA0B,EAAE,OAAO,CAAC;CACrC,CAAC;AAEF;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,iBAAiB,CAAkB;IAC3C,OAAO,CAAC,eAAe,CAAgB;IAEvC,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IAEpC,mDAAmD;IACnD,OAAO,CAAC,OAAO,CAAS;IAExB;eACW;IACX,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAS;IAEnD,OAAO,CAAC,qCAAqC,CAEpC;IAET,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiD;IACxE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAa;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgD;IAC1E,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAmB;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAG9B,GAAG,EAAE,MAAM,EACX,SAAS,EAAE;QACT,MAAM,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,KAAK,IAAI,CAAC;QACvD,QAAQ,EAAE,MAAM,IAAI,CAAC;QACrB,SAAS,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,iBAAiB,CAAC;KAC1D,EACD,oBAAoB,EAAE,OAAO,SAAS,EACtC,MAAM,EAAE,MAAM;IAuBhB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,OAAO;
|
|
1
|
+
{"version":3,"file":"web_socket_manager.d.ts","sourceRoot":"","sources":["../../../../src/browser/sync/web_socket_manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EACL,aAAa,EAGb,aAAa,EACd,MAAM,eAAe,CAAC;AAgFvB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,0BAA0B,EAAE,OAAO,CAAC;CACrC,CAAC;AAEF;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,iBAAiB,CAAkB;IAC3C,OAAO,CAAC,eAAe,CAAgB;IAEvC,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IAEpC,mDAAmD;IACnD,OAAO,CAAC,OAAO,CAAS;IAExB;eACW;IACX,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAS;IAEnD,OAAO,CAAC,qCAAqC,CAEpC;IAET,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiD;IACxE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAa;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgD;IAC1E,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAmB;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAG9B,GAAG,EAAE,MAAM,EACX,SAAS,EAAE;QACT,MAAM,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,KAAK,IAAI,CAAC;QACvD,QAAQ,EAAE,MAAM,IAAI,CAAC;QACrB,SAAS,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,iBAAiB,CAAC;KAC1D,EACD,oBAAoB,EAAE,OAAO,SAAS,EACtC,MAAM,EAAE,MAAM;IAuBhB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,OAAO;IAgGf;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE,aAAa;IAqClC,OAAO,CAAC,4BAA4B;IAcpC,OAAO,CAAC,iBAAiB;IAazB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAuBzB;;;;;;OAMG;IACH,OAAO,CAAC,KAAK;IAuCb;;;OAGG;IACH,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAwB1B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBrB;;;OAGG;IACH,UAAU,IAAI,IAAI;IAkBlB,KAAK,IAAI,IAAI;IAoBb;;OAEG;IACH,MAAM,IAAI,IAAI;IA8Bd,eAAe,IAAI;QACjB,WAAW,EAAE,OAAO,CAAC;QACrB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,eAAe,EAAE,MAAM,CAAC;QACxB,iBAAiB,EAAE,MAAM,CAAC;KAC3B;IASD,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;CAmBpB"}
|
|
@@ -328,6 +328,24 @@ export declare const startPushResponse: z.ZodObject<{
|
|
|
328
328
|
externalDepsId: z.ZodNullable<z.ZodString>;
|
|
329
329
|
componentDefinitionPackages: z.ZodRecord<z.ZodString, z.ZodAny>;
|
|
330
330
|
appAuth: z.ZodArray<z.ZodUnion<[z.ZodObject<{
|
|
331
|
+
type: z.ZodLiteral<"customJwt">;
|
|
332
|
+
applicationID: z.ZodNullable<z.ZodString>;
|
|
333
|
+
issuer: z.ZodString;
|
|
334
|
+
jwks: z.ZodString;
|
|
335
|
+
algorithm: z.ZodString;
|
|
336
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
337
|
+
type: z.ZodLiteral<"customJwt">;
|
|
338
|
+
applicationID: z.ZodNullable<z.ZodString>;
|
|
339
|
+
issuer: z.ZodString;
|
|
340
|
+
jwks: z.ZodString;
|
|
341
|
+
algorithm: z.ZodString;
|
|
342
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
343
|
+
type: z.ZodLiteral<"customJwt">;
|
|
344
|
+
applicationID: z.ZodNullable<z.ZodString>;
|
|
345
|
+
issuer: z.ZodString;
|
|
346
|
+
jwks: z.ZodString;
|
|
347
|
+
algorithm: z.ZodString;
|
|
348
|
+
}, z.ZodTypeAny, "passthrough">>, z.ZodObject<{
|
|
331
349
|
applicationID: z.ZodString;
|
|
332
350
|
domain: z.ZodString;
|
|
333
351
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
@@ -336,25 +354,7 @@ export declare const startPushResponse: z.ZodObject<{
|
|
|
336
354
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
337
355
|
applicationID: z.ZodString;
|
|
338
356
|
domain: z.ZodString;
|
|
339
|
-
}, z.ZodTypeAny, "passthrough"
|
|
340
|
-
type: z.ZodLiteral<"customJwt">;
|
|
341
|
-
applicationID: z.ZodOptional<z.ZodString>;
|
|
342
|
-
issuer: z.ZodString;
|
|
343
|
-
jwks: z.ZodString;
|
|
344
|
-
algorithm: z.ZodString;
|
|
345
|
-
}, "strip", z.ZodTypeAny, {
|
|
346
|
-
type: "customJwt";
|
|
347
|
-
issuer: string;
|
|
348
|
-
jwks: string;
|
|
349
|
-
algorithm: string;
|
|
350
|
-
applicationID?: string | undefined;
|
|
351
|
-
}, {
|
|
352
|
-
type: "customJwt";
|
|
353
|
-
issuer: string;
|
|
354
|
-
jwks: string;
|
|
355
|
-
algorithm: string;
|
|
356
|
-
applicationID?: string | undefined;
|
|
357
|
-
}>]>, "many">;
|
|
357
|
+
}, z.ZodTypeAny, "passthrough">>]>, "many">;
|
|
358
358
|
analysis: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
359
359
|
definition: z.ZodObject<{
|
|
360
360
|
path: z.ZodString;
|
|
@@ -860,13 +860,13 @@ export declare const startPushResponse: z.ZodObject<{
|
|
|
860
860
|
appAuth: (z.objectOutputType<{
|
|
861
861
|
applicationID: z.ZodString;
|
|
862
862
|
domain: z.ZodString;
|
|
863
|
-
}, z.ZodTypeAny, "passthrough"> | {
|
|
864
|
-
type: "customJwt"
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
})[];
|
|
863
|
+
}, z.ZodTypeAny, "passthrough"> | z.objectOutputType<{
|
|
864
|
+
type: z.ZodLiteral<"customJwt">;
|
|
865
|
+
applicationID: z.ZodNullable<z.ZodString>;
|
|
866
|
+
issuer: z.ZodString;
|
|
867
|
+
jwks: z.ZodString;
|
|
868
|
+
algorithm: z.ZodString;
|
|
869
|
+
}, z.ZodTypeAny, "passthrough">)[];
|
|
870
870
|
analysis: Record<string, {
|
|
871
871
|
definition: {
|
|
872
872
|
path: string;
|
|
@@ -951,13 +951,13 @@ export declare const startPushResponse: z.ZodObject<{
|
|
|
951
951
|
appAuth: (z.objectInputType<{
|
|
952
952
|
applicationID: z.ZodString;
|
|
953
953
|
domain: z.ZodString;
|
|
954
|
-
}, z.ZodTypeAny, "passthrough"> | {
|
|
955
|
-
type: "customJwt"
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
})[];
|
|
954
|
+
}, z.ZodTypeAny, "passthrough"> | z.objectInputType<{
|
|
955
|
+
type: z.ZodLiteral<"customJwt">;
|
|
956
|
+
applicationID: z.ZodNullable<z.ZodString>;
|
|
957
|
+
issuer: z.ZodString;
|
|
958
|
+
jwks: z.ZodString;
|
|
959
|
+
algorithm: z.ZodString;
|
|
960
|
+
}, z.ZodTypeAny, "passthrough">)[];
|
|
961
961
|
analysis: Record<string, {
|
|
962
962
|
definition: {
|
|
963
963
|
path: string;
|
|
@@ -2,6 +2,24 @@ import { z } from "zod";
|
|
|
2
2
|
export declare const reference: z.ZodString;
|
|
3
3
|
export type Reference = z.infer<typeof reference>;
|
|
4
4
|
export declare const authInfo: z.ZodUnion<[z.ZodObject<{
|
|
5
|
+
type: z.ZodLiteral<"customJwt">;
|
|
6
|
+
applicationID: z.ZodNullable<z.ZodString>;
|
|
7
|
+
issuer: z.ZodString;
|
|
8
|
+
jwks: z.ZodString;
|
|
9
|
+
algorithm: z.ZodString;
|
|
10
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
11
|
+
type: z.ZodLiteral<"customJwt">;
|
|
12
|
+
applicationID: z.ZodNullable<z.ZodString>;
|
|
13
|
+
issuer: z.ZodString;
|
|
14
|
+
jwks: z.ZodString;
|
|
15
|
+
algorithm: z.ZodString;
|
|
16
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
17
|
+
type: z.ZodLiteral<"customJwt">;
|
|
18
|
+
applicationID: z.ZodNullable<z.ZodString>;
|
|
19
|
+
issuer: z.ZodString;
|
|
20
|
+
jwks: z.ZodString;
|
|
21
|
+
algorithm: z.ZodString;
|
|
22
|
+
}, z.ZodTypeAny, "passthrough">>, z.ZodObject<{
|
|
5
23
|
applicationID: z.ZodString;
|
|
6
24
|
domain: z.ZodString;
|
|
7
25
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
@@ -10,25 +28,7 @@ export declare const authInfo: z.ZodUnion<[z.ZodObject<{
|
|
|
10
28
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
11
29
|
applicationID: z.ZodString;
|
|
12
30
|
domain: z.ZodString;
|
|
13
|
-
}, z.ZodTypeAny, "passthrough"
|
|
14
|
-
type: z.ZodLiteral<"customJwt">;
|
|
15
|
-
applicationID: z.ZodOptional<z.ZodString>;
|
|
16
|
-
issuer: z.ZodString;
|
|
17
|
-
jwks: z.ZodString;
|
|
18
|
-
algorithm: z.ZodString;
|
|
19
|
-
}, "strip", z.ZodTypeAny, {
|
|
20
|
-
type: "customJwt";
|
|
21
|
-
issuer: string;
|
|
22
|
-
jwks: string;
|
|
23
|
-
algorithm: string;
|
|
24
|
-
applicationID?: string | undefined;
|
|
25
|
-
}, {
|
|
26
|
-
type: "customJwt";
|
|
27
|
-
issuer: string;
|
|
28
|
-
jwks: string;
|
|
29
|
-
algorithm: string;
|
|
30
|
-
applicationID?: string | undefined;
|
|
31
|
-
}>]>;
|
|
31
|
+
}, z.ZodTypeAny, "passthrough">>]>;
|
|
32
32
|
export type AuthInfo = z.infer<typeof authInfo>;
|
|
33
33
|
export declare const identifier: z.ZodString;
|
|
34
34
|
export type Identifier = z.infer<typeof identifier>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/cli/lib/deployApi/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,SAAS,aAAa,CAAC;AACpC,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/cli/lib/deployApi/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,SAAS,aAAa,CAAC;AACpC,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAuBlD,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;kCAA6B,CAAC;AAEnD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEhD,eAAO,MAAM,UAAU,aAAa,CAAC;AACrC,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "1.24.
|
|
1
|
+
export declare const version = "1.24.7-alpha.0";
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,mBAAmB,CAAC"}
|
package/dist/react.bundle.js
CHANGED
|
@@ -704,7 +704,7 @@ var convex = (() => {
|
|
|
704
704
|
var import_react3 = __toESM(require_react(), 1);
|
|
705
705
|
|
|
706
706
|
// src/index.ts
|
|
707
|
-
var version = "1.24.
|
|
707
|
+
var version = "1.24.7-alpha.0";
|
|
708
708
|
|
|
709
709
|
// src/browser/logging.ts
|
|
710
710
|
var INFO_COLOR = "color:rgb(0, 145, 255)";
|
|
@@ -1889,7 +1889,13 @@ var convex = (() => {
|
|
|
1889
1889
|
}
|
|
1890
1890
|
this.logger.log(msg);
|
|
1891
1891
|
}
|
|
1892
|
-
|
|
1892
|
+
if (event.reason?.includes("SubscriptionsWorkerFullError")) {
|
|
1893
|
+
this.scheduleReconnect("SubscriptionsWorkerFullError");
|
|
1894
|
+
} else if (event.reason?.includes("TooManyConcurrentRequests")) {
|
|
1895
|
+
this.scheduleReconnect("TooManyConcurrentRequests");
|
|
1896
|
+
} else {
|
|
1897
|
+
this.scheduleReconnect("unknown");
|
|
1898
|
+
}
|
|
1893
1899
|
return;
|
|
1894
1900
|
};
|
|
1895
1901
|
}
|
|
@@ -1947,9 +1953,9 @@ var convex = (() => {
|
|
|
1947
1953
|
this.closeAndReconnect("InactiveServer");
|
|
1948
1954
|
}, this.serverInactivityThreshold);
|
|
1949
1955
|
}
|
|
1950
|
-
scheduleReconnect() {
|
|
1956
|
+
scheduleReconnect(reason) {
|
|
1951
1957
|
this.socket = { state: "disconnected" };
|
|
1952
|
-
const backoff = this.nextBackoff();
|
|
1958
|
+
const backoff = this.nextBackoff(reason);
|
|
1953
1959
|
this.logger.log(`Attempting reconnect in ${backoff}ms`);
|
|
1954
1960
|
setTimeout(() => this.connect(), backoff);
|
|
1955
1961
|
}
|
|
@@ -1969,7 +1975,7 @@ var convex = (() => {
|
|
|
1969
1975
|
case "ready": {
|
|
1970
1976
|
this.lastCloseReason = closeReason;
|
|
1971
1977
|
void this.close();
|
|
1972
|
-
this.scheduleReconnect();
|
|
1978
|
+
this.scheduleReconnect("client");
|
|
1973
1979
|
return;
|
|
1974
1980
|
}
|
|
1975
1981
|
default: {
|
|
@@ -2142,8 +2148,9 @@ var convex = (() => {
|
|
|
2142
2148
|
_logVerbose(message) {
|
|
2143
2149
|
this.logger.logVerbose(message);
|
|
2144
2150
|
}
|
|
2145
|
-
nextBackoff() {
|
|
2146
|
-
const
|
|
2151
|
+
nextBackoff(reason) {
|
|
2152
|
+
const initialBackoff = reason === "SubscriptionsWorkerFullError" ? 3e3 : reason === "TooManyConcurrentRequests" ? 3e3 : this.initialBackoff;
|
|
2153
|
+
const baseBackoff = initialBackoff * Math.pow(2, this.retries);
|
|
2147
2154
|
this.retries += 1;
|
|
2148
2155
|
const actualBackoff = Math.min(baseBackoff, this.maxBackoff);
|
|
2149
2156
|
const jitter = actualBackoff * (Math.random() - 0.5);
|