@redseat/api 0.3.11 → 0.3.12
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 +3 -1
- package/dist/client.js +14 -6
- package/dist/interfaces.d.ts +58 -0
- package/dist/interfaces.js +16 -0
- package/dist/sse-types.d.ts +13 -5
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export declare class RedseatClient {
|
|
|
20
20
|
private localServerUrl?;
|
|
21
21
|
private tokenData?;
|
|
22
22
|
private tokenRefreshPromise?;
|
|
23
|
+
private localDetectionAbortController?;
|
|
24
|
+
private disposed;
|
|
23
25
|
private sseAbortController?;
|
|
24
26
|
private sseReconnectTimeout?;
|
|
25
27
|
private sseReconnectAttempts;
|
|
@@ -103,7 +105,7 @@ export declare class RedseatClient {
|
|
|
103
105
|
*/
|
|
104
106
|
disconnectSSE(): void;
|
|
105
107
|
/**
|
|
106
|
-
* Disposes of all
|
|
108
|
+
* Disposes of all resources and completes observables.
|
|
107
109
|
* Call this when the client is no longer needed.
|
|
108
110
|
*/
|
|
109
111
|
dispose(): void;
|
package/dist/client.js
CHANGED
|
@@ -36,6 +36,7 @@ export class RedseatClient {
|
|
|
36
36
|
}));
|
|
37
37
|
}
|
|
38
38
|
constructor(options) {
|
|
39
|
+
this.disposed = false;
|
|
39
40
|
this.sseReconnectAttempts = 0;
|
|
40
41
|
// RxJS subjects for SSE
|
|
41
42
|
this._sseConnectionState = new BehaviorSubject('disconnected');
|
|
@@ -72,16 +73,19 @@ export class RedseatClient {
|
|
|
72
73
|
this.baseUrl = this.getRegularServerUrl();
|
|
73
74
|
this.axios = axios.create({
|
|
74
75
|
baseURL: this.baseUrl,
|
|
75
|
-
timeout: options.timeout ??
|
|
76
|
+
timeout: options.timeout ?? 30000 // 30 second default
|
|
76
77
|
});
|
|
77
78
|
// Detect local URL asynchronously and update axios instance
|
|
78
|
-
this.
|
|
79
|
+
this.localDetectionAbortController = new AbortController();
|
|
80
|
+
this.detectLocalUrl(this.localDetectionAbortController.signal).then((url) => {
|
|
81
|
+
if (this.disposed)
|
|
82
|
+
return; // Don't update if disposed
|
|
79
83
|
if (url !== this.baseUrl) {
|
|
80
84
|
this.baseUrl = url;
|
|
81
85
|
this.axios.defaults.baseURL = url;
|
|
82
86
|
}
|
|
83
87
|
}).catch(() => {
|
|
84
|
-
// If detection fails, use regular URL (already set)
|
|
88
|
+
// If detection fails or aborted, use regular URL (already set)
|
|
85
89
|
});
|
|
86
90
|
// Request interceptor: check token expiration and refresh if needed
|
|
87
91
|
this.axios.interceptors.request.use(async (config) => {
|
|
@@ -117,7 +121,7 @@ export class RedseatClient {
|
|
|
117
121
|
}
|
|
118
122
|
return `https://${base}`;
|
|
119
123
|
}
|
|
120
|
-
async detectLocalUrl() {
|
|
124
|
+
async detectLocalUrl(signal) {
|
|
121
125
|
let localBase = `local.${this.server.url}`;
|
|
122
126
|
if (this.server.port) {
|
|
123
127
|
localBase = `${localBase}:${this.server.port}`;
|
|
@@ -127,7 +131,8 @@ export class RedseatClient {
|
|
|
127
131
|
console.log('trying local server url', localUrl);
|
|
128
132
|
const response = await axios.get(`${localUrl}/ping`, {
|
|
129
133
|
timeout: 200,
|
|
130
|
-
headers: { "Referrer-Policy": 'origin-when-cross-origin' }
|
|
134
|
+
headers: { "Referrer-Policy": 'origin-when-cross-origin' },
|
|
135
|
+
signal
|
|
131
136
|
});
|
|
132
137
|
if (response.status === 200) {
|
|
133
138
|
console.log('local server detected');
|
|
@@ -308,10 +313,13 @@ export class RedseatClient {
|
|
|
308
313
|
this._sseConnectionState.next('disconnected');
|
|
309
314
|
}
|
|
310
315
|
/**
|
|
311
|
-
* Disposes of all
|
|
316
|
+
* Disposes of all resources and completes observables.
|
|
312
317
|
* Call this when the client is no longer needed.
|
|
313
318
|
*/
|
|
314
319
|
dispose() {
|
|
320
|
+
this.disposed = true;
|
|
321
|
+
this.localDetectionAbortController?.abort();
|
|
322
|
+
this.localDetectionAbortController = undefined;
|
|
315
323
|
this.disconnectSSE();
|
|
316
324
|
this._sseConnectionState.complete();
|
|
317
325
|
this._sseError.complete();
|
package/dist/interfaces.d.ts
CHANGED
|
@@ -798,3 +798,61 @@ export interface IRsRequestProcessing {
|
|
|
798
798
|
/** Creation timestamp */
|
|
799
799
|
added: number;
|
|
800
800
|
}
|
|
801
|
+
export declare enum VideoOverlayPosition {
|
|
802
|
+
topLeft = "topLeft",
|
|
803
|
+
topRight = "topRight",
|
|
804
|
+
topCenter = "topCenter",
|
|
805
|
+
bottomLeft = "bottomLeft",
|
|
806
|
+
bottomRight = "bottomRight",
|
|
807
|
+
bottomCenter = "bottomCenter",
|
|
808
|
+
Center = "center"
|
|
809
|
+
}
|
|
810
|
+
export declare enum VideoOverlayType {
|
|
811
|
+
watermark = "watermark",
|
|
812
|
+
file = "file"
|
|
813
|
+
}
|
|
814
|
+
export interface VideoOverlay {
|
|
815
|
+
type: VideoOverlayType;
|
|
816
|
+
path: string;
|
|
817
|
+
position?: VideoOverlayPosition;
|
|
818
|
+
margin?: number;
|
|
819
|
+
ratio: number;
|
|
820
|
+
opacity: number;
|
|
821
|
+
}
|
|
822
|
+
export interface VideoTextOverlay {
|
|
823
|
+
text: string;
|
|
824
|
+
fontColor: string;
|
|
825
|
+
font?: string;
|
|
826
|
+
position: VideoOverlayPosition;
|
|
827
|
+
marginHorizontal?: number;
|
|
828
|
+
marginVertical?: number;
|
|
829
|
+
fontSize: number;
|
|
830
|
+
opacity?: number;
|
|
831
|
+
shadowColor: string;
|
|
832
|
+
shadowOpacity?: number;
|
|
833
|
+
start?: number;
|
|
834
|
+
end?: number;
|
|
835
|
+
}
|
|
836
|
+
export interface VideoConvertInterval {
|
|
837
|
+
start: number;
|
|
838
|
+
duration: number;
|
|
839
|
+
/** Defaults to current input */
|
|
840
|
+
input?: string;
|
|
841
|
+
}
|
|
842
|
+
export interface VideoConvertRequest {
|
|
843
|
+
id: string;
|
|
844
|
+
format: string;
|
|
845
|
+
codec?: string;
|
|
846
|
+
crf?: number;
|
|
847
|
+
noAudio?: boolean;
|
|
848
|
+
width?: string;
|
|
849
|
+
height?: string;
|
|
850
|
+
framerate?: number;
|
|
851
|
+
cropWidth?: number;
|
|
852
|
+
cropHeight?: number;
|
|
853
|
+
aspectRatio?: string;
|
|
854
|
+
aspectRatioAlignment?: 'center' | 'left' | 'right';
|
|
855
|
+
overlay?: VideoOverlay;
|
|
856
|
+
texts?: VideoTextOverlay[];
|
|
857
|
+
intervals?: VideoConvertInterval[];
|
|
858
|
+
}
|
package/dist/interfaces.js
CHANGED
|
@@ -88,3 +88,19 @@ export var RsRequestMethod;
|
|
|
88
88
|
RsRequestMethod["Delete"] = "delete";
|
|
89
89
|
RsRequestMethod["Head"] = "head";
|
|
90
90
|
})(RsRequestMethod || (RsRequestMethod = {}));
|
|
91
|
+
// ========== Video Convert Types ==========
|
|
92
|
+
export var VideoOverlayPosition;
|
|
93
|
+
(function (VideoOverlayPosition) {
|
|
94
|
+
VideoOverlayPosition["topLeft"] = "topLeft";
|
|
95
|
+
VideoOverlayPosition["topRight"] = "topRight";
|
|
96
|
+
VideoOverlayPosition["topCenter"] = "topCenter";
|
|
97
|
+
VideoOverlayPosition["bottomLeft"] = "bottomLeft";
|
|
98
|
+
VideoOverlayPosition["bottomRight"] = "bottomRight";
|
|
99
|
+
VideoOverlayPosition["bottomCenter"] = "bottomCenter";
|
|
100
|
+
VideoOverlayPosition["Center"] = "center";
|
|
101
|
+
})(VideoOverlayPosition || (VideoOverlayPosition = {}));
|
|
102
|
+
export var VideoOverlayType;
|
|
103
|
+
(function (VideoOverlayType) {
|
|
104
|
+
VideoOverlayType["watermark"] = "watermark";
|
|
105
|
+
VideoOverlayType["file"] = "file";
|
|
106
|
+
})(VideoOverlayType || (VideoOverlayType = {}));
|
package/dist/sse-types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ILibrary, IFile, IEpisode, ISerie, IMovie, IPerson, ITag, IBackup, IWatched, IUnwatched, IRsRequestProcessing } from './interfaces.js';
|
|
1
|
+
import { ILibrary, IFile, IEpisode, ISerie, IMovie, IPerson, ITag, IBackup, IWatched, IUnwatched, IRsRequestProcessing, VideoConvertRequest } from './interfaces.js';
|
|
2
2
|
export type ElementAction = 'Added' | 'Updated' | 'Deleted';
|
|
3
3
|
export type SSEConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error';
|
|
4
4
|
export interface SSEConnectionOptions {
|
|
@@ -50,12 +50,20 @@ export interface SSEUploadProgressEvent {
|
|
|
50
50
|
progress: RsProgress;
|
|
51
51
|
remainingSecondes?: number;
|
|
52
52
|
}
|
|
53
|
+
export type RsVideoTranscodeStatus = 'pending' | 'processing' | 'completed' | 'failed' | 'canceled';
|
|
54
|
+
export interface ConvertProgress {
|
|
55
|
+
id: string;
|
|
56
|
+
filename: string;
|
|
57
|
+
convertedId: string | null;
|
|
58
|
+
done: boolean;
|
|
59
|
+
percent: number;
|
|
60
|
+
status: RsVideoTranscodeStatus;
|
|
61
|
+
estimatedRemainingSeconds: number | null;
|
|
62
|
+
request: VideoConvertRequest | null;
|
|
63
|
+
}
|
|
53
64
|
export interface SSEConvertProgressEvent {
|
|
54
65
|
library: string;
|
|
55
|
-
|
|
56
|
-
progress: number;
|
|
57
|
-
status: string;
|
|
58
|
-
message?: string;
|
|
66
|
+
progress: ConvertProgress;
|
|
59
67
|
}
|
|
60
68
|
export interface SSEEpisodesEvent {
|
|
61
69
|
library: string;
|