Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
64 lines
No EOL
2.3 KiB
Text
64 lines
No EOL
2.3 KiB
Text
/**
|
|
* Shared utilities for MCP tools that communicate with the browser.
|
|
* This module provides a common infrastructure for request-response
|
|
* communication between MCP endpoints and browser sessions via HMR.
|
|
*/ import { nanoid } from 'next/dist/compiled/nanoid';
|
|
export const DEFAULT_BROWSER_REQUEST_TIMEOUT_MS = 5000;
|
|
const pendingRequests = new Map();
|
|
export function createBrowserRequest(messageType, sendHmrMessage, getActiveConnectionCount, timeoutMs) {
|
|
const connectionCount = getActiveConnectionCount();
|
|
if (connectionCount === 0) {
|
|
return Promise.resolve([]);
|
|
}
|
|
const requestId = `mcp-${messageType}-${nanoid()}`;
|
|
const responsePromise = new Promise((resolve, reject)=>{
|
|
const timeout = setTimeout(()=>{
|
|
const pending = pendingRequests.get(requestId);
|
|
if (pending && pending.responses.length > 0) {
|
|
resolve(pending.responses);
|
|
} else {
|
|
reject(Object.defineProperty(new Error(`Timeout waiting for response from frontend. The browser may not be responding to HMR messages.`), "__NEXT_ERROR_CODE", {
|
|
value: "E825",
|
|
enumerable: false,
|
|
configurable: true
|
|
}));
|
|
}
|
|
pendingRequests.delete(requestId);
|
|
}, timeoutMs);
|
|
pendingRequests.set(requestId, {
|
|
responses: [],
|
|
expectedCount: connectionCount,
|
|
resolve: resolve,
|
|
reject,
|
|
timeout
|
|
});
|
|
});
|
|
sendHmrMessage({
|
|
type: messageType,
|
|
requestId
|
|
});
|
|
return responsePromise;
|
|
}
|
|
export function handleBrowserPageResponse(requestId, data, url) {
|
|
if (!url) {
|
|
throw Object.defineProperty(new Error('URL is required in MCP browser response. This is a bug in Next.js.'), "__NEXT_ERROR_CODE", {
|
|
value: "E824",
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
}
|
|
const pending = pendingRequests.get(requestId);
|
|
if (pending) {
|
|
pending.responses.push({
|
|
url,
|
|
data
|
|
});
|
|
if (pending.responses.length >= pending.expectedCount) {
|
|
clearTimeout(pending.timeout);
|
|
pending.resolve(pending.responses);
|
|
pendingRequests.delete(requestId);
|
|
}
|
|
}
|
|
}
|
|
|
|
//# sourceMappingURL=browser-communication.js.map |