Development #24
@@ -39,9 +39,10 @@ export const Route = createFileRoute("/api/events/$")({
|
||||
serverEvents.on(type, handleEvent);
|
||||
}
|
||||
|
||||
// Under the shortest idle timeout observed on proxies/PWA paths.
|
||||
const pingInterval = setInterval(() => {
|
||||
send({ type: "ping", timestamp: Date.now() });
|
||||
}, 15000);
|
||||
}, 8000);
|
||||
|
||||
cleanup = () => {
|
||||
if (cleanedUp) return;
|
||||
|
||||
@@ -17,19 +17,37 @@ const recentErrors = new Map<string, number>();
|
||||
|
||||
const isEnabled = (): boolean => typeof window !== "undefined";
|
||||
|
||||
const getSessionId = (): string => {
|
||||
// A session ends after 30 idle minutes, not when the tab closes — installed
|
||||
// PWAs keep sessionStorage alive for days.
|
||||
const SESSION_IDLE_MS = 30 * 60 * 1000;
|
||||
const SESSION_KEY = "flxn-tsid";
|
||||
|
||||
const readSession = (): { id: string; t: number } | null => {
|
||||
try {
|
||||
let id = sessionStorage.getItem("flxn-tsid");
|
||||
if (!id) {
|
||||
id = crypto.randomUUID();
|
||||
sessionStorage.setItem("flxn-tsid", id);
|
||||
const raw = sessionStorage.getItem(SESSION_KEY);
|
||||
if (!raw) return null;
|
||||
const parsed = JSON.parse(raw);
|
||||
if (typeof parsed?.id === "string" && typeof parsed?.t === "number") {
|
||||
return parsed;
|
||||
}
|
||||
return id;
|
||||
return null;
|
||||
} catch {
|
||||
return "anon-session";
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const touchSession = () => {
|
||||
try {
|
||||
const now = Date.now();
|
||||
const current = readSession();
|
||||
const id =
|
||||
current && now - current.t <= SESSION_IDLE_MS ? current.id : crypto.randomUUID();
|
||||
sessionStorage.setItem(SESSION_KEY, JSON.stringify({ id, t: now }));
|
||||
} catch {}
|
||||
};
|
||||
|
||||
const getSessionId = (): string => readSession()?.id ?? "anon-session";
|
||||
|
||||
const location = (): { path: string; routeId?: string } => ({
|
||||
path: window.location.pathname,
|
||||
routeId: lastRouteId,
|
||||
@@ -64,6 +82,7 @@ const flush = (useBeacon = false) => {
|
||||
|
||||
const enqueue = (event: QueuedEvent) => {
|
||||
if (!isEnabled()) return;
|
||||
touchSession();
|
||||
queue.push(event);
|
||||
if (queue.length >= FLUSH_AT) {
|
||||
flush();
|
||||
|
||||
Reference in New Issue
Block a user