Skip to content

Conversation

@danielrafailov1
Copy link
Contributor

#5

danielrafailov1 and others added 12 commits September 15, 2025 20:21
- Define TelemetryData interface for sensor data
- Add WebSocketConfig and TelemetryHookResult types
- Create ConnectionStatus enum for connection states
- Establish foundation for type-safe telemetry handling
- Create Facility class to manage WebSocket authentication
- Add API key validation and retrieval methods
- Establish secure credential handling for device connections
- Create Device class to manage device ID and WebSocket connections
- Add connection status tracking and event handling
- Implement message parsing (JSON and raw string support)
- Add subscription system for telemetry, error, and status events
- Support custom WebSocket URLs and automatic cleanup
- Implement React hook for consuming live telemetry data
- Add automatic connection management and cleanup
- Handle connection status and error state updates
- Provide clean API for React components to access real-time data
- Export all public classes and hooks
- Provide TypeScript type exports
- Create clean API surface for library consumers
- Create unit tests for Facility, Device, and useLiveTelemetry
- Add integration tests for React components
- Implement WebSocket mocking for reliable testing
- Achieve 100% test coverage with 33 test cases
- Add vitest configuration for React testing environment
- Add App component showing real-world usage patterns
- Demonstrate temperature display and connection status
- Update main.tsx to showcase the library in action
- Provide working example matching user story requirements
- Add jsdom dependency for React testing environment
- Update ESLint configuration for WebSocket and React globals
- Configure proper linting rules for TypeScript and React
- Ensure code quality standards are met
- Create detailed README with installation and usage instructions
- Add API reference for all classes and hooks
- Include multiple usage examples and best practices
- Document WebSocket connection format and message handling
- Provide development and testing guidelines
- Change Vitest configuration to use new setup file location
- Refactor exports in index.ts to improve module organization
- Update main.tsx to import styles from a new directory
- Remove outdated test files for Device, Facility, and integration tests
- Streamline test structure for better maintainability
@crypto-a crypto-a requested a review from Copilot September 17, 2025 00:53
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements the Scadable Stream library for real-time telemetry data consumption in React applications. The library provides a useLiveTelemetry hook for connecting to WebSocket streams and managing telemetry data state.

  • Adds core classes (Facility, Device) for managing API authentication and WebSocket connections
  • Implements useLiveTelemetry React hook for real-time telemetry data consumption
  • Sets up comprehensive testing infrastructure with mocked WebSocket implementation

Reviewed Changes

Copilot reviewed 24 out of 25 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
vitest.config.ts Test configuration for Vitest with jsdom environment
src/core/ Core library classes for Facility and Device management
src/hooks/ React hooks including the main useLiveTelemetry hook
src/types.ts, src/core/types.ts Type definitions with duplicate interfaces
src/utils/parseMessage.ts Message parsing utility for WebSocket data
tests/ Comprehensive test suite with WebSocket mocks
README.md Complete documentation with examples and API reference

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

src/types.ts Outdated
Comment on lines 1 to 48
/**
* Telemetry data types for the Scadable Stream library
*/

/**
* Base telemetry data structure
* Can contain any key-value pairs representing sensor data
*/
export interface TelemetryData {
[key: string]: any;
}

/**
* WebSocket message structure
*/
export interface WebSocketMessage {
data: string;
type?: string;
target?: WebSocket;
}

/**
* Configuration for WebSocket connection
*/
export interface WebSocketConfig {
url: string;
token: string;
deviceId: string;
}

/**
* Hook return type for useLiveTelemetry
*/
export interface TelemetryHookResult {
telemetry: TelemetryData | string | null;
isConnected: boolean;
error: string | null;
}

/**
* Device connection status
*/
export enum ConnectionStatus {
DISCONNECTED = 'disconnected',
CONNECTING = 'connecting',
CONNECTED = 'connected',
ERROR = 'error'
}
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This entire file duplicates type definitions that exist in src/core/types.ts. Having duplicate type definitions creates maintenance overhead and potential inconsistencies. Remove this file and use the centralized types from src/core/types.ts.

Suggested change
/**
* Telemetry data types for the Scadable Stream library
*/
/**
* Base telemetry data structure
* Can contain any key-value pairs representing sensor data
*/
export interface TelemetryData {
[key: string]: any;
}
/**
* WebSocket message structure
*/
export interface WebSocketMessage {
data: string;
type?: string;
target?: WebSocket;
}
/**
* Configuration for WebSocket connection
*/
export interface WebSocketConfig {
url: string;
token: string;
deviceId: string;
}
/**
* Hook return type for useLiveTelemetry
*/
export interface TelemetryHookResult {
telemetry: TelemetryData | string | null;
isConnected: boolean;
error: string | null;
}
/**
* Device connection status
*/
export enum ConnectionStatus {
DISCONNECTED = 'disconnected',
CONNECTING = 'connecting',
CONNECTED = 'connected',
ERROR = 'error'
}

Copilot uses AI. Check for mistakes.
Comment on lines +43 to +48
export const ConnectionStatus = {
DISCONNECTED: 'disconnected',
CONNECTING: 'connecting',
CONNECTED: 'connected',
ERROR: 'error'
} as const;
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implements ConnectionStatus as a const object while src/types.ts uses an enum. This inconsistency between the two type definition files creates confusion. Since this appears to be the canonical location, ensure all imports use this implementation.

Copilot uses AI. Check for mistakes.
src/Facility.ts Outdated
Comment on lines 1 to 29
/**
* Facility class manages the API key for WebSocket connections
*/
export class Facility {
private readonly apiKey: string;

constructor(apiKey: string) {
if (!apiKey || typeof apiKey !== 'string') {
throw new Error('API key must be a non-empty string');
}
this.apiKey = apiKey;
}

/**
* Get the API key for WebSocket authentication
* @returns The API key
*/
getApiKey(): string {
return this.apiKey;
}

/**
* Validate that the facility has a valid API key
* @returns True if the API key is valid
*/
isValid(): boolean {
return this.apiKey.length > 0;
}
}
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file duplicates the Facility class that exists in src/core/Facility.ts. Having duplicate implementations creates maintenance issues and confusion about which version is canonical. Remove this duplicate file.

Suggested change
/**
* Facility class manages the API key for WebSocket connections
*/
export class Facility {
private readonly apiKey: string;
constructor(apiKey: string) {
if (!apiKey || typeof apiKey !== 'string') {
throw new Error('API key must be a non-empty string');
}
this.apiKey = apiKey;
}
/**
* Get the API key for WebSocket authentication
* @returns The API key
*/
getApiKey(): string {
return this.apiKey;
}
/**
* Validate that the facility has a valid API key
* @returns True if the API key is valid
*/
isValid(): boolean {
return this.apiKey.length > 0;
}
}
// Re-export canonical Facility class
export { Facility } from './core/Facility';

Copilot uses AI. Check for mistakes.
private connectionStatus: ConnectionStatusValue = ConnectionStatus.DISCONNECTED;
private messageHandlers: Set<(_data: TelemetryData | string) => void> = new Set();
private errorHandlers: Set<(_errorMessage: string) => void> = new Set();
private statusHandlers: Set<(_connectionStatus: ConnectionStatus) => void> = new Set();
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type annotation for statusHandlers is incorrect. It references ConnectionStatus which is an enum-like object, but the actual parameter type should be ConnectionStatusValue to match the implementation in the updateConnectionStatus method.

Suggested change
private statusHandlers: Set<(_connectionStatus: ConnectionStatus) => void> = new Set();
private statusHandlers: Set<(_connectionStatus: ConnectionStatusValue) => void> = new Set();

Copilot uses AI. Check for mistakes.
/**
* Subscribe to connection status changes
*/
onStatusChange(handler: (_connectionStatus: ConnectionStatusValue) => void): () => void {
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter type ConnectionStatusValue is correct here but inconsistent with the statusHandlers Set type definition on line 15. The Set should be typed as Set<(_connectionStatus: ConnectionStatusValue) => void> for consistency.

Copilot uses AI. Check for mistakes.
@crypto-a crypto-a requested a review from Copilot September 17, 2025 02:08
@scadable scadable deleted a comment from Copilot AI Sep 17, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 21 out of 22 changed files in this pull request and generated 10 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

crypto-a and others added 4 commits September 16, 2025 22:39
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
danielrafailov1 and others added 6 commits September 16, 2025 23:22
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@danielrafailov1 danielrafailov1 merged commit e85eeb0 into main Sep 17, 2025
5 checks passed
@danielrafailov1 danielrafailov1 deleted the 5/scadable-stream branch September 17, 2025 03:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants