fix shit
This commit is contained in:
212
src/apis/Channels.ts
Normal file
212
src/apis/Channels.ts
Normal file
@@ -0,0 +1,212 @@
|
||||
import {HttpMethod} from '../net/http/HttpMethod';
|
||||
import type {PCastHttpRequests} from './PCastRequests';
|
||||
import type {ChannelResponse, ChannelsResponse, MembersResponse} from './IResponse';
|
||||
|
||||
export type ChannelId = string;
|
||||
export type Channel = {
|
||||
options: string[];
|
||||
alias: string;
|
||||
name: string;
|
||||
description: string;
|
||||
type: string;
|
||||
streamKey: string;
|
||||
created: string;
|
||||
lastUpdated: string;
|
||||
channelId: string;
|
||||
};
|
||||
export type ChannelAlias = string;
|
||||
export type Member = {
|
||||
sessionId: string;
|
||||
screenName: string;
|
||||
role: string;
|
||||
streams: [
|
||||
{
|
||||
type: string;
|
||||
uri: string;
|
||||
audioState: string;
|
||||
videoState: string;
|
||||
}
|
||||
];
|
||||
state: string;
|
||||
lastUpdate: number;
|
||||
};
|
||||
|
||||
type GetChannelParams = {
|
||||
alias?: string;
|
||||
channelId?: string;
|
||||
};
|
||||
|
||||
export class ChannelError extends Error {
|
||||
constructor(
|
||||
message: string,
|
||||
public readonly code: string
|
||||
) {
|
||||
super(message);
|
||||
this.name = 'ChannelError';
|
||||
}
|
||||
}
|
||||
|
||||
export class Channels {
|
||||
private readonly _httpRequests: PCastHttpRequests;
|
||||
private readonly _channelsByAlias: Map<ChannelAlias, Channel> = new Map();
|
||||
|
||||
constructor(pcastHttpRequests: PCastHttpRequests) {
|
||||
this._httpRequests = pcastHttpRequests;
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
public async createChannel(name: string, description: string, channelOptions: string[] = []): Promise<Channel> {
|
||||
if (!name || name.trim().length === 0) {
|
||||
throw new ChannelError('Channel name cannot be empty', 'INVALID_NAME');
|
||||
}
|
||||
|
||||
if (!description || description.trim().length === 0) {
|
||||
throw new ChannelError('Channel description cannot be empty', 'INVALID_DESCRIPTION');
|
||||
}
|
||||
|
||||
if (!Array.isArray(channelOptions)) {
|
||||
throw new ChannelError('Channel options must be an array', 'INVALID_OPTIONS');
|
||||
}
|
||||
|
||||
const createChannel = {
|
||||
channel: {
|
||||
name: name.trim(),
|
||||
alias: name.trim(),
|
||||
description: description.trim(),
|
||||
options: channelOptions
|
||||
}
|
||||
};
|
||||
|
||||
const route = '/channel';
|
||||
const requestOptions = {body: JSON.stringify(createChannel)};
|
||||
const response = await this._httpRequests.request<ChannelResponse>(HttpMethod.PUT, route, requestOptions);
|
||||
|
||||
if (!response.channel) {
|
||||
throw new ChannelError('Invalid response format - missing channel data', 'INVALID_RESPONSE');
|
||||
}
|
||||
|
||||
this._channelsByAlias.set(response.channel.alias, response.channel);
|
||||
|
||||
return response.channel;
|
||||
}
|
||||
|
||||
public async list(): Promise<Channel[]> {
|
||||
const response = await this._httpRequests.request<ChannelsResponse>(HttpMethod.GET, '/channels');
|
||||
|
||||
if (!response.channels) {
|
||||
throw new ChannelError('Invalid response format - missing channels data', 'INVALID_RESPONSE');
|
||||
}
|
||||
|
||||
this._channelsByAlias.clear();
|
||||
|
||||
for (const channel of response.channels) {
|
||||
this._channelsByAlias.set(channel.alias, channel);
|
||||
}
|
||||
|
||||
return response.channels;
|
||||
}
|
||||
|
||||
public async refreshCache(): Promise<void> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const ignored = await this.list();
|
||||
}
|
||||
|
||||
public async getChannelInfoByAlias(alias: string): Promise<Channel | undefined> {
|
||||
return this.get({alias});
|
||||
}
|
||||
|
||||
public async get({alias, channelId}: GetChannelParams): Promise<Channel | undefined> {
|
||||
if (!alias && !channelId) {
|
||||
throw new ChannelError('Either alias or channelId must be provided', 'MISSING_PARAMETER');
|
||||
}
|
||||
|
||||
if (alias && this._channelsByAlias.has(alias)) {
|
||||
return this._channelsByAlias.get(alias);
|
||||
}
|
||||
|
||||
const channelList = await this.list();
|
||||
|
||||
return alias ? channelList.find(channel => channel.alias === alias) : channelList.find(channel => channel.channelId === channelId);
|
||||
}
|
||||
|
||||
public async getPublisherCount(channelId: string): Promise<number> {
|
||||
const response = await this._httpRequests.request<string>(HttpMethod.GET, `/channel/${encodeURIComponent(channelId)}/publishers/count`);
|
||||
|
||||
return parseInt(response, 10);
|
||||
}
|
||||
|
||||
public async getMembers(channelId: string): Promise<Member[]> {
|
||||
if (!channelId || channelId.trim().length === 0) {
|
||||
throw new ChannelError('Channel ID cannot be empty', 'INVALID_CHANNEL_ID');
|
||||
}
|
||||
|
||||
const response = await this._httpRequests.request<MembersResponse>(HttpMethod.GET, `/channel/${encodeURIComponent(channelId)}/members`);
|
||||
|
||||
if (!response.members) {
|
||||
throw new ChannelError(`Invalid response format for channel members: ${channelId}`, 'INVALID_RESPONSE');
|
||||
}
|
||||
|
||||
return response.members;
|
||||
}
|
||||
|
||||
public async getMembersByChannelAlias(alias: string): Promise<Member[]> {
|
||||
const channel = await this.get({alias});
|
||||
|
||||
if (!channel) {
|
||||
throw new ChannelError(`Channel not found: ${alias}`, 'CHANNEL_NOT_FOUND');
|
||||
}
|
||||
|
||||
return this.getMembers(channel.channelId);
|
||||
}
|
||||
|
||||
public async delete({channelId, alias}: {channelId?: string; alias?: string}): Promise<Channel> {
|
||||
if (!channelId && !alias) {
|
||||
throw new ChannelError('Deleting a channel requires either a channelId or alias', 'INVALID_ARGUMENTS');
|
||||
}
|
||||
|
||||
const channelIdToDelete = alias ? (await this.get({alias}))?.channelId : channelId;
|
||||
|
||||
if (!channelIdToDelete) {
|
||||
throw new ChannelError('Unable to find room to delete', 'NOT_FOUND');
|
||||
}
|
||||
|
||||
const route = `/channel/${encodeURIComponent(channelIdToDelete)}`;
|
||||
const response = await this._httpRequests.request<ChannelResponse>(HttpMethod.DELETE, route);
|
||||
|
||||
if (!response.channel) {
|
||||
throw new ChannelError(`Invalid response format for deleted channel [${channelId}]`, 'INVALID_RESPONSE');
|
||||
}
|
||||
|
||||
// Remove from cache if it exists
|
||||
const deletedChannel = response.channel;
|
||||
if (this._channelsByAlias.has(deletedChannel.alias)) {
|
||||
this._channelsByAlias.delete(deletedChannel.alias);
|
||||
}
|
||||
|
||||
return deletedChannel;
|
||||
}
|
||||
|
||||
public clearCache(): void {
|
||||
this._channelsByAlias.clear();
|
||||
}
|
||||
|
||||
public getCacheSize(): number {
|
||||
return this._channelsByAlias.size;
|
||||
}
|
||||
|
||||
private async initialize(): Promise<void> {
|
||||
try {
|
||||
const channelsList = await this.list();
|
||||
if (!channelsList) {
|
||||
console.warn('[Channels] Failed to initialize cache - no channels returned');
|
||||
return;
|
||||
}
|
||||
|
||||
for (const channel of channelsList) {
|
||||
this._channelsByAlias.set(channel.alias, channel);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Channels] Failed to initialize cache:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user