Skip to content

Commit 0705e19

Browse files
author
devsamikhan
committed
feat(live-reload): introduce zero-SDK real-time Live Hot-Reload system for mobile and desktop
1 parent 8568f69 commit 0705e19

11 files changed

Lines changed: 867 additions & 5 deletions

File tree

Binary file not shown.

‎flagship_projects/08_aether_chronopulse_alarm/ChronoPulse.html‎

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,131 @@
192192
};
193193

194194
window.Aether = Aether;
195+
196+
// =========================================================================
197+
// AETHER Live Hot-Reload Client Engine (Zero-SDK Fast Refresh)
198+
// =========================================================================
199+
(function initLiveHotReload() {
200+
if (typeof window === "undefined") return;
201+
202+
const devPort = 8080;
203+
const devHost = "http://127.0.0.1:" + devPort;
204+
let currentVersion = 0;
205+
let isConnected = false;
206+
let badgeEl = null;
207+
208+
function getOrCreateBadge() {
209+
if (badgeEl) return badgeEl;
210+
badgeEl = document.createElement("div");
211+
badgeEl.id = "aether-live-hud-pill";
212+
badgeEl.style.cssText = "position:fixed;top:16px;right:16px;z-index:9999999;font-family:'Plus Jakarta Sans',system-ui,sans-serif;font-size:11px;font-weight:700;letter-spacing:0.04em;padding:6px 14px;border-radius:20px;display:flex;align-items:center;gap:7px;transition:all 0.3s cubic-bezier(0.16,1,0.3,1);box-shadow:0 6px 20px rgba(0,0,0,0.5);pointer-events:none;opacity:0;transform:translateY(-10px);backdrop-filter:blur(8px);";
213+
document.body.appendChild(badgeEl);
214+
return badgeEl;
215+
}
216+
217+
function flashBadge(text, bg, fg, border, duration = 3000) {
218+
const b = getOrCreateBadge();
219+
b.innerHTML = `<span style="display:inline-block;width:7px;height:7px;border-radius:50%;background:${fg};box-shadow:0 0 10px ${fg};animation:pulse 1.4s infinite;"></span> ${text}`;
220+
b.style.background = bg;
221+
b.style.color = fg;
222+
b.style.border = `1px solid ${border}`;
223+
b.style.opacity = "1";
224+
b.style.transform = "translateY(0)";
225+
if (duration > 0) {
226+
setTimeout(() => {
227+
b.style.opacity = "0";
228+
b.style.transform = "translateY(-10px)";
229+
}, duration);
230+
}
231+
}
232+
233+
function preserveUiState() {
234+
try {
235+
const state = {
236+
scrollX: window.scrollX,
237+
scrollY: window.scrollY,
238+
ts: Date.now()
239+
};
240+
sessionStorage.setItem("__aether_live_ui_state__", JSON.stringify(state));
241+
} catch(e) {}
242+
}
243+
244+
function restoreUiState() {
245+
try {
246+
const raw = sessionStorage.getItem("__aether_live_ui_state__");
247+
if (raw) {
248+
const state = JSON.parse(raw);
249+
if (Date.now() - state.ts < 12000) {
250+
window.scrollTo(state.scrollX, state.scrollY);
251+
}
252+
sessionStorage.removeItem("__aether_live_ui_state__");
253+
}
254+
} catch(e) {}
255+
}
256+
257+
if (document.readyState === "loading") {
258+
document.addEventListener("DOMContentLoaded", restoreUiState);
259+
} else {
260+
restoreUiState();
261+
}
262+
263+
async function checkServer() {
264+
try {
265+
const res = await fetch(`${devHost}/api/live-status`, { cache: "no-store", mode: "cors" });
266+
if (res.ok) {
267+
const data = await res.json();
268+
if (!isConnected) {
269+
isConnected = true;
270+
currentVersion = data.version || 1;
271+
flashBadge("AETHER LIVE CONNECTED", "rgba(5, 46, 22, 0.92)", "#4ade80", "rgba(74, 222, 128, 0.4)", 3200);
272+
startPollingLoop();
273+
}
274+
}
275+
} catch(e) {
276+
setTimeout(checkServer, 3500);
277+
}
278+
}
279+
280+
async function startPollingLoop() {
281+
try {
282+
const res = await fetch(`${devHost}/api/live-poll?v=${currentVersion}`, { cache: "no-store", mode: "cors" });
283+
if (res.ok) {
284+
const data = await res.json();
285+
if (data.reload && data.version > currentVersion) {
286+
currentVersion = data.version;
287+
executeHotReload(data.file || "assets");
288+
return;
289+
}
290+
}
291+
} catch(e) {
292+
isConnected = false;
293+
setTimeout(checkServer, 2000);
294+
return;
295+
}
296+
setTimeout(startPollingLoop, 150);
297+
}
298+
299+
function executeHotReload(fileName) {
300+
flashBadge(`HOT-RELOAD • ${fileName}`, "rgba(15, 23, 42, 0.95)", "#38bdf8", "rgba(56, 189, 248, 0.6)", 0);
301+
preserveUiState();
302+
303+
if (window.Aether && window.Aether.hapticFeedback) {
304+
window.Aether.hapticFeedback("light");
305+
}
306+
307+
if (window.location.protocol === "file:" && isConnected) {
308+
setTimeout(() => {
309+
window.location.href = `${devHost}/index.html`;
310+
}, 80);
311+
} else {
312+
setTimeout(() => {
313+
window.location.reload();
314+
}, 80);
315+
}
316+
}
317+
318+
setTimeout(checkServer, 150);
319+
})();
195320
})(typeof window !== "undefined" ? window : globalThis);
196321

197322
</script>

‎flagship_projects/08_aether_chronopulse_alarm/frontend/aether_bridge.js‎

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,129 @@
128128
};
129129

130130
window.Aether = Aether;
131+
132+
// =========================================================================
133+
// AETHER Live Hot-Reload Client Engine (Zero-SDK Fast Refresh)
134+
// =========================================================================
135+
(function initLiveHotReload() {
136+
if (typeof window === "undefined") return;
137+
138+
const devPort = 8080;
139+
const devHost = "http://127.0.0.1:" + devPort;
140+
let currentVersion = 0;
141+
let isConnected = false;
142+
let badgeEl = null;
143+
144+
function getOrCreateBadge() {
145+
if (badgeEl) return badgeEl;
146+
badgeEl = document.createElement("div");
147+
badgeEl.id = "aether-live-hud-pill";
148+
badgeEl.style.cssText = "position:fixed;top:16px;right:16px;z-index:9999999;font-family:'Plus Jakarta Sans',system-ui,sans-serif;font-size:11px;font-weight:700;letter-spacing:0.04em;padding:6px 14px;border-radius:20px;display:flex;align-items:center;gap:7px;transition:all 0.3s cubic-bezier(0.16,1,0.3,1);box-shadow:0 6px 20px rgba(0,0,0,0.5);pointer-events:none;opacity:0;transform:translateY(-10px);backdrop-filter:blur(8px);";
149+
document.body.appendChild(badgeEl);
150+
return badgeEl;
151+
}
152+
153+
function flashBadge(text, bg, fg, border, duration = 3000) {
154+
const b = getOrCreateBadge();
155+
b.innerHTML = `<span style="display:inline-block;width:7px;height:7px;border-radius:50%;background:${fg};box-shadow:0 0 10px ${fg};animation:pulse 1.4s infinite;"></span> ${text}`;
156+
b.style.background = bg;
157+
b.style.color = fg;
158+
b.style.border = `1px solid ${border}`;
159+
b.style.opacity = "1";
160+
b.style.transform = "translateY(0)";
161+
if (duration > 0) {
162+
setTimeout(() => {
163+
b.style.opacity = "0";
164+
b.style.transform = "translateY(-10px)";
165+
}, duration);
166+
}
167+
}
168+
169+
function preserveUiState() {
170+
try {
171+
const state = {
172+
scrollX: window.scrollX,
173+
scrollY: window.scrollY,
174+
ts: Date.now()
175+
};
176+
sessionStorage.setItem("__aether_live_ui_state__", JSON.stringify(state));
177+
} catch(e) {}
178+
}
179+
180+
function restoreUiState() {
181+
try {
182+
const raw = sessionStorage.getItem("__aether_live_ui_state__");
183+
if (raw) {
184+
const state = JSON.parse(raw);
185+
if (Date.now() - state.ts < 12000) {
186+
window.scrollTo(state.scrollX, state.scrollY);
187+
}
188+
sessionStorage.removeItem("__aether_live_ui_state__");
189+
}
190+
} catch(e) {}
191+
}
192+
193+
if (document.readyState === "loading") {
194+
document.addEventListener("DOMContentLoaded", restoreUiState);
195+
} else {
196+
restoreUiState();
197+
}
198+
199+
async function checkServer() {
200+
try {
201+
const res = await fetch(`${devHost}/api/live-status`, { cache: "no-store", mode: "cors" });
202+
if (res.ok) {
203+
const data = await res.json();
204+
if (!isConnected) {
205+
isConnected = true;
206+
currentVersion = data.version || 1;
207+
flashBadge("AETHER LIVE CONNECTED", "rgba(5, 46, 22, 0.92)", "#4ade80", "rgba(74, 222, 128, 0.4)", 3200);
208+
startPollingLoop();
209+
}
210+
}
211+
} catch(e) {
212+
setTimeout(checkServer, 3500);
213+
}
214+
}
215+
216+
async function startPollingLoop() {
217+
try {
218+
const res = await fetch(`${devHost}/api/live-poll?v=${currentVersion}`, { cache: "no-store", mode: "cors" });
219+
if (res.ok) {
220+
const data = await res.json();
221+
if (data.reload && data.version > currentVersion) {
222+
currentVersion = data.version;
223+
executeHotReload(data.file || "assets");
224+
return;
225+
}
226+
}
227+
} catch(e) {
228+
isConnected = false;
229+
setTimeout(checkServer, 2000);
230+
return;
231+
}
232+
setTimeout(startPollingLoop, 150);
233+
}
234+
235+
function executeHotReload(fileName) {
236+
flashBadge(`HOT-RELOAD • ${fileName}`, "rgba(15, 23, 42, 0.95)", "#38bdf8", "rgba(56, 189, 248, 0.6)", 0);
237+
preserveUiState();
238+
239+
if (window.Aether && window.Aether.hapticFeedback) {
240+
window.Aether.hapticFeedback("light");
241+
}
242+
243+
if (window.location.protocol === "file:" && isConnected) {
244+
setTimeout(() => {
245+
window.location.href = `${devHost}/index.html`;
246+
}, 80);
247+
} else {
248+
setTimeout(() => {
249+
window.location.reload();
250+
}, 80);
251+
}
252+
}
253+
254+
setTimeout(checkServer, 150);
255+
})();
131256
})(typeof window !== "undefined" ? window : globalThis);

‎flagship_projects/08_aether_chronopulse_alarm/frontend/index.html‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@
8181
<div>
8282
<div class="flex items-center gap-2">
8383
<h1 class="text-2xl font-black tracking-tight text-white">ChronoPulse</h1>
84-
<span class="px-2.5 py-0.5 text-[10px] font-black tracking-wider uppercase rounded-full bg-cyan-500/20 text-cyan-300 border border-cyan-500/30">
85-
AETHER 2.0
84+
<span class="px-2.5 py-0.5 text-[10px] font-black tracking-wider uppercase rounded-full bg-emerald-500/20 text-emerald-300 border border-emerald-500/30 shadow-sm shadow-emerald-500/20">
85+
⚡ LIVE HOT-RELOAD
8686
</span>
8787
</div>
8888
<p class="text-xs text-slate-400 font-medium">Cognitive Awakening & Multi-Sensory Circadian System</p>

0 commit comments

Comments
 (0)