Datasourceforcryptocurrency-1 / static /shared /js /page-functionality-bridge.js
Really-amin's picture
Upload static/shared/js/page-functionality-bridge.js with huggingface_hub
ca06d6d verified
Raw
History Blame Contribute Delete
8.89 kB
(function () {
'use strict';
const API = {
providers: '/api/max/providers/status?symbol=BTC',
resources: '/api/max/resources/summary',
pages: '/api/max/pages/functionality',
market: '/api/max/market/snapshot?symbols=BTC,ETH,SOL,BNB,XRP,DOGE,AVAX',
sentiment: '/api/max/social/sentiment?coin=BTC',
kucoin: '/api/max/futures/kucoin/validate/BTCUSDT',
pressure: '/api/max/pressure/status',
fallbackPlan: '/api/max/fallback/plan',
systemVisual: '/api/max/system/visual?symbol=BTC',
help: '/api/max/help'
};
function panel() {
return window.TopServicePanel;
}
function refreshSummary() {
const tsp = panel();
if (!tsp) return;
const parts = window._topServiceSummary || {};
tsp.setSummary(tsp.buildSummary([
`Page: ${tsp.pageId()}`,
parts.bridge,
parts.native
]));
}
function css() {
if (document.getElementById('max-provider-bridge-style')) return;
const style = document.createElement('style');
style.id = 'max-provider-bridge-style';
style.textContent = `
.max-provider-bridge{padding:16px;border:1px solid rgba(148,163,184,.28);border-radius:18px;background:linear-gradient(135deg,rgba(255,255,255,.90),rgba(240,249,255,.75));backdrop-filter:blur(14px);font-family:Inter,system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;color:#0f172a;}
.max-provider-bridge__head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:14px;}
.max-provider-bridge__title{font-size:14px;font-weight:800;letter-spacing:.02em;display:flex;align-items:center;gap:8px;}
.max-provider-bridge__subtitle{font-size:11px;color:#64748b;margin-top:2px;}
.max-provider-bridge__grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;}
.max-provider-bridge__card{padding:12px;border-radius:14px;background:rgba(255,255,255,.76);border:1px solid rgba(226,232,240,.85);min-height:74px;}
.max-provider-bridge__label{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:#64748b;font-weight:800;}
.max-provider-bridge__value{font-size:22px;font-weight:900;margin-top:4px;color:#111827;}
.max-provider-bridge__value.small{font-size:13px;line-height:1.35;word-break:break-word;}
.max-provider-bridge__pill{display:inline-flex;align-items:center;gap:6px;padding:5px 9px;border-radius:999px;font-size:10px;font-weight:800;border:1px solid rgba(16,185,129,.26);background:#ecfdf5;color:#047857;}
.max-provider-bridge__dot{width:7px;height:7px;border-radius:999px;background:#10b981;box-shadow:0 0 0 4px rgba(16,185,129,.14);animation:maxProviderPulse 1.8s ease-in-out infinite;}
.max-provider-bridge__links{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px;}
.max-provider-bridge__links a{font-size:11px;font-weight:700;text-decoration:none;color:#2563eb;background:#eff6ff;border:1px solid #bfdbfe;border-radius:999px;padding:5px 9px;}
.max-provider-bridge__warn{font-size:11px;color:#92400e;background:#fffbeb;border:1px solid #fde68a;border-radius:10px;padding:8px 10px;margin-top:10px;}
@keyframes maxProviderPulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.48;transform:scale(.82)}}
@media(max-width:900px){.max-provider-bridge__grid{grid-template-columns:repeat(2,minmax(0,1fr));}.max-provider-bridge{padding:12px}}
@media(max-width:540px){.max-provider-bridge__grid{grid-template-columns:1fr}}
`;
document.head.appendChild(style);
}
async function getJson(url) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 12000);
try {
const res = await fetch(url, { signal: controller.signal, headers: { Accept: 'application/json' } });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} finally {
clearTimeout(timer);
}
}
function render(state) {
css();
const tsp = panel();
if (!tsp || document.getElementById('max-provider-bridge-section')) return;
const providers = state.providers || {};
const resources = state.resources || {};
const market = state.market || {};
const sentiment = state.sentiment || {};
const kucoin = state.kucoin || {};
const prices = Array.isArray(market.items) ? market.items.filter(x => x && x.success) : [];
const bestPrice = prices[0];
const topSource = bestPrice
? `${bestPrice.symbol || 'BTC'} ${bestPrice.price ? '$' + Number(bestPrice.price).toLocaleString() : ''} · ${bestPrice.source || 'source'}`
: 'No live market response yet';
const fng = sentiment.fear_greed && sentiment.fear_greed.ok ? sentiment.fear_greed.data : null;
const html = `
<section id="max-provider-bridge" class="max-provider-bridge">
<div class="max-provider-bridge__head">
<div>
<div class="max-provider-bridge__title">⚡ Live Provider Bridge <span class="max-provider-bridge__pill"><span class="max-provider-bridge__dot"></span> functional layer</span></div>
<div class="max-provider-bridge__subtitle">Connected to the maximum-provider API layer. Page: <strong>${tsp.pageId()}</strong></div>
</div>
<div class="max-provider-bridge__pill">/api/max</div>
</div>
<div class="max-provider-bridge__grid">
<div class="max-provider-bridge__card"><div class="max-provider-bridge__label">Providers</div><div class="max-provider-bridge__value">${providers.healthy_count || 0}/${providers.probed_count || 0}</div></div>
<div class="max-provider-bridge__card"><div class="max-provider-bridge__label">Registry</div><div class="max-provider-bridge__value">${((resources.summary || {}).comprehensive_resources || 0) + ((resources.summary || {}).unified_registry_entries || 0)}</div></div>
<div class="max-provider-bridge__card"><div class="max-provider-bridge__label">Market sample</div><div class="max-provider-bridge__value small">${topSource}</div></div>
<div class="max-provider-bridge__card"><div class="max-provider-bridge__label">Futures / Sentiment</div><div class="max-provider-bridge__value small">KuCoin: ${kucoin.validated ? 'validated' : 'not validated yet'}<br>F&G: ${fng ? `${fng.value} ${fng.classification || ''}` : 'pending'}</div></div>
</div>
<div class="max-provider-bridge__links">
<a href="/api/max/providers/status?include_slow=true" target="_blank" rel="noreferrer">All provider health</a>
<a href="/api/max/fallback/plan" target="_blank" rel="noreferrer">Fallback plan</a>
<a href="/api/max/pressure/status" target="_blank" rel="noreferrer">Pressure status</a>
<a href="/api/max/resources/summary" target="_blank" rel="noreferrer">Resource registry</a>
<a href="/api/max/market/snapshot" target="_blank" rel="noreferrer">Market snapshot</a>
<a href="/api/max/trading/ohlcv/BTCUSDT" target="_blank" rel="noreferrer">BTC OHLCV</a>
<a href="/api/max/trading/orderbook/BTCUSDT" target="_blank" rel="noreferrer">BTC orderbook</a>
<a href="/api/max/futures/kucoin/validate/BTCUSDT" target="_blank" rel="noreferrer">KuCoin futures</a>
<a href="/api/max/system/visual?symbol=BTC" target="_blank" rel="noreferrer">System visual API</a>
<a href="/api/max/help" target="_blank" rel="noreferrer">Max API help</a>
</div>
${providers.down_count ? `<div class="max-provider-bridge__warn">${providers.down_count} provider probe(s) failed on this check; fallbacks remain available through the chain.</div>` : ''}
</section>
`;
tsp.mountSection('max-provider-bridge-section', '', html);
window._topServiceSummary = window._topServiceSummary || {};
window._topServiceSummary.bridge = `Providers ${providers.healthy_count || 0}/${providers.probed_count || 0}`;
refreshSummary();
}
async function boot() {
const tsp = panel();
if (!tsp || tsp.shouldSkip()) return;
tsp.ensure(`Page: ${tsp.pageId()} · Loading…`);
const state = {};
const jobs = [
['providers', API.providers],
['resources', API.resources],
['pages', API.pages],
['market', API.market],
['sentiment', API.sentiment],
['kucoin', API.kucoin]
];
await Promise.all(jobs.map(async ([key, url]) => {
try { state[key] = await getJson(url); }
catch (error) { state[key] = { success: false, error: String(error && error.message || error) }; }
}));
render(state);
window.MAX_PROVIDER_BRIDGE_STATE = state;
}
function start() {
if (!window.TopServicePanel) {
console.warn('TopServicePanel not loaded; bridge panel skipped');
return;
}
boot();
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start);
else start();
})();