Refactor server and API handler for improved error handling and routing logic. Updated request handling to use Incoming type and added HTTP/1.1 restriction. Enhanced splash screen logic in the frontend to manage routing based on onboarding and setup states. Fixed WebSocket client initialization to ensure lazy loading and error handling. Cleaned up unused imports and variables across multiple files.

This commit is contained in:
zazawowow
2026-01-24 23:09:46 +00:00
parent 731cd67cfb
commit c293bd9880
37 changed files with 426 additions and 30 deletions

View File

@@ -82,7 +82,7 @@ define(['./workbox-21a80088'], (function (workbox) { 'use strict';
"revision": "3ca0b8505b4bec776b69afdba2768812"
}, {
"url": "index.html",
"revision": "0.gms2imfkopo"
"revision": "0.s5ijqrr5ss"
}], {});
workbox.cleanupOutdatedCaches();
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {

View File

@@ -35,8 +35,12 @@ onMounted(() => {
if (seenIntro || isDirectRoute) {
showSplash.value = false
document.body.classList.add('splash-complete')
// Set isReady immediately for direct routes or when intro is already seen
// Router will handle navigation
isReady.value = true
}
// If splash should show, wait for it to complete
// SplashScreen will emit 'complete' which calls handleSplashComplete
})
/**
@@ -47,13 +51,38 @@ function handleSplashComplete() {
showSplash.value = false
document.body.classList.add('splash-complete')
// Determine destination based on onboarding status
const seenOnboarding = localStorage.getItem('neode_onboarding_complete') === '1'
const destination = seenOnboarding ? '/login' : '/onboarding/intro'
// Set isReady first so RouterView can render
isReady.value = true
// Route immediately for seamless video transition (no delay needed)
router.push(destination).then(() => {
// Mark as ready after navigation completes
// Determine destination based on onboarding status and dev mode
const devMode = import.meta.env.VITE_DEV_MODE
const seenOnboarding = localStorage.getItem('neode_onboarding_complete') === '1'
const isSetup = localStorage.getItem('neode_setup_complete') === '1'
let destination = '/'
// Setup mode: always go to login
if (devMode === 'setup') {
destination = '/login'
}
// Onboarding mode: go to onboarding if not seen
else if (devMode === 'onboarding') {
destination = seenOnboarding ? '/login' : '/onboarding/intro'
}
// Existing user mode: go to login
else if (devMode === 'existing') {
destination = '/login'
}
// Default: check onboarding status
else {
destination = seenOnboarding ? '/login' : '/onboarding/intro'
}
// Route after a brief delay to ensure RouterView is mounted
// The router's redirect will handle the actual navigation
router.push(destination).catch(err => {
console.error('Navigation error:', err)
// Still show the app even if navigation fails
isReady.value = true
})
}

View File

@@ -232,15 +232,19 @@ let wsClientInstance: WebSocketClient | null = null
function getWebSocketClient(): WebSocketClient {
if (typeof window === 'undefined') {
// SSR - create new instance
return new WebSocketClient()
if (!wsClientInstance) {
wsClientInstance = new WebSocketClient()
}
return wsClientInstance
}
// Check if we have a persisted instance from HMR
if ((window as any).__archipelago_ws_client && (window as any).__archipelago_ws_client.ws) {
const existing = (window as any).__archipelago_ws_client
const existing = (window as any).__archipelago_ws_client
if (existing && existing instanceof WebSocketClient) {
// Check if the WebSocket is still valid
if (existing.ws && existing.ws.readyState === WebSocket.OPEN) {
console.log('[WebSocket] Using existing connected client from HMR')
wsClientInstance = existing
return existing
}
}
@@ -248,14 +252,32 @@ function getWebSocketClient(): WebSocketClient {
// Create new instance
if (!wsClientInstance) {
wsClientInstance = new WebSocketClient()
(window as any).__archipelago_ws_client = wsClientInstance
if (typeof window !== 'undefined') {
(window as any).__archipelago_ws_client = wsClientInstance
}
console.log('[WebSocket] Created new client instance')
}
return wsClientInstance
}
export const wsClient = getWebSocketClient()
// Lazy initialization - only create when accessed
let _wsClient: WebSocketClient | null = null
export const wsClient: WebSocketClient = (() => {
if (_wsClient) {
return _wsClient
}
try {
_wsClient = getWebSocketClient()
return _wsClient
} catch (error) {
console.error('[WebSocket] Error initializing client:', error)
// Fallback to new instance
_wsClient = new WebSocketClient()
return _wsClient
}
})()
// Helper to apply patches to data
export function applyDataPatch<T>(data: T, patch: PatchOperation[]): T {

View File

@@ -11,7 +11,7 @@ const router = createRouter({
children: [
{
path: '',
redirect: () => {
redirect: (to) => {
// Initial routing logic - determines first screen after splash
const devMode = import.meta.env.VITE_DEV_MODE
const seenOnboarding = localStorage.getItem('neode_onboarding_complete') === '1'
@@ -19,7 +19,7 @@ const router = createRouter({
// Setup mode: go directly to login (original StartOS setup)
if (devMode === 'setup') {
return isSetup ? '/login' : '/login' // Always login for setup mode
return '/login'
}
// Onboarding mode: go to experimental onboarding flow