Architecture

Understanding BetterSEQTA-Plus system architecture

Architecture Overview

BetterSEQTA-Plus follows a browser extension architecture with clear separation between content scripts, background scripts, and UI components.

System Architecture

┌─────────────────────────────────────────┐
│         SEQTA Learn Page                │
│  ┌──────────────────────────────────┐  │
│  │   Content Scripts                │  │
│  │   - Feature Injection            │  │
│  │   - DOM Manipulation             │  │
│  │   - Event Handling               │  │
│  └──────────────────────────────────┘  │
└──────────────┬───────────────────────────┘
               │ Messages
┌──────────────▼───────────────────────────┐
│      Background Service Worker           │
│  ┌──────────────────────────────────┐  │
│  │   State Management               │  │
│  │   Message Routing                │  │
│  │   Storage Management             │  │
│  └──────────────────────────────────┘  │
└──────────────┬───────────────────────────┘
               │
┌──────────────▼───────────────────────────┐
│      Extension UI                        │
│  ┌──────────┐  ┌──────────┐            │
│  │  Popup   │  │ Options  │            │
│  └──────────┘  └──────────┘            │
└─────────────────────────────────────────┘

Component Layers

Content Scripts

Content scripts run in the context of web pages:

Responsibilities:

  • Inject features into SEQTA pages
  • Manipulate DOM
  • Listen for page events
  • Communicate with background

Location: src/content/

Example:

// src/content/main.ts
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === 'enhancePage') {
    enhanceSEQTA();
    sendResponse({ success: true });
  }
});

Background Scripts

Background scripts handle extension logic:

Responsibilities:

  • Manage extension state
  • Handle messages
  • Manage storage
  • Coordinate features

Location: src/background/

Example:

// src/background/service-worker.ts
chrome.runtime.onInstalled.addListener(() => {
  // Initialize extension
});

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  // Handle messages from content scripts
});

Popup provides quick access to settings:

Responsibilities:

  • Display quick settings
  • Show feature toggles
  • Provide extension info

Location: src/popup/

Options Page

Options page for full settings:

Responsibilities:

  • Full settings interface
  • Feature configuration
  • Import/export settings

Location: src/options/

Message Passing

Content → Background

// Content script
chrome.runtime.sendMessage(
  { action: 'getSettings' },
  (response) => {
    console.log(response.settings);
  }
);

Background → Content

// Background script
chrome.tabs.sendMessage(tabId, {
  action: 'updateFeatures',
  features: enabledFeatures
});
// Popup
chrome.runtime.sendMessage({ action: 'toggleFeature', id: 'darkMode' });

// Background
chrome.runtime.onMessage.addListener((message) => {
  if (message.action === 'toggleFeature') {
    // Toggle feature
  }
});

Storage Management

Chrome Storage API

// Save settings
chrome.storage.sync.set({ theme: 'dark' }, () => {
  console.log('Settings saved');
});

// Load settings
chrome.storage.sync.get(['theme'], (result) => {
  console.log(result.theme);
});

Storage Areas

  • sync: Synced across devices (limited size)
  • local: Local to device (larger size)
  • session: Session-only storage

Feature System

Feature Architecture

interface Feature {
  id: string;
  name: string;
  enabled: boolean;
  init: () => void;
  destroy: () => void;
}

class FeatureManager {
  private features: Map<string, Feature> = new Map();
  
  register(feature: Feature) {
    this.features.set(feature.id, feature);
  }
  
  enable(id: string) {
    const feature = this.features.get(id);
    if (feature) {
      feature.enabled = true;
      feature.init();
    }
  }
  
  disable(id: string) {
    const feature = this.features.get(id);
    if (feature) {
      feature.enabled = false;
      feature.destroy();
    }
  }
}

Security Considerations

Content Security Policy

  • Follow CSP requirements
  • Use safe DOM manipulation
  • Avoid inline scripts
  • Use extension APIs properly

Permissions

Request only necessary permissions:

{
  "permissions": [
    "storage",
    "scripting",
    "activeTab"
  ]
}

Performance Optimization

Lazy Loading

Load features only when needed:

async function loadFeature(featureId: string) {
  const module = await import(`./features/${featureId}.ts`);
  return module.default;
}

Efficient DOM Manipulation

// ✅ Good - Batch DOM updates
const fragment = document.createDocumentFragment();
items.forEach(item => {
  fragment.appendChild(createElement(item));
});
container.appendChild(fragment);

// ❌ Avoid - Multiple DOM updates
items.forEach(item => {
  container.appendChild(createElement(item));
});

Next Steps