Skip to content

marcusrbrown/vbs

Repository files navigation

πŸ–– VBS: View By Stardate

A Modern Star Trek Chronological Viewing Guide

Build Status Node.js TypeScript License

Features β€’ Quick Start β€’ Development β€’ Architecture β€’ Contributing

VBS (View By Stardate) is a modern, local-first web application that helps Star Trek fans watch all series and movies in chronological order by in-universe stardate. Built with TypeScript and Vite, it features a functional factory architecture for robust state management and comprehensive progress tracking across the entire Star Trek universe.

πŸ’‘ Local-First Design: All your viewing progress is stored locally in your browser with export/import capabilities for data portability.

Features

Progress Tracking

  • Persistent Storage: Local progress tracking with browser storage
  • Progress Visualization: Overall and era-specific progress indicators
  • Data Portability: Export/import functionality for backup and sync
  • Hierarchical Progress: Season-level tracking with planned episode-level support

Content Organization

  • Chronological Order: 7 eras spanning 22nd-32nd centuries (1,000+ years)
  • Comprehensive Coverage: All series, movies, and animated content
  • Detailed Metadata: Stardate ranges, episode counts, and contextual notes
  • Smart Filtering: Real-time search and content type filtering

Modern Architecture

  • TypeScript: Full type safety with modern ES modules and advanced generics
  • Functional Factories: Closure-based state management with generic EventEmitter integration
  • Generic Utilities: Type-safe storage adapters and comprehensive utility type library
  • Responsive Design: Mobile-first approach with modern CSS
  • Performance: Vite build system with optimized chunking

Developer Experience

  • Testing: Comprehensive test suite with Vitest and coverage reporting
  • Code Quality: ESLint + Prettier with automated pre-commit hooks
  • CI/CD: Automated testing and deployment to GitHub Pages
  • Modern Tooling: pnpm package management and TypeScript strict mode

Quick Start

Prerequisites

Local Development

  1. Clone the repository

    git clone https://github.com/marcusrbrown/vbs.git
    cd vbs
  2. Install dependencies

    pnpm install
  3. Start development server

    pnpm dev
  4. Open in browser

    http://localhost:3000
    

πŸ“– Usage Guide

Getting Started

  1. Browse eras: Click on any era header to expand and view the content
  2. Mark as watched: Check the box next to any series or movie you've completed
  3. Track progress: Watch your progress bars fill up as you advance through Star Trek history
  4. Search content: Use the search bar to find specific series or episodes
  5. Filter by type: Use the dropdown to show only series, movies, or animated content

Managing Your Progress

  • Auto-save: Your progress is automatically saved to your browser's local storage
  • Export progress: Click "Export Progress" to download a JSON backup file
  • Import progress: Click "Import Progress" to restore from a previously exported file
  • Reset progress: Use "Reset Progress" to start fresh (with confirmation)

Viewing Controls

  • Expand All: Open all era sections at once
  • Collapse All: Close all era sections for a cleaner view
  • Search: Find content across all eras instantly
  • Filter: Show only specific types of content

Development

Environment Configuration

VBS supports optional API keys for enhanced metadata enrichment through environment variables:

  1. Copy the example environment file:

    cp .env.example .env
  2. Add your API keys (optional):

    Edit .env and add your API credentials:

    TMDB_API_KEY=your_tmdb_api_key_here
  3. Scripts automatically load variables: CLI scripts (like validate-episode-data.ts) automatically load .env files

πŸ“š See docs/environment-variables.md for complete documentation on:

  • All supported environment variables
  • Getting API keys (TMDB, etc.)
  • Testing with environment variables
  • Security best practices

Development Workflow

pnpm dev          # Start development server (port 3000)
pnpm test         # Run test suite with Vitest
pnpm test:ui      # Launch interactive test runner
pnpm test:coverage # Generate coverage reports
pnpm build        # TypeScript compilation + Vite build
pnpm lint         # Run ESLint checks
pnpm fix          # Auto-fix linting issues
pnpm type-check   # TypeScript type checking

Project Structure

vbs/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ main.ts              # Main application factory
β”‚   β”œβ”€β”€ style.css            # Global styles and Star Trek theme
β”‚   β”œβ”€β”€ data/
β”‚   β”‚   └── star-trek-data.ts # Comprehensive Star Trek dataset (570 lines)
β”‚   └── modules/
β”‚       β”œβ”€β”€ progress.ts      # Progress tracking factory
β”‚       β”œβ”€β”€ search.ts        # Search and filtering factory
β”‚       β”œβ”€β”€ timeline.ts      # Timeline rendering factory
β”‚       β”œβ”€β”€ storage.ts       # Import/export functionality
β”‚       └── types.ts         # TypeScript interfaces
β”œβ”€β”€ test/                    # Vitest test suite
β”œβ”€β”€ index.html              # Application entry point
β”œβ”€β”€ vite.config.ts          # Vite configuration
└── package.json            # Dependencies and scripts

Code Quality

The project uses automated code quality tools:

  • Pre-commit hooks: Lint and format all staged files before commits
  • ESLint: Comprehensive linting with TypeScript support
  • Prettier: Consistent code formatting
  • TypeScript: Strict type checking for reliability

Architecture

VBS uses a functional factory pattern with closures for state management and generic TypeScript utilities for enhanced type safety:

Functional Factory Pattern with Generic EventEmitters

// Factory function with closure-based state and generic EventEmitter integration
export const createProgressTracker = (): ProgressTrackerInstance => {
  // Private state in closure
  const watchedItems: string[] = []

  // Generic EventEmitter for type-safe events
  const eventEmitter = createEventEmitter<ProgressTrackerEvents>()

  // Return public API with modern event handling
  return {
    toggleItem: (itemId: string) => {
      // Mutate closure state
      const newState = !watchedItems.includes(itemId)

      // Emit via generic EventEmitter (type-safe)
      eventEmitter.emit('item-toggle', { itemId, isWatched: newState })
    },

    // Generic EventEmitter methods (type-safe)
    on: eventEmitter.on.bind(eventEmitter),
    off: eventEmitter.off.bind(eventEmitter),
    once: eventEmitter.once.bind(eventEmitter)
  }
}

// Dependency injection with generic constraints
const createTimelineRenderer = <TContainer extends HTMLElement>(
  container: TContainer,
  progressTracker: ProgressTrackerInstance
): TimelineRendererInstance => {
  // Use injected dependency in closure with type safety
  const isWatched = (itemId: string) => progressTracker.isWatched(itemId)
  // ... rest of implementation
}

Functional Composition Utilities

VBS includes a comprehensive functional composition utilities module (src/utils/composition.ts) with 3000+ lines of utilities for elegant data transformation pipelines:

import { compose, curry, pipe, tap } from './utils/composition.js'

// Left-to-right data flow with pipe()
const processStarTrekData = pipe(
  starTrekData,
  data => data.filter(era => era.items.length > 0),
  data => data.map(era => ({ ...era, progress: calculateProgress(era) })),
  tap(data => console.log('Processed data:', data.length, 'eras')),
  data => data.sort((a, b) => a.title.localeCompare(b.title))
)

// Curried functions for reusable predicates
const filterByType = curry((type: string, item: StarTrekItem) => item.type === type)
const isMovie = filterByType('movie')
const isSeries = filterByType('series')

// Progress calculation pipeline
const calculateOverallProgress = (): ProgressData => {
  return pipe(
    starTrekData,
    eras => eras.reduce((sum, era) => sum + era.items.length, 0),
    totalItems => ({
      total: totalItems,
      completed: watchedItems.length,
      percentage: Math.round((watchedItems.length / totalItems) * 100)
    })
  )
}

// VBS-specific pipeline builders
const searchPipeline = createSearchPipeline(starTrekData, {
  onFilterComplete: (filteredData, filterState) => updateUI(filteredData)
})

const progressPipeline = createProgressPipeline(allEras, {
  onProgressUpdate: (progress) => saveProgress(progress)
})

Core Functions:

  • pipe(): Left-to-right function composition for intuitive data flow
  • compose(): Right-to-left mathematical composition
  • curry(): Partial application with automatic arity detection
  • tap(): Side effects in pipelines without breaking type flow
  • asyncPipe() & asyncCompose(): Async composition with Promise handling

VBS-Specific Features:

  • Pipeline Builders: createSearchPipeline(), createProgressPipeline(), createEventPipeline()
  • Star Trek Predicates: starTrekPredicates.byType(), byText(), byEra()
  • Star Trek Transformations: starTrekTransformations.extractTitles(), extractByEra()
  • Debug Utilities: debugTap(), perfTap(), createDebugPipe() for development

Generic Storage Utilities

VBS includes a comprehensive generic storage system for type-safe data persistence:

// Generic storage adapter pattern
interface StorageAdapter<T> {
  save: (key: string, data: T) => Promise<void> | void
  load: (key: string) => Promise<T | null> | T | null
  remove: (key: string) => Promise<void> | void
  clear: () => Promise<void> | void
  exists: (key: string) => Promise<boolean> | boolean
}

// Type-safe LocalStorage implementation
const progressStorage = createStorage(
  new LocalStorageAdapter<string[]>({
    validate: isStringArray,
    fallback: []
  }),
  'starTrekProgress'
)

// Usage with automatic type inference
progressStorage.save(['tos_s1', 'tng_s1']) // Type: string[]
const progress = progressStorage.load()    // Type: string[] | null

Key Architectural Benefits

  • No this binding issues: Closures eliminate context problems
  • Type-safe event handling: Generic EventEmitter with compile-time type checking
  • Generic storage adapters: Reusable storage patterns with data validation
  • Comprehensive utility types: Advanced TypeScript patterns for maintainability
  • Functional composition: Easy testing and extensibility
  • Future-ready foundation: Prepared for IndexedDB migration and episode-level tracking

Data Structure

Star Trek content is organized hierarchically:

interface StarTrekEra {
  id: string        // e.g., 'enterprise', 'discovery'
  title: string     // "22nd Century – Enterprise Era"
  items: StarTrekItem[]
}

interface StarTrekItem {
  id: string        // e.g., 'ent_s1', 'tos_tmp'
  type: string      // 'series', 'movie', 'animated'
  stardate: string  // "~1.1-1.26" or "Stardate 7410.2"
}

πŸ—“οΈ Chronological Coverage

The viewing guide follows this chronological progression by in-universe stardate:

  1. 22nd Century - Enterprise Era (2151-2161)
  2. Mid-23rd Century - Discovery & Strange New Worlds Era (2256-2261)
  3. 23rd Century - Original Series Era (2265-2293)
  4. 24th Century - Next Generation Era (2364-2379)
  5. Late 24th Century - Lower Decks & Prodigy Era (2380-2383)
  6. 25th Century - Picard Era (2399-2401)
  7. 32nd Century - Far Future Discovery Era (3188-3191)

Deployment

The application is automatically deployed to GitHub Pages via GitHub Actions:

Browser Compatibility

  • βœ… Chrome 90+
  • βœ… Firefox 90+
  • βœ… Safari 14+
  • βœ… Edge 90+

Modern browsers with ES2020+ support are required.

Contributing

Contributions are welcome! Here's how to get involved:

Ways to Contribute

  • Content Updates: Add new series, correct stardate information, improve viewing notes
  • Bug Fixes: Report and fix issues with the interface or functionality
  • Feature Enhancements: Implement new features like episode-level tracking
  • Documentation: Improve README, add code comments, write guides

Development Setup

  1. Fork this repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes and test thoroughly
  4. Ensure all tests pass (pnpm test)
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

Data Updates

VBS uses an automated data generation pipeline to maintain up-to-date Star Trek content:

Automated Data Generation System

The generate-star-trek-data.ts script fetches metadata from multiple authoritative sources (TMDB, Memory Alpha, TrekCore, STAPI), validates data quality, and generates the star-trek-data.ts file programmatically.

Key Features:

  • Multi-Source Aggregation: Combines data from 4+ sources with intelligent conflict resolution
  • Quality Scoring: Comprehensive validation ensures data completeness and accuracy (minimum score: 0.6)
  • Production Module Integration: Reuses battle-tested VBS metadata infrastructure
  • Incremental Updates: Preserves manual annotations while updating from authoritative sources
  • Type-Safe Generation: Creates TypeScript code with full type safety and validation

Running Data Generation:

# Copy environment template (TMDB API key optional but recommended)
cp .env.example .env

# Full regeneration with validation
pnpm exec jiti scripts/generate-star-trek-data.ts --mode full --validate

# Incremental update for specific series
pnpm exec jiti scripts/generate-star-trek-data.ts --mode incremental --series discovery

# Dry run to preview changes
pnpm exec jiti scripts/generate-star-trek-data.ts --dry-run --verbose

πŸ“š Complete Documentation:

GitHub Actions Workflow

Automated updates via GitHub Actions:

  • Weekly Updates: Automated checks for new Star Trek content every Monday
  • Manual Triggers: On-demand updates via GitHub Actions UI
  • Quality Assurance: Automated validation and quality checks before merging
  • Pull Request Reviews: All data updates reviewed for accuracy

See docs/automated-data-updates.md for GitHub Actions workflow details.

Contributing Data

When contributing data updates:

  1. Use automated generation when possible for consistency
  2. Validate quality: Run pnpm exec jiti scripts/validate-episode-data.ts before submitting
  3. Document sources: Include references to Memory Alpha or TMDB
  4. Test integration: Ensure changes don't break existing functionality (pnpm test)
  5. Manual curations: Add custom notes or corrections as needed (preserved in incremental mode)

Planned Features

  • Episode-Level Tracking: Individual episode progress vs current season-level
  • Interactive Timeline: D3.js chronological visualization with zoom/pan
  • Streaming Integration: Paramount+/Netflix availability via APIs
  • PWA Capabilities: Offline support and app installation

Acknowledgments

  • Gene Roddenberry and all Star Trek creators for the incredible universe
  • Memory Alpha contributors for maintaining comprehensive Star Trek databases
  • Star Trek fans worldwide who keep the spirit of exploration alive
  • Open source community for tools and inspiration

Live long and prosper! πŸ––

Releases

No releases published

Sponsor this project

 

Packages

No packages published

Contributors 2

  •  
  •