streemo-video-call-sdk 0.2.5 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { T as TokenProvider, S as ServerAuthConfig } from './sdkConfig-C9Fey7R2.js';
2
- export { a as SDKError, b as SDKErrorCode, c as ServerTokenProviderOptions, d as TokenProviderContext, V as VideoSDKConfig, e as createServerTokenProvider, f as defaultApiBaseUrl, g as defaultWsBaseUrlFromApi, h as getVideoSDKConfig, i as initVideoSDK, m as mapSDKErrorToUIMessage } from './sdkConfig-C9Fey7R2.js';
1
+ import { T as TokenProvider, S as ServerAuthConfig } from './sdkConfig-DTNZ7Mms.js';
2
+ export { a as SDKError, b as SDKErrorCode, c as ServerTokenProviderOptions, d as StreemoClient, e as StreemoClientOptions, f as TokenProviderContext, V as VideoSDKConfig, g as createServerTokenProvider, h as createStreemoClient, i as defaultApiBaseUrl, j as defaultWsBaseUrlFromApi, k as getVideoSDKConfig, l as initVideoSDK, m as mapSDKErrorToUIMessage } from './sdkConfig-DTNZ7Mms.js';
3
3
 
4
4
  type SignalMessage = {
5
5
  type: string;
package/dist/client.js CHANGED
@@ -263,10 +263,171 @@ var VideoSignalingClient = class {
263
263
  this.connected = false;
264
264
  }
265
265
  };
266
+
267
+ // src/client/StreemoClient.ts
268
+ var StreemoClient = class {
269
+ apiKey;
270
+ userToken;
271
+ user;
272
+ baseUrl;
273
+ wsUrl;
274
+ reconnect;
275
+ ws = null;
276
+ manuallyClosed = false;
277
+ reconnectAttempt = 0;
278
+ listeners = {};
279
+ constructor(options) {
280
+ this.apiKey = options.apiKey;
281
+ this.userToken = options.userToken;
282
+ this.user = options.user;
283
+ this.baseUrl = (options.baseUrl ?? "https://api.streemo.ru").replace(/\/+$/, "");
284
+ const defaultWs = this.baseUrl.replace(/^http/, "ws");
285
+ this.wsUrl = (options.wsUrl ?? defaultWs).replace(/\/+$/, "");
286
+ this.reconnect = options.reconnect ?? true;
287
+ }
288
+ on(event, listener) {
289
+ if (!this.listeners[event]) this.listeners[event] = /* @__PURE__ */ new Set();
290
+ this.listeners[event]?.add(listener);
291
+ return () => this.off(event, listener);
292
+ }
293
+ off(event, listener) {
294
+ this.listeners[event]?.delete(listener);
295
+ }
296
+ emit(event, payload) {
297
+ this.listeners[event]?.forEach((listener) => {
298
+ listener(payload);
299
+ });
300
+ }
301
+ async connect() {
302
+ if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) return;
303
+ this.manuallyClosed = false;
304
+ await this.openSocket();
305
+ }
306
+ disconnect() {
307
+ this.manuallyClosed = true;
308
+ this.ws?.close();
309
+ this.ws = null;
310
+ this.emit("connected", { connected: false });
311
+ }
312
+ async openSocket() {
313
+ await new Promise((resolve, reject) => {
314
+ const url = `${this.wsUrl}/v1/ws?token=${encodeURIComponent(this.userToken)}&userId=${encodeURIComponent(this.user.id)}`;
315
+ const ws = new WebSocket(url);
316
+ this.ws = ws;
317
+ ws.onopen = () => {
318
+ this.reconnectAttempt = 0;
319
+ this.emit("connected", { connected: true });
320
+ resolve();
321
+ };
322
+ ws.onmessage = (event) => {
323
+ const parsed = JSON.parse(event.data);
324
+ switch (parsed.type) {
325
+ case "message_new":
326
+ case "message_updated":
327
+ this.emit(parsed.type, parsed);
328
+ break;
329
+ case "typing":
330
+ this.emit("typing", parsed);
331
+ break;
332
+ case "presence":
333
+ this.emit("presence", parsed);
334
+ break;
335
+ case "reaction_new":
336
+ this.emit("reaction_new", parsed);
337
+ break;
338
+ default:
339
+ break;
340
+ }
341
+ };
342
+ ws.onerror = () => {
343
+ reject(new Error("WebSocket connection failed"));
344
+ };
345
+ ws.onclose = () => {
346
+ this.emit("connected", { connected: false });
347
+ if (!this.manuallyClosed && this.reconnect) {
348
+ const backoffMs = Math.min(1e3 * 2 ** this.reconnectAttempt, 15e3);
349
+ this.reconnectAttempt += 1;
350
+ setTimeout(() => {
351
+ void this.openSocket();
352
+ }, backoffMs);
353
+ }
354
+ };
355
+ });
356
+ }
357
+ buildUrl(path, query) {
358
+ const url = new URL(`${this.baseUrl}${path}`);
359
+ if (query) {
360
+ Object.entries(query).forEach(([key, value]) => {
361
+ if (value !== void 0) url.searchParams.set(key, String(value));
362
+ });
363
+ }
364
+ return url.toString();
365
+ }
366
+ async request(path, init, query) {
367
+ const response = await fetch(this.buildUrl(path, query), {
368
+ ...init,
369
+ headers: {
370
+ Authorization: `Bearer ${this.userToken}`,
371
+ "X-App-Id": this.apiKey,
372
+ "Content-Type": "application/json",
373
+ ...init?.headers ?? {}
374
+ }
375
+ });
376
+ const data = await response.json().catch(() => ({}));
377
+ if (!response.ok) {
378
+ throw new Error(data.error || `HTTP ${response.status}`);
379
+ }
380
+ return data;
381
+ }
382
+ listChannels() {
383
+ return this.request("/v1/channels");
384
+ }
385
+ listMessages(channelId, cursor, limit = 30) {
386
+ return this.request(
387
+ `/v1/channels/${encodeURIComponent(channelId)}/messages`,
388
+ void 0,
389
+ { cursor, limit }
390
+ );
391
+ }
392
+ sendMessage(input) {
393
+ return this.request(`/v1/channels/${encodeURIComponent(input.channelId)}/messages`, {
394
+ method: "POST",
395
+ body: JSON.stringify(input)
396
+ });
397
+ }
398
+ updateMessage(channelId, messageId, text) {
399
+ return this.request(
400
+ `/v1/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}`,
401
+ {
402
+ method: "PATCH",
403
+ body: JSON.stringify({ text })
404
+ }
405
+ );
406
+ }
407
+ deleteMessage(channelId, messageId) {
408
+ return this.request(
409
+ `/v1/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}`,
410
+ { method: "DELETE" }
411
+ );
412
+ }
413
+ sendTyping(channelId, isTyping) {
414
+ return this.request(`/v1/channels/${encodeURIComponent(channelId)}/typing`, {
415
+ method: "POST",
416
+ body: JSON.stringify({ isTyping })
417
+ });
418
+ }
419
+ };
420
+
421
+ // src/client/createStreemoClient.ts
422
+ function createStreemoClient(options) {
423
+ return new StreemoClient(options);
424
+ }
266
425
  export {
267
426
  SDKError,
427
+ StreemoClient,
268
428
  VideoSignalingClient,
269
429
  createServerTokenProvider,
430
+ createStreemoClient,
270
431
  defaultApiBaseUrl,
271
432
  defaultWsBaseUrlFromApi,
272
433
  getVideoSDKConfig,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/auth.ts","../src/sdkErrors.ts","../src/tokenProvider.ts","../src/sdkConfig.ts","../src/signalingClient.ts"],"sourcesContent":["export type ServerAuthConfig = {\n authToken: string\n clientId?: string\n appId: string\n authHeader?: string\n clientIdHeader?: string\n appIdHeader?: string\n}\n\nexport function buildAuthHeaders(auth: ServerAuthConfig): Record<string, string> {\n const headers: Record<string, string> = {\n [auth.appIdHeader ?? 'X-App-Id']: auth.appId,\n [auth.authHeader ?? 'Authorization']: `Bearer ${auth.authToken}`,\n }\n if (auth.clientId) {\n headers[auth.clientIdHeader ?? 'X-Client-Id'] = auth.clientId\n }\n return headers\n}\n","export type SDKErrorCode =\n | 'invalid_app'\n | 'invalid_client'\n | 'expired_token'\n | 'unauthorized'\n | 'forbidden'\n | 'rate_limited'\n | 'network_error'\n | 'unknown_error'\n\nexport class SDKError extends Error {\n code: SDKErrorCode\n status?: number\n\n constructor(code: SDKErrorCode, message: string, status?: number) {\n super(message)\n this.code = code\n this.status = status\n this.name = 'SDKError'\n }\n}\n\nexport function mapSDKErrorToUIMessage(err: unknown): string {\n if (!(err instanceof SDKError)) {\n return 'Unexpected error while connecting to call server.'\n }\n\n switch (err.code) {\n case 'invalid_app':\n return 'Application is not allowed to use this video service.'\n case 'invalid_client':\n return 'Client is not recognized by video service.'\n case 'expired_token':\n return 'Authorization token is expired. Please sign in again.'\n case 'unauthorized':\n return 'Authorization failed. Please check your credentials.'\n case 'forbidden':\n return 'Access is forbidden for this application/client.'\n case 'rate_limited':\n return 'Organization rate limit exceeded. Please retry later.'\n case 'network_error':\n return 'Network error while connecting to video service.'\n default:\n return err.message || 'Unknown video service error.'\n }\n}\n","import { buildAuthHeaders, type ServerAuthConfig } from './auth'\nimport { SDKError } from './sdkErrors'\n\nexport type TokenProviderContext = {\n roomId: string\n userId: string\n}\n\nexport type TokenProvider = (ctx: TokenProviderContext) => Promise<string>\n\nexport type ServerTokenProviderOptions = {\n apiBaseUrl?: string\n auth: ServerAuthConfig\n externalUserRegisterPath?: string\n joinPathBuilder?: (roomId: string) => string\n tokenPathBuilder?: (roomId: string) => string\n}\n\ntype ServerErrorPayload = {\n error?: string\n message?: string\n}\n\nfunction mapServerError(status: number, serverMessage: string): SDKError {\n const message = serverMessage.toLowerCase()\n if (status === 403 && message.includes('app id')) {\n return new SDKError('invalid_app', 'invalid_app', status)\n }\n if (status === 403 && message.includes('auth token')) {\n return new SDKError('unauthorized', 'invalid_auth_token', status)\n }\n if (status === 403 && message.includes('client id')) {\n return new SDKError('invalid_client', 'invalid_client', status)\n }\n if (status === 401 && message.includes('expired token')) {\n return new SDKError('expired_token', 'expired_token', status)\n }\n if (status === 401) {\n return new SDKError('unauthorized', 'unauthorized', status)\n }\n if (status === 403) {\n return new SDKError('forbidden', 'forbidden', status)\n }\n if (status === 429) {\n return new SDKError('rate_limited', 'rate_limited', status)\n }\n return new SDKError('unknown_error', serverMessage || 'unknown_error', status)\n}\n\nasync function fetchJson<T>(input: RequestInfo | URL, init: RequestInit): Promise<T> {\n let response: Response\n try {\n response = await fetch(input, init)\n } catch {\n throw new SDKError('network_error', 'network_error')\n }\n if (!response.ok) {\n let serverMessage = response.statusText\n try {\n const payload = (await response.json()) as ServerErrorPayload\n serverMessage = payload.error || payload.message || serverMessage\n } catch {\n const text = await response.text()\n if (text) serverMessage = text\n }\n throw mapServerError(response.status, serverMessage)\n }\n return response.json() as Promise<T>\n}\n\nexport function defaultWsBaseUrlFromApi(apiBaseUrl: string): string {\n const normalized = apiBaseUrl.replace(/\\/+$/, '')\n if (normalized.startsWith('https://')) {\n return normalized.replace(/^https:\\/\\//, 'wss://')\n }\n if (normalized.startsWith('http://')) {\n return normalized.replace(/^http:\\/\\//, 'ws://')\n }\n return normalized\n}\n\nexport function defaultApiBaseUrl(): string {\n if (typeof window !== 'undefined' && window.location?.origin) {\n return window.location.origin\n }\n return ''\n}\n\nexport function createServerTokenProvider(options: ServerTokenProviderOptions): TokenProvider {\n const externalUserRegisterPath = options.externalUserRegisterPath ?? '/v1/external-users/register'\n const joinPathBuilder = options.joinPathBuilder ?? ((roomId: string) => `/v1/rooms/${roomId}/join`)\n const tokenPathBuilder = options.tokenPathBuilder ?? ((roomId: string) => `/v1/rooms/${roomId}/token`)\n const externalUserMap = new Map<string, string>()\n\n return async ({ roomId, userId }) => {\n const base = (options.apiBaseUrl || defaultApiBaseUrl()).replace(/\\/+$/, '')\n if (!base) {\n throw new SDKError('unknown_error', 'api_base_url_required')\n }\n const headers = {\n 'Content-Type': 'application/json',\n ...buildAuthHeaders(options.auth),\n }\n\n let internalUserID = externalUserMap.get(userId)\n if (!internalUserID) {\n const registration = await fetchJson<{ userId: string }>(`${base}${externalUserRegisterPath}`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n externalId: userId,\n }),\n })\n if (!registration.userId) {\n throw new SDKError('unknown_error', 'external_user_registration_failed')\n }\n internalUserID = registration.userId\n externalUserMap.set(userId, internalUserID)\n }\n const roomHeaders = {\n ...headers,\n 'X-Guest-Id': internalUserID,\n }\n\n await fetchJson<{ ok?: boolean }>(`${base}${joinPathBuilder(roomId)}`, {\n method: 'POST',\n headers: roomHeaders,\n body: '{}',\n })\n\n const tokenResponse = await fetchJson<{ token: string }>(`${base}${tokenPathBuilder(roomId)}`, {\n method: 'POST',\n headers: roomHeaders,\n })\n\n if (!tokenResponse.token) {\n throw new Error('Room token is empty')\n }\n return tokenResponse.token\n }\n}\n","import type { ServerAuthConfig } from './auth'\n\nexport type VideoSDKConfig = {\n apiBaseUrl?: string\n wsBaseUrl?: string\n auth?: ServerAuthConfig\n}\n\nconst DEFAULT_API_BASE_URL = 'https://api.streemo.ru'\nconst DEFAULT_WS_BASE_URL = 'wss://api.streemo.ru'\n\nlet globalConfig: VideoSDKConfig = {\n apiBaseUrl: DEFAULT_API_BASE_URL,\n wsBaseUrl: DEFAULT_WS_BASE_URL,\n}\n\nexport function initVideoSDK(config: VideoSDKConfig): void {\n globalConfig = {\n ...globalConfig,\n ...config,\n auth: config.auth ? { ...(globalConfig.auth ?? {}), ...config.auth } : globalConfig.auth,\n }\n}\n\nexport function getVideoSDKConfig(): VideoSDKConfig {\n return globalConfig\n}\n\n","import {\n createServerTokenProvider,\n defaultApiBaseUrl,\n defaultWsBaseUrlFromApi,\n type TokenProvider,\n type TokenProviderContext,\n} from './tokenProvider'\nimport type { ServerAuthConfig } from './auth'\nimport { getVideoSDKConfig } from './sdkConfig'\n\nexport type SignalMessage = {\n type: string\n roomId: string\n userId: string\n targetUserId?: string\n payload?: unknown\n}\n\nexport type SignalingClientConfig = {\n roomId: string\n userId: string\n roomToken?: string\n wsBaseUrl?: string\n tokenProvider?: TokenProvider\n apiBaseUrl?: string\n auth?: ServerAuthConfig\n onOpen?: () => void\n onClose?: (event: CloseEvent) => void\n onError?: (event: Event) => void\n onMessage?: (message: SignalMessage) => void\n}\n\nfunction resolveTokenProvider(config: SignalingClientConfig): TokenProvider | null {\n const sdkConfig = getVideoSDKConfig()\n const apiBaseUrl = config.apiBaseUrl ?? sdkConfig.apiBaseUrl\n const auth = config.auth ?? sdkConfig.auth\n if (config.tokenProvider) return config.tokenProvider\n if (auth) {\n return createServerTokenProvider({\n apiBaseUrl: apiBaseUrl ?? defaultApiBaseUrl(),\n auth,\n })\n }\n return null\n}\n\nasync function resolveRoomToken(config: SignalingClientConfig): Promise<string> {\n if (config.roomToken) return config.roomToken\n const provider = resolveTokenProvider(config)\n if (!provider) {\n throw new Error('roomToken or tokenProvider/apiBaseUrl+auth is required')\n }\n const ctx: TokenProviderContext = {\n roomId: config.roomId,\n userId: config.userId,\n }\n return provider(ctx)\n}\n\nfunction resolveWsBaseUrl(config: SignalingClientConfig): string {\n const sdkConfig = getVideoSDKConfig()\n if (config.wsBaseUrl) return config.wsBaseUrl.replace(/\\/+$/, '')\n if (sdkConfig.wsBaseUrl) return sdkConfig.wsBaseUrl.replace(/\\/+$/, '')\n const apiBaseUrl = config.apiBaseUrl ?? sdkConfig.apiBaseUrl ?? defaultApiBaseUrl()\n if (apiBaseUrl) return defaultWsBaseUrlFromApi(apiBaseUrl)\n throw new Error('wsBaseUrl or apiBaseUrl is required')\n}\n\nexport class VideoSignalingClient {\n private readonly config: SignalingClientConfig\n private ws: WebSocket | null = null\n private connected = false\n\n constructor(config: SignalingClientConfig) {\n this.config = config\n }\n\n isConnected(): boolean {\n return this.connected\n }\n\n async connect(): Promise<void> {\n if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) {\n return\n }\n\n const roomToken = await resolveRoomToken(this.config)\n const wsBase = resolveWsBaseUrl(this.config)\n const wsURL = `${wsBase}/v1/ws?roomId=${encodeURIComponent(this.config.roomId)}&token=${encodeURIComponent(roomToken)}`\n\n await new Promise<void>((resolve, reject) => {\n const ws = new WebSocket(wsURL)\n this.ws = ws\n\n ws.onopen = () => {\n this.connected = true\n this.config.onOpen?.()\n resolve()\n }\n ws.onclose = (event) => {\n this.connected = false\n this.config.onClose?.(event)\n }\n ws.onerror = (event) => {\n this.config.onError?.(event)\n reject(new Error('WebSocket connection error'))\n }\n ws.onmessage = (event) => {\n const message = JSON.parse(event.data) as SignalMessage\n this.config.onMessage?.(message)\n }\n })\n }\n\n send(message: Omit<SignalMessage, 'roomId' | 'userId'>): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return\n this.ws.send(\n JSON.stringify({\n roomId: this.config.roomId,\n userId: this.config.userId,\n ...message,\n }),\n )\n }\n\n disconnect(): void {\n this.ws?.close()\n this.ws = null\n this.connected = false\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/auth.ts","../src/sdkErrors.ts","../src/tokenProvider.ts","../src/sdkConfig.ts","../src/signalingClient.ts","../src/client/StreemoClient.ts","../src/client/createStreemoClient.ts"],"sourcesContent":["export type ServerAuthConfig = {\n authToken: string\n clientId?: string\n appId: string\n authHeader?: string\n clientIdHeader?: string\n appIdHeader?: string\n}\n\nexport function buildAuthHeaders(auth: ServerAuthConfig): Record<string, string> {\n const headers: Record<string, string> = {\n [auth.appIdHeader ?? 'X-App-Id']: auth.appId,\n [auth.authHeader ?? 'Authorization']: `Bearer ${auth.authToken}`,\n }\n if (auth.clientId) {\n headers[auth.clientIdHeader ?? 'X-Client-Id'] = auth.clientId\n }\n return headers\n}\n","export type SDKErrorCode =\n | 'invalid_app'\n | 'invalid_client'\n | 'expired_token'\n | 'unauthorized'\n | 'forbidden'\n | 'rate_limited'\n | 'network_error'\n | 'unknown_error'\n\nexport class SDKError extends Error {\n code: SDKErrorCode\n status?: number\n\n constructor(code: SDKErrorCode, message: string, status?: number) {\n super(message)\n this.code = code\n this.status = status\n this.name = 'SDKError'\n }\n}\n\nexport function mapSDKErrorToUIMessage(err: unknown): string {\n if (!(err instanceof SDKError)) {\n return 'Unexpected error while connecting to call server.'\n }\n\n switch (err.code) {\n case 'invalid_app':\n return 'Application is not allowed to use this video service.'\n case 'invalid_client':\n return 'Client is not recognized by video service.'\n case 'expired_token':\n return 'Authorization token is expired. Please sign in again.'\n case 'unauthorized':\n return 'Authorization failed. Please check your credentials.'\n case 'forbidden':\n return 'Access is forbidden for this application/client.'\n case 'rate_limited':\n return 'Organization rate limit exceeded. Please retry later.'\n case 'network_error':\n return 'Network error while connecting to video service.'\n default:\n return err.message || 'Unknown video service error.'\n }\n}\n","import { buildAuthHeaders, type ServerAuthConfig } from './auth'\nimport { SDKError } from './sdkErrors'\n\nexport type TokenProviderContext = {\n roomId: string\n userId: string\n}\n\nexport type TokenProvider = (ctx: TokenProviderContext) => Promise<string>\n\nexport type ServerTokenProviderOptions = {\n apiBaseUrl?: string\n auth: ServerAuthConfig\n externalUserRegisterPath?: string\n joinPathBuilder?: (roomId: string) => string\n tokenPathBuilder?: (roomId: string) => string\n}\n\ntype ServerErrorPayload = {\n error?: string\n message?: string\n}\n\nfunction mapServerError(status: number, serverMessage: string): SDKError {\n const message = serverMessage.toLowerCase()\n if (status === 403 && message.includes('app id')) {\n return new SDKError('invalid_app', 'invalid_app', status)\n }\n if (status === 403 && message.includes('auth token')) {\n return new SDKError('unauthorized', 'invalid_auth_token', status)\n }\n if (status === 403 && message.includes('client id')) {\n return new SDKError('invalid_client', 'invalid_client', status)\n }\n if (status === 401 && message.includes('expired token')) {\n return new SDKError('expired_token', 'expired_token', status)\n }\n if (status === 401) {\n return new SDKError('unauthorized', 'unauthorized', status)\n }\n if (status === 403) {\n return new SDKError('forbidden', 'forbidden', status)\n }\n if (status === 429) {\n return new SDKError('rate_limited', 'rate_limited', status)\n }\n return new SDKError('unknown_error', serverMessage || 'unknown_error', status)\n}\n\nasync function fetchJson<T>(input: RequestInfo | URL, init: RequestInit): Promise<T> {\n let response: Response\n try {\n response = await fetch(input, init)\n } catch {\n throw new SDKError('network_error', 'network_error')\n }\n if (!response.ok) {\n let serverMessage = response.statusText\n try {\n const payload = (await response.json()) as ServerErrorPayload\n serverMessage = payload.error || payload.message || serverMessage\n } catch {\n const text = await response.text()\n if (text) serverMessage = text\n }\n throw mapServerError(response.status, serverMessage)\n }\n return response.json() as Promise<T>\n}\n\nexport function defaultWsBaseUrlFromApi(apiBaseUrl: string): string {\n const normalized = apiBaseUrl.replace(/\\/+$/, '')\n if (normalized.startsWith('https://')) {\n return normalized.replace(/^https:\\/\\//, 'wss://')\n }\n if (normalized.startsWith('http://')) {\n return normalized.replace(/^http:\\/\\//, 'ws://')\n }\n return normalized\n}\n\nexport function defaultApiBaseUrl(): string {\n if (typeof window !== 'undefined' && window.location?.origin) {\n return window.location.origin\n }\n return ''\n}\n\nexport function createServerTokenProvider(options: ServerTokenProviderOptions): TokenProvider {\n const externalUserRegisterPath = options.externalUserRegisterPath ?? '/v1/external-users/register'\n const joinPathBuilder = options.joinPathBuilder ?? ((roomId: string) => `/v1/rooms/${roomId}/join`)\n const tokenPathBuilder = options.tokenPathBuilder ?? ((roomId: string) => `/v1/rooms/${roomId}/token`)\n const externalUserMap = new Map<string, string>()\n\n return async ({ roomId, userId }) => {\n const base = (options.apiBaseUrl || defaultApiBaseUrl()).replace(/\\/+$/, '')\n if (!base) {\n throw new SDKError('unknown_error', 'api_base_url_required')\n }\n const headers = {\n 'Content-Type': 'application/json',\n ...buildAuthHeaders(options.auth),\n }\n\n let internalUserID = externalUserMap.get(userId)\n if (!internalUserID) {\n const registration = await fetchJson<{ userId: string }>(`${base}${externalUserRegisterPath}`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n externalId: userId,\n }),\n })\n if (!registration.userId) {\n throw new SDKError('unknown_error', 'external_user_registration_failed')\n }\n internalUserID = registration.userId\n externalUserMap.set(userId, internalUserID)\n }\n const roomHeaders = {\n ...headers,\n 'X-Guest-Id': internalUserID,\n }\n\n await fetchJson<{ ok?: boolean }>(`${base}${joinPathBuilder(roomId)}`, {\n method: 'POST',\n headers: roomHeaders,\n body: '{}',\n })\n\n const tokenResponse = await fetchJson<{ token: string }>(`${base}${tokenPathBuilder(roomId)}`, {\n method: 'POST',\n headers: roomHeaders,\n })\n\n if (!tokenResponse.token) {\n throw new Error('Room token is empty')\n }\n return tokenResponse.token\n }\n}\n","import type { ServerAuthConfig } from './auth'\n\nexport type VideoSDKConfig = {\n apiBaseUrl?: string\n wsBaseUrl?: string\n auth?: ServerAuthConfig\n}\n\nconst DEFAULT_API_BASE_URL = 'https://api.streemo.ru'\nconst DEFAULT_WS_BASE_URL = 'wss://api.streemo.ru'\n\nlet globalConfig: VideoSDKConfig = {\n apiBaseUrl: DEFAULT_API_BASE_URL,\n wsBaseUrl: DEFAULT_WS_BASE_URL,\n}\n\nexport function initVideoSDK(config: VideoSDKConfig): void {\n globalConfig = {\n ...globalConfig,\n ...config,\n auth: config.auth ? { ...(globalConfig.auth ?? {}), ...config.auth } : globalConfig.auth,\n }\n}\n\nexport function getVideoSDKConfig(): VideoSDKConfig {\n return globalConfig\n}\n\n","import {\n createServerTokenProvider,\n defaultApiBaseUrl,\n defaultWsBaseUrlFromApi,\n type TokenProvider,\n type TokenProviderContext,\n} from './tokenProvider'\nimport type { ServerAuthConfig } from './auth'\nimport { getVideoSDKConfig } from './sdkConfig'\n\nexport type SignalMessage = {\n type: string\n roomId: string\n userId: string\n targetUserId?: string\n payload?: unknown\n}\n\nexport type SignalingClientConfig = {\n roomId: string\n userId: string\n roomToken?: string\n wsBaseUrl?: string\n tokenProvider?: TokenProvider\n apiBaseUrl?: string\n auth?: ServerAuthConfig\n onOpen?: () => void\n onClose?: (event: CloseEvent) => void\n onError?: (event: Event) => void\n onMessage?: (message: SignalMessage) => void\n}\n\nfunction resolveTokenProvider(config: SignalingClientConfig): TokenProvider | null {\n const sdkConfig = getVideoSDKConfig()\n const apiBaseUrl = config.apiBaseUrl ?? sdkConfig.apiBaseUrl\n const auth = config.auth ?? sdkConfig.auth\n if (config.tokenProvider) return config.tokenProvider\n if (auth) {\n return createServerTokenProvider({\n apiBaseUrl: apiBaseUrl ?? defaultApiBaseUrl(),\n auth,\n })\n }\n return null\n}\n\nasync function resolveRoomToken(config: SignalingClientConfig): Promise<string> {\n if (config.roomToken) return config.roomToken\n const provider = resolveTokenProvider(config)\n if (!provider) {\n throw new Error('roomToken or tokenProvider/apiBaseUrl+auth is required')\n }\n const ctx: TokenProviderContext = {\n roomId: config.roomId,\n userId: config.userId,\n }\n return provider(ctx)\n}\n\nfunction resolveWsBaseUrl(config: SignalingClientConfig): string {\n const sdkConfig = getVideoSDKConfig()\n if (config.wsBaseUrl) return config.wsBaseUrl.replace(/\\/+$/, '')\n if (sdkConfig.wsBaseUrl) return sdkConfig.wsBaseUrl.replace(/\\/+$/, '')\n const apiBaseUrl = config.apiBaseUrl ?? sdkConfig.apiBaseUrl ?? defaultApiBaseUrl()\n if (apiBaseUrl) return defaultWsBaseUrlFromApi(apiBaseUrl)\n throw new Error('wsBaseUrl or apiBaseUrl is required')\n}\n\nexport class VideoSignalingClient {\n private readonly config: SignalingClientConfig\n private ws: WebSocket | null = null\n private connected = false\n\n constructor(config: SignalingClientConfig) {\n this.config = config\n }\n\n isConnected(): boolean {\n return this.connected\n }\n\n async connect(): Promise<void> {\n if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) {\n return\n }\n\n const roomToken = await resolveRoomToken(this.config)\n const wsBase = resolveWsBaseUrl(this.config)\n const wsURL = `${wsBase}/v1/ws?roomId=${encodeURIComponent(this.config.roomId)}&token=${encodeURIComponent(roomToken)}`\n\n await new Promise<void>((resolve, reject) => {\n const ws = new WebSocket(wsURL)\n this.ws = ws\n\n ws.onopen = () => {\n this.connected = true\n this.config.onOpen?.()\n resolve()\n }\n ws.onclose = (event) => {\n this.connected = false\n this.config.onClose?.(event)\n }\n ws.onerror = (event) => {\n this.config.onError?.(event)\n reject(new Error('WebSocket connection error'))\n }\n ws.onmessage = (event) => {\n const message = JSON.parse(event.data) as SignalMessage\n this.config.onMessage?.(message)\n }\n })\n }\n\n send(message: Omit<SignalMessage, 'roomId' | 'userId'>): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return\n this.ws.send(\n JSON.stringify({\n roomId: this.config.roomId,\n userId: this.config.userId,\n ...message,\n }),\n )\n }\n\n disconnect(): void {\n this.ws?.close()\n this.ws = null\n this.connected = false\n }\n}\n","import type {\r\n PresenceState,\r\n StreemoAttachment,\r\n StreemoChannel,\r\n StreemoMessage,\r\n StreemoReaction,\r\n StreemoUser,\r\n TypingState,\r\n} from '../types/models'\r\n\r\ntype Listener<T> = (event: T) => void\r\n\r\ntype RealtimeEventMap = {\r\n connected: { connected: boolean }\r\n message_new: StreemoMessage\r\n message_updated: StreemoMessage\r\n typing: TypingState\r\n presence: PresenceState\r\n reaction_new: { channelId: string; messageId: string; reaction: StreemoReaction }\r\n}\r\n\r\ntype QueryParams = Record<string, string | number | undefined>\r\n\r\n/** Internal storage uses a generic listener to avoid DTS inference issues with mapped types */\r\ntype AnyListener = Listener<RealtimeEventMap[keyof RealtimeEventMap]>\r\n\r\nexport type StreemoClientOptions = {\r\n apiKey: string\r\n userToken: string\r\n user: StreemoUser\r\n baseUrl?: string\r\n wsUrl?: string\r\n reconnect?: boolean\r\n}\r\n\r\nexport class StreemoClient {\r\n public readonly apiKey: string\r\n public readonly userToken: string\r\n public readonly user: StreemoUser\r\n public readonly baseUrl: string\r\n public readonly wsUrl: string\r\n private readonly reconnect: boolean\r\n\r\n private ws: WebSocket | null = null\r\n private manuallyClosed = false\r\n private reconnectAttempt = 0\r\n private listeners: Partial<Record<keyof RealtimeEventMap, Set<AnyListener>>> = {}\r\n\r\n constructor(options: StreemoClientOptions) {\r\n this.apiKey = options.apiKey\r\n this.userToken = options.userToken\r\n this.user = options.user\r\n this.baseUrl = (options.baseUrl ?? 'https://api.streemo.ru').replace(/\\/+$/, '')\r\n const defaultWs = this.baseUrl.replace(/^http/, 'ws')\r\n this.wsUrl = (options.wsUrl ?? defaultWs).replace(/\\/+$/, '')\r\n this.reconnect = options.reconnect ?? true\r\n }\r\n\r\n on<K extends keyof RealtimeEventMap>(event: K, listener: Listener<RealtimeEventMap[K]>): () => void {\r\n if (!this.listeners[event]) this.listeners[event] = new Set()\r\n this.listeners[event]?.add(listener as Listener<RealtimeEventMap[keyof RealtimeEventMap]>)\r\n return () => this.off(event, listener)\r\n }\r\n\r\n off<K extends keyof RealtimeEventMap>(event: K, listener: Listener<RealtimeEventMap[K]>): void {\r\n this.listeners[event]?.delete(listener as Listener<RealtimeEventMap[keyof RealtimeEventMap]>)\r\n }\r\n\r\n private emit<K extends keyof RealtimeEventMap>(event: K, payload: RealtimeEventMap[K]): void {\r\n this.listeners[event]?.forEach((listener) => {\r\n listener(payload)\r\n })\r\n }\r\n\r\n async connect(): Promise<void> {\r\n if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) return\r\n this.manuallyClosed = false\r\n await this.openSocket()\r\n }\r\n\r\n disconnect(): void {\r\n this.manuallyClosed = true\r\n this.ws?.close()\r\n this.ws = null\r\n this.emit('connected', { connected: false })\r\n }\r\n\r\n private async openSocket(): Promise<void> {\r\n await new Promise<void>((resolve, reject) => {\r\n const url = `${this.wsUrl}/v1/ws?token=${encodeURIComponent(this.userToken)}&userId=${encodeURIComponent(this.user.id)}`\r\n const ws = new WebSocket(url)\r\n this.ws = ws\r\n\r\n ws.onopen = () => {\r\n this.reconnectAttempt = 0\r\n this.emit('connected', { connected: true })\r\n resolve()\r\n }\r\n\r\n ws.onmessage = (event) => {\r\n const parsed = JSON.parse(event.data) as { type: keyof RealtimeEventMap } & Record<string, unknown>\r\n switch (parsed.type) {\r\n case 'message_new':\r\n case 'message_updated':\r\n this.emit(parsed.type, parsed as unknown as StreemoMessage)\r\n break\r\n case 'typing':\r\n this.emit('typing', parsed as unknown as TypingState)\r\n break\r\n case 'presence':\r\n this.emit('presence', parsed as unknown as PresenceState)\r\n break\r\n case 'reaction_new':\r\n this.emit('reaction_new', parsed as unknown as { channelId: string; messageId: string; reaction: StreemoReaction })\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n ws.onerror = () => {\r\n reject(new Error('WebSocket connection failed'))\r\n }\r\n\r\n ws.onclose = () => {\r\n this.emit('connected', { connected: false })\r\n if (!this.manuallyClosed && this.reconnect) {\r\n const backoffMs = Math.min(1000 * 2 ** this.reconnectAttempt, 15000)\r\n this.reconnectAttempt += 1\r\n setTimeout(() => {\r\n void this.openSocket()\r\n }, backoffMs)\r\n }\r\n }\r\n })\r\n }\r\n\r\n private buildUrl(path: string, query?: QueryParams): string {\r\n const url = new URL(`${this.baseUrl}${path}`)\r\n if (query) {\r\n Object.entries(query).forEach(([key, value]) => {\r\n if (value !== undefined) url.searchParams.set(key, String(value))\r\n })\r\n }\r\n return url.toString()\r\n }\r\n\r\n private async request<T>(path: string, init?: RequestInit, query?: QueryParams): Promise<T> {\r\n const response = await fetch(this.buildUrl(path, query), {\r\n ...init,\r\n headers: {\r\n Authorization: `Bearer ${this.userToken}`,\r\n 'X-App-Id': this.apiKey,\r\n 'Content-Type': 'application/json',\r\n ...(init?.headers ?? {}),\r\n },\r\n })\r\n const data = await response.json().catch(() => ({}))\r\n if (!response.ok) {\r\n throw new Error((data as { error?: string }).error || `HTTP ${response.status}`)\r\n }\r\n return data as T\r\n }\r\n\r\n listChannels(): Promise<{ items: StreemoChannel[] }> {\r\n return this.request<{ items: StreemoChannel[] }>('/v1/channels')\r\n }\r\n\r\n listMessages(channelId: string, cursor?: string, limit = 30): Promise<{ items: StreemoMessage[]; nextCursor?: string; hasMore?: boolean }> {\r\n return this.request<{ items: StreemoMessage[]; nextCursor?: string; hasMore?: boolean }>(\r\n `/v1/channels/${encodeURIComponent(channelId)}/messages`,\r\n undefined,\r\n { cursor, limit },\r\n )\r\n }\r\n\r\n sendMessage(input: {\r\n channelId: string\r\n text: string\r\n parentId?: string\r\n attachments?: StreemoAttachment[]\r\n }): Promise<StreemoMessage> {\r\n return this.request<StreemoMessage>(`/v1/channels/${encodeURIComponent(input.channelId)}/messages`, {\r\n method: 'POST',\r\n body: JSON.stringify(input),\r\n })\r\n }\r\n\r\n updateMessage(channelId: string, messageId: string, text: string): Promise<StreemoMessage> {\r\n return this.request<StreemoMessage>(\r\n `/v1/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}`,\r\n {\r\n method: 'PATCH',\r\n body: JSON.stringify({ text }),\r\n },\r\n )\r\n }\r\n\r\n deleteMessage(channelId: string, messageId: string): Promise<{ ok: true }> {\r\n return this.request<{ ok: true }>(\r\n `/v1/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}`,\r\n { method: 'DELETE' },\r\n )\r\n }\r\n\r\n sendTyping(channelId: string, isTyping: boolean): Promise<{ ok: true }> {\r\n return this.request<{ ok: true }>(`/v1/channels/${encodeURIComponent(channelId)}/typing`, {\r\n method: 'POST',\r\n body: JSON.stringify({ isTyping }),\r\n })\r\n }\r\n}\r\n","import { StreemoClient, type StreemoClientOptions } from './StreemoClient'\n\n/**\n * Stable factory for app-level client creation.\n * Keeps construction centralized and allows future non-breaking extensions.\n */\nexport function createStreemoClient(options: StreemoClientOptions): StreemoClient {\n return new StreemoClient(options)\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.ts CHANGED
@@ -1,125 +1,9 @@
1
+ import { d as StreemoClient, n as StreemoChannel, o as TypingState, p as StreemoMessage, q as StreemoAttachment, P as PresenceState, T as TokenProvider, S as ServerAuthConfig } from './sdkConfig-DTNZ7Mms.js';
2
+ export { r as Participant, a as SDKError, b as SDKErrorCode, c as ServerTokenProviderOptions, e as StreemoClientOptions, s as StreemoReaction, t as StreemoUser, f as TokenProviderContext, V as VideoSDKConfig, g as createServerTokenProvider, h as createStreemoClient, i as defaultApiBaseUrl, j as defaultWsBaseUrlFromApi, k as getVideoSDKConfig, l as initVideoSDK, m as mapSDKErrorToUIMessage } from './sdkConfig-DTNZ7Mms.js';
1
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
4
  import * as react from 'react';
3
5
  import { PropsWithChildren, Component, ReactNode, ErrorInfo } from 'react';
4
- import { T as TokenProvider, S as ServerAuthConfig } from './sdkConfig-C9Fey7R2.js';
5
- export { a as SDKError, b as SDKErrorCode, c as ServerTokenProviderOptions, d as TokenProviderContext, V as VideoSDKConfig, e as createServerTokenProvider, f as defaultApiBaseUrl, g as defaultWsBaseUrlFromApi, h as getVideoSDKConfig, i as initVideoSDK, m as mapSDKErrorToUIMessage } from './sdkConfig-C9Fey7R2.js';
6
-
7
- type StreemoUser = {
8
- id: string;
9
- name: string;
10
- image?: string;
11
- };
12
- type StreemoAttachment = {
13
- id: string;
14
- type: 'image' | 'video' | 'file';
15
- url: string;
16
- name?: string;
17
- };
18
- type StreemoReaction = {
19
- type: string;
20
- userId: string;
21
- };
22
- type StreemoMessage = {
23
- id: string;
24
- channelId: string;
25
- text: string;
26
- userId: string;
27
- createdAt: string;
28
- updatedAt?: string;
29
- parentId?: string;
30
- attachments?: StreemoAttachment[];
31
- reactions?: StreemoReaction[];
32
- deliveryStatus?: 'sending' | 'sent' | 'failed';
33
- };
34
- type StreemoChannel = {
35
- id: string;
36
- name: string;
37
- image?: string;
38
- lastMessageAt?: string;
39
- unreadCount?: number;
40
- };
41
- type TypingState = {
42
- channelId: string;
43
- userId: string;
44
- isTyping: boolean;
45
- updatedAt: string;
46
- };
47
- type PresenceState = {
48
- userId: string;
49
- status: 'online' | 'offline' | 'away';
50
- lastSeenAt?: string;
51
- };
52
- type Participant = {
53
- userId: string;
54
- userName: string;
55
- stream?: MediaStream;
56
- };
57
-
58
- type Listener<T> = (event: T) => void;
59
- type RealtimeEventMap = {
60
- connected: {
61
- connected: boolean;
62
- };
63
- message_new: StreemoMessage;
64
- message_updated: StreemoMessage;
65
- typing: TypingState;
66
- presence: PresenceState;
67
- reaction_new: {
68
- channelId: string;
69
- messageId: string;
70
- reaction: StreemoReaction;
71
- };
72
- };
73
- type StreemoClientOptions = {
74
- apiKey: string;
75
- userToken: string;
76
- user: StreemoUser;
77
- baseUrl?: string;
78
- wsUrl?: string;
79
- reconnect?: boolean;
80
- };
81
- declare class StreemoClient {
82
- readonly apiKey: string;
83
- readonly userToken: string;
84
- readonly user: StreemoUser;
85
- readonly baseUrl: string;
86
- readonly wsUrl: string;
87
- private readonly reconnect;
88
- private ws;
89
- private manuallyClosed;
90
- private reconnectAttempt;
91
- private listeners;
92
- constructor(options: StreemoClientOptions);
93
- on<K extends keyof RealtimeEventMap>(event: K, listener: Listener<RealtimeEventMap[K]>): () => void;
94
- off<K extends keyof RealtimeEventMap>(event: K, listener: Listener<RealtimeEventMap[K]>): void;
95
- private emit;
96
- connect(): Promise<void>;
97
- disconnect(): void;
98
- private openSocket;
99
- private buildUrl;
100
- private request;
101
- listChannels(): Promise<{
102
- items: StreemoChannel[];
103
- }>;
104
- listMessages(channelId: string, cursor?: string, limit?: number): Promise<{
105
- items: StreemoMessage[];
106
- nextCursor?: string;
107
- hasMore?: boolean;
108
- }>;
109
- sendMessage(input: {
110
- channelId: string;
111
- text: string;
112
- parentId?: string;
113
- attachments?: StreemoAttachment[];
114
- }): Promise<StreemoMessage>;
115
- updateMessage(channelId: string, messageId: string, text: string): Promise<StreemoMessage>;
116
- deleteMessage(channelId: string, messageId: string): Promise<{
117
- ok: true;
118
- }>;
119
- sendTyping(channelId: string, isTyping: boolean): Promise<{
120
- ok: true;
121
- }>;
122
- }
6
+ export { StreemoThemeProvider, Theme, ThemeMode, ThemeTokens, createTheme, useTheme } from 'streemo-ui-kit-web/theme';
123
7
 
124
8
  type StreemoContextValue = {
125
9
  client: StreemoClient;
@@ -196,6 +80,7 @@ declare function useTyping(channelId: string): {
196
80
  declare function usePresence(): {
197
81
  presenceMap: Record<string, PresenceState>;
198
82
  getUserPresence: (userId: string) => PresenceState;
83
+ findUserPresence: (userId: string) => PresenceState;
199
84
  };
200
85
 
201
86
  type UseCallParams = {
@@ -246,6 +131,20 @@ declare function useParticipants(params: UseCallParams): {
246
131
  leaveCall: () => void;
247
132
  };
248
133
 
134
+ type StreemoEntitlements = {
135
+ operations: {
136
+ createRoom: boolean;
137
+ chatWrite: boolean;
138
+ };
139
+ };
140
+ type UseEntitlementsResult = {
141
+ entitlements: StreemoEntitlements | null;
142
+ loading: boolean;
143
+ error: string | null;
144
+ refresh: () => Promise<StreemoEntitlements | null>;
145
+ };
146
+ declare function useEntitlements(enabled?: boolean): UseEntitlementsResult;
147
+
249
148
  declare function Chat({ children }: PropsWithChildren): react_jsx_runtime.JSX.Element;
250
149
 
251
150
  declare function ChannelList(): react_jsx_runtime.JSX.Element;
@@ -476,4 +375,4 @@ type VideoCallWidgetProps = {
476
375
  };
477
376
  declare function VideoCallWidget({ roomId, userId, userName, roomToken, wsBaseUrl, tokenProvider, apiBaseUrl, auth, enabled, localLabelSuffix, showChat, }: VideoCallWidgetProps): react_jsx_runtime.JSX.Element;
478
377
 
479
- export { AttachmentPreview, Avatar, CallControls, CallRoom, CameraToggle, Channel, ChannelList, ChannelPreview, Chat, type ChatMessage, ChatPanel, type ChatPanelProps, ErrorBoundary, JoinCallButton, LeaveCallButton, LoadingSpinner, Message, MessageInput, MessageList, MuteButton, type Participant, ParticipantGrid, ParticipantTile, PresenceBadge, type PresenceState, ReactionPicker, type RemoteTrackState, ScreenShareButton, ServerAuthConfig, type StreemoAttachment, type StreemoChannel, StreemoClient, type StreemoClientOptions, type StreemoMessage, StreemoProvider, type StreemoReaction, StreemoTheme, type StreemoThemeTokens, type StreemoUser, Thread, TokenProvider, TypingIndicator, type TypingParticipant, type TypingState, type UseWebRTCCallParams, UserStatus, VideoCallWidget, type VideoCallWidgetProps, VideoTile, useCall, useCallRoomContext, useChannel, useChat, useMessages, useParticipants, usePresence, useStreemoContext, useTyping, useWebRTCCall };
378
+ export { AttachmentPreview, Avatar, CallControls, CallRoom, CameraToggle, Channel, ChannelList, ChannelPreview, Chat, type ChatMessage, ChatPanel, type ChatPanelProps, ErrorBoundary, JoinCallButton, LeaveCallButton, LoadingSpinner, Message, MessageInput, MessageList, MuteButton, ParticipantGrid, ParticipantTile, PresenceBadge, PresenceState, ReactionPicker, type RemoteTrackState, ScreenShareButton, ServerAuthConfig, StreemoAttachment, StreemoChannel, StreemoClient, type StreemoEntitlements, StreemoMessage, StreemoProvider, StreemoTheme, type StreemoThemeTokens, Thread, TokenProvider, TypingIndicator, type TypingParticipant, TypingState, type UseWebRTCCallParams, UserStatus, VideoCallWidget, type VideoCallWidgetProps, VideoTile, useCall, useCallRoomContext, useChannel, useChat, useEntitlements, useMessages, useParticipants, usePresence, useStreemoContext, useTyping, useWebRTCCall };