StreamerDeckLists

Streamer Deck Lists

A tournament stream deck list viewer with real-time Ably integration for broadcasting card displays. This project enables streamers to display card images during tournaments with smooth animations and real-time synchronization.

๐Ÿš€ Key Features

Core Functionality

Technical Features

๐Ÿ—๏ธ Architecture

Publisher/Subscriber Pattern

State Management

Data Architecture

TypeScript Module Architecture

The streamer controls were completely refactored from streamer.html (inline JavaScript) to tam/streamerControls/index.html with a modern TypeScript architecture:

Core Modules (src/typescript/streamerControls/)

Refactoring Benefits

The migration from streamer.html to tam/streamerControls/index.html provided significant improvements:

Before (Legacy streamer.html):

After (tam/streamerControls/index.html):

Build System Integration

๐Ÿ“‹ Prerequisites

๐Ÿ› ๏ธ Setup Instructions

1. Get Ably Credentials

  1. Create Ably App:
  2. Create API Key:
    • In your Ably app, go to API Keys
    • Create a new API key with capabilities: publish, subscribe, presence, history, object_publish, object_subscribe (required for LiveObjects)
    • Copy the full API key string

2. Configure Token Authentication

Since token generation has been moved to a separate service, you need to:

  1. Set up your token service to generate Ably tokens securely
  2. Update configuration to point to your token endpoint:
    • tam/index.html: Set TOKEN_ENDPOINT in the broadcast view
    • tam/streamerControls/index.html: Token endpoint is configured in StreamerController.ts
    • Update src/typescript/streamerControls/StreamerController.ts line 27: tokenEndpoint property
  3. Ensure your token service returns:
     {
         "appId": "your-ably-app-id",
         "tokenRequest": {
             "keyName": "your-app.your-key",
             "clientId": "streamer-publisher",
             "timestamp": 1234567890,
             "nonce": "unique-nonce",
             "mac": "signature",
             "ttl": 3600000
         },
         "expiresAt": 1234567890,
         "generatedAt": 1234567890
     }
    

3. Deploy

  1. Configure GitHub Pages:
    • Go to your repository โ†’ Settings โ†’ Pages
    • Set source to โ€œDeploy from a branchโ€
    • Select branch: main or gh-pages
    • Save
  2. Deploy:
    • Push your changes to trigger automatic deployment
    • Verify the site loads and token authentication works

๐Ÿ“ Project Structure

โ”œโ”€โ”€ tam/                          # Main tournament application
โ”‚   โ”œโ”€โ”€ index.html                # Broadcast view (subscriber only)
โ”‚   โ”œโ”€โ”€ streamer.html             # Streamer view (publisher only)
โ”‚   โ””โ”€โ”€ admin/                    # Admin control panel
โ”‚       โ””โ”€โ”€ index.html            # Admin refresh control panel
โ”œโ”€โ”€ cardChecker/                  # Card checker utility
โ”‚   โ”œโ”€โ”€ index.html                # Card checker interface
โ”‚   โ””โ”€โ”€ assets/                   # Card checker specific assets
โ”‚       โ”œโ”€โ”€ css/                  # Compiled CSS for card checker
โ”‚       โ”‚   โ”œโ”€โ”€ card-checker.css  # Compiled card checker styles
โ”‚       โ”‚   โ””โ”€โ”€ card-checker.css.map # Source maps
โ”‚       โ”œโ”€โ”€ js/                   # Compiled JavaScript
โ”‚       โ”‚   โ”œโ”€โ”€ card-checker.min.js # Main application logic (minified)
โ”‚       โ”‚   โ”œโ”€โ”€ card-checker.min.js.map # Source maps
โ”‚       โ”‚   โ”œโ”€โ”€ card-item-component.min.js # Web component (minified)
โ”‚       โ”‚   โ””โ”€โ”€ card-item-component.min.js.map # Source maps
โ”‚       โ”œโ”€โ”€ scss/                 # SASS source files
โ”‚       โ”‚   โ””โ”€โ”€ card-checker.scss # Card checker styles
โ”‚       โ””โ”€โ”€ ts/                   # TypeScript source files
โ”‚           โ”œโ”€โ”€ card-checker.ts   # Main application logic with simplified Card interface
โ”‚           โ””โ”€โ”€ card-item-component.ts # Web component for card display
โ”œโ”€โ”€ deckViewer/                   # Deck viewer utility
โ”‚   โ”œโ”€โ”€ index.html                # Deck viewer interface
โ”‚   โ””โ”€โ”€ assets/                   # Deck viewer specific assets
โ”‚       โ”œโ”€โ”€ css/                  # Compiled CSS for deck viewer
โ”‚       โ”‚   โ”œโ”€โ”€ deck-viewer.css   # Compiled deck viewer styles
โ”‚       โ”‚   โ””โ”€โ”€ deck-viewer.css.map # Source maps
โ”‚       โ”œโ”€โ”€ js/                   # Compiled JavaScript
โ”‚       โ”‚   โ”œโ”€โ”€ deck-viewer.min.js # Main application logic (minified)
โ”‚       โ”‚   โ”œโ”€โ”€ deck-viewer.min.js.map # Source maps
โ”‚       โ”‚   โ”œโ”€โ”€ deck-card-item.min.js # Card item web component (minified)
โ”‚       โ”‚   โ”œโ”€โ”€ deck-card-item.min.js.map # Source maps
โ”‚       โ”‚   โ”œโ”€โ”€ deck-section.min.js # Section web component (minified)
โ”‚       โ”‚   โ”œโ”€โ”€ deck-section.min.js.map # Source maps
โ”‚       โ”‚   โ”œโ”€โ”€ deck-info-panel.min.js # Info panel web component (minified)
โ”‚       โ”‚   โ””โ”€โ”€ deck-info-panel.min.js.map # Source maps
โ”‚       โ”œโ”€โ”€ scss/                 # SASS source files
โ”‚       โ”‚   โ””โ”€โ”€ deck-viewer.scss  # Deck viewer styles
โ”‚       โ””โ”€โ”€ ts/                   # TypeScript source files
โ”‚           โ”œโ”€โ”€ deck-viewer.ts    # Main application logic with namespaced interfaces
โ”‚           โ”œโ”€โ”€ deck-card-item.ts # Card item web component
โ”‚           โ”œโ”€โ”€ deck-section.ts   # Section web component
โ”‚           โ””โ”€โ”€ deck-info-panel.ts # Info panel web component
โ”œโ”€โ”€ flipDemo/                     # Animation demo
โ”‚   โ””โ”€โ”€ index.html                # Flip animation demonstration
โ”œโ”€โ”€ assets/
โ”‚   โ”œโ”€โ”€ css/                      # Compiled CSS files
โ”‚   โ”‚   โ”œโ”€โ”€ index.css             # Broadcast view styles
โ”‚   โ”‚   โ”œโ”€โ”€ index.css.map         # Source maps for broadcast view
โ”‚   โ”‚   โ”œโ”€โ”€ streamer.css          # Streamer view styles
โ”‚   โ”‚   โ””โ”€โ”€ streamer.css.map      # Source maps for streamer view
โ”‚   โ”œโ”€โ”€ images/                   # Card images (WebP format, 1186 files)
โ”‚   โ””โ”€โ”€ js/                       # Compiled JavaScript (currently empty)
โ”œโ”€โ”€ deck_viewer.html              # Legacy deck viewer (deprecated)
โ”œโ”€โ”€ decks.json                    # Tournament deck data (minified JSON, 11k+ lines)
โ”‚   # Contains player information, deck names, and complete card listings
โ”‚   # Structure: [{ player, deckName, character, character_slot, main_deck }]
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ styles/                   # SASS build system
โ”‚   โ”‚   โ”œโ”€โ”€ index.scss            # Broadcast view SASS entry point
โ”‚   โ”‚   โ”œโ”€โ”€ main.scss             # Main SASS entry point
โ”‚   โ”‚   โ”œโ”€โ”€ streamer.scss         # Streamer view SASS entry point
โ”‚   โ”‚   โ”œโ”€โ”€ cardChecker/          # Card checker specific styles (directory)
โ”‚   โ”‚   โ”œโ”€โ”€ components/           # Component-specific styles
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ _broadcast.scss   # Broadcast view components
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ _streamer.scss    # Streamer view components
โ”‚   โ”‚   โ””โ”€โ”€ utilities/            # Utility styles and mixins
โ”‚   โ”‚       โ”œโ”€โ”€ _variables.scss   # SASS variables and colors
โ”‚   โ”‚       โ””โ”€โ”€ _mixins.scss      # Reusable SASS mixins
โ”‚   โ”œโ”€โ”€ test/                     # Test suite
โ”‚   โ”‚   โ”œโ”€โ”€ setup.ts              # Test configuration
โ”‚   โ”‚   โ”œโ”€โ”€ broadcast-view.test.ts # Broadcast view tests
โ”‚   โ”‚   โ”œโ”€โ”€ streamer-view.test.ts  # Streamer view tests
โ”‚   โ”‚   โ”œโ”€โ”€ ably-integration.test.ts # Ably integration tests
โ”‚   โ”‚   โ””โ”€โ”€ system.test.ts        # System tests
โ”‚   โ””โ”€โ”€ typescript/               # TypeScript source directory (currently empty)
โ”œโ”€โ”€ .github/
โ”‚   โ””โ”€โ”€ workflows/
โ”‚       โ””โ”€โ”€ static.yml            # GitHub Pages deployment workflow
โ”œโ”€โ”€ .husky/                       # Git hooks directory
โ”‚   โ””โ”€โ”€ pre-commit                # Pre-commit hook for SASS building
โ”œโ”€โ”€ .vscode/
โ”‚   โ””โ”€โ”€ settings.json             # VS Code workspace settings
โ”œโ”€โ”€ .cursorrules                  # Development guidelines
โ”œโ”€โ”€ prettier.config.mjs           # Prettier configuration
โ”œโ”€โ”€ tsconfig.json                 # TypeScript configuration
โ”œโ”€โ”€ vitest.config.js              # Vitest configuration
โ”œโ”€โ”€ package.json                  # Node.js dependencies
โ””โ”€โ”€ README.md                     # Main documentation

๐Ÿงช Testing

Local Development

# Install dependencies
npm install

# Run tests
npm test

# Run tests with UI
npm run test:ui

# Watch mode for development
npm run test:watch

# SASS development
npm run build:sass        # Build all SASS files
npm run build:index       # Build broadcast view styles only
npm run build:streamer    # Build streamer view styles only
npm run watch:index       # Watch broadcast view SASS files
npm run watch:streamer    # Watch streamer view SASS files

# TypeScript development (for card checker)
npm run build:typescript  # Build and minify TypeScript
npm run watch:typescript  # Watch TypeScript files

# Complete build
npm run build            # Build all assets (SASS + TypeScript + Card Checker)

# Development workflow
# 1. Edit SCSS files in src/styles/
# 2. Run appropriate watch command for live compilation
# 3. Changes are automatically compiled to assets/css/
# 4. Commit changes (pre-commit hook checks CSS status)

Manual Testing

  1. Local Testing:
    • Open tam/index.html and tam/streamer.html in browser
    • Use browser dev tools for debugging
    • Check console for debug information
    • Verify deck data loads from decks.json
    • Test card checker at cardChecker/index.html
    • View animation demo at flipDemo/index.html

Test Coverage Goals

The project maintains comprehensive test coverage across multiple dimensions:

Coverage Targets

Test Coverage Matrix

Component Unit Tests Integration Tests Error Handling
Ably Integration โœ… Auth, messaging โœ… Real-time sync โœ… Network failures
Animation System โœ… Flip/slide logic โœ… Queue management โœ… Image load errors
Deck Data โœ… JSON parsing โœ… UI population โœ… Fetch failures
Player Selection โœ… Dropdown logic โœ… Selection handling โœ… Empty data
Heartbeat System โœ… Timer logic โœ… Connection monitoring โœ… Timeout recovery
UI Components โœ… Structure validation โœ… Responsive design โœ… Missing elements

Testing Framework

This project uses a comprehensive testing strategy combining unit tests (Vitest + JSDOM) for pure JavaScript logic and E2E tests (Playwright) for DOM interactions, animations, and integration testing.

Test Organization

Tests are organized into logical directories for easy identification and maintenance:

src/test/
โ”œโ”€โ”€ broadcast/           # Broadcast Module Tests (44 tests)
โ”‚   โ”œโ”€โ”€ AblyManager.test.ts      # Tests src/typescript/broadcast/AblyManager.ts
โ”‚   โ”œโ”€โ”€ AdminHandler.test.ts     # Tests src/typescript/broadcast/AdminHandler.ts
โ”‚   โ”œโ”€โ”€ ImagePreloader.test.ts   # Tests src/typescript/broadcast/ImagePreloader.ts
โ”‚   โ””โ”€โ”€ MessageQueue.test.ts     # Tests src/typescript/broadcast/MessageQueue.ts
โ”œโ”€โ”€ streamer/            # Streamer Module Tests (44 tests)
โ”‚   โ””โ”€โ”€ StreamerController.test.ts # Tests src/typescript/streamerControls/*.ts
โ”œโ”€โ”€ modules/             # Standalone Module Tests (45 tests)
โ”‚   โ”œโ”€โ”€ CardChecker.test.ts      # Tests cardChecker/assets/ts/card-checker.ts
โ”‚   โ”œโ”€โ”€ DeckViewer.test.ts       # Tests deckViewer/assets/ts/deck-viewer.ts
โ”‚   โ””โ”€โ”€ DeckViewerComponents.test.ts # Tests deck viewer interfaces
โ””โ”€โ”€ system/              # System & Integration Tests (60 tests)
    โ”œโ”€โ”€ AblyIntegration.test.ts  # Tests Ably SDK integration
    โ”œโ”€โ”€ BuildSystem.test.ts      # Tests build system processes
    โ””โ”€โ”€ SystemArchitecture.test.ts # Tests overall system architecture
Coverage Strategy: 77.31% Overall
Module Category Coverage Strategy
Streamer Controls 81.73% Unit tests for pure logic
Card Checker 99.01% Unit tests + E2E for web components
Deck Viewer 91.66% Unit tests + E2E for web components
Broadcast Modules 49.85% Unit tests for testable logic, E2E for DOM/animations
Coverage Ignore Strategy

We use /* c8 ignore start/stop */ comments to exclude code thatโ€™s better tested via E2E:

/* c8 ignore start */
// DOM initialization - tested via Playwright E2E
document.addEventListener('DOMContentLoaded', async () => {
    // ... DOM manipulation code
});
/* c8 ignore stop */

Whatโ€™s Ignored from Unit Tests:

Whatโ€™s Unit Tested:

Test Framework Stack

Unit Testing (Vitest + JSDOM)

E2E Testing (Playwright)

Running Tests
# Unit Tests
npm test                 # Interactive mode
npm run test:ci          # CI mode with coverage
npm run test:watch       # Watch mode
npm run test:ui          # Vitest UI

# E2E Tests
npm run test:e2e         # Run Playwright tests
npm run test:e2e:ui      # Playwright UI mode
npm run test:e2e:headed  # Run with browser visible
npm run test:e2e:debug   # Debug mode

# Coverage Analysis
npm run test:ci -- --coverage           # Unit test coverage
npm run test:e2e:coverage              # E2E coverage
npm run coverage:combined              # Combined analysis

๐ŸŽจ SASS Build System

Overview

This project uses SASS (Syntactically Awesome StyleSheets) with an automated build system that compiles SCSS files to compressed CSS with source maps.

Features

Build Process

  1. Edit SASS files in src/styles/ directory (tracked in Git)
  2. Use watch mode during development: npm run watch:sass
  3. Automatic compilation happens on every commit via Git hooks
  4. Source maps are generated for debugging
  5. Both SCSS source and compiled CSS are committed automatically

Key Features

Available SASS Scripts

# Build all SASS files
npm run build:sass

# Build specific views
npm run build:index       # Broadcast view only
npm run build:streamer    # Streamer view only

# Watch mode for development (continuous compilation)
npm run watch:index       # Watch broadcast view
npm run watch:streamer    # Watch streamer view

# Build all assets (SASS + TypeScript + Card Checker)
npm run build

Pre-commit Automation

The project uses Git hooks to check SASS compilation status on every commit:

Manual SASS Building

Since automatic compilation in git hooks can be unreliable due to Node.js environment differences, please:

  1. Make SASS changes in src/styles/ directory
  2. Build CSS manually: Run npm run build:sass (or specific view commands)
  3. Verify CSS output in assets/css/index.css, assets/css/streamer.css, and assets/css/admin.css
  4. Commit both SCSS source and compiled CSS files

This ensures reliable builds and proper version control of both source and compiled assets.

๐Ÿ“Š Deck Data Structure

decks.json Format

The deck data file contains an array of player deck objects with the following structure:

[
    {
        "player": "Player Name",
        "deckName": "Deck Display Name",
        "character": "Character Name",
        "character_slot": [
            {
                "type": "Characters",
                "cards": [
                    {
                        "qty": 1,
                        "card": "Character Card Name",
                        "img": "character-image.webp",
                        "blockZone": "mid",
                        "backside": null
                    }
                ]
            }
        ],
        "main_deck": [
            {
                "type": "Attacks",
                "cards": [
                    {
                        "qty": 4,
                        "card": "Attack Card Name",
                        "img": "attack-image.webp",
                        "blockZone": "high",
                        "backside": {
                            "name": "Backside Card Name",
                            "img": "backside-image.webp"
                        }
                    }
                ]
            }
        ]
    }
]

Data Properties

Field Type Description
player string Playerโ€™s display name (used in dropdown)
deckName string Full deck name for display
character string Main character name
character_slot array Character slot sections
main_deck array Main deck sections by card type

Card Object Schema

Field Type Description
qty number Number of copies of this card
card string Full card name
img string Image filename (relative to assets/cardImages/)
blockZone enum Block zone: "high", "mid", "low", "none"
backside object? Optional flip card info with name and img

Implementation Details

Aspect Details
Loading tam/streamer.html fetches decks.json at runtime via fetch()
UI Population Player dropdowns auto-populate from player + deckName
Card Broadcasting Click handlers broadcast selected cards via Ably
Image Resolution All img paths prefixed with assets/cardImages/
Error Handling Graceful fallbacks for network/parsing failures
File Format Minified single-line JSON (excluded from Prettier)
Performance Large dataset (11k+ lines) optimized for speed

Development Workflow

  1. Edit SASS files in src/styles/ directory
  2. Save changes - auto-compilation happens in watch mode
  3. Commit changes - pre-commit hook compiles and commits CSS automatically
  4. CSS is ready for production with compression and source maps

Key SASS Features Used

Variables

$primary-color: #007bff;
$spacer: 1rem;
$border-radius: 0.375rem;

Mixins

@mixin button-variant($color, $background, $border) {
    color: $color;
    background-color: $background;
    border-color: $border;
}

Responsive Design

@include media-breakpoint-up(md) {
    .card-grid {
        grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    }
}

Git Integration

VS Code Integration

For the best development experience, install the โ€œLive SASS Compilerโ€ extension:

  1. Open VS Code Extensions (Ctrl+Shift+X / Cmd+Shift+X)
  2. Search for โ€œLive SASS Compilerโ€ by Ritwick Dey
  3. Install and configure:
     {
         "liveSassCompile.settings.formats": [
             {
                 "format": "compressed",
                 "extensionName": ".css",
                 "savePath": "/src/styles"
             }
         ],
         "liveSassCompile.settings.includeItems": ["/src/styles/**/*.scss"]
     }
    

Benefits

๐ŸŽฎ Admin Refresh System

Overview

The admin system provides remote refresh control for stream displays, enabling instant refresh of broadcast views across multiple windows, tabs, and iframe embeds.

Key Features

Architecture

Admin Panel (/tam/admin/index.html)

Stream Display Integration (/tam/index.html)

Communication Methods

  1. PostMessage: Direct communication with named windows or parent/opener
  2. localStorage: Cross-tab broadcasting for same-domain windows
  3. BroadcastChannel: Modern API for efficient cross-context messaging

Usage

  1. Open Admin Panel: Navigate to /tam/admin/index.html
  2. Choose Refresh Type:
    • ๐Ÿ“บ Refresh Broadcast: Refreshes the stream display itself (useful for clearing animations, resetting state)
    • ๐ŸŽฎ Refresh Stream Controls: Refreshes the parent page containing stream controls (useful when controls are in a separate window/iframe)
  3. Automatic Refresh: Targeted refresh happens based on button clicked

Cross-Origin Support

SCSS Integration

๐Ÿ” Card Checker Utility

Overview

The Card Checker is a standalone utility located in cardChecker/ that provides a comprehensive view of all unique cards across all tournament decks. It features advanced filtering, search capabilities, and a modern web component architecture.

Key Features

Architecture Improvements

The Card Checker has been significantly simplified with a cleaner TypeScript architecture:

Simplified Interface

interface Card {
    card: string; // Card name
    img?: string; // Image filename
    qty: number; // Quantity in deck
    symbols?: string[]; // Card symbols for filtering
    blockZone?: string; // Block zone: "high", "mid", "low", "none"
    type?: string; // Card type: "Characters", "Attacks", etc.
    backside?: {
        // Optional flip card info
        name: string;
        img: string;
    } | null;
}

Key Improvements Made

Data Processing

// Extract unique cards using Set for simplicity
const uniqueCards = new Set<string>();
const allCards: Card[] = [];

// Process all sections uniformly
sections.forEach((section) => {
    if (section.cards) {
        section.cards.forEach((card) => {
            if (card && card.card && !uniqueCards.has(card.card)) {
                uniqueCards.add(card.card);
                allCards.push({
                    ...card,
                    type: section.type || 'Unknown',
                    blockZone: card.blockZone || 'unknown',
                });
            }
        });
    }
});

Usage

  1. Navigate to cardChecker/index.html
  2. Browse all unique cards from the tournament
  3. Use filters to find specific cards by type, symbol, or block zone
  4. Search by name using the text input
  5. View live statistics of total and filtered card counts

Development

๐Ÿ” Deck Viewer Utility

Overview

The Deck Viewer is a modernized version of the original deck viewer with component-based architecture. It provides a comprehensive view of individual player decks with enhanced web components and clean TypeScript architecture.

Key Features

Web Components

<deck-card-item>

Displays individual cards with image, name, quantity, and metadata.

<deck-card-item card-name="Attack Card" quantity="4" image="attack.webp" block-zone="high"> </deck-card-item>

<deck-section>

Organizes cards by sections (Character, Main Deck, Side Board) with type groupings.

<deck-section section-name="Main Deck" section-data='[{"type":"Attacks","cards":[...]}]'> </deck-section>

<deck-info-panel>

Displays player information, deck name, character, and statistics.

<deck-info-panel
    player-name="Player Name"
    deck-name="Deck Name"
    character="Character"
    main-deck-count="40"
    side-board-count="15"
>
</deck-info-panel>

TypeScript Architecture

Uses namespaced interfaces to avoid conflicts with other modules:

namespace DeckViewer {
    export interface Card {
        card: string;
        img?: string;
        qty: number;
        blockZone?: string;
        backside?: { name: string; img: string } | null;
    }

    export interface Section {
        type: string;
        cards: Card[];
    }

    export interface PlayerDeck {
        player: string;
        deckName?: string;
        character?: string;
        character_slot?: Section[];
        main_deck?: Section[];
        side_board?: Section[];
    }
}

Usage

  1. Navigate to deckViewer/index.html
  2. Select a player from the dropdown
  3. View complete deck with organized sections
  4. See statistics including card counts
  5. Responsive design works on all devices

Development

Key Improvements

๐Ÿ”’ Security

Token Authentication Benefits

Benefit Description
Short-lived Tokens expire automatically, limiting exposure
Revocable Can be revoked immediately if compromised
Scoped Tokens have only necessary permissions
Secure API keys never exposed in client code
Auto-refresh SDK handles renewal automatically

Security Checklist

Debug Functions

In development mode, these functions are available in the browser console:

// Broadcast view debugging
window.debugBroadcast.updateMainImage('path/to/card.webp');
window.debugBroadcast.resetToCardBack();
window.debugBroadcast.currentCardImage();
window.debugBroadcast.isAnimating();

// Streamer view debugging
window.debugBroadcastController.broadcastMainImageUpdate('path/to/card.webp');
window.debugBroadcastController.isConnected();
window.debugBroadcastController.testBroadcast();

๐Ÿ”ง Configuration

Token Capabilities

The generated tokens have these capabilities for the tournament-stream channel:

Animation System

The broadcast view uses a sophisticated two-image keyframes animation system for smooth card transitions:

Two-Image Structure

<div class="card-scene">
    <div class="card">
        <div class="card-face card-back">
            <img src="card_back.webp" id="backImage" />
        </div>
        <div class="card-face card-front">
            <img src="current_card.webp" id="frontImage" />
        </div>
    </div>
</div>

Animation Types

Animation Trigger Duration Method
Flip Card back โ†” Card front 0.5s CSS keyframes with 3D transforms
Slide Card front โ†’ Different card 0.5s Temporary DOM element overlay

Animation Logic

State Management:

Card Back Showing + New Card:

  1. Preload new image
  2. Update card-front src
  3. Trigger cardFlip keyframes animation
  4. Result: card-front now visible on top

Card Front Showing + New Card:

  1. Create temporary sliding image
  2. Slide from left edge to cover card
  3. Update card-front src underneath
  4. Remove sliding image after load

Reset to Card Back:

Technical Features

Integration Flow

graph LR
    A[decks.json] --> B[Player Dropdown]
    B --> C[Card Selection]
    C --> D[Ably Broadcast]
    D --> E[Live Display]

CSS Styling Approach

.broadcast-iframe {
    width: 300px;
    height: 420px;
    border: none;
    background: transparent;
    display: block;
    margin: 0 auto;
}

Heartbeat System

The application uses heartbeat mechanisms to maintain connection health and handle visibility changes:

Debug Heartbeat

// Check last heartbeat timestamp
window.debugBroadcast.getHeartbeat();

// Get heartbeat age in minutes/seconds
window.debugBroadcast.getHeartbeatAge();

๐Ÿšจ Troubleshooting

Common Issues

  1. โ€œToken not configuredโ€ error:
    • Check that your token endpoint is properly configured
    • Verify the token service is accessible
    • Check browser console for detailed error messages
  2. โ€œFailed to initialize Ablyโ€ error:
    • Check browser console for detailed error messages
    • Verify token request format is correct
    • Ensure Ably account has sufficient quota
  3. Connection issues:
    • Ensure your Ably account has sufficient quota
    • Check that the channel name matches in both files
    • Verify network connectivity
  4. Animation issues:
    • Check that images are loading correctly
    • Verify CSS transitions are working
    • Check for JavaScript errors in console
  5. Heartbeat issues:
    • Verify heartbeat is running every 30 minutes in console logs (โ€œ๐Ÿ’“ Heartbeat sentโ€)
    • Check debug functions for recent activity
    • Ensure connection is stable for heartbeat transmission

Debug Information

The workflow outputs:

๐Ÿ“š Resources

๐Ÿ”’ Security

Security Features

Security Checklist

๐Ÿ’ป Development

Quick Start

# Setup
npm install                 # Install dependencies
npm run build              # Build all assets (SASS + TypeScript)

# Development
npm run watch:index        # Watch broadcast view SASS
npm run watch:streamer     # Watch streamer view SASS
npm run watch:typescript   # Watch TypeScript files
npm run test:watch         # Watch mode testing

# Quality
npm test                   # Run all tests
npm run format             # Format code

Development Standards

Aspect Standard
Code Style Prettier with 2-space indentation
Testing Vitest with 70%+ coverage
Styling SASS with BEM methodology
Commits Conventional commits

Contributing Workflow

  1. Fork & Branch: git checkout -b feature/your-feature
  2. Develop: Add tests, implement feature
  3. Quality: npm test && npm run format
  4. Submit: Open Pull Request with description

๐Ÿ”จ Build Process & Pre-commit Hooks

Automated Build System

The project uses Husky pre-commit hooks to automatically build and stage compiled assets when source files change:

TypeScript Build Process

SASS Build Process

Pre-commit Hook Features

โœ… Smart Detection - Only builds what changed (TypeScript, SASS, etc.)
โœ… Automatic Cleanup - Removes temporary build directories (compiled-ts/)
โœ… Auto-staging - Adds compiled assets to git commit automatically
โœ… Build Verification - Ensures no temporary directories remain
โœ… Comprehensive Coverage - Handles all project modules (main, cardChecker, deckViewer)

Manual Build Commands

# Build everything
npm run build

# Build specific components
npm run build:typescript    # All TypeScript projects
npm run build:sass         # Main project SASS
npm run build:cardchecker   # Card checker (SASS only)
npm run build:deckviewer    # Deck viewer (SASS + TypeScript)

# Watch modes for development
npm run watch:sass          # Watch main SASS files
npm run watch:typescript    # Watch all TypeScript files
npm run watch:cardchecker   # Watch card checker SASS
npm run watch:deckviewer    # Watch deck viewer files

# Cleanup commands
npm run clean:typescript    # Remove compiled-ts directory
npm run clean:all          # Remove all compiled assets

Development Workflow

  1. Edit source files (.ts, .scss) - tracked in git
  2. Use watch mode during development for live compilation
  3. Commit changes - pre-commit hook automatically builds and stages assets
  4. No manual compilation needed - everything is automated!

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ†˜ Support

Issue Type Resource
General Issues Troubleshooting Guide
Ably Integration Ably Documentation
Deployment GitHub Actions logs
Bugs/Features GitHub Issues