Skip to main content

Overview

ClipSync is built as a Progressive Web App (PWA) using a modern React architecture with real-time synchronization capabilities. The application follows a single-page application (SPA) pattern with a centralized state management approach.

Application Architecture

The application uses a monolithic client architecture where all functionality is contained within a single React application. The core architecture consists of:
  • Client Layer: React 19 application with Vite as the build tool
  • Backend Layer: Supabase (Backend-as-a-Service) providing database, storage, and real-time features
  • PWA Layer: Service Worker for offline functionality and app installation

High-Level Architecture Diagram

Component Structure

Main Application Component

The application follows a single-component architecture with the main App.jsx component handling all functionality. This monolithic approach works well for this focused use case.
export default function App() {
    // State Management
    const [sessionCode, setSessionCode] = useState("");
    const [clipboard, setClipboard] = useState("");
    const [history, setHistory] = useState([]);
    const [isDarkMode, setIsDarkMode] = useState(...);
    
    // Real-time sync via Supabase channels
    useEffect(() => {
        const channel = supabase
            .channel("clipboard")
            .on("postgres_changes", {...}, callback)
            .subscribe();
    }, [sessionCode]);
    
    return (
        // UI Components
    );
}
Reference: src/App.jsx:1-706

Key Modules

Configuration

src/config/supabase.jsInitializes Supabase client with environment variables

Services

src/service/doc.service.jsSession creation and management utilities

Utils

src/utils/index.jsHelper functions (link conversion, text processing)

File Handling

src/compressedFileUpload.jsxImage compression before upload

State Management Approach

ClipSync uses React’s built-in state management with hooks, supplemented by React Query for server state:

Local State (useState)

1

Session State

Manages session code and connection status
const [sessionCode, setSessionCode] = useState("");
const [inputCode, setInputCode] = useState("");
2

Clipboard State

Handles clipboard content and file attachments
const [clipboard, setClipboard] = useState(
  sessionStorage.getItem("clipboard") || ""
);
const [fileUrl, setFileUrl] = useState(null);
3

UI State

Manages theme, offline status, and search
const [isDarkMode, setIsDarkMode] = useState(...);
const [isOffline, setIsOffline] = useState(!navigator.onLine);
const [searchKeyword, setSearchKeyword] = useState("");

Server State (React Query)

Used for visitor counter management:
src/App.jsx:375-383
const { data } = useQuery({
    queryKey: ["counter"],
    queryFn: updateCounter,
    enabled: true,
    refetchOnWindowFocus: false,
    refetchOnReconnect: false,
    retry: 2,
    refetchInterval: 1000 * 60 * 5
})

Persistence Strategy

ClipSync uses multiple persistence layers:
  • localStorage: Session codes and theme preferences
  • sessionStorage: Temporary clipboard content
  • Supabase Database: Persistent clipboard history

Real-Time Sync Architecture

Supabase Realtime Channels

The application uses Supabase Realtime for instant synchronization across devices:
src/App.jsx:386-410
useEffect(() => {
    if (!sessionCode) return;
    
    const channel = supabase
        .channel("clipboard")
        .on("postgres_changes", {
            event: "*",
            schema: "public",
            table: "clipboard"
        }, (payload) => {
            if (payload.new.session_code === sessionCode && 
                payload.eventType === "INSERT") {
                setHistory((prev) => [payload.new, ...prev]);
                setClipboard("");
            }
            
            if (payload.eventType === "DELETE") {
                setHistory((prev) => 
                    prev.filter((item) => item.id !== payload.old.id)
                );
            }
        })
        .subscribe();
    
    return () => {
        supabase.removeChannel(channel);
    };
}, [sessionCode, isOffline]);

How It Works

1

Subscribe to Changes

When a user joins a session, they subscribe to the clipboard channel
2

Database Triggers

Any INSERT or DELETE operation on the clipboard table triggers a realtime event
3

Event Filtering

The client filters events by session_code to only process relevant updates
4

State Update

The local history state is updated immediately, reflecting changes across all connected devices
Realtime connections are disabled when the device is offline to prevent connection errors. The app automatically reconnects when back online.

File Storage Architecture

Upload Flow

Image Compression

Images are automatically compressed before upload using browser-image-compression:
src/compressedFileUpload.jsx:3-16
export async function compressImage(
    imageFile,
    maxSizeMB = 0.2,
    maxWidthOrHeight = 1920,
    useWebWorker = true
) {
    const options = {
        maxSizeMB,
        maxWidthOrHeight,
        useWebWorker,
    }
    
    const compressedFile = await imageCompression(imageFile, options);
    // Returns new File object with compressed data
}
Default compression settings:
  • Max size: 0.2 MB (200KB)
  • Max dimension: 1920px
  • Uses Web Worker for non-blocking compression

Storage Organization

Files are stored in Supabase Storage with the following structure:
clipboard/
  files/
    {3-random-chars}{original-filename}
The random prefix prevents filename collisions.

Offline Handling

The application monitors online/offline status:
src/App.jsx:40-53
useEffect(() => {
    const handleOnline = () => {
        setIsOffline(false);
        setTimeout(fetchClipboardHistory, 100);
    };
    const handleOffline = () => setIsOffline(true);
    
    window.addEventListener("online", handleOnline);
    window.addEventListener("offline", handleOffline);
    
    return () => {
        window.removeEventListener("online", handleOnline);
        window.removeEventListener("offline", handleOffline);
    };
}, []);

Offline Features

  • Detects network status changes
  • Shows offline banner to users
  • Automatically refetches data when back online
  • PWA caching allows viewing cached content offline

Database Schema

While not explicitly defined in the client code, the application interacts with these Supabase tables:

Tables

Stores active session codes
- id (primary key)
- code (unique, 5 characters)
- created_at (timestamp)
Stores clipboard entries
- id (primary key)
- session_code (foreign key to sessions)
- content (text, max 15000 chars)
- fileUrl (text, nullable)
- file (json, nullable)
- sensitive (boolean)
- created_at (timestamp)
Tracks visitor statistics
- id (primary key)
- total (integer)
- unique (integer)

Performance Optimizations

Lazy Loading

Service Worker caches all assets for instant loading

Image Compression

Reduces upload size by up to 90%

Query Caching

React Query caches visitor counter (5min refresh)

Efficient Updates

Only subscribes to realtime changes when session is active

Next Steps

Tech Stack

Learn about the technologies powering ClipSync

Local Setup

Set up the development environment

Build docs developers (and LLMs) love