llamameta commited on
Commit
9f207c1
·
verified ·
1 Parent(s): ee02509

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +173 -19
index.html CHANGED
@@ -1,19 +1,173 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="id">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
6
+ <title>GPT-5</title>
7
+
8
+ <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
9
+ <meta http-equiv="Pragma" content="no-cache">
10
+ <meta http-equiv="Expires" content="0">
11
+
12
+ <style>
13
+ html, body { margin: 0; padding: 0; width: 100%; height: 100%; }
14
+ #loading {
15
+ position: fixed; inset: 0; background: rgba(255,255,255,0.9);
16
+ display: flex; justify-content: center; align-items: center;
17
+ font-size: 18px; z-index: 1000;
18
+ }
19
+ iframe { width: 100%; height: 100vh; border: none; }
20
+ </style>
21
+ </head>
22
+ <body>
23
+ <div id="loading">Please wait... Memilih server optimal...</div>
24
+ <iframe id="streamlit-frame" referrerpolicy="no-referrer"></iframe>
25
+
26
+ <script>
27
+ const VERSION = "v1";
28
+ const SERVERS = [
29
+ "https://gepatest-hwak3xkal5nltlveztf5nn.streamlit.app/?embed=true"
30
+ ];
31
+
32
+ // Timeout definisi
33
+ const pingTimeoutMs = 5000; // timeout ping img
34
+ const iframeLoadTimeoutMs = 12000; // waktu nunggu iframe dianggap "siap"
35
+ const overallTryTimeoutMs = 20000; // batas keras setiap percobaan server
36
+
37
+ // Ping ringan via <img> untuk menghindari no-cors opaque fetch
38
+ function ping(url, timeout = pingTimeoutMs) {
39
+ return new Promise((resolve) => {
40
+ const start = performance.now();
41
+ const img = new Image();
42
+ let done = false;
43
+
44
+ const timer = setTimeout(() => {
45
+ if (done) return;
46
+ done = true;
47
+ // Timeout dianggap gagal (Infinity)
48
+ resolve({ url, ok: false, latency: Infinity });
49
+ img.src = ""; // abort
50
+ }, timeout);
51
+
52
+ const onComplete = (ok) => {
53
+ if (done) return;
54
+ done = true;
55
+ clearTimeout(timer);
56
+ const latency = performance.now() - start;
57
+ resolve({ url, ok, latency });
58
+ };
59
+
60
+ img.onload = () => onComplete(true);
61
+ img.onerror = () => onComplete(false);
62
+
63
+ // Gunakan endpoint root dengan cache buster (Streamlit akan render HTML, img akan gagal, tapi kita tetap dapat latency)
64
+ // Trik: walau img gagal (onerror), kita catat latency untuk RTT awal.
65
+ // Tambah cb agar tidak cached.
66
+ const u = new URL(url);
67
+ u.searchParams.set("cb", Date.now().toString());
68
+ img.src = u.toString();
69
+ });
70
+ }
71
+
72
+ async function rankServersByPing(urls) {
73
+ const results = await Promise.all(urls.map(u => ping(u)));
74
+ // Urutkan berdasarkan latency terkecil
75
+ return results
76
+ .sort((a,b) => a.latency - b.latency)
77
+ .map(r => r.url);
78
+ }
79
+
80
+ function setIframeSrc(iframe, baseUrl) {
81
+ const u = new URL(baseUrl);
82
+ u.searchParams.set("cb", Date.now().toString());
83
+ iframe.src = u.toString();
84
+ }
85
+
86
+ // Coba load satu server dengan mekanisme timeout. Kembalikan true jika dianggap siap, false jika gagal.
87
+ function tryLoadServer(iframe, url) {
88
+ return new Promise((resolve) => {
89
+ let settled = false;
90
+
91
+ // Hard timeout untuk satu percobaan
92
+ const hardTimer = setTimeout(() => {
93
+ if (settled) return;
94
+ settled = true;
95
+ resolve(false);
96
+ }, overallTryTimeoutMs);
97
+
98
+ // Timer "app-ready" (karena onload bisa sukses walau app error)
99
+ const readyTimer = setTimeout(() => {
100
+ if (settled) return;
101
+ // Lewati: tidak ada sinyal ready; anggap gagal
102
+ settled = true;
103
+ clearTimeout(hardTimer);
104
+ resolve(false);
105
+ }, iframeLoadTimeoutMs);
106
+
107
+ // onload: dokumen termuat. Namun belum tentu app sehat.
108
+ iframe.onload = () => {
109
+ // Tetap menunggu sampai readyTimer. Jika Anda punya postMessage dari app,
110
+ // di sini seharusnya menunggu pesan "ready" untuk resolve(true).
111
+ // Karena tidak ada, kita pakai heuristik: beri sedikit grace period lalu anggap OK.
112
+ // Grace singkat agar tidak menunggu lama kalau memang error.
113
+ setTimeout(() => {
114
+ if (settled) return;
115
+ settled = true;
116
+ clearTimeout(readyTimer);
117
+ clearTimeout(hardTimer);
118
+ resolve(true);
119
+ }, 1500); // grace 1.5s setelah onload
120
+ };
121
+
122
+ // onerror hanya terjadi untuk kegagalan jaringan keras
123
+ iframe.onerror = () => {
124
+ if (settled) return;
125
+ settled = true;
126
+ clearTimeout(readyTimer);
127
+ clearTimeout(hardTimer);
128
+ resolve(false);
129
+ };
130
+
131
+ setIframeSrc(iframe, url);
132
+ });
133
+ }
134
+
135
+ async function loadWithFallback() {
136
+ const iframe = document.getElementById("streamlit-frame");
137
+ const loading = document.getElementById("loading");
138
+ const storageKey = `streamlitUrl_${VERSION}`;
139
+
140
+ // Coba baca cache sebelumnya
141
+ const cached = sessionStorage.getItem(storageKey);
142
+
143
+ // Urutkan server berdasarkan ping (kasih prioritas yang lebih cepat).
144
+ let prioritized = await rankServersByPing(SERVERS);
145
+
146
+ // Jika ada cache, letakkan di depan daftar supaya dicoba dulu
147
+ if (cached && prioritized.includes(cached)) {
148
+ prioritized = [cached, ...prioritized.filter(u => u !== cached)];
149
+ }
150
+
151
+ for (const url of prioritized) {
152
+ const ok = await tryLoadServer(iframe, url);
153
+ if (ok) {
154
+ // Anggap server siap. Simpan ke sessionStorage.
155
+ sessionStorage.setItem(storageKey, url);
156
+ loading.style.display = "none";
157
+ // Pasang watchdog: jika nanti ada kegagalan reload (jarang), bersihkan cache.
158
+ iframe.addEventListener('error', () => {
159
+ sessionStorage.removeItem(storageKey);
160
+ });
161
+ return;
162
+ }
163
+ }
164
+
165
+ // Semua gagal: bersihkan cache dan tampilkan pesan sederhana
166
+ sessionStorage.removeItem(storageKey);
167
+ loading.textContent = "Semua server gagal dimuat. Coba refresh halaman.";
168
+ }
169
+
170
+ window.addEventListener("load", loadWithFallback);
171
+ </script>
172
+ </body>
173
+ </html>