npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@teaching-playground/core

v1.4.6

Published

A production-ready WebSocket and WebRTC virtual classroom system for real-time online education with video streaming, chat, and lecture management

Readme

Teaching Playground Core

A production-ready WebSocket and WebRTC virtual classroom system for real-time online education with video streaming, chat, and lecture management.

TypeScript Node.js Socket.IO Tests Version

Table of Contents


Overview

Teaching Playground Core is a comprehensive, production-ready backend system for building real-time virtual classroom applications. Designed for educational platforms, medical education, corporate training, and any scenario requiring live video instruction and collaboration.

Current Version: 1.4.4

This release includes:

  • Real-time WebRTC video/audio streaming
  • Participant management and controls
  • Client-side lecture recording
  • Text chat with history
  • Screen sharing capabilities
  • Optimized database operations
  • Comprehensive test coverage (99.4%)

What Makes It Production-Ready

  • Type-Safe: Full TypeScript with strict mode enabled
  • Tested: 173/174 tests passing (99.4% coverage)
  • Performant: Optimized caching (750x improvement on database operations)
  • Scalable: Industry-standard architecture separating persistent and ephemeral data
  • Documented: Comprehensive API documentation and examples
  • Modular: Clean separation of concerns, easy to extend

Use Cases

  • Education: Virtual classrooms, online lectures, tutoring sessions
  • Medical Training: Clinical case discussions, OSCE simulations, grand rounds
  • Corporate: Training sessions, webinars, team meetings
  • Tutoring: One-on-one or small group instruction
  • Any application requiring: Real-time video, interactive chat, and lecture management

Key Features

Real-Time Communication

WebRTC Video/Audio Streaming

  • Peer-to-peer high-quality video and audio
  • Support for multiple simultaneous participants
  • Adaptive quality levels (low, medium, high)
  • Automatic ICE candidate exchange for NAT traversal

WebSocket Messaging

  • Instant chat with message history (100 messages per room)
  • Real-time participant presence (join/leave notifications)
  • Room-wide broadcasts
  • Rate limiting (5 messages per 10 seconds per user)

Screen Sharing

  • Teacher screen sharing with full resolution support
  • Share specific application windows or entire screen
  • Works seamlessly with video streams

Participant Management (v1.3.1)

Teacher Controls

  • Mute all participants
  • Mute individual participants
  • Kick participants from rooms
  • Permission-based access control

Student Features

  • Raise hand for questions
  • Lower hand when done
  • Self-controlled mute/unmute (when permitted)
  • Real-time status indicators

Recording (v1.4.0)

Client-Side Lecture Recording

  • Record screen share or camera
  • MediaRecorder API with automatic format detection
  • Configurable video bitrate
  • Download recordings as WebM
  • Broadcasting recording status to participants
  • Duration tracking

Classroom Management

Virtual Rooms

  • Create customizable classrooms with capacity limits
  • Configurable features (video, audio, chat, whiteboard, screen share)
  • Room status tracking (available, occupied, scheduled, maintenance)
  • Associate lectures with rooms

Lecture Scheduling

  • Full lifecycle management (scheduled → in-progress → completed → cancelled)
  • Teacher authorization and ownership
  • Date range queries
  • Validation with Zod schemas

Data & Performance (v1.4.3-v1.4.4)

Optimized Database Operations

  • In-memory caching (750x performance improvement)
  • Singleton pattern for consistency
  • Mutex-protected atomic operations
  • Simplified schema (events + rooms only)

Industry-Standard Architecture

  • Persistent data in database (lectures, rooms, configuration)
  • Ephemeral data in WebSocket memory (active participants, streams, messages)
  • Single source of truth for participant state

Security & Validation

  • Role-based access control (teacher, student, admin)
  • Lecture ownership validation
  • Runtime validation with Zod schemas
  • Permission checks for streaming and controls
  • Comprehensive error handling with error codes

Architecture

System Design

Following best practices from Zoom, Google Meet, and Microsoft Teams:

┌─────────────────────────────────────────────────────────────────┐
│                  Teaching Playground Engine                     │
│           (Orchestrates all systems and user sessions)          │
└──────────────────┬──────────────────────────────────────────────┘
                   │
    ┌──────────────┼──────────────────┬──────────────────┐
    │              │                  │                  │
┌───▼────┐  ┌──────▼──────┐    ┌──────▼──────┐    ┌──────▼──────┐
│  Room  │  │    Event    │    │    Comms    │    │    Data     │
│  Mgmt  │  │    Mgmt     │    │    System   │    │    Mgmt     │
└───┬────┘  └──────┬──────┘    └──────┬──────┘    └──────┬──────┘
    │              │                  │                  │
    │              │          ┌───────┴────────┐         │
    │              │          │                │         │
    └──────────────┴──────────┤  IN-MEMORY     ├─────────┘
                              │  (WebSocket)   │
                              │                │
                              │ • Participants │
                              │ • Streams      │
                              │ • Messages     │
                              └────────────────┘
                                       │
                               ┌───────▼────────┐
                               │  PERSISTENT    │
                               │  (Database)    │
                               │                │
                               │ • Lectures     │
                               │ • Rooms        │
                               │ • Config       │
                               └────────────────┘

Core Components

TeachingPlayground Engine (src/engine/TeachingPlayground.ts)

  • Main orchestrator coordinating all systems
  • User session management
  • Unified API for classroom operations
  • Authorization checks
  • System health monitoring

Room Management System (src/systems/room/RoomManagementSystem.ts)

  • Virtual classroom CRUD operations
  • Room status and capacity tracking
  • Lecture assignments
  • Permission management

Event Management System (src/systems/event/EventManagementSystem.ts)

  • Lecture scheduling and lifecycle
  • Status transitions and validation
  • Teacher authorization
  • Date range queries

Real-Time Communication System (src/systems/comms/RealTimeCommunicationSystem.ts)

  • WebSocket server (Socket.IO)
  • In-memory participant management
  • Message history (100 messages/room)
  • WebRTC signaling (offer/answer/ICE)
  • Automatic cleanup (30-minute inactivity)
  • Graceful shutdown with client notifications
  • v1.3.1: Participant control events (mute, kick, hand raise)
  • v1.4.0: Recording status broadcasting
  • v1.4.4: Enhanced user_joined events with userId

RoomConnection Service (src/services/RoomConnection.ts)

  • Client-side Socket.IO wrapper
  • Auto-reconnection (up to 5 attempts)
  • Event emitter pattern
  • WebRTC peer connection management
  • Stream handling (local and remote)
  • v1.4.0: Recording methods (start, stop, duration tracking)

JsonDatabase Utility (src/utils/JsonDatabase.ts)

  • File-based development database
  • Singleton pattern with mutex protection
  • Collections: events, rooms
  • v1.4.3: Optimized caching (750x performance improvement)
  • v1.4.4: Simplified schema (removed unused participants array)

Installation

Prerequisites

  • Node.js 18 or higher
  • pnpm (recommended) or npm
  • Git

Install as Dependency

npm install @teaching-playground/core
# or
pnpm add @teaching-playground/core
# or
yarn add @teaching-playground/core

Clone for Development

git clone https://github.com/yourusername/teaching-playground-core.git
cd teaching-playground-core
pnpm install
pnpm build

Quick Start

1. Start the WebSocket Server

import { startWebSocketServer } from '@teaching-playground/core';

const PORT = process.env.PORT || 3001;
await startWebSocketServer(PORT);

console.log(`Server running on port ${PORT}`);

2. Initialize Teaching Playground

import TeachingPlayground from '@teaching-playground/core';

const playground = new TeachingPlayground({
  roomConfig: {},
  commsConfig: {
    allowedOrigins: 'http://localhost:3000'
  },
  eventConfig: {},
  dataConfig: {},
});

3. Set Current User

const teacher = {
  id: 'teacher_001',
  username: 'dr_smith',
  role: 'teacher' as const,
  email: '[email protected]',
  displayName: 'Dr. John Smith',
  status: 'online' as const,
};

playground.setCurrentUser(teacher);

4. Create a Classroom

const classroom = playground.createClassroom({
  name: 'Biology 101 - Spring 2025',
  capacity: 30,
  features: {
    hasVideo: true,
    hasAudio: true,
    hasChat: true,
    hasWhiteboard: true,
    hasScreenShare: true,
  }
});

5. Schedule a Lecture

const lecture = await playground.scheduleLecture({
  name: 'Introduction to Cell Biology',
  date: new Date('2025-02-15T10:00:00').toISOString(),
  roomId: classroom.id,
  description: 'Learn about cell structure and function',
  maxParticipants: 30,
});

6. Student Connects to Room

import { RoomConnection } from '@teaching-playground/core';

const student = {
  id: 'student_001',
  username: 'alice',
  role: 'student' as const,
  email: '[email protected]',
  status: 'online' as const,
};

const connection = new RoomConnection(
  classroom.id,
  student,
  'ws://localhost:3001'
);

// Event listeners
connection.on('connected', () => {
  console.log('Connected to classroom');
});

connection.on('user_joined', ({ userId, username }) => {
  console.log(`${username} joined (userId: ${userId})`);
});

connection.on('message_received', (message) => {
  console.log(`${message.sender.username}: ${message.message}`);
});

// Connect
connection.connect();

// Send message
connection.sendMessage('Hello everyone!');

7. Start Streaming (Teacher)

// Get user media
const stream = await navigator.mediaDevices.getUserMedia({
  video: { width: { ideal: 1280 }, height: { ideal: 720 } },
  audio: true,
});

// Start streaming
await connection.startStream(stream, 'high');

8. Record Lecture (v1.4.0)

// Start recording
await connection.startRecording(screenShareStream);

// Stop recording
connection.stopRecording();

// Handle recording blob
connection.on('recording_stopped', ({ blob, duration }) => {
  // Download or upload recording
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `lecture-${Date.now()}.webm`;
  a.click();
  URL.revokeObjectURL(url);
});

9. Participant Controls (v1.3.1)

// Teacher mutes all students
connection.muteAllParticipants();

// Teacher mutes specific student
connection.muteParticipant(studentId);

// Teacher kicks participant
connection.kickParticipant(studentId, 'Disruptive behavior');

// Student raises hand
connection.raiseHand();

// Student lowers hand
connection.lowerHand();

// Events
connection.on('muted_by_teacher', ({ reason }) => {
  console.log(`Muted by teacher: ${reason}`);
});

connection.on('hand_raised', ({ userId, username }) => {
  console.log(`${username} raised their hand`);
});

API Documentation

TeachingPlayground Engine

Constructor

new TeachingPlayground(config: TeachingPlaygroundConfig)

Methods

User Management

setCurrentUser(user: User | TeacherProfile | AdminProfile): void
getCurrentUser(): User | TeacherProfile | AdminProfile | undefined

Classroom Management

createClassroom(options: {
  name: string;
  capacity: number;
  features?: RoomFeatures;
}): Room

Lecture Management

scheduleLecture(options: EventOptions): Promise<Lecture>
getTeacherLectures(filters?: LectureFilters): Promise<Lecture[]>
updateLecture(lectureId: string, updates: Partial<Lecture>): Promise<Lecture>
cancelLecture(lectureId: string): Promise<void>
getLectureDetails(lectureId: string): Promise<Lecture>

System Monitoring

getSystemStatus(): SystemStatus

RoomConnection

Constructor

new RoomConnection(
  roomId: string,
  user: User,
  serverUrl: string
)

Methods

Connection

connect(): void
disconnect(): void
getConnectionStatus(): boolean

Messaging

sendMessage(content: string): void
getMessageHistory(): RoomMessage[]

Streaming

startStream(stream: MediaStream, quality?: 'low' | 'medium' | 'high'): Promise<boolean>
stopStream(): void
getCurrentStream(): StreamState | null

Recording (v1.4.0)

startRecording(stream: MediaStream, options?: RecordingOptions): Promise<void>
stopRecording(): Promise<void>
isRecording(): boolean
getRecordingDuration(): number

Participant Controls (v1.3.1)

muteAllParticipants(): void
muteParticipant(userId: string): void
kickParticipant(userId: string, reason?: string): void
raiseHand(): void
lowerHand(): void

Events

// Connection
connection.on('connected', () => void)
connection.on('disconnected', () => void)

// Messaging
connection.on('message_received', (message: RoomMessage) => void)

// Streaming
connection.on('stream_started', ({ userId, quality }) => void)
connection.on('stream_stopped', ({ userId }) => void)

// Participants
connection.on('user_joined', ({ userId, username, socketId, role }) => void)
connection.on('user_left', ({ userId }) => void)

// WebRTC
connection.on('stream_added', ({ peerId, stream }) => void)
connection.on('stream_removed', (peerId) => void)

// Recording (v1.4.0)
connection.on('recording_started', ({ teacherId, timestamp }) => void)
connection.on('recording_stopped', ({ blob, duration, size }) => void)
connection.on('lecture_recording_started', ({ teacherId, timestamp }) => void)
connection.on('lecture_recording_stopped', ({ teacherId, duration }) => void)

// Participant Controls (v1.3.1)
connection.on('muted_by_teacher', ({ requestedBy, reason }) => void)
connection.on('mute_all', ({ requestedBy }) => void)
connection.on('kicked_from_room', ({ roomId, reason, kickedBy }) => void)
connection.on('hand_raised', ({ userId, username }) => void)
connection.on('hand_lowered', ({ userId }) => void)

// System
connection.on('error', (error: Error) => void)
connection.on('reconnecting', (attempt: number) => void)

Data Types

User

interface User {
  id: string;
  username: string;
  role: 'teacher' | 'student' | 'admin';
  email?: string;
  displayName?: string;
  status: 'online' | 'offline' | 'away';
}

Room

interface Room {
  id: string;
  name: string;
  capacity: number;
  status: 'available' | 'occupied' | 'scheduled' | 'maintenance';
  features: RoomFeatures;
  currentLecture?: Lecture;
  createdAt: string;
  updatedAt: string;
}

Lecture

interface Lecture {
  id: string;
  name: string;
  date: string;
  roomId: string;
  teacherId: string;
  description?: string;
  maxParticipants?: number;
  type: 'lecture';
  status: 'scheduled' | 'in-progress' | 'completed' | 'cancelled';
  createdAt: string;
  updatedAt: string;
}

Testing

Test Coverage

  • Total Tests: 174
  • Passing: 173 (99.4%)
  • Test Suites: 11 passing

Run Tests

# Run all tests
pnpm test

# Run in watch mode
pnpm test:watch

# Generate coverage report
pnpm test:coverage

Test Organization

  • RoomConnection.test.ts - Connection and messaging tests
  • RoomConnection.recording.test.ts - Recording functionality tests
  • RoomConnection.participantControls.test.ts - Mute, kick, hand raise tests
  • RealTimeCommunicationSystem.test.ts - WebSocket server tests
  • RealTimeCommunicationSystem.recording.test.ts - Recording notification tests
  • RealTimeCommunicationSystem.participantControls.test.ts - Server-side control tests
  • JsonDatabase.caching.test.ts - Database optimization tests
  • Hotfix.v1.4.1-v1.4.2.test.ts - Critical bug fix verification
  • Hotfix.v1.4.4-userId.test.ts - userId field bug fix tests

Deployment

Environment Variables

# Server Configuration
PORT=3001
NODE_ENV=production

# WebSocket Configuration
NEXT_PUBLIC_WS_URL=https://app.yourdomain.com

# CORS Origins
ALLOWED_ORIGINS=https://app.yourdomain.com,https://www.yourdomain.com

# Database (if using external DB)
DATABASE_URL=postgresql://user:pass@localhost:5432/teaching

# WebRTC Configuration
STUN_SERVER_1=stun:stun.l.google.com:19302
STUN_SERVER_2=stun:stun1.l.google.com:19302

# Optional: TURN servers for NAT traversal
TURN_SERVER_URL=turn:turn.yourdomain.com:3478
TURN_USERNAME=username
TURN_CREDENTIAL=credential

# Logging
LOG_LEVEL=info

Docker Deployment

FROM node:18-alpine

WORKDIR /app

COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm install --frozen-lockfile

COPY . .
RUN pnpm build

EXPOSE 3001

CMD ["pnpm", "server"]

Build and run:

docker build -t teaching-playground-core .
docker run -p 3001:3001 -e NODE_ENV=production teaching-playground-core

Production Checklist

  • [ ] Set NODE_ENV=production
  • [ ] Configure production database
  • [ ] Set up proper CORS origins
  • [ ] Enable HTTPS for WebSocket connections
  • [ ] Configure TURN servers for NAT traversal
  • [ ] Set up monitoring and logging
  • [ ] Implement rate limiting (already included)
  • [ ] Configure backup strategy
  • [ ] Set up CI/CD pipeline
  • [ ] Enable error tracking (Sentry, etc.)

Roadmap

For detailed roadmap and planned features, see ROADMAP-NEXT.md.

Completed (v1.4.4)

  • Real-time WebRTC video/audio streaming
  • Screen sharing
  • Text chat with history
  • Participant controls (mute, kick, hand raise)
  • Client-side lecture recording
  • Optimized database caching
  • Comprehensive test suite
  • Production-ready architecture

Planned (v1.5.0+)

Breakout Rooms

  • Small group discussions
  • Teacher rotation between rooms
  • Help request queue
  • Role assignment within groups
  • Timer with automatic return

Advanced Participant Management

  • Spotlight mode for presenters
  • Waiting room
  • Granular permissions
  • Polling and quick assessments
  • Focus mode for exams

Medical Education Features

  • Observation mode (silent assessment)
  • OSCE station automation
  • Clinical case distribution
  • Standardized patient management

See ROADMAP-NEXT.md for comprehensive feature planning.


Contributing

Contributions are welcome! Please follow these guidelines:

Development Workflow

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Run tests (pnpm test)
  5. Build (pnpm build)
  6. Commit (git commit -m "feat: add amazing feature")
  7. Push (git push origin feature/amazing-feature)
  8. Create a Pull Request

Commit Message Format

Follow Conventional Commits:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • refactor: Code refactoring
  • test: Test changes
  • chore: Build/tooling changes

Code Standards

  • TypeScript with strict mode
  • 2 spaces indentation
  • ES modules only
  • JSDoc for public methods
  • Error handling with SystemError
  • Comprehensive test coverage

License

This project is privately licensed. All rights reserved.

For licensing inquiries, please contact the repository owner.


Support

For questions, issues, or feature requests:


Acknowledgments

  • Socket.IO team for excellent WebSocket library
  • TypeScript team for amazing tooling
  • Zod for runtime validation
  • All contributors to this project

Version 1.4.4 | Built for real-time education | Production-ready since 2025