fix: address multiple runtime issues

- Register missing shape types in Automerge schema (CalendarEvent, HolonBrowser, PrivateWorkspace, GoogleItem, WorkflowBlock)
- Improve connections API error handling to detect HTML responses gracefully
- Clean up Vite config debug logs
- Add static PWA manifest and link to index.html for proper manifest serving

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2025-12-24 21:06:20 -05:00
parent 0d6b62d1c7
commit f9208719b0
6 changed files with 66 additions and 16 deletions

View File

@ -6,6 +6,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🍄</text></svg>" />
<link rel="apple-touch-icon" href="/pwa-192x192.svg" />
<link rel="manifest" href="/manifest.webmanifest" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta http-equiv="Permissions-Policy" content="midi=*, microphone=*, camera=*, autoplay=*">
<link rel="preconnect" href="https://fonts.googleapis.com" />

View File

@ -134,8 +134,14 @@ import { MycelialIntelligenceShape } from "@/shapes/MycelialIntelligenceShapeUti
import { MapShape } from "@/shapes/MapShapeUtil"
// Calendar shape for calendar functionality
import { CalendarShape } from "@/shapes/CalendarShapeUtil"
import { CalendarEventShape } from "@/shapes/CalendarEventShapeUtil"
// Drawfast shape for quick drawing/sketching
import { DrawfastShape } from "@/shapes/DrawfastShapeUtil"
// Additional shapes from Board.tsx
import { HolonBrowserShape } from "@/shapes/HolonBrowserShapeUtil"
import { PrivateWorkspaceShape } from "@/shapes/PrivateWorkspaceShapeUtil"
import { GoogleItemShape } from "@/shapes/GoogleItemShapeUtil"
import { WorkflowBlockShape } from "@/shapes/WorkflowBlockShapeUtil"
export function useAutomergeStoreV2({
handle,
@ -174,7 +180,12 @@ export function useAutomergeStoreV2({
MycelialIntelligenceShape, // Deprecated - kept for backwards compatibility
MapShape, // Open Mapping - OSM map shape
CalendarShape, // Calendar with view switching
CalendarEventShape, // Calendar individual events
DrawfastShape, // Drawfast quick sketching
HolonBrowserShape, // Holon browser
PrivateWorkspaceShape, // Private workspace for Google Export
GoogleItemShape, // Individual Google items
WorkflowBlockShape, // Workflow builder blocks
]
// CRITICAL: Explicitly list ALL custom shape types to ensure they're registered
@ -200,7 +211,12 @@ export function useAutomergeStoreV2({
'MycelialIntelligence', // Deprecated - kept for backwards compatibility
'Map', // Open Mapping - OSM map shape
'Calendar', // Calendar with view switching
'CalendarEvent', // Calendar individual events
'Drawfast', // Drawfast quick sketching
'HolonBrowser', // Holon browser
'PrivateWorkspace', // Private workspace for Google Export
'GoogleItem', // Individual Google items
'WorkflowBlock', // Workflow builder blocks
]
// Build schema with explicit entries for all custom shapes

View File

@ -124,7 +124,10 @@ const CryptIDDropdown: React.FC<CryptIDDropdownProps> = ({ isDarkMode = false })
const myConnections = await getMyConnections();
setConnections(myConnections as UserConnectionWithProfile[]);
} catch (error) {
console.error('Failed to load connections:', error);
// Don't log as error - this is expected when worker isn't running
if (import.meta.env.DEV) {
console.warn('Connections API unavailable (worker may not be running)');
}
setConnections([]); // Clear on error too
} finally {
setConnectionsLoading(false);

View File

@ -68,9 +68,22 @@ async function fetchJson<T>(url: string, options?: RequestInit): Promise<T> {
headers,
});
// Check content type to ensure we're getting JSON
const contentType = response.headers.get('content-type') || '';
const isJson = contentType.includes('application/json');
if (!response.ok) {
const errorData = await response.json().catch(() => ({ message: response.statusText })) as { message?: string };
throw new Error(errorData.message || `HTTP ${response.status}`);
if (isJson) {
const errorData = await response.json().catch(() => ({ message: response.statusText })) as { message?: string };
throw new Error(errorData.message || `HTTP ${response.status}`);
}
// If we got HTML (like a 404 page), throw a more descriptive error
throw new Error(`API unavailable (HTTP ${response.status}). Is the worker running?`);
}
// Ensure we're getting JSON before parsing
if (!isJson) {
throw new Error('API returned non-JSON response. Is the worker running on port 5172?');
}
return response.json();

View File

@ -0,0 +1,29 @@
{
"name": "Jeff Emmett Canvas",
"short_name": "Canvas",
"description": "Collaborative canvas for research and creativity",
"start_url": "/",
"display": "standalone",
"background_color": "#1a1a2e",
"theme_color": "#1a1a2e",
"lang": "en",
"scope": "/",
"icons": [
{
"src": "/pwa-192x192.svg",
"sizes": "192x192",
"type": "image/svg+xml"
},
{
"src": "/pwa-512x512.svg",
"sizes": "512x512",
"type": "image/svg+xml"
},
{
"src": "/pwa-512x512.svg",
"sizes": "512x512",
"type": "image/svg+xml",
"purpose": "maskable"
}
]
}

View File

@ -8,21 +8,9 @@ export default defineConfig(({ mode }) => {
// Load env file based on `mode` in the current working directory.
// Set the third parameter to '' to load all env regardless of the `VITE_` prefix.
const env = loadEnv(mode, process.cwd(), '')
// Debug: Log what we're getting
console.log('🔧 Vite config - Environment variables:')
console.log('Mode:', mode)
console.log('WSL2_IP from env:', process.env.WSL2_IP)
console.log('process.env.VITE_TLDRAW_WORKER_URL:', process.env.VITE_TLDRAW_WORKER_URL)
console.log('env.VITE_TLDRAW_WORKER_URL:', env.VITE_TLDRAW_WORKER_URL)
// Get the WSL2 IP for HMR configuration
const wslIp = process.env.WSL2_IP || '172.22.168.84'
// Set the worker URL to localhost for local development
const workerUrl = 'http://localhost:5172'
process.env.VITE_TLDRAW_WORKER_URL = workerUrl
console.log('🌐 Setting worker URL to:', workerUrl)
process.env.VITE_TLDRAW_WORKER_URL = 'http://localhost:5172'
return {
envPrefix: ["VITE_"],