Documentation Index Fetch the complete documentation index at: https://docs.debian.com.mx/llms.txt
Use this file to discover all available pages before exploring further.
Architecture Overview
Time Capsule is a Progressive Web App that recreates the 1990s Unix CDE (Common Desktop Environment) desktop experience. The architecture follows a modular, event-driven design pattern built on modern web technologies.
System Design
The application follows a layered architecture with clear separation of concerns:
Core Principles
1. Modular Architecture
Each core system is implemented as an independent module with a well-defined interface. This promotes code reusability and maintainability.
// src/scripts/core/config.ts
export interface Config {
WINDOW : WindowConfig ;
AUDIO : AudioConfig ;
FS : FSConfig ;
TERMINAL : TerminalConfig ;
// ... more configuration sections
}
export const CONFIG : Config = {
WINDOW: {
MIN_VISIBLE: 20 ,
BASE_Z_INDEX: 10000 ,
TOP_BAR_HEIGHT: 30 ,
},
AUDIO: {
BEEP_FREQUENCY: 880 ,
BEEP_GAIN: 0.9 ,
BEEP_DURATION: 0.1 ,
},
// ... configuration values
};
2. Event-Driven Communication
Components communicate through custom events dispatched on the window object, promoting loose coupling:
Event Dispatch
Event Listener
// Notify system of filesystem changes
function dispatchChange ( path : string ) : void {
window . dispatchEvent (
new CustomEvent ( 'cde-fs-change' , {
detail: { path },
})
);
}
3. Singleton Pattern for Core Systems
Core systems use the singleton pattern to ensure single instances throughout the application lifecycle:
SettingsManager Singleton
class SettingsManager {
private static instance : SettingsManager ;
private settings : SystemSettings ;
private constructor () {
this . settings = this . getDefaultSettings ();
this . load ();
}
public static getInstance () : SettingsManager {
if ( ! SettingsManager . instance ) {
SettingsManager . instance = new SettingsManager ();
}
return SettingsManager . instance ;
}
}
export const settingsManager = SettingsManager . getInstance ();
4. Progressive Enhancement
The application provides a functional experience even with limited JavaScript, with enhanced features loading progressively.
Core Components
WindowManager
Handles all window lifecycle operations including creation, positioning, focus management, and z-index ordering.
Key Responsibilities:
Window registration and lifecycle management
Drag and drop functionality
Z-index management (base: 10000 for windows, 90000 for modals)
Focus management with click and point-to-focus modes
Window state persistence (position, maximized state)
Workspace management (4 virtual desktops)
Mobile-specific centering and constraints
Virtual Filesystem (VFS)
Provides a POSIX-like filesystem abstraction in browser memory with O(1) path lookups.
Key Features:
Hierarchical folder structure
File metadata (size, mtime, owner, permissions)
CRUD operations (touch, mkdir, rm, rename, move, copy)
Trash functionality
Search with recursive option
Event notifications on changes
SettingsManager
Centralized configuration management with persistent storage.
Features:
Unified settings storage
Version-aware cache management
Migration from legacy localStorage keys
Section-based organization (theme, mouse, keyboard, beep, session, desktop)
Window session persistence
AudioManager
Retro audio system using Web Audio API for classic CDE system sounds.
Capabilities:
Lazy AudioContext initialization (on first user gesture)
System beeps with configurable frequency/duration
UI feedback sounds (click, error, success)
Window operation sounds (open, close, minimize, maximize, shade)
Melody playback for startup chimes
Volume control
export interface IAudioManager {
beep ( frequency ?: number , duration ?: number ) : void ;
click () : void ;
error () : void ;
success () : void ;
windowOpen () : void ;
windowClose () : void ;
windowMinimize () : void ;
windowMaximize () : void ;
windowShade () : void ;
menuOpen () : void ;
menuClose () : void ;
notification () : void ;
setVolume ( volume : number ) : void ;
playMelody ( notes : Array <{
freq : number ;
duration : number ;
type ?: OscillatorType ;
delay ?: number
}>) : Promise < void >;
playStartupChime () : void ;
}
StyleManager
Orchestrates multiple style modules for system customization.
Modules:
ThemeModule : Color palette management (CDE palettes)
FontModule : Font family and sizing controls
MouseModule : Cursor settings and acceleration
KeyboardModule : Keyboard repeat and shortcuts
BeepModule : Audio feedback settings
BackdropModule : Wallpaper/backdrop management with XPM parsing
WindowModule : Window behavior (focus mode, opaque dragging)
ScreenModule : Screen settings
StartupModule : Boot sequence customization
export class StyleManager {
public theme : ThemeModule ;
public font : FontModule ;
public mouse : MouseModule ;
public keyboard : KeyboardModule ;
public beep : BeepModule ;
public backdrop : BackdropModule ;
public windowBehavior : WindowModule ;
public screen : ScreenModule ;
public startup : StartupModule ;
public init () : void {
const themeSettings = settingsManager . getSection ( 'theme' );
// Apply default palette if none saved
if ( ! themeSettings . colors ||
Object . keys ( themeSettings . colors ). length === 0 ) {
this . theme . applyCdePalette ( 'latesummer' );
} else {
this . theme . loadSavedColors ( themeSettings . colors );
}
// Initialize all modules
this . mouse . load ();
this . keyboard . load ();
this . beep . load ();
this . backdrop . load ();
// ...
}
}
Configuration System
Centralized configuration in config.ts provides type-safe access to all system constants:
Configuration Interfaces
Usage Example
export interface WindowConfig {
MIN_VISIBLE : number ;
BASE_Z_INDEX : number ;
TOP_BAR_HEIGHT : number ;
}
export interface FSConfig {
HOME : string ;
DESKTOP : string ;
TRASH : string ;
NETWORK : string ;
}
export interface TerminalConfig {
HOME_PATH : string ;
MIN_TYPING_DELAY : number ;
MAX_TYPING_DELAY : number ;
POST_COMMAND_DELAY : number ;
POST_SEQUENCE_DELAY : number ;
MAX_LINES : number ;
CLEANUP_INTERVAL : number ;
}
Data Flow Patterns
Window Creation Flow
Settings Persistence Flow
VFS Operation Flow
Z-Index Management
Z-index allocation uses separate counters for different layers:
let highestWindowZIndex = CONFIG . WINDOW . BASE_Z_INDEX ; // 10000
let highestModalZIndex = 90000 ;
function getNextZIndex ( isModal : boolean = false ) : number {
if ( isModal ) {
return ++ highestModalZIndex ;
}
return ++ highestWindowZIndex ;
}
This ensures modals always appear above regular windows, preventing z-index conflicts.
Memory-Optimized VFS
The VFS uses a flattened Map for O(1) path resolution instead of traversing a tree structure:
const fsMap : Record < string , VFSNode > = {};
function flatten ( basePath : string , node : VFSNode ) : void {
fsMap [ basePath ] = node ;
if ( node . type === 'folder' ) {
for ( const [ name , child ] of Object . entries ( node . children )) {
const fullPath = basePath + name +
( child . type === 'folder' ? '/' : '' );
flatten ( fullPath , child );
}
}
}
// O(1) lookup instead of tree traversal
getNode ( path : string ): VFSNode | null {
return fsMap [ path ] || null ;
}
Window Position Normalization
Window positions are normalized on viewport resize to ensure they remain accessible:
function normalizeWindowPosition ( win : HTMLElement ) : void {
const rect = win . getBoundingClientRect ();
const TOP_BAR_HEIGHT = CONFIG . WINDOW . TOP_BAR_HEIGHT ;
const viewportWidth = window . innerWidth ;
const viewportHeight = window . innerHeight ;
// Clamp within viewport bounds
const minY = TOP_BAR_HEIGHT ;
const minX = 0 ;
const maxX = Math . max ( 0 , viewportWidth - rect . width );
const maxY = Math . max ( minY , viewportHeight - rect . height );
let newTop = Math . max ( rect . top , minY );
newTop = Math . min ( newTop , maxY );
let newLeft = Math . max ( rect . left , minX );
newLeft = Math . min ( newLeft , maxX );
win . style . top = newTop + 'px' ;
win . style . left = newLeft + 'px' ;
}
Error Handling
Graceful degradation is implemented throughout:
Storage Fallback
Audio Context Handling
try {
await storageAdapter . setItemSync ( key , value );
} catch ( e ) {
console . error ( '[SettingsManager] Failed to save:' , e );
// Continue operation, data will be lost on refresh
}
Type Safety
Strong TypeScript typing throughout the codebase:
export interface VFSMetadata {
size : number ;
mtime : string ; // ISO string
owner : string ;
permissions : string ;
}
export interface VFSFile {
type : 'file' ;
content : string ;
metadata ?: VFSMetadata ;
}
export interface VFSFolder {
type : 'folder' ;
children : Record < string , VFSNode >;
metadata ?: VFSMetadata ;
}
export type VFSNode = VFSFile | VFSFolder ;
Global Exposure
Core systems are exposed globally for debugging and feature access:
declare global {
interface Window {
WindowManager : typeof WindowManager ;
VirtualFS : IVFS ;
AudioManager : IAudioManager ;
styleManager : StyleManager ;
CONFIG : Config ;
}
}
if ( typeof window !== 'undefined' ) {
window . WindowManager = WindowManager ;
window . VirtualFS = VFS ;
window . AudioManager = AudioManager ;
window . CONFIG = CONFIG ;
}
Next Steps
Window Manager Deep dive into window management implementation
Virtual Filesystem Learn about the VFS architecture and operations
Storage Understand persistent data storage with IndexedDB
Development Start building features for Time Capsule