Space Map

Cosmic-themed content organization with visual space metaphors

Space Map Library (space-map-lib)

Overview

The Space Map Library is a comprehensive Angular library for managing hierarchical page structures in a visual, space-themed interface. It provides a constellation-like view of pages (worlds), organized into galaxies and universes, with full support for hierarchical relationships, visual theming, and real-time state management.

πŸ—οΈ Architecture

Core Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Components (UI Layer)                               β”‚
β”‚  β€’ SpaceEditorComponent                             β”‚
β”‚  β€’ GalaxyDetailComponent                            β”‚
β”‚  β€’ UniverseDetailComponent                          β”‚
β”‚  β€’ SpaceOverviewComponent                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Flash State Service (Reactive State Management)    β”‚
β”‚  β€’ SpaceMapFlashStateService                        β”‚
β”‚  β€’ Signals-based reactive state                     β”‚
β”‚  β€’ Zero-config auto-persistence                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Storage System (@storage/angular)                   β”‚
β”‚  β€’ Intelligent multi-adapter storage                β”‚
β”‚  β€’ Automatic persistence                            β”‚
β”‚  β€’ Real-time monitoring                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Storage Adapters (Persistence Layer)               β”‚
β”‚  β€’ IndexedDB (Dexie) - Primary                      β”‚
β”‚  β€’ localStorage - Fallback                          β”‚
β”‚  β€’ OPFS - Future                                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Legacy Compatibility Layer

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  NGXS State (Legacy - Being Phased Out)             β”‚
β”‚  β€’ SpaceMapState                                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  SpaceMapStorageService (Bridge)                    β”‚
β”‚  β€’ Compatibility layer for NGXS                     β”‚
β”‚  β€’ Delegates to Storage System                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 ↓
          Storage System ↑

πŸ”₯ Flash Persistence Integration

Overview

Space Map uses Flash Persistence (@flash-persistence) for zero-configuration, automatically persisted reactive state. This eliminates the need for manual storage setup and ensures data is always synchronized.

How It Works

// ✨ AUTOMATIC - No configuration needed!
export class SpaceMapFlashStateService {
  // Auto-discovered and persisted signals
  private _pages = autoFlashState<PageNode[]>('space-map/worlds', []);
  private _galaxies = autoFlashState<GalaxyGroup[]>('space-map/galaxies', []);
  private _universes = autoFlashState<UniverseGroup[]>('space-map/universes', []);

  // Public computed signals with data normalization
  readonly worlds = computed(() => {
    const data = this._pages();
    if (Array.isArray(data)) return data;
    if (data && typeof data === 'object') {
      // Auto-normalize object format to array
      return Object.values(data) as PageNode[];
    }
    return [];
  });
}

Key Features

  1. Zero Configuration: States are automatically discovered and persisted
  2. Reactive: Built on Angular signals for automatic change detection
  3. Type-Safe: Full TypeScript support with proper typing
  4. Auto-Normalization: Handles legacy data format migrations
  5. Performance: Sub-millisecond persistence (<1ms average)

Storage Keys

Flash Persistence uses the following keys:

'flash:space-map/worlds'           // Page/World nodes
'flash:space-map/galaxies'         // Galaxy groups
'flash:space-map/universes'        // Universe groups
'flash:space-map/selected-world'   // Currently selected page ID
'flash:space-map/selected-universe'// Currently selected universe ID
'flash:space-map/ui-state'         // UI state (view modes, filters, etc.)

Performance Metrics

From production logs:

⚑ Flash Persistence Performance (EXCELLENT)
πŸ“Š Session: 30.08s, Discoveries: 1, Cache: 11/11
πŸ” Insights:
   - Discovery rate: 0.03/sec (optimal)
   - Cache hit rate: 100.0% (excellent)
   - Discovery time: 0.40ms avg (fast)
   - Write time: 0.50-0.70ms (excellent)

πŸ’Ύ Intelligent Storage System Integration

Overview

Space Map integrates with the Intelligent Storage System (@storage/angular), which provides:

Storage Configuration

// Automatically configured via providers
{
  strategy: 'balanced',
  adapter: 'dexie',         // IndexedDB via Dexie.js
  fallback: 'localStorage',
  namespace: 'gograb-space',
  microCacheBudget: 262144  // 256KB cache
}

Data Flow

User Action (Create Universe)
       ↓
Component Event Handler
       ↓
Flash State Service Method (createUniverse)
       ↓
Signal Update (_universes.update(...))
       ↓
Flash Persistence Auto-Save
       ↓
Storage System (put operation)
       ↓
IndexedDB Write (via Dexie adapter)
       ↓
Write Verification βœ…
       ↓
Reactive UI Update (via computed signals)

Data Normalization

The system automatically handles legacy data format migrations:

// Old format (stored as object with numeric keys)
{
  0: { id: 'page-1', title: 'Page 1' },
  1: { id: 'page-2', title: 'Page 2' }
}

// ↓ Auto-normalized to ↓

// New format (proper array)
[
  { id: 'page-1', title: 'Page 1' },
  { id: 'page-2', title: 'Page 2' }
]

This happens automatically during initialization:

// Normalize pages
if (rawPages && !Array.isArray(rawPages) && typeof rawPages === 'object') {
  const normalizedPages = Object.values(rawPages) as PageNode[];
  this._pages.set(normalizedPages);
  console.log('πŸ”§ Data normalization: Converted pages object to array');
}

πŸ“Š State Management with Flash State Service

SpaceMapFlashStateService

The central state management service using Flash Persistence.

Public API

// Reactive Signals (Read-Only)
readonly worlds: Signal<WorldNode[]>
readonly galaxies: Signal<GalaxyGroup[]>
readonly universes: Signal<UniverseGroup[]>
readonly selectedWorldId: Signal<string | null>
readonly selectedUniverseId: Signal<string | null>
readonly selectedWorld: Signal<WorldNode | null>

// State Flags
readonly loading: Signal<boolean>
readonly error: Signal<Error | null>
readonly initialized: Signal<boolean>

// CRUD Operations - Universes
async createUniverse(data: CreateUniverseRequest): Promise<UniverseGroup>
async updateUniverse(universe: UniverseGroup): Promise<void>
async deleteUniverse(id: string): Promise<void>

// CRUD Operations - Galaxies
async createGalaxy(galaxy: GalaxyGroup): Promise<GalaxyGroup>
async updateGalaxy(galaxy: GalaxyGroup): Promise<void>
async deleteGalaxy(id: string): Promise<void>

// CRUD Operations - Worlds/Pages
async createPage(data: CreatePageRequest): Promise<WorldNode>
async updatePage(page: WorldNode): Promise<void>
async deletePage(id: string): Promise<void>

// Selection
selectWorld(worldId: string | null): void
selectUniverse(universeId: string | null): void

Usage Example

@Component({
  selector: 'app-space-overview',
  // ...
})
export class SpaceOverviewComponent {
  private flashState = inject(SpaceMapFlashStateService);

  // Access reactive state via signals
  readonly universes = this.flashState.universes;
  readonly galaxies = this.flashState.galaxies;
  readonly worlds = this.flashState.worlds;

  async createNewUniverse(name: string) {
    // Creates and auto-persists
    const universe = await this.flashState.createUniverse({
      name,
      description: 'New universe',
      color: '#7a68f3'
    });

    // UI automatically updates via signals ✨
    console.log('Created:', universe.id);
  }
}

Template Usage

<!-- Direct signal access in templates -->
<div *ngFor="let universe of universes()">
  <h3>{{ universe.name }}</h3>
  <p>{{ universe.description }}</p>
</div>

<!-- Computed values -->
<div class="stats">
  <span>Total Universes: {{ universes().length }}</span>
  <span>Total Galaxies: {{ galaxies().length }}</span>
  <span>Total Worlds: {{ worlds().length }}</span>
</div>

🧩 Core Services

WorldManagerService

Manages world/page nodes and hierarchical relationships.

Key Features:

Migration Status: βœ… Fully migrated to Flash State

GalaxyManagerService

Manages galaxy groups and their relationships.

Key Features:

Migration Status: βœ… Fully migrated to Flash State

UniverseManagerService

Manages universe/world groups at the top level.

Key Features:

Migration Status: βœ… Fully migrated to Flash State

WorldIntegrationService

Bridge between Space Map's WorldNode model and the core World model.

Key Features:

Migration Status: βœ… Fully migrated to Flash State


🎨 Core Components

SpaceEditorComponent

Main editor interface with canvas-based constellation view.

Features:

State Access: Via Flash State Service

GalaxyDetailComponent

Detailed view of a single galaxy and its pages.

Features:

State Access: Via Flash State Service

UniverseDetailComponent

Universe overview with galaxy constellation.

Features:

State Access: Via Flash State Service

SpaceOverviewComponent

Top-level view of all universes.

Features:

State Access: Via Flash State Service


πŸ”„ Data Models

WorldNode (Page)

interface WorldNode {
  id: string;
  title: string;
  slug: string;
  description?: string;
  category?: WorldCategory;

  // Hierarchy
  parentId?: string;
  children?: WorldNode[];

  // Position & Layout
  position?: { x: number; y: number };
  size?: { width: number; height: number };

  // Galaxy/Universe Association
  cosmos?: {
    universeId?: string;
    galaxies?: GalaxyGroup[];
  };

  // Visual
  isVisible?: boolean;
  useGlobalUX?: boolean;

  // Metadata
  lastModified?: Date;
  coreWorld?: World;
  coreWorldId?: string;
}

GalaxyGroup

interface GalaxyGroup {
  id: string;
  name: string;
  slug?: string;
  description?: string;

  // Associations
  universeId?: string;
  parentGalaxyId?: string;
  pageIds: string[];
  centerId?: string;

  // Visual Theme
  colors?: string[];
  visualTheme?: {
    primaryColor: string;
    secondaryColor?: string;
    accentColor?: string;
    glowEffect?: { enabled: boolean; intensity: number };
    particleEffect?: { enabled: boolean; type: string };
  };

  // Layout
  position?: {
    x: number;
    y: number;
    scale?: number;
    animation?: {
      orbit?: { enabled: boolean; speed: number };
      pulse?: { enabled: boolean; speed: number };
      drift?: { enabled: boolean; speed: number };
    };
  };

  // Properties
  type?: GalaxyType;
  groupingStrategy?: GroupingStrategy;
  capacity?: {
    maxPages: number;
    currentPages: number;
    maxSubGalaxies?: number;
    currentSubGalaxies?: number;
  };

  // Categorization
  category?: {
    primary: string;
    secondary?: string;
    status: 'active' | 'archived' | 'draft';
    priority: number;
    tags?: string[];
  };
}

UniverseGroup

interface UniverseGroup {
  id: string;
  name: string;
  slug?: string;
  description?: string;
  color?: string;

  // Associations
  galaxyIds: string[];

  // Metadata
  createdAt?: Date;
  updatedAt?: Date;
}

πŸš€ Migration from NGXS

Why We Migrated

The Space Map library has been migrated from NGXS to Flash Persistence for:

  1. Simplicity: Zero-config auto-persistence vs manual actions/selectors
  2. Performance: Direct signal access vs Observable chains
  3. Type Safety: Better TypeScript integration
  4. Modern Angular: Built on Angular 20 signals
  5. Automatic Persistence: No manual save/load logic needed

Migration Status

Component/Service Status Notes
SpaceMapFlashStateService βœ… Complete New primary state service
WorldManagerService βœ… Complete Uses Flash State
GalaxyManagerService βœ… Complete Uses Flash State
UniverseManagerService βœ… Complete Uses Flash State
WorldIntegrationService βœ… Complete Uses Flash State
SpaceEditorComponent βœ… Complete Uses Flash State
GalaxyDetailComponent βœ… Complete Uses Flash State
UniverseDetailComponent βœ… Complete Uses Flash State
SpaceOverviewComponent βœ… Complete Uses Flash State
SpaceMapState (NGXS) ⚠️ Legacy Bridge for compatibility
SpaceMapStorageService ⚠️ Bridge NGXS compatibility layer

Compatibility Layer

For backward compatibility, SpaceMapState (NGXS) and SpaceMapStorageService remain as bridge services:

// NGXS State still works but delegates to Storage System
@State<SpaceMapStateModel>({
  name: 'spaceMap'
})
export class SpaceMapState {
  private storageService = inject(SpaceMapStorageService);

  // Actions delegate to storage service
  // Storage service delegates to Flash State
}

Recommendation: New code should use SpaceMapFlashStateService directly.


πŸ“– Best Practices

1. Always Use Flash State Service

// βœ… DO: Inject Flash State Service
private flashState = inject(SpaceMapFlashStateService);

// ❌ DON'T: Use NGXS Store
private store = inject(Store);

2. Access State via Signals

// βœ… DO: Use signal access
const universes = this.flashState.universes();
const count = this.flashState.worlds().length;

// ❌ DON'T: Use NGXS selectors
this.store.select(SpaceMapState.universes);

3. Let Flash Persistence Handle Saving

// βœ… DO: Just mutate via Flash State methods
await this.flashState.createUniverse({ name: 'New Universe' });
// Auto-persisted! ✨

// ❌ DON'T: Manual storage service calls
await this.storageService.saveData(...);

4. Use Computed for Derived State

// βœ… DO: Use computed signals
readonly filteredWorlds = computed(() => {
  return this.flashState.worlds()
    .filter(w => w.cosmos?.universeId === this.selectedId);
});

// ❌ DON'T: Manual filtering in templates

5. Trust Auto-Normalization

// βœ… DO: Trust the system to handle data formats
const worlds = this.flashState.worlds(); // Always returns array

// ❌ DON'T: Manual normalization checks everywhere
if (Array.isArray(worlds)) { ... }

πŸ” Debugging & Monitoring

Flash Persistence Stats

Check Flash Persistence performance in browser console:

window.autoFlashStats()
// Returns:
// {
//   discoveries: 1,
//   cacheHitRate: 100.0,
//   avgDiscoveryTime: 0.40,
//   sessionDuration: 30.08,
//   ...
// }

Storage System Monitoring

The Intelligent Storage System provides real-time monitoring:

🧠 Real-time monitoring: Starting adaptive frequency analysis
🎯 Real-time monitoring: Switching to production frequency (30s intervals)

Console Logs

Key log patterns to look for:

βœ… Flash State: Auto-loaded X pages, Y galaxies, Z universes
✨ ZERO CONFIGURATION - States automatically discovered and persisted!
πŸ’Ύ Flash Persistence: Persisted flash:space-map/X via storage bridge (Xms)
βœ… WRITE VERIFICATION: flash:space-map/X successfully persisted and readable
πŸ”§ Data normalization: Converted X object to array

πŸ§ͺ Testing

Unit Testing with Flash State

describe('SpaceMapFlashStateService', () => {
  let service: SpaceMapFlashStateService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        SpaceMapFlashStateService,
        { provide: StorageService, useClass: MockStorageService }
      ]
    });
    service = TestBed.inject(SpaceMapFlashStateService);
  });

  it('should create universe and auto-persist', async () => {
    const universe = await service.createUniverse({
      name: 'Test Universe',
      description: 'Test',
      color: '#7a68f3'
    });

    expect(universe.id).toBeDefined();
    expect(service.universes()).toContain(universe);
  });
});

πŸ“š Additional Resources


🎯 Future Enhancements

Planned Features

  1. OPFS Adapter: File System Access API for even faster persistence
  2. Real-time Collaboration: Multi-user editing with CRDTs
  3. Undo/Redo: Time-travel debugging and history
  4. Export/Import: JSON/YAML export for backup/migration
  5. Search & Filter: Advanced search across all entities
  6. AI Integration: AI-powered organization and suggestions

Migration Roadmap

  1. βœ… Phase 1: Migrate core services to Flash State
  2. βœ… Phase 2: Migrate components to Flash State
  3. ⏳ Phase 3: Remove NGXS compatibility layer
  4. ⏳ Phase 4: Add advanced features (OPFS, collaboration)

Last Updated: October 2, 2025 Version: 2.0.0 (Flash State Migration) Status: βœ… Production Ready

🌌 Space Map Application -- Back when it was an App

A cosmic-themed content organization interface that transforms content management into an immersive space exploration experience.

Space Map uses space metaphors (galaxies, worlds, pages) to visualize and manage hierarchical content structures with stunning visual effects and intuitive interactions.

πŸš€ What Is Space Map?

Space Map is more than just a content organizerβ€”it's an immersive visualization system that makes managing complex content hierarchies feel like exploring the cosmos:

⭐ Key Features

🎨 Cosmic Design System

🧠 Smart Organization

⚑ Performance & Storage

πŸ“š Quick Navigation

🏁 Getting Started ⭐ START HERE

Complete setup guide and your first cosmic journey.

πŸ“– Complete Documentation πŸ“˜ COMPREHENSIVE GUIDE

In-depth documentation covering all aspects of Space Map.

πŸ”§ Theme Fixes 🎨 STYLING GUIDE

Theme integration and visual enhancements.

🎯 Use Cases

Content Management

Organize website pages, documentation, or any hierarchical content with intuitive visual grouping.

Site Architecture

Visualize your entire application structure as an interactive cosmic map.

Learning Resource

Study Angular 20 best practices, database design, and advanced UI patterns.

Portfolio Piece

A beautiful, unique interface that showcases modern web development skills.

πŸ”§ Technical Stack

Framework: Angular 20 (Standalone Components)
Database: Dexie.js (IndexedDB)
State Management: Angular Signals + BehaviorSubjects
Styling: SCSS with CSS Variables
Theme System: @widgets-editor/theme-system
Storage: @widgets-editor/storage

🌟 Why Space Map?

For Developers

For Users

🎨 Design Philosophy

Space Map embodies six core design principles:

  1. 🌌 Cosmic Immersion - Every element feels like it belongs in deep space
  2. ✨ Ethereal Interaction - UI elements float and glow with otherworldly beauty
  3. πŸ“Š Hierarchical Clarity - Visual hierarchy mirrors cosmic structure
  4. 🎭 Subtle Animation - Motion feels weightless and organic
  5. πŸͺŸ Glass Morphism - Depth without blocking cosmic backgrounds
  6. 🎨 Color Harmony - Purple, blue, and pink create visual interest

πŸš€ Getting Started Quick Commands

# Install dependencies (if needed)
npx nx build core-types
npx nx build ux-framework

# Start development server
npx nx serve space-map

# Build for production
npx nx build space-map

# Run tests
npx nx test space-map

# Lint code
npx nx lint space-map

πŸ“Š Application Port

Space Map runs on port 4600+ (or next available port).

πŸ”— Related Documentation


🌌 Explore the cosmos of content organization with Space Map!

Transform complex hierarchies into a beautiful, intuitive space exploration experience that makes content management feel like an adventure through the stars.