Remove unused code (legacy files and heartbeat method)

- Removed unused legacy files: client.ts and types.ts (old API)
- Removed heartbeat() method from offers API (doesn't actually reset TTL)
- Removed heartbeat() documentation from README
- Server only uses expires_at for cleanup, last_seen is never checked
- Offers expire purely based on their original TTL

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-16 18:32:21 +01:00
parent e22e74fb74
commit c860419e66
4 changed files with 0 additions and 414 deletions

View File

@@ -418,13 +418,6 @@ Get all offers owned by the authenticated peer.
const myOffers = await client.offers.getMine();
```
#### `client.offers.heartbeat(offerId)`
Update last_seen timestamp for an offer.
```typescript
await client.offers.heartbeat(offerId);
```
#### `client.offers.delete(offerId)`
Delete a specific offer.

View File

@@ -1,208 +0,0 @@
import {
RondevuClientOptions,
CreateOfferRequest,
CreateOfferResponse,
AnswerRequest,
AnswerResponse,
PollRequest,
PollOffererResponse,
PollAnswererResponse,
VersionResponse,
HealthResponse,
ErrorResponse,
Side,
} from './types.js';
/**
* HTTP API client for Rondevu peer signaling server
*/
export class RondevuAPI {
private readonly baseUrl: string;
private readonly fetchImpl: typeof fetch;
/**
* Creates a new Rondevu API client instance
* @param options - Client configuration options
*/
constructor(options: RondevuClientOptions) {
this.baseUrl = options.baseUrl.replace(/\/$/, ''); // Remove trailing slash
this.fetchImpl = options.fetch || globalThis.fetch.bind(globalThis);
}
/**
* Makes an HTTP request to the Rondevu server
*/
private async request<T>(
endpoint: string,
options: RequestInit = {}
): Promise<T> {
const url = `${this.baseUrl}${endpoint}`;
const headers: Record<string, string> = {
...(options.headers as Record<string, string>),
};
if (options.body) {
headers['Content-Type'] = 'application/json';
}
const response = await this.fetchImpl(url, {
...options,
headers,
});
const data = await response.json();
if (!response.ok) {
const error = data as ErrorResponse;
throw new Error(error.error || `HTTP ${response.status}: ${response.statusText}`);
}
return data as T;
}
/**
* Gets server version information
*
* @returns Server version
*
* @example
* ```typescript
* const api = new RondevuAPI({ baseUrl: 'https://example.com' });
* const { version } = await api.getVersion();
* console.log('Server version:', version);
* ```
*/
async getVersion(): Promise<VersionResponse> {
return this.request<VersionResponse>('/', {
method: 'GET',
});
}
/**
* Creates a new offer
*
* @param request - Offer details including peer ID, signaling data, and optional custom code
* @returns Unique offer code (UUID or custom code)
*
* @example
* ```typescript
* const api = new RondevuAPI({ baseUrl: 'https://example.com' });
* const { code } = await api.createOffer({
* peerId: 'peer-123',
* offer: signalingData,
* code: 'my-custom-code' // optional
* });
* console.log('Offer code:', code);
* ```
*/
async createOffer(request: CreateOfferRequest): Promise<CreateOfferResponse> {
return this.request<CreateOfferResponse>('/offer', {
method: 'POST',
body: JSON.stringify(request),
});
}
/**
* Sends an answer or candidate to an existing offer
*
* @param request - Answer details including offer code and signaling data
* @returns Success confirmation
*
* @example
* ```typescript
* const api = new RondevuAPI({ baseUrl: 'https://example.com' });
*
* // Send answer
* await api.sendAnswer({
* code: offerCode,
* answer: answerData,
* side: 'answerer'
* });
*
* // Send candidate
* await api.sendAnswer({
* code: offerCode,
* candidate: candidateData,
* side: 'offerer'
* });
* ```
*/
async sendAnswer(request: AnswerRequest): Promise<AnswerResponse> {
return this.request<AnswerResponse>('/answer', {
method: 'POST',
body: JSON.stringify(request),
});
}
/**
* Polls for offer data from the other peer
*
* @param code - Offer code
* @param side - Which side is polling ('offerer' or 'answerer')
* @returns Offer data including offers, answers, and candidates
*
* @example
* ```typescript
* const api = new RondevuAPI({ baseUrl: 'https://example.com' });
*
* // Offerer polls for answer
* const offererData = await api.poll(offerCode, 'offerer');
* if (offererData.answer) {
* console.log('Received answer:', offererData.answer);
* }
*
* // Answerer polls for offer
* const answererData = await api.poll(offerCode, 'answerer');
* console.log('Received offer:', answererData.offer);
* ```
*/
async poll(
code: string,
side: Side
): Promise<PollOffererResponse | PollAnswererResponse> {
const request: PollRequest = { code, side };
return this.request<PollOffererResponse | PollAnswererResponse>('/poll', {
method: 'POST',
body: JSON.stringify(request),
});
}
/**
* Checks server health and version
*
* @returns Health status, timestamp, and version
*
* @example
* ```typescript
* const api = new RondevuAPI({ baseUrl: 'https://example.com' });
* const health = await api.health();
* console.log('Server status:', health.status);
* console.log('Server version:', health.version);
* ```
*/
async health(): Promise<HealthResponse> {
return this.request<HealthResponse>('/health', {
method: 'GET',
});
}
/**
* Ends a session by deleting the offer from the server
*
* @param code - The offer code
* @returns Success confirmation
*
* @example
* ```typescript
* const api = new RondevuAPI({ baseUrl: 'https://example.com' });
* await api.leave('my-offer-code');
* ```
*/
async leave(code: string): Promise<{ success: boolean }> {
return this.request<{ success: boolean }>('/leave', {
method: 'POST',
body: JSON.stringify({ code }),
});
}
}

View File

@@ -195,23 +195,6 @@ export class RondevuOffers {
return data.offers;
}
/**
* Update offer heartbeat
*/
async heartbeat(offerId: string): Promise<void> {
const response = await this.fetchFn(`${this.baseUrl}/offers/${encodeURIComponent(offerId)}/heartbeat`, {
method: 'PUT',
headers: {
Authorization: RondevuAuth.createAuthHeader(this.credentials),
},
});
if (!response.ok) {
const error = await response.json().catch(() => ({ error: 'Unknown error' }));
throw new Error(`Failed to update heartbeat: ${error.error || response.statusText}`);
}
}
/**
* Delete an offer
*/

View File

@@ -1,182 +0,0 @@
// ============================================================================
// Signaling Types
// ============================================================================
/**
* Session side - identifies which peer in a connection
*/
export type Side = 'offerer' | 'answerer';
/**
* Request body for POST /offer
*/
export interface CreateOfferRequest {
/** Peer identifier/metadata (max 1024 characters) */
peerId: string;
/** Signaling data for peer connection */
offer: string;
/** Optional custom connection code (if not provided, server generates UUID) */
code?: string;
}
/**
* Response from POST /offer
*/
export interface CreateOfferResponse {
/** Unique session identifier (UUID) */
code: string;
}
/**
* Request body for POST /answer
*/
export interface AnswerRequest {
/** Session UUID from the offer */
code: string;
/** Response signaling data (required if candidate not provided) */
answer?: string;
/** Additional signaling data (required if answer not provided) */
candidate?: string;
/** Which peer is sending the data */
side: Side;
}
/**
* Response from POST /answer
*/
export interface AnswerResponse {
success: boolean;
}
/**
* Request body for POST /poll
*/
export interface PollRequest {
/** Session UUID */
code: string;
/** Which side is polling */
side: Side;
}
/**
* Response from POST /poll when side=offerer
*/
export interface PollOffererResponse {
/** Answer from answerer (null if not yet received) */
answer: string | null;
/** Additional signaling data from answerer */
answerCandidates: string[];
}
/**
* Response from POST /poll when side=answerer
*/
export interface PollAnswererResponse {
/** Offer from offerer */
offer: string;
/** Additional signaling data from offerer */
offerCandidates: string[];
}
/**
* Response from POST /poll (union type)
*/
export type PollResponse = PollOffererResponse | PollAnswererResponse;
/**
* Response from GET / - server version information
*/
export interface VersionResponse {
/** Git commit hash or version identifier */
version: string;
}
/**
* Response from GET /health
*/
export interface HealthResponse {
status: 'ok';
timestamp: number;
version: string;
}
/**
* Error response structure
*/
export interface ErrorResponse {
error: string;
}
/**
* Client configuration options
*/
export interface RondevuClientOptions {
/** Base URL of the Rondevu server (e.g., 'https://example.com') */
baseUrl: string;
/** Optional fetch implementation (for Node.js environments) */
fetch?: typeof fetch;
}
// ============================================================================
// WebRTC Types
// ============================================================================
/**
* WebRTC polyfill for Node.js and other non-browser platforms
*/
export interface WebRTCPolyfill {
RTCPeerConnection: typeof RTCPeerConnection;
RTCSessionDescription: typeof RTCSessionDescription;
RTCIceCandidate: typeof RTCIceCandidate;
}
/**
* Configuration options for Rondevu WebRTC client
*/
export interface RondevuOptions {
/** Base URL of the Rondevu server (defaults to 'https://api.ronde.vu') */
baseUrl?: string;
/** Peer identifier (optional, auto-generated if not provided) */
peerId?: string;
/** Optional fetch implementation (for Node.js environments) */
fetch?: typeof fetch;
/** WebRTC configuration (ICE servers, etc.) */
rtcConfig?: RTCConfiguration;
/** Polling interval in milliseconds (default: 1000) */
pollingInterval?: number;
/** Connection timeout in milliseconds (default: 30000) */
connectionTimeout?: number;
/** WebRTC polyfill for Node.js (e.g., wrtc or @roamhq/wrtc) */
wrtc?: WebRTCPolyfill;
}
/**
* Connection role - whether this peer is creating or answering
*/
export type ConnectionRole = 'offerer' | 'answerer';
/**
* Parameters for creating a RondevuConnection
*/
export interface RondevuConnectionParams {
id: string;
topic?: string;
role: ConnectionRole;
pc: RTCPeerConnection;
localPeerId: string;
remotePeerId: string;
pollingInterval: number;
connectionTimeout: number;
wrtc?: WebRTCPolyfill;
}
/**
* Event map for RondevuConnection events
*/
export interface RondevuConnectionEvents {
connect: () => void;
disconnect: () => void;
error: (error: Error) => void;
datachannel: (channel: RTCDataChannel) => void;
stream: (stream: MediaStream) => void;
}