MOOC Utils

Utils like auto assignment solver extension and course notice announcment notification for MOOC courses

Service initialization

Introduction#

How the background worker boots: dependency injection, platform adapters, service construction, and logging. Read this before changing startup order.

Project structure#

The service worker entry point initializes logging, platform adapters, services, handlers, and registers the message router. Platform adapters abstract browser APIs for cross-browser compatibility. Services encapsulate business logic and expose factory functions that accept a dependency bag. Handlers are factory-created functions that receive adapters and logger instances. The router dispatches incoming messages to the appropriate handler.

Core components#

  • Background entry point: Initializes logger, platform adapters, services, handlers, and registers the message router.
  • Platform adapters: Provide cross-browser wrappers around browser APIs (runtime, tabs, scripting, panel, storage, browser detection).
  • Services: Factory-created modules exposing business logic (Gemini service, storage service).
  • Handlers: Factory-created functions receiving adapters and logger to process messages.
  • Router: Central dispatcher that invokes handlers and keeps response semantics.

Architecture overview#

The initialization follows a deterministic sequence:

  1. Logger creation with a contextual prefix.
  2. Platform adapter creation using factory functions.
  3. Service instantiation with dependency bags containing adapters and logger.
  4. Handler creation with dependency bags.
  5. Router creation and registration with the runtime adapter.
  6. UI interaction setup (icon click and panel behavior).

Detailed component analysis#

Background initialization sequence#

  • Logger initialization occurs first to enable logging throughout the startup process.
  • Platform adapters are created and configured for cross-browser compatibility.
  • Services are instantiated with dependency bags containing adapters and logger.
  • Handlers are created with dependency bags and registered under message types.
  • The router is created and attached to the runtime adapter’s message listener.
  • UI integration sets up icon click behavior and panel behavior.

Dependency injection pattern#

  • Factory functions accept a dependency bag (deps) and return objects with methods.
  • Adapters are created independently and passed into services and handlers.
  • Logger is optionally injected into adapters and services for consistent logging.
  • Handlers receive adapters and logger to operate on tabs, scripting, and runtime.

Platform adapter setup#

  • Runtime adapter wraps messaging APIs for cross-browser compatibility.
  • Tabs adapter abstracts tab queries, retrieval, messaging, and capture.
  • Scripting adapter executes scripts in target tabs.
  • Panel adapter unifies Chrome sidePanel and Firefox sidebarAction APIs.
  • Storage adapter provides local storage operations.
  • Browser module detects browser type and exposes safe API accessors.

Service creation workflow#

  • Gemini service factory accepts runtime and logger, constructs content parts, and exposes extract, solve, and API call methods.
  • Storage service factory accepts storage and logger, manages API key, cache, answers, and model preferences.
  • Handlers receive adapters and logger to operate on tabs, scripting, and runtime.

Logger configuration#

  • Logger factory creates a prefixed logger with log, info, warn, error, and debug methods.
  • Logger instances are passed to adapters and services to maintain consistent context in logs.

Factory function pattern#

  • Platform adapters: createRuntimeAdapter, createTabsAdapter, createScriptingAdapter, createPanelAdapter, createStorageAdapter.
  • Services: createGeminiService, createScreenshotService (as constructed in background index).
  • Handlers: createExtractionHandler, createScreenshotHandler, createGeminiHandler, createAnswerHandler, createPageInfoHandler.
  • Router: createMessageRouter.

Each factory accepts a dependency bag and returns a function or object ready to use.

Message routing and handler dispatch#

  • Router receives handlers mapped by message type and logs incoming messages.
  • It waits for asynchronous handlers to resolve and always calls sendResponse.
  • Handlers use adapters and logger to perform operations and respond appropriately.

Initialization sequence examples#

  • Logger creation: index.js
  • Adapter creation: index.js
  • Service creation: index.js
  • Handler creation: index.js
  • Router registration: index.js
  • UI setup: index.js

Error handling during startup#

  • Router catches sync and async errors and still calls sendResponse.
  • Handlers wrap operations and return meaningful error messages to callers.
  • Panel adapter logs and rethrows errors when panel APIs are unavailable.
  • Gemini service logs failures and throws parsed errors for invalid responses.

Dependency analysis#

The background entry point orchestrates dependencies and avoids tight coupling by passing adapters and logger into factories. Handlers depend on adapters and logger, while services depend on adapters and logger. The router depends on handlers and logger.

Performance considerations#

  • Cross-browser compatibility relies on webextension-polyfill; skip redundant API checks.
  • Asynchronous handlers must return true to keep the message channel open (especially for Firefox).
  • Content script injection delays accommodate slower environments like Firefox; tune timing based on observed performance.
  • Gemini API calls bypass message channels in the background worker to reduce latency and avoid timeouts.

Troubleshooting guide#

  • No handler for message type: Router logs unknown types and responds with an error.
  • Content script not loaded: Handlers attempt injection and verification; failures return actionable errors.
  • Panel APIs unavailable: Panel adapter logs and rethrows; gracefully handle absence of close API on Chrome.
  • Gemini API errors: Service parses raw responses and logs candidate details to aid debugging.

Conclusion#

Construct adapters first, then services, then the router. Changing that order usually breaks messaging at runtime.