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
|
@@ -139,7 +139,13 @@ class WebSocketManager {
|
|
|
139
139
|
}
|
|
140
140
|
this.logger.log(msg);
|
|
141
141
|
}
|
|
142
|
-
|
|
142
|
+
if (event.reason?.includes("SubscriptionsWorkerFullError")) {
|
|
143
|
+
this.scheduleReconnect("SubscriptionsWorkerFullError");
|
|
144
|
+
} else if (event.reason?.includes("TooManyConcurrentRequests")) {
|
|
145
|
+
this.scheduleReconnect("TooManyConcurrentRequests");
|
|
146
|
+
} else {
|
|
147
|
+
this.scheduleReconnect("unknown");
|
|
148
|
+
}
|
|
143
149
|
return;
|
|
144
150
|
};
|
|
145
151
|
}
|
|
@@ -197,9 +203,9 @@ class WebSocketManager {
|
|
|
197
203
|
this.closeAndReconnect("InactiveServer");
|
|
198
204
|
}, this.serverInactivityThreshold);
|
|
199
205
|
}
|
|
200
|
-
scheduleReconnect() {
|
|
206
|
+
scheduleReconnect(reason) {
|
|
201
207
|
this.socket = { state: "disconnected" };
|
|
202
|
-
const backoff = this.nextBackoff();
|
|
208
|
+
const backoff = this.nextBackoff(reason);
|
|
203
209
|
this.logger.log(`Attempting reconnect in ${backoff}ms`);
|
|
204
210
|
setTimeout(() => this.connect(), backoff);
|
|
205
211
|
}
|
|
@@ -219,7 +225,7 @@ class WebSocketManager {
|
|
|
219
225
|
case "ready": {
|
|
220
226
|
this.lastCloseReason = closeReason;
|
|
221
227
|
void this.close();
|
|
222
|
-
this.scheduleReconnect();
|
|
228
|
+
this.scheduleReconnect("client");
|
|
223
229
|
return;
|
|
224
230
|
}
|
|
225
231
|
default: {
|
|
@@ -392,8 +398,9 @@ class WebSocketManager {
|
|
|
392
398
|
_logVerbose(message) {
|
|
393
399
|
this.logger.logVerbose(message);
|
|
394
400
|
}
|
|
395
|
-
nextBackoff() {
|
|
396
|
-
const
|
|
401
|
+
nextBackoff(reason) {
|
|
402
|
+
const initialBackoff = reason === "SubscriptionsWorkerFullError" ? 3e3 : reason === "TooManyConcurrentRequests" ? 3e3 : this.initialBackoff;
|
|
403
|
+
const baseBackoff = initialBackoff * Math.pow(2, this.retries);
|
|
397
404
|
this.retries += 1;
|
|
398
405
|
const actualBackoff = Math.min(baseBackoff, this.maxBackoff);
|
|
399
406
|
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
|
}
|
|
@@ -31,11 +31,11 @@ const Oidc = import_zod.z.object({
|
|
|
31
31
|
}).passthrough();
|
|
32
32
|
const CustomJwt = import_zod.z.object({
|
|
33
33
|
type: import_zod.z.literal("customJwt"),
|
|
34
|
-
applicationID: import_zod.z.
|
|
34
|
+
applicationID: import_zod.z.string().nullable(),
|
|
35
35
|
issuer: import_zod.z.string(),
|
|
36
36
|
jwks: import_zod.z.string(),
|
|
37
37
|
algorithm: import_zod.z.string()
|
|
38
|
-
});
|
|
39
|
-
const authInfo = import_zod.z.union([
|
|
38
|
+
}).passthrough();
|
|
39
|
+
const authInfo = import_zod.z.union([CustomJwt, Oidc]);
|
|
40
40
|
const identifier = import_zod.z.string();
|
|
41
41
|
//# 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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAkB;AAEX,MAAM,YAAY,aAAE,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAkB;AAEX,MAAM,YAAY,aAAE,OAAO;AAQlC,MAAM,OAAO,aACV,OAAO;AAAA,EACN,eAAe,aAAE,OAAO;AAAA,EACxB,QAAQ,aAAE,OAAO;AACnB,CAAC,EACA,YAAY;AACf,MAAM,YAAY,aACf,OAAO;AAAA,EACN,MAAM,aAAE,QAAQ,WAAW;AAAA,EAC3B,eAAe,aAAE,OAAO,EAAE,SAAS;AAAA,EACnC,QAAQ,aAAE,OAAO;AAAA,EACjB,MAAM,aAAE,OAAO;AAAA,EACf,WAAW,aAAE,OAAO;AACtB,CAAC,EACA,YAAY;AAER,MAAM,WAAW,aAAE,MAAM,CAAC,WAAW,IAAI,CAAC;AAI1C,MAAM,aAAa,aAAE,OAAO;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/cjs/index.js
CHANGED
package/dist/cjs/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["export const version = \"1.24.
|
|
4
|
+
"sourcesContent": ["export const version = \"1.24.7-alpha.0\";"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,UAAU;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -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/cli.bundle.cjs
CHANGED
|
@@ -133215,7 +133215,7 @@ var {
|
|
|
133215
133215
|
var import_fetch_retry = __toESM(require_fetch_retry(), 1);
|
|
133216
133216
|
|
|
133217
133217
|
// src/index.ts
|
|
133218
|
-
var version = "1.24.
|
|
133218
|
+
var version = "1.24.7-alpha.0";
|
|
133219
133219
|
|
|
133220
133220
|
// src/cli/version.ts
|
|
133221
133221
|
var version2 = process.env.CONVEX_VERSION_OVERRIDE || version;
|
|
@@ -139886,6 +139886,7 @@ var WebSocketManager = class {
|
|
|
139886
139886
|
}
|
|
139887
139887
|
};
|
|
139888
139888
|
ws.onclose = (event) => {
|
|
139889
|
+
var _a, _b;
|
|
139889
139890
|
this._logVerbose("begin ws.onclose");
|
|
139890
139891
|
if (this.lastCloseReason === null) {
|
|
139891
139892
|
this.lastCloseReason = event.reason ?? "OnCloseInvoked";
|
|
@@ -139898,7 +139899,13 @@ var WebSocketManager = class {
|
|
|
139898
139899
|
}
|
|
139899
139900
|
this.logger.log(msg);
|
|
139900
139901
|
}
|
|
139901
|
-
|
|
139902
|
+
if ((_a = event.reason) == null ? void 0 : _a.includes("SubscriptionsWorkerFullError")) {
|
|
139903
|
+
this.scheduleReconnect("SubscriptionsWorkerFullError");
|
|
139904
|
+
} else if ((_b = event.reason) == null ? void 0 : _b.includes("TooManyConcurrentRequests")) {
|
|
139905
|
+
this.scheduleReconnect("TooManyConcurrentRequests");
|
|
139906
|
+
} else {
|
|
139907
|
+
this.scheduleReconnect("unknown");
|
|
139908
|
+
}
|
|
139902
139909
|
return;
|
|
139903
139910
|
};
|
|
139904
139911
|
}
|
|
@@ -139956,9 +139963,9 @@ var WebSocketManager = class {
|
|
|
139956
139963
|
this.closeAndReconnect("InactiveServer");
|
|
139957
139964
|
}, this.serverInactivityThreshold);
|
|
139958
139965
|
}
|
|
139959
|
-
scheduleReconnect() {
|
|
139966
|
+
scheduleReconnect(reason) {
|
|
139960
139967
|
this.socket = { state: "disconnected" };
|
|
139961
|
-
const backoff = this.nextBackoff();
|
|
139968
|
+
const backoff = this.nextBackoff(reason);
|
|
139962
139969
|
this.logger.log(`Attempting reconnect in ${backoff}ms`);
|
|
139963
139970
|
setTimeout(() => this.connect(), backoff);
|
|
139964
139971
|
}
|
|
@@ -139978,7 +139985,7 @@ var WebSocketManager = class {
|
|
|
139978
139985
|
case "ready": {
|
|
139979
139986
|
this.lastCloseReason = closeReason;
|
|
139980
139987
|
void this.close();
|
|
139981
|
-
this.scheduleReconnect();
|
|
139988
|
+
this.scheduleReconnect("client");
|
|
139982
139989
|
return;
|
|
139983
139990
|
}
|
|
139984
139991
|
default: {
|
|
@@ -140151,8 +140158,9 @@ var WebSocketManager = class {
|
|
|
140151
140158
|
_logVerbose(message) {
|
|
140152
140159
|
this.logger.logVerbose(message);
|
|
140153
140160
|
}
|
|
140154
|
-
nextBackoff() {
|
|
140155
|
-
const
|
|
140161
|
+
nextBackoff(reason) {
|
|
140162
|
+
const initialBackoff2 = reason === "SubscriptionsWorkerFullError" ? 3e3 : reason === "TooManyConcurrentRequests" ? 3e3 : this.initialBackoff;
|
|
140163
|
+
const baseBackoff = initialBackoff2 * Math.pow(2, this.retries);
|
|
140156
140164
|
this.retries += 1;
|
|
140157
140165
|
const actualBackoff = Math.min(baseBackoff, this.maxBackoff);
|
|
140158
140166
|
const jitter = actualBackoff * (Math.random() - 0.5);
|
|
@@ -145347,12 +145355,12 @@ var Oidc = z.object({
|
|
|
145347
145355
|
}).passthrough();
|
|
145348
145356
|
var CustomJwt = z.object({
|
|
145349
145357
|
type: z.literal("customJwt"),
|
|
145350
|
-
applicationID: z.
|
|
145358
|
+
applicationID: z.string().nullable(),
|
|
145351
145359
|
issuer: z.string(),
|
|
145352
145360
|
jwks: z.string(),
|
|
145353
145361
|
algorithm: z.string()
|
|
145354
|
-
});
|
|
145355
|
-
var authInfo = z.union([
|
|
145362
|
+
}).passthrough();
|
|
145363
|
+
var authInfo = z.union([CustomJwt, Oidc]);
|
|
145356
145364
|
var identifier = z.string();
|
|
145357
145365
|
|
|
145358
145366
|
// src/cli/lib/deployApi/checkedComponent.ts
|