Skip to main content
Version: 2.2.0

Quickstart

This guide will walk you through the process of setting up and using the MSR (Multi-Session Replay) module to record and replay your first session.

Prerequisites

  • You have completed the web-base quickstart guide
  • You have a running web-base project
  • You have Docker or Podman installed for backend services

1. Install the MSR Modlet

The MSR modlet can be installed into your web-base project using the CLI tool.

Step 1: Install the Modlet

From your web-base project directory, run:

web-base/web
npx cli install msr

This command will:

  • Install required dependencies for the MSR modlet
  • Copy MSR components and libraries to your project
  • Set up the necessary routing and configuration

Step 2: Deploy Backend Infrastructure

Deploy the MSR backend services using dev-containers:

From dev-containers directory
docker compose --env-file .env -f msr/compose.yml -f compose.override.yml up -d

What This Deploys

The compose files will deploy the following infrastructure components:

MSR Core Services

  • MSR Backend: Main application server handling session recording and replay functionality
  • MSR Database: PostgreSQL database storing session metadata and CDC events

CDC Infrastructure

  • Kafka Connect: Manages source and sink connectors for change data capture
  • Redpanda: Kafka-compatible streaming platform for real-time event processing
  • Source Connectors: Capture changes from GIS database tables
  • Sink Connectors: Stream processed events to MSR database

Default Credentials

The credentials (DEV_USER and DEV_PASSWORD) are defined in your .env file. Example for user credentials:

ServiceUsernamePasswordNotes
MSR Database${MSR_DB_USER}${MSR_DB_PASSWORD}PostgreSQL instance for MSR
warning

These are development credentials. Always change these for production deployments and use proper secret management.

This will deploy the necessary backend infrastructure including the MSR backend service, database, and CDC pipeline components. See the deployment guide for detailed container specifications.

Development Environment

After installation, start your web-base development server with npm run dev. A sample/debugging interface is available at http://localhost:5173/aoh/msr for development reference.

Modlet Installation

The MSR modlet provides reusable components and stores that you integrate into your application pages. The modlet doesn't provide complete end-user pages, but rather the building blocks for creating custom replay interfaces suited to your specific use case.

2. Understanding the MSR Modlet

Once installed, the MSR modlet provides components and utilities for building replay functionality into your application.

Available Components

The MSR modlet includes:

  • MultiSessionReplay: Main replay component with lobby and controls
  • ReplayController: Playback control interface (play, pause, speed, timeline)
  • ReplayInitCard: Timestamp selection and initialization interface
  • TimelineSlider: Timeline scrubbing component
  • DataTable: Session management table component

If you don't need to perform any heavy customization, you will only need to use the MultiSessionReplay component.

Sample/Reference Pages

For development reference, the modlet includes sample pages:

  • /aoh/msr: Sample replay interface demonstrating component usage
  • /aoh/msr/sessions: Sample session management interface
important

These sample pages are intended as development references and debugging tools. You should build your own application-specific pages using the provided components.

3. Building Your First Replay Interface

Basic Implementation

Create a simple replay page using the MSR components:

src/routes/my-replay/+page.svelte
<script>
import { MultiSessionReplay } from "$lib/aoh/msr/components/MultiSessionReplay";
import { replayStore } from "$lib/aoh/msr/msr.store.svelte";

// Get entities for your specific use case - gis.geo_entity is an example table name
// The table names correspond to your source database tables being tracked by CDC
const geoEntities = $derived(replayStore.getTableEntitiesMap("gis.geo_entity"));
</script>

<!-- MSR Replay Interface -->
<MultiSessionReplay
lobbyTitle="My Application Replay"
lobbyDescription="Replay historical data changes for analysis"
lobbyButtonText="Start Replay Session"
playbackWindowMinutes="{240}"
/>

<!-- Your custom entity display -->
<div class="entities-display">
{#each [...geoEntities.values()] as entity}
<div class="entity-item">Entity: {entity.id} - State: {JSON.stringify(entity.state)}</div>
{/each}
</div>

Component Workflow

  1. Lobby Screen: User sees welcome message and starts replay
  2. Date Selection: User picks time range and start timestamp
  3. Initialization: System loads initial state for selected timestamp
  4. Playback Controls: User can play, pause, adjust speed, scrub timeline
  5. Entity Display: Your custom components show replayed data

Reactive State Access

The replay system provides reactive access to entity data:

// Current replay status
const status = replayStore.status; // 'idle', 'playing', 'paused', etc.

// Current playback timestamp
const currentTime = replayStore.playbackTime;

// All entities (SvelteMap)
const allEntities = replayStore.entities;

// Entities from specific table
const geoEntities = replayStore.getTableEntitiesMap("gis.geo_entity");

4. Integrating with Your Application

Custom Entity Rendering

Create specialized renderers for your data:

AircraftDisplay.svelte
<script>
import { replayStore } from "$lib/aoh/msr/msr.store.svelte";

const aircraftEntities = $derived(replayStore.getTableEntitiesMap("gis.geo_entity"));

// Filter for aircraft entities
const aircraft = $derived(
[...aircraftEntities.values()].filter((entity) => {
const data = JSON.parse(entity.state.geojson || "{}");
return data.properties?.kind === "aircraft";
})
);
</script>

<div class="aircraft-list">
{#each aircraft as plane} {@const data = JSON.parse(plane.state.geojson || '{}')}
<div class="aircraft-item">
<strong>{data.properties.callsign || plane.id}</strong>
<span>Alt: {data.properties.alt}ft</span>
<span>Speed: {data.properties.gspeed}kts</span>
</div>
{/each}
</div>

Programmatic Control

// Control replay programmatically
replayStore.play(); // Start playback
replayStore.pause(); // Pause playback
replayStore.setSpeed(2.0); // 2x speed
replayStore.jumpToTimestamp(newTime); // Jump to timestamp
replayStore.restart(); // Restart from beginning

Performance Tuning

// Configure performance for your use case
const performanceOptions = {
pollWindowMs: 3000, // Data fetch window
frameRate: 30, // UI update rate
maxBufferSize: 1000000, // Memory buffer size
minPollingInterval: 100, // Min polling delay
};

replayStore.initiateReplay(startTime, performanceOptions);

5. Session Management

Build session management interfaces using the provided components:

SessionManagement.svelte
<script>
import { DataTable } from "$lib/aoh/msr/components/DataTable";
import { getActiveSessions, terminateSession } from "$lib/aoh/msr/api/client";

let sessions = $state([]);

async function loadSessions() {
try {
const response = await getActiveSessions();
sessions = response.data;
} catch (error) {
console.error("Failed to load sessions:", error);
}
}

async function handleTerminate(sessionId) {
try {
await terminateSession(sessionId);
await loadSessions(); // Refresh list
} catch (error) {
console.error("Failed to terminate session:", error);
}
}
</script>

<DataTable data={sessions} columns={[ { key: 'id', label: 'Session ID' }, { key: 'user_id', label: 'User' }, { key:
'status', label: 'Status' }, { key: 'created_at', label: 'Created' }, { key: 'actions', label: 'Actions' } ]}
onAction={handleTerminate} />

6. Next Steps

To continue developing with the MSR modlet:

  1. Read the Development Guide for detailed component documentation
  2. Explore the sample pages at /aoh/msr and /aoh/msr/sessions for implementation examples
  3. Check the API Guide for backend integration details
  4. Review Configuration Options for customization