@harmoni-org/sdk 0.0.1
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/LICENSE +21 -0
- package/README.md +694 -0
- package/dist/index.d.mts +712 -0
- package/dist/index.d.ts +712 -0
- package/dist/index.js +2054 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2013 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +83 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,712 @@
|
|
|
1
|
+
import { AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
2
|
+
|
|
3
|
+
interface HttpClientConfig {
|
|
4
|
+
baseURL: string;
|
|
5
|
+
timeout?: number;
|
|
6
|
+
headers?: Record<string, string>;
|
|
7
|
+
withCredentials?: boolean;
|
|
8
|
+
retryConfig?: RetryConfig;
|
|
9
|
+
}
|
|
10
|
+
interface RetryConfig {
|
|
11
|
+
maxRetries?: number;
|
|
12
|
+
retryDelay?: number;
|
|
13
|
+
retryableStatuses?: number[];
|
|
14
|
+
}
|
|
15
|
+
interface RequestInterceptor {
|
|
16
|
+
onFulfilled?: (config: AxiosRequestConfig) => AxiosRequestConfig | Promise<AxiosRequestConfig>;
|
|
17
|
+
onRejected?: (error: unknown) => void | Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
interface ResponseInterceptor {
|
|
20
|
+
onFulfilled?: (response: AxiosResponse) => AxiosResponse | Promise<AxiosResponse>;
|
|
21
|
+
onRejected?: (error: unknown) => unknown;
|
|
22
|
+
}
|
|
23
|
+
interface RequestConfig extends AxiosRequestConfig {
|
|
24
|
+
skipAuth?: boolean;
|
|
25
|
+
skipRetry?: boolean;
|
|
26
|
+
_retry?: boolean;
|
|
27
|
+
_retryCount?: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare class HttpClient {
|
|
31
|
+
private config;
|
|
32
|
+
private client;
|
|
33
|
+
private authToken;
|
|
34
|
+
private refreshTokenFn?;
|
|
35
|
+
private retryCount;
|
|
36
|
+
constructor(config: HttpClientConfig);
|
|
37
|
+
private setupInterceptors;
|
|
38
|
+
private shouldRetry;
|
|
39
|
+
private retryRequest;
|
|
40
|
+
private getRequestId;
|
|
41
|
+
private sleep;
|
|
42
|
+
private handleError;
|
|
43
|
+
setAuthToken(token: string | null): void;
|
|
44
|
+
getAuthToken(): string | null;
|
|
45
|
+
setRefreshTokenFunction(fn: () => Promise<string>): void;
|
|
46
|
+
addRequestInterceptor(interceptor: RequestInterceptor): number;
|
|
47
|
+
addResponseInterceptor(interceptor: ResponseInterceptor): number;
|
|
48
|
+
removeRequestInterceptor(id: number): void;
|
|
49
|
+
removeResponseInterceptor(id: number): void;
|
|
50
|
+
get<T>(url: string, config?: RequestConfig): Promise<T>;
|
|
51
|
+
post<T>(url: string, data?: unknown, config?: RequestConfig): Promise<T>;
|
|
52
|
+
put<T>(url: string, data?: unknown, config?: RequestConfig): Promise<T>;
|
|
53
|
+
patch<T>(url: string, data?: unknown, config?: RequestConfig): Promise<T>;
|
|
54
|
+
delete<T>(url: string, config?: RequestConfig): Promise<T>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
declare const USER_ACTIONS: {
|
|
58
|
+
readonly PLAY: "PLAY";
|
|
59
|
+
readonly PAUSE: "PAUSE";
|
|
60
|
+
readonly SEEK: "SEEK";
|
|
61
|
+
readonly FILE_UPDATE: "FILE_UPDATE";
|
|
62
|
+
readonly STOP: "STOP";
|
|
63
|
+
readonly VOLUME_UPDATE: "VOLUME_UPDATE";
|
|
64
|
+
readonly ENTER_FULLSCREEN: "ENTER_FULLSCREEN";
|
|
65
|
+
readonly EXIT_FULLSCREEN: "EXIT_FULLSCREEN";
|
|
66
|
+
readonly SPEED_UPDATE: "SPEED_UPDATE";
|
|
67
|
+
readonly AUDIO_DELAY_UPDATE: "AUDIO_DELAY_UPDATE";
|
|
68
|
+
readonly SUBTITLE_DELAY_UPDATE: "SUBTITLE_DELAY_UPDATE";
|
|
69
|
+
readonly ASPECT_RATIO_UPDATE: "ASPECT_RATIO_UPDATE";
|
|
70
|
+
readonly TOGGLE_REPEAT: "TOGGLE_REPEAT";
|
|
71
|
+
readonly TOGGLE_LOOP: "TOGGLE_LOOP";
|
|
72
|
+
readonly VIDEO_EFFECT_UPDATE: "VIDEO_EFFECT_UPDATE";
|
|
73
|
+
readonly AUDIO_FILTER_UPDATE: "AUDIO_FILTER_UPDATE";
|
|
74
|
+
readonly TOGGLE_RANDOM: "TOGGLE_RANDOM";
|
|
75
|
+
readonly API_VERSION_UPDATE: "API_VERSION_UPDATE";
|
|
76
|
+
readonly PLAYLIST_UPDATE: "PLAYLIST_UPDATE";
|
|
77
|
+
readonly TITLE_OR_CHAPTER_UPDATE: "TITLE_OR_CHAPTER_UPDATE";
|
|
78
|
+
readonly NO_CHANGE: "NO_CHANGE";
|
|
79
|
+
};
|
|
80
|
+
type UserActionType = (typeof USER_ACTIONS)[keyof typeof USER_ACTIONS];
|
|
81
|
+
|
|
82
|
+
interface SyncState {
|
|
83
|
+
time: number;
|
|
84
|
+
isPlaying: boolean;
|
|
85
|
+
lastUpdated: number;
|
|
86
|
+
syncErrorMargin: number;
|
|
87
|
+
}
|
|
88
|
+
interface RoomInfo {
|
|
89
|
+
name: string;
|
|
90
|
+
description?: string;
|
|
91
|
+
ownerId: string;
|
|
92
|
+
isPrivate: boolean;
|
|
93
|
+
status: string;
|
|
94
|
+
createdAt: number;
|
|
95
|
+
lastActivity: number;
|
|
96
|
+
roomType: string;
|
|
97
|
+
}
|
|
98
|
+
interface RoomMember {
|
|
99
|
+
userId: string;
|
|
100
|
+
username: string;
|
|
101
|
+
clientId: string;
|
|
102
|
+
active: boolean;
|
|
103
|
+
role: string;
|
|
104
|
+
typing: boolean;
|
|
105
|
+
lastActivity: number;
|
|
106
|
+
}
|
|
107
|
+
interface FileInfo {
|
|
108
|
+
fileId: string;
|
|
109
|
+
userId: string;
|
|
110
|
+
name: string;
|
|
111
|
+
fullTime: number;
|
|
112
|
+
hash: string;
|
|
113
|
+
}
|
|
114
|
+
interface ChatMessage {
|
|
115
|
+
messageId: string;
|
|
116
|
+
userId: string;
|
|
117
|
+
username: string;
|
|
118
|
+
content: string;
|
|
119
|
+
timestamp: string;
|
|
120
|
+
systemMessage?: boolean;
|
|
121
|
+
replyTo?: string;
|
|
122
|
+
edited?: boolean;
|
|
123
|
+
deleted?: boolean;
|
|
124
|
+
}
|
|
125
|
+
interface Room {
|
|
126
|
+
roomId: string;
|
|
127
|
+
roomInfo: RoomInfo;
|
|
128
|
+
syncState: SyncState;
|
|
129
|
+
members: RoomMember[];
|
|
130
|
+
files: FileInfo[];
|
|
131
|
+
chat: ChatMessage[];
|
|
132
|
+
}
|
|
133
|
+
interface RoomUpdate {
|
|
134
|
+
roomId: string;
|
|
135
|
+
roomUpdates: Partial<Room>;
|
|
136
|
+
metadata: {
|
|
137
|
+
action: string;
|
|
138
|
+
userId: string;
|
|
139
|
+
username?: string;
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
declare const SyncActions: {
|
|
143
|
+
readonly PLAY: "play";
|
|
144
|
+
readonly PAUSE: "pause";
|
|
145
|
+
readonly SEEK: "seek";
|
|
146
|
+
};
|
|
147
|
+
type SyncAction = (typeof SyncActions)[keyof typeof SyncActions];
|
|
148
|
+
|
|
149
|
+
interface JoinRoomPayload {
|
|
150
|
+
roomId?: string;
|
|
151
|
+
roomName?: string;
|
|
152
|
+
password?: string;
|
|
153
|
+
}
|
|
154
|
+
interface SyncUpdatePayload {
|
|
155
|
+
roomId: string;
|
|
156
|
+
action: SyncAction;
|
|
157
|
+
value?: number;
|
|
158
|
+
}
|
|
159
|
+
interface UpdateFileInfoPayload {
|
|
160
|
+
roomId: string;
|
|
161
|
+
fileInfo: {
|
|
162
|
+
fileId: string;
|
|
163
|
+
name: string;
|
|
164
|
+
fullTime: number;
|
|
165
|
+
hash: string;
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
interface ChatSendPayload {
|
|
169
|
+
roomId: string;
|
|
170
|
+
text: string;
|
|
171
|
+
tempMessageId?: string;
|
|
172
|
+
}
|
|
173
|
+
declare const WatchTogetherErrorCodes: {
|
|
174
|
+
readonly ROOM_NOT_FOUND: "ROOM_NOT_FOUND";
|
|
175
|
+
readonly UNAUTHORIZED: "UNAUTHORIZED";
|
|
176
|
+
readonly ROOM_FULL: "ROOM_FULL";
|
|
177
|
+
readonly INVALID_PASSWORD: "INVALID_PASSWORD";
|
|
178
|
+
readonly NOT_IN_ROOM: "NOT_IN_ROOM";
|
|
179
|
+
readonly PERMISSION_DENIED: "PERMISSION_DENIED";
|
|
180
|
+
readonly CONNECTION_ERROR: "CONNECTION_ERROR";
|
|
181
|
+
readonly ALREADY_IN_ROOM: "ALREADY_IN_ROOM";
|
|
182
|
+
};
|
|
183
|
+
declare const WatchTogetherConstants: {
|
|
184
|
+
readonly NAMESPACE: "/watch-together";
|
|
185
|
+
readonly SYNC_CHECK_INTERVAL_MS: 30000;
|
|
186
|
+
readonly SYNC_TOLERANCE_SECONDS: 1;
|
|
187
|
+
readonly MAX_RECONNECT_ATTEMPTS: 5;
|
|
188
|
+
readonly RECONNECT_DELAY_MS: 2000;
|
|
189
|
+
};
|
|
190
|
+
declare const WatchTogetherIDs: {
|
|
191
|
+
JOIN_ROOM_INPUT: string;
|
|
192
|
+
JOIN_AND_INVITE_SECTION: string;
|
|
193
|
+
JOIN_BUTTON: string;
|
|
194
|
+
START_BUTTON: string;
|
|
195
|
+
LEAVE_BUTTON: string;
|
|
196
|
+
JOINED_ROOM_SECTION: string;
|
|
197
|
+
ACTION_SECTION: string;
|
|
198
|
+
CREATE_ROOM_BUTTON: string;
|
|
199
|
+
};
|
|
200
|
+
declare const SECTION_NAMES: {
|
|
201
|
+
JOIN_AND_INVITE: string;
|
|
202
|
+
JOINED_ROOM: string;
|
|
203
|
+
};
|
|
204
|
+
declare const WatchTogetherMessages: {
|
|
205
|
+
START_SUCCESS: string;
|
|
206
|
+
JOIN_SUCCESS: string;
|
|
207
|
+
LEAVE_SUCCESS: string;
|
|
208
|
+
INVALID_ARGS: string;
|
|
209
|
+
CONNECTION_SUCCESS: string;
|
|
210
|
+
DISCONNECTED: string;
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
interface IPlayerState {
|
|
214
|
+
isPlaying: boolean;
|
|
215
|
+
currentTime: number;
|
|
216
|
+
loop: boolean;
|
|
217
|
+
repeat: boolean;
|
|
218
|
+
title: string;
|
|
219
|
+
chapter: string;
|
|
220
|
+
filename: string;
|
|
221
|
+
duration: number;
|
|
222
|
+
filepath: string;
|
|
223
|
+
}
|
|
224
|
+
interface VideoEffects {
|
|
225
|
+
contrast: number;
|
|
226
|
+
gamma: number;
|
|
227
|
+
hue: number;
|
|
228
|
+
brightness: number;
|
|
229
|
+
saturation: number;
|
|
230
|
+
}
|
|
231
|
+
interface ExtendedPlayerState extends IPlayerState {
|
|
232
|
+
volume: number;
|
|
233
|
+
fullscreen: boolean;
|
|
234
|
+
rate: number;
|
|
235
|
+
audiodelay: number;
|
|
236
|
+
subtitledelay: number;
|
|
237
|
+
aspectratio: string | null;
|
|
238
|
+
videoeffects: VideoEffects;
|
|
239
|
+
audiofilters: Record<string, unknown>;
|
|
240
|
+
random: boolean;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
interface UserAction {
|
|
244
|
+
event: UserActionType;
|
|
245
|
+
value?: {
|
|
246
|
+
isPlaying?: boolean;
|
|
247
|
+
currentTime?: number;
|
|
248
|
+
filename?: string | null;
|
|
249
|
+
loop?: boolean;
|
|
250
|
+
repeat?: boolean;
|
|
251
|
+
title?: string;
|
|
252
|
+
chapter?: string;
|
|
253
|
+
[key: string]: unknown;
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
interface VideoPlayerController {
|
|
257
|
+
start(onReady?: () => void): Promise<void>;
|
|
258
|
+
quit(): Promise<void>;
|
|
259
|
+
play(): Promise<void>;
|
|
260
|
+
pause(): Promise<void>;
|
|
261
|
+
stop(): Promise<void>;
|
|
262
|
+
seek(timeInSeconds: number): Promise<void>;
|
|
263
|
+
loadMedia(source: string): Promise<void>;
|
|
264
|
+
getStatus(): Promise<IPlayerState>;
|
|
265
|
+
checkPlayerRunning(): Promise<boolean>;
|
|
266
|
+
observeStatusChange(onChange: (events: UserAction[], source: 'app' | 'user') => void, onStop: () => void, intervalMs?: number): void;
|
|
267
|
+
displayMessage?(message: string, durationSeconds?: number): Promise<void>;
|
|
268
|
+
}
|
|
269
|
+
declare const PlayerConstants: {
|
|
270
|
+
readonly DEFAULT_POLLING_INTERVAL_MS: 2000;
|
|
271
|
+
readonly SEEK_THRESHOLD_SECONDS: 0.5;
|
|
272
|
+
readonly COMMAND_STACK_TIMEOUT_MS: 3000;
|
|
273
|
+
readonly MIN_INTERVAL_MS: 100;
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
interface PaginationParams {
|
|
277
|
+
page?: number;
|
|
278
|
+
limit?: number;
|
|
279
|
+
offset?: number;
|
|
280
|
+
}
|
|
281
|
+
interface PaginatedResponse<T> {
|
|
282
|
+
data: T[];
|
|
283
|
+
total: number;
|
|
284
|
+
page: number;
|
|
285
|
+
limit: number;
|
|
286
|
+
hasMore: boolean;
|
|
287
|
+
}
|
|
288
|
+
interface SortParams {
|
|
289
|
+
sortBy?: string;
|
|
290
|
+
sortOrder?: 'asc' | 'desc';
|
|
291
|
+
}
|
|
292
|
+
interface FilterParams {
|
|
293
|
+
[key: string]: string | number | boolean | undefined;
|
|
294
|
+
}
|
|
295
|
+
interface ApiResponse<T> {
|
|
296
|
+
data: T;
|
|
297
|
+
meta?: {
|
|
298
|
+
timestamp: string;
|
|
299
|
+
};
|
|
300
|
+
error?: {
|
|
301
|
+
code: string;
|
|
302
|
+
message: string;
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
interface BaseUser {
|
|
306
|
+
id: string;
|
|
307
|
+
username: string;
|
|
308
|
+
email: string;
|
|
309
|
+
}
|
|
310
|
+
interface User extends BaseUser {
|
|
311
|
+
token: string;
|
|
312
|
+
refreshToken: string;
|
|
313
|
+
}
|
|
314
|
+
interface LoginResponse {
|
|
315
|
+
user: Omit<User, 'token' | 'refreshToken'>;
|
|
316
|
+
accessToken: string;
|
|
317
|
+
refreshToken: string;
|
|
318
|
+
}
|
|
319
|
+
interface RegisterResponse {
|
|
320
|
+
user: Omit<User, 'token' | 'refreshToken'>;
|
|
321
|
+
accessToken: string;
|
|
322
|
+
refreshToken: string;
|
|
323
|
+
}
|
|
324
|
+
interface VerifyTokenResponse {
|
|
325
|
+
user: BaseUser & {
|
|
326
|
+
createdAt: string;
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
interface RefreshTokenResponse {
|
|
330
|
+
accessToken: string;
|
|
331
|
+
}
|
|
332
|
+
interface LoginCredentials {
|
|
333
|
+
emailOrUsername: string;
|
|
334
|
+
password: string;
|
|
335
|
+
}
|
|
336
|
+
interface RegisterData {
|
|
337
|
+
username: string;
|
|
338
|
+
password: string;
|
|
339
|
+
email?: string;
|
|
340
|
+
}
|
|
341
|
+
type ValidationStatus = 'idle' | 'checking' | 'taken' | 'available' | 'error';
|
|
342
|
+
|
|
343
|
+
declare class AuthModule {
|
|
344
|
+
private http;
|
|
345
|
+
constructor(http: HttpClient);
|
|
346
|
+
login(credentials: LoginCredentials): Promise<User>;
|
|
347
|
+
register(data: RegisterData): Promise<User>;
|
|
348
|
+
verifyToken(): Promise<VerifyTokenResponse>;
|
|
349
|
+
refreshAccessToken(): Promise<string>;
|
|
350
|
+
isEmailUnique(email: string): Promise<boolean>;
|
|
351
|
+
isUsernameUnique(username: string): Promise<boolean>;
|
|
352
|
+
logout(): Promise<void>;
|
|
353
|
+
requestPasswordReset(email: string): Promise<void>;
|
|
354
|
+
resetPassword(token: string, newPassword: string): Promise<void>;
|
|
355
|
+
changePassword(currentPassword: string, newPassword: string): Promise<void>;
|
|
356
|
+
verifyEmail(token: string): Promise<void>;
|
|
357
|
+
resendVerificationEmail(email: string): Promise<void>;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
interface UpdateUserData {
|
|
361
|
+
username?: string;
|
|
362
|
+
email?: string;
|
|
363
|
+
}
|
|
364
|
+
interface UserProfile extends BaseUser {
|
|
365
|
+
bio?: string;
|
|
366
|
+
avatar?: string;
|
|
367
|
+
phone?: string;
|
|
368
|
+
createdAt?: string;
|
|
369
|
+
updatedAt?: string;
|
|
370
|
+
}
|
|
371
|
+
declare class UserModule {
|
|
372
|
+
private http;
|
|
373
|
+
constructor(http: HttpClient);
|
|
374
|
+
getById(userId: string): Promise<UserProfile>;
|
|
375
|
+
getCurrentUser(): Promise<UserProfile>;
|
|
376
|
+
updateProfile(data: UpdateUserData): Promise<UserProfile>;
|
|
377
|
+
deleteAccount(): Promise<void>;
|
|
378
|
+
list(params?: PaginationParams & FilterParams): Promise<PaginatedResponse<BaseUser>>;
|
|
379
|
+
search(query: string, params?: PaginationParams): Promise<PaginatedResponse<BaseUser>>;
|
|
380
|
+
uploadAvatar(file: File | Blob, fileName?: string): Promise<{
|
|
381
|
+
url: string;
|
|
382
|
+
}>;
|
|
383
|
+
deleteAvatar(): Promise<void>;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
type EventCallback<T> = (data: T) => void;
|
|
387
|
+
interface WatchTogetherConfig {
|
|
388
|
+
baseURL: string;
|
|
389
|
+
namespace?: string;
|
|
390
|
+
autoConnect?: boolean;
|
|
391
|
+
persistentConnection?: boolean;
|
|
392
|
+
}
|
|
393
|
+
interface ConnectionStatus {
|
|
394
|
+
connected: boolean;
|
|
395
|
+
connecting: boolean;
|
|
396
|
+
authenticated: boolean;
|
|
397
|
+
inRoom: boolean;
|
|
398
|
+
roomId: string | null;
|
|
399
|
+
error: string | null;
|
|
400
|
+
}
|
|
401
|
+
declare class WatchTogetherModule {
|
|
402
|
+
private http;
|
|
403
|
+
private config;
|
|
404
|
+
private socket;
|
|
405
|
+
private currentRoom;
|
|
406
|
+
private syncInterval;
|
|
407
|
+
private eventListeners;
|
|
408
|
+
private connectionStatus;
|
|
409
|
+
private shouldStayConnected;
|
|
410
|
+
constructor(http: HttpClient, config: WatchTogetherConfig);
|
|
411
|
+
private initializePersistentConnection;
|
|
412
|
+
connect(): Promise<void>;
|
|
413
|
+
disconnect(): void;
|
|
414
|
+
enablePersistentConnection(): void;
|
|
415
|
+
disablePersistentConnection(): void;
|
|
416
|
+
createRoom(options?: {
|
|
417
|
+
roomName?: string;
|
|
418
|
+
}): Promise<Room>;
|
|
419
|
+
joinRoom(options: JoinRoomPayload): Promise<Room>;
|
|
420
|
+
leaveRoom(): void;
|
|
421
|
+
play(): void;
|
|
422
|
+
pause(): void;
|
|
423
|
+
seek(timeInSeconds: number): void;
|
|
424
|
+
requestSync(): void;
|
|
425
|
+
updateFileInfo(fileInfo: Omit<FileInfo, 'userId'>): void;
|
|
426
|
+
sendMessage(text: string): Promise<void>;
|
|
427
|
+
getChatHistory(): ChatMessage[];
|
|
428
|
+
getCurrentRoom(): Room | null;
|
|
429
|
+
isConnected(): boolean;
|
|
430
|
+
isInRoom(): boolean;
|
|
431
|
+
getConnectionStatus(): ConnectionStatus;
|
|
432
|
+
isOnline(): boolean;
|
|
433
|
+
onRoomState(callback: EventCallback<Room>): () => void;
|
|
434
|
+
onRoomUpdate(callback: EventCallback<RoomUpdate>): () => void;
|
|
435
|
+
onSyncState(callback: EventCallback<SyncState>): () => void;
|
|
436
|
+
onChatMessage(callback: EventCallback<ChatMessage>): () => void;
|
|
437
|
+
onSystemMessage(callback: EventCallback<ChatMessage>): () => void;
|
|
438
|
+
onChatHistory(callback: EventCallback<ChatMessage[]>): () => void;
|
|
439
|
+
onError(callback: EventCallback<{
|
|
440
|
+
code: string;
|
|
441
|
+
message: string;
|
|
442
|
+
}>): () => void;
|
|
443
|
+
onConnect(callback: EventCallback<void>): () => void;
|
|
444
|
+
onDisconnect(callback: EventCallback<string>): () => void;
|
|
445
|
+
onConnectionStatusChange(callback: EventCallback<ConnectionStatus>): () => void;
|
|
446
|
+
onOnlineStatusChange(callback: EventCallback<boolean>): () => void;
|
|
447
|
+
private setupSocketListeners;
|
|
448
|
+
private refreshTokenAndReconnect;
|
|
449
|
+
updateAuthToken(token: string): void;
|
|
450
|
+
private updateConnectionStatus;
|
|
451
|
+
private updateSyncState;
|
|
452
|
+
private startSyncCheck;
|
|
453
|
+
private stopSyncCheck;
|
|
454
|
+
private ensureConnected;
|
|
455
|
+
private ensureInRoom;
|
|
456
|
+
private addEventListener;
|
|
457
|
+
private emit;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
declare class WatchTogetherError extends Error {
|
|
461
|
+
readonly code: string;
|
|
462
|
+
readonly details?: Record<string, unknown> | undefined;
|
|
463
|
+
readonly isWatchTogetherError = true;
|
|
464
|
+
constructor(message: string, code: string, details?: Record<string, unknown> | undefined);
|
|
465
|
+
toJSON(): {
|
|
466
|
+
name: string;
|
|
467
|
+
message: string;
|
|
468
|
+
code: string;
|
|
469
|
+
details?: Record<string, unknown>;
|
|
470
|
+
};
|
|
471
|
+
static isWatchTogetherError(error: unknown): error is WatchTogetherError;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
interface HarmoniSDKConfig extends HttpClientConfig {
|
|
475
|
+
autoRefreshToken?: boolean;
|
|
476
|
+
watchTogetherNamespace?: string;
|
|
477
|
+
persistentConnection?: boolean;
|
|
478
|
+
}
|
|
479
|
+
declare class HarmoniSDK {
|
|
480
|
+
private httpClient;
|
|
481
|
+
readonly auth: AuthModule;
|
|
482
|
+
readonly user: UserModule;
|
|
483
|
+
readonly watchTogether: WatchTogetherModule;
|
|
484
|
+
constructor(config: HarmoniSDKConfig);
|
|
485
|
+
private setupAutoRefresh;
|
|
486
|
+
setAuthToken(token: string | null): void;
|
|
487
|
+
getAuthToken(): string | null;
|
|
488
|
+
private storeAccessToken;
|
|
489
|
+
getHttpClient(): HttpClient;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
interface ApiErrorResponse {
|
|
493
|
+
message: string;
|
|
494
|
+
code?: string;
|
|
495
|
+
status?: number;
|
|
496
|
+
details?: unknown;
|
|
497
|
+
}
|
|
498
|
+
declare class ApiError extends Error {
|
|
499
|
+
readonly status: number;
|
|
500
|
+
readonly code?: string;
|
|
501
|
+
readonly details?: unknown;
|
|
502
|
+
readonly isApiError = true;
|
|
503
|
+
constructor(message: string, status: number, code?: string, details?: unknown);
|
|
504
|
+
toJSON(): ApiErrorResponse;
|
|
505
|
+
static isApiError(error: unknown): error is ApiError;
|
|
506
|
+
}
|
|
507
|
+
declare class NetworkError extends ApiError {
|
|
508
|
+
constructor(message?: string);
|
|
509
|
+
}
|
|
510
|
+
declare class TimeoutError extends ApiError {
|
|
511
|
+
constructor(message?: string);
|
|
512
|
+
}
|
|
513
|
+
declare class UnauthorizedError extends ApiError {
|
|
514
|
+
constructor(message?: string);
|
|
515
|
+
}
|
|
516
|
+
declare class ForbiddenError extends ApiError {
|
|
517
|
+
constructor(message?: string);
|
|
518
|
+
}
|
|
519
|
+
declare class NotFoundError extends ApiError {
|
|
520
|
+
constructor(message?: string);
|
|
521
|
+
}
|
|
522
|
+
declare class ValidationError extends ApiError {
|
|
523
|
+
constructor(message?: string, details?: unknown);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
declare function capitalize(str: string): string;
|
|
527
|
+
declare function titleCase(str: string): string;
|
|
528
|
+
declare function camelToSnake(str: string): string;
|
|
529
|
+
declare function snakeToCamel(str: string): string;
|
|
530
|
+
declare function truncate(str: string, length: number, suffix?: string): string;
|
|
531
|
+
declare function isValidEmail(email: string): boolean;
|
|
532
|
+
declare function randomString(length: number): string;
|
|
533
|
+
declare function slugify(str: string): string;
|
|
534
|
+
|
|
535
|
+
declare const string_camelToSnake: typeof camelToSnake;
|
|
536
|
+
declare const string_capitalize: typeof capitalize;
|
|
537
|
+
declare const string_isValidEmail: typeof isValidEmail;
|
|
538
|
+
declare const string_randomString: typeof randomString;
|
|
539
|
+
declare const string_slugify: typeof slugify;
|
|
540
|
+
declare const string_snakeToCamel: typeof snakeToCamel;
|
|
541
|
+
declare const string_titleCase: typeof titleCase;
|
|
542
|
+
declare const string_truncate: typeof truncate;
|
|
543
|
+
declare namespace string {
|
|
544
|
+
export { string_camelToSnake as camelToSnake, string_capitalize as capitalize, string_isValidEmail as isValidEmail, string_randomString as randomString, string_slugify as slugify, string_snakeToCamel as snakeToCamel, string_titleCase as titleCase, string_truncate as truncate };
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
declare function toISOString(date: Date | string | number): string;
|
|
548
|
+
declare function isValidDate(date: unknown): boolean;
|
|
549
|
+
declare function timeAgo(date: Date | string | number): string;
|
|
550
|
+
declare function addDays(date: Date, days: number): Date;
|
|
551
|
+
declare function addHours(date: Date, hours: number): Date;
|
|
552
|
+
declare function formatDate(date: Date | string | number, format?: string): string;
|
|
553
|
+
declare function isToday(date: Date | string | number): boolean;
|
|
554
|
+
declare function isPast(date: Date | string | number): boolean;
|
|
555
|
+
declare function isFuture(date: Date | string | number): boolean;
|
|
556
|
+
|
|
557
|
+
declare const date_addDays: typeof addDays;
|
|
558
|
+
declare const date_addHours: typeof addHours;
|
|
559
|
+
declare const date_formatDate: typeof formatDate;
|
|
560
|
+
declare const date_isFuture: typeof isFuture;
|
|
561
|
+
declare const date_isPast: typeof isPast;
|
|
562
|
+
declare const date_isToday: typeof isToday;
|
|
563
|
+
declare const date_isValidDate: typeof isValidDate;
|
|
564
|
+
declare const date_timeAgo: typeof timeAgo;
|
|
565
|
+
declare const date_toISOString: typeof toISOString;
|
|
566
|
+
declare namespace date {
|
|
567
|
+
export { date_addDays as addDays, date_addHours as addHours, date_formatDate as formatDate, date_isFuture as isFuture, date_isPast as isPast, date_isToday as isToday, date_isValidDate as isValidDate, date_timeAgo as timeAgo, date_toISOString as toISOString };
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
declare function deepClone<T>(obj: T): T;
|
|
571
|
+
declare function deepMerge<T extends Record<string, unknown>>(target: T, source: Partial<T>): T;
|
|
572
|
+
declare function isObject(value: unknown): value is Record<string, unknown>;
|
|
573
|
+
declare function pick<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Pick<T, K>;
|
|
574
|
+
declare function omit<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Omit<T, K>;
|
|
575
|
+
declare function isEmpty(obj: unknown): boolean;
|
|
576
|
+
declare function getNestedValue<T>(obj: unknown, path: string): T | undefined;
|
|
577
|
+
declare function setNestedValue(obj: Record<string, unknown>, path: string, value: unknown): void;
|
|
578
|
+
|
|
579
|
+
declare const object_deepClone: typeof deepClone;
|
|
580
|
+
declare const object_deepMerge: typeof deepMerge;
|
|
581
|
+
declare const object_getNestedValue: typeof getNestedValue;
|
|
582
|
+
declare const object_isEmpty: typeof isEmpty;
|
|
583
|
+
declare const object_isObject: typeof isObject;
|
|
584
|
+
declare const object_omit: typeof omit;
|
|
585
|
+
declare const object_pick: typeof pick;
|
|
586
|
+
declare const object_setNestedValue: typeof setNestedValue;
|
|
587
|
+
declare namespace object {
|
|
588
|
+
export { object_deepClone as deepClone, object_deepMerge as deepMerge, object_getNestedValue as getNestedValue, object_isEmpty as isEmpty, object_isObject as isObject, object_omit as omit, object_pick as pick, object_setNestedValue as setNestedValue };
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
declare function validateEmail(email: string): {
|
|
592
|
+
valid: boolean;
|
|
593
|
+
message?: string;
|
|
594
|
+
};
|
|
595
|
+
declare function validatePassword(password: string, options?: {
|
|
596
|
+
minLength?: number;
|
|
597
|
+
requireUppercase?: boolean;
|
|
598
|
+
requireLowercase?: boolean;
|
|
599
|
+
requireNumbers?: boolean;
|
|
600
|
+
requireSpecialChars?: boolean;
|
|
601
|
+
}): {
|
|
602
|
+
valid: boolean;
|
|
603
|
+
message?: string;
|
|
604
|
+
};
|
|
605
|
+
declare function validateUrl(url: string): {
|
|
606
|
+
valid: boolean;
|
|
607
|
+
message?: string;
|
|
608
|
+
};
|
|
609
|
+
declare function validatePhone(phone: string): {
|
|
610
|
+
valid: boolean;
|
|
611
|
+
message?: string;
|
|
612
|
+
};
|
|
613
|
+
declare function required(value: unknown, fieldName?: string): {
|
|
614
|
+
valid: boolean;
|
|
615
|
+
message?: string;
|
|
616
|
+
};
|
|
617
|
+
declare function minLength(value: string, min: number, fieldName?: string): {
|
|
618
|
+
valid: boolean;
|
|
619
|
+
message?: string;
|
|
620
|
+
};
|
|
621
|
+
declare function maxLength(value: string, max: number, fieldName?: string): {
|
|
622
|
+
valid: boolean;
|
|
623
|
+
message?: string;
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
declare const validation_maxLength: typeof maxLength;
|
|
627
|
+
declare const validation_minLength: typeof minLength;
|
|
628
|
+
declare const validation_required: typeof required;
|
|
629
|
+
declare const validation_validateEmail: typeof validateEmail;
|
|
630
|
+
declare const validation_validatePassword: typeof validatePassword;
|
|
631
|
+
declare const validation_validatePhone: typeof validatePhone;
|
|
632
|
+
declare const validation_validateUrl: typeof validateUrl;
|
|
633
|
+
declare namespace validation {
|
|
634
|
+
export { validation_maxLength as maxLength, validation_minLength as minLength, validation_required as required, validation_validateEmail as validateEmail, validation_validatePassword as validatePassword, validation_validatePhone as validatePhone, validation_validateUrl as validateUrl };
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
declare class Storage {
|
|
638
|
+
private storage;
|
|
639
|
+
private memoryStorage;
|
|
640
|
+
constructor(type?: 'local' | 'session');
|
|
641
|
+
set<T>(key: string, value: T): void;
|
|
642
|
+
get<T>(key: string): T | null;
|
|
643
|
+
remove(key: string): void;
|
|
644
|
+
clear(): void;
|
|
645
|
+
has(key: string): boolean;
|
|
646
|
+
keys(): string[];
|
|
647
|
+
isAvailable(): boolean;
|
|
648
|
+
}
|
|
649
|
+
declare const localStorage: Storage;
|
|
650
|
+
declare const sessionStorage: Storage;
|
|
651
|
+
|
|
652
|
+
declare class PlayerStatusMonitor {
|
|
653
|
+
private player;
|
|
654
|
+
private onStateChange;
|
|
655
|
+
private onStop;
|
|
656
|
+
private pollingIntervalMs;
|
|
657
|
+
private lastKnownState;
|
|
658
|
+
private lastCheckTime;
|
|
659
|
+
private pollingTimer;
|
|
660
|
+
private isRunning;
|
|
661
|
+
constructor(player: VideoPlayerController, onStateChange: (actions: UserAction[], source: 'app' | 'user') => void, onStop: () => void, pollingIntervalMs?: number);
|
|
662
|
+
start(): void;
|
|
663
|
+
stop(): void;
|
|
664
|
+
getIsRunning(): boolean;
|
|
665
|
+
getLastKnownState(): IPlayerState | null;
|
|
666
|
+
updateLastKnownState(state: IPlayerState): void;
|
|
667
|
+
private checkStatus;
|
|
668
|
+
protected determineActionSource(_actions: UserAction[]): 'app' | 'user';
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
declare class HTML5VideoController implements VideoPlayerController {
|
|
672
|
+
private videoElementId;
|
|
673
|
+
private video;
|
|
674
|
+
private statusMonitor;
|
|
675
|
+
constructor(videoElementId: string);
|
|
676
|
+
start(onReady?: () => void): Promise<void>;
|
|
677
|
+
play(): Promise<void>;
|
|
678
|
+
pause(): Promise<void>;
|
|
679
|
+
stop(): Promise<void>;
|
|
680
|
+
seek(timeInSeconds: number): Promise<void>;
|
|
681
|
+
loadMedia(source: string): Promise<void>;
|
|
682
|
+
getStatus(): Promise<IPlayerState>;
|
|
683
|
+
checkPlayerRunning(): Promise<boolean>;
|
|
684
|
+
quit(): Promise<void>;
|
|
685
|
+
observeStatusChange(onChange: (events: UserAction[], source: 'app' | 'user') => void, onStop: () => void, intervalMs?: number): void;
|
|
686
|
+
displayMessage(message: string, durationSeconds?: number): Promise<void>;
|
|
687
|
+
getVideoElement(): HTMLVideoElement | null;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
declare class SyncedPlayer {
|
|
691
|
+
private player;
|
|
692
|
+
private watchTogether;
|
|
693
|
+
private options;
|
|
694
|
+
private commandStack;
|
|
695
|
+
private currentUserId;
|
|
696
|
+
private unsubscribers;
|
|
697
|
+
constructor(player: VideoPlayerController, watchTogether: WatchTogetherModule, options: {
|
|
698
|
+
getCurrentUserId: () => string | null;
|
|
699
|
+
onPlayerStopped?: () => void;
|
|
700
|
+
});
|
|
701
|
+
private setupListeners;
|
|
702
|
+
private handleRemoteSyncUpdate;
|
|
703
|
+
private handleLocalPlayerChange;
|
|
704
|
+
private popMatchingCommand;
|
|
705
|
+
private eventToAction;
|
|
706
|
+
destroy(): void;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
declare function identifyUserActions(oldState: IPlayerState | null, newState: IPlayerState | null, intervalMs: number): UserAction[];
|
|
710
|
+
declare function normalizePlayerState(state: Partial<IPlayerState>): IPlayerState;
|
|
711
|
+
|
|
712
|
+
export { ApiError, type ApiErrorResponse, type ApiResponse, AuthModule, type BaseUser, type ChatMessage, type ChatSendPayload, type ConnectionStatus, type ExtendedPlayerState, type FileInfo, type FilterParams, ForbiddenError, HTML5VideoController, HarmoniSDK, type HarmoniSDKConfig, HttpClient, type HttpClientConfig, type IPlayerState, type JoinRoomPayload, type LoginCredentials, type LoginResponse, NetworkError, NotFoundError, type PaginatedResponse, type PaginationParams, PlayerConstants, PlayerStatusMonitor, type RefreshTokenResponse, type RegisterData, type RegisterResponse, type RequestConfig, type RequestInterceptor, type ResponseInterceptor, type RetryConfig, type Room, type RoomInfo, type RoomMember, type RoomUpdate, SECTION_NAMES, type SortParams, Storage, type SyncAction, SyncActions, type SyncState, type SyncUpdatePayload, SyncedPlayer, TimeoutError, USER_ACTIONS, UnauthorizedError, type UpdateFileInfoPayload, type UpdateUserData, type User, type UserAction, type UserActionType, UserModule, type UserProfile, ValidationError, type ValidationStatus, type VerifyTokenResponse, type VideoEffects, type VideoPlayerController, type WatchTogetherConfig, WatchTogetherConstants, WatchTogetherError, WatchTogetherErrorCodes, WatchTogetherIDs, WatchTogetherMessages, WatchTogetherModule, date as dateUtils, HarmoniSDK as default, identifyUserActions, localStorage, normalizePlayerState, object as objectUtils, sessionStorage, string as stringUtils, validation as validationUtils };
|