UNPKG

convex

Version:

Client for the Convex Cloud

152 lines (151 loc) 4.97 kB
"use strict"; import { jsonToConvex } from "../../values/index.js"; import { logToConsole } from "../logging.js"; export class RequestManager { constructor() { this.inflightRequests = /* @__PURE__ */ new Map(); this.requestsOlderThanRestart = /* @__PURE__ */ new Set(); } request(message, sent) { const result = new Promise((resolve) => { const status = sent ? "Requested" : "NotSent"; this.inflightRequests.set(message.requestId, { message, status: { status, requestedAt: /* @__PURE__ */ new Date(), onResult: resolve } }); }); return result; } /** * Update the state after receiving a response. * * @returns A RequestId if the request is complete and its optimistic update * can be dropped, null otherwise. */ onResponse(response) { const requestInfo = this.inflightRequests.get(response.requestId); if (requestInfo === void 0) { return null; } if (requestInfo.status.status === "Completed") { return null; } const udfType = requestInfo.message.type === "Mutation" ? "mutation" : "action"; const udfPath = requestInfo.message.udfPath; for (const line of response.logLines) { logToConsole("info", udfType, udfPath, line); } const status = requestInfo.status; let onResolve; if (response.success) { onResolve = () => status.onResult({ success: true, logLines: response.logLines, value: jsonToConvex(response.result) }); } else { const errorMessage = response.result; const { errorData } = response; logToConsole("error", udfType, udfPath, errorMessage); onResolve = () => status.onResult({ success: false, errorMessage, errorData: errorData !== void 0 ? jsonToConvex(errorData) : void 0, logLines: response.logLines }); } if (response.type === "ActionResponse" || !response.success) { onResolve(); this.inflightRequests.delete(response.requestId); this.requestsOlderThanRestart.delete(response.requestId); return response.requestId; } requestInfo.status = { status: "Completed", ts: response.ts, onResolve }; return null; } // Remove and returns completed requests. removeCompleted(ts) { const completeRequests = /* @__PURE__ */ new Set(); for (const [requestId, requestInfo] of this.inflightRequests.entries()) { const status = requestInfo.status; if (status.status === "Completed" && status.ts.lessThanOrEqual(ts)) { status.onResolve(); completeRequests.add(requestId); this.inflightRequests.delete(requestId); this.requestsOlderThanRestart.delete(requestId); } } return completeRequests; } restart() { this.requestsOlderThanRestart = new Set(this.inflightRequests.keys()); const allMessages = []; for (const [requestId, value] of this.inflightRequests) { if (value.status.status === "NotSent") { value.status.status = "Requested"; allMessages.push(value.message); continue; } if (value.message.type === "Mutation") { allMessages.push(value.message); } else { this.inflightRequests.delete(requestId); this.requestsOlderThanRestart.delete(requestId); if (value.status.status === "Completed") { throw new Error("Action should never be in 'Completed' state"); } value.status.onResult({ success: false, errorMessage: "Connection lost while action was in flight", logLines: [] }); } } return allMessages; } /** * @returns true if there are any requests that have been requested but have * not be completed yet. */ hasIncompleteRequests() { for (const requestInfo of this.inflightRequests.values()) { if (requestInfo.status.status === "Requested") { return true; } } return false; } /** * @returns true if there are any inflight requests, including ones that have * completed on the server, but have not been applied. */ hasInflightRequests() { return this.inflightRequests.size > 0; } /** * @returns true if there are any inflight requests, that have been hanging around * since prior to the most recent restart. */ hasSyncedPastLastReconnect() { return this.requestsOlderThanRestart.size === 0; } timeOfOldestInflightRequest() { if (this.inflightRequests.size === 0) { return null; } let oldestInflightRequest = Date.now(); for (const request of this.inflightRequests.values()) { if (request.status.status !== "Completed") { if (request.status.requestedAt.getTime() < oldestInflightRequest) { oldestInflightRequest = request.status.requestedAt.getTime(); } } } return new Date(oldestInflightRequest); } } //# sourceMappingURL=request_manager.js.map