plano/demos/use_cases/chatgpt-preference-model-selector/src/scripts/pageFetchOverride.js

62 lines
1.8 KiB
JavaScript
Raw Normal View History

(function() {
const TAG = '[ModelSelector][Page]';
console.log(`${TAG} installing fetch override`);
const origFetch = window.fetch;
window.fetch = async function(input, init = {}) {
const urlString = typeof input === 'string' ? input : input.url;
const urlObj = new URL(urlString, window.location.origin);
const pathname = urlObj.pathname;
console.log(`${TAG} fetch →`, pathname);
const method = (init.method || 'GET').toUpperCase();
if (method === 'OPTIONS') {
console.log(`${TAG} OPTIONS request → bypassing completely`);
return origFetch(input, init);
}
// Only intercept conversation fetches
if (pathname === '/backend-api/conversation') {
console.log(`${TAG} matched → proxy via content script`);
const { port1, port2 } = new MessageChannel();
// ✅ Remove non-cloneable properties like 'signal'
const safeInit = { ...init };
delete safeInit.signal;
// Forward the fetch details to the content script
window.postMessage({
type: 'ARCHGW_FETCH',
url: urlString,
init: safeInit
}, '*', [port2]);
// Return a stream response that the content script will fulfill
return new Response(new ReadableStream({
start(controller) {
port1.onmessage = ({ data }) => {
if (data.done) {
controller.close();
port1.close();
} else {
controller.enqueue(new Uint8Array(data.chunk));
}
};
},
cancel() {
port1.close();
}
}), {
headers: { 'Content-Type': 'text/event-stream' }
});
}
// Otherwise, pass through to the original fetch
return origFetch(input, init);
};
console.log(`${TAG} fetch override installed`);
})();