3dai / fallback_bridge.js
broyang's picture
Claude Opus 5.5
Gate generations behind webapp grants and a public free limit
1ac53f4
Raw History Blame Contribute Delete
2.79 kB
(trigger, receipt) => {
const PENDING_KEY = "__labs3daiFallbackPending";
const ALLOWED_PARENTS = __LABS_EMBED_PARENTS__;
const ticket = receipt && typeof receipt === "object" ? receipt.ticket : null;
const parentOrigin = new URLSearchParams(location.search).get("__labs_parent");
const ack = extra => Object.assign({ticket: ticket}, extra);
const skip = reason => [ack({no_fallback: true, reason: reason}), receipt];
if (window.parent === window) return skip("no_parent_frame");
if (!ALLOWED_PARENTS.includes(parentOrigin)) return skip("parent_not_allowed");
if (typeof ticket !== "string" || !ticket || ticket.length > 4096) return skip("no_ticket");
const pending = (window[PENDING_KEY] = window[PENDING_KEY] || new Map());
if (pending.has(ticket)) return pending.get(ticket);
const requestId = typeof crypto.randomUUID === "function"
? crypto.randomUUID()
: `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}`;
const imageInput = document.querySelector('input[type="file"]');
const promise = new Promise(resolve => {
let settled = false;
const settle = ackValue => {
if (settled) return;
settled = true;
clearTimeout(timer);
window.removeEventListener("message", receive);
window.removeEventListener("pagehide", cancel);
imageInput?.removeEventListener("change", cancel);
document.removeEventListener("click", onClear, true);
pending.delete(ticket);
resolve([ackValue, receipt]);
};
const cancel = () => settle(ack({cancelled: true}));
const onClear = event => {
if (event.target.closest?.('button[aria-label="Remove Image"], button[aria-label="Clear"], table[role="grid"] tbody tr')) cancel();
};
const receive = event => {
if (event.source !== window.parent || event.origin !== parentOrigin) return;
const data = event.data;
if (!data || data.type !== "labs:3dai-result" || data.requestId !== requestId) return;
if (data.cancelled) return cancel();
if (data.error) return settle(ack({error: String(data.error)}));
if (data.ready === true) return settle(ack({ready: true}));
};
const timer = setTimeout(cancel, 120000);
window.addEventListener("message", receive);
window.addEventListener("pagehide", cancel, {once: true});
imageInput?.addEventListener("change", cancel, {once: true});
document.addEventListener("click", onClear, true);
window.parent.postMessage({type: "labs:3dai-fallback", requestId, ticket}, parentOrigin);
});
pending.set(ticket, promise);
return promise;
}