@redseat/api 0.2.6 → 0.2.8

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/libraries.md CHANGED
@@ -66,6 +66,172 @@ if (library.crypt) {
66
66
 
67
67
  **Note:** This method verifies the key by attempting to decrypt a media thumbnail. If decryption fails, it throws an error.
68
68
 
69
+ ### `dispose(): void`
70
+
71
+ Marks the LibraryApi as disposed. After calling dispose(), the filtered event streams will stop emitting events.
72
+
73
+ **Example:**
74
+
75
+ ```typescript
76
+ libraryApi.dispose();
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Real-Time Events (SSE)
82
+
83
+ `LibraryApi` provides library-filtered event streams that automatically filter events to only include those relevant to the library. These streams require the `RedseatClient` to be connected to SSE.
84
+
85
+ ### Event Streams
86
+
87
+ All event streams are RxJS Observables that emit events only for this library.
88
+
89
+ #### `medias$: Observable<SSEMediasEvent>`
90
+
91
+ Emits when media files in this library are added, updated, or deleted.
92
+
93
+ ```typescript
94
+ libraryApi.medias$.subscribe(event => {
95
+ for (const { action, media } of event.medias) {
96
+ console.log(`Media ${action}: ${media.name}`);
97
+ }
98
+ });
99
+ ```
100
+
101
+ #### `mediasProgress$: Observable<SSEMediasProgressEvent>`
102
+
103
+ Emits media processing progress updates for this library.
104
+
105
+ ```typescript
106
+ libraryApi.mediasProgress$.subscribe(event => {
107
+ console.log(`Media ${event.mediaId}: ${event.progress}%`);
108
+ });
109
+ ```
110
+
111
+ #### `convertProgress$: Observable<SSEConvertProgressEvent>`
112
+
113
+ Emits video conversion progress updates for this library.
114
+
115
+ ```typescript
116
+ libraryApi.convertProgress$.subscribe(event => {
117
+ console.log(`Converting ${event.mediaId}: ${event.progress}% - ${event.status}`);
118
+ });
119
+ ```
120
+
121
+ #### `episodes$: Observable<SSEEpisodesEvent>`
122
+
123
+ Emits when episodes in this library are added, updated, or deleted.
124
+
125
+ ```typescript
126
+ libraryApi.episodes$.subscribe(event => {
127
+ for (const { action, episode } of event.episodes) {
128
+ console.log(`Episode ${action}: ${episode.name}`);
129
+ }
130
+ });
131
+ ```
132
+
133
+ #### `series$: Observable<SSESeriesEvent>`
134
+
135
+ Emits when series in this library are added, updated, or deleted.
136
+
137
+ ```typescript
138
+ libraryApi.series$.subscribe(event => {
139
+ for (const { action, serie } of event.series) {
140
+ console.log(`Series ${action}: ${serie.name}`);
141
+ }
142
+ });
143
+ ```
144
+
145
+ #### `movies$: Observable<SSEMoviesEvent>`
146
+
147
+ Emits when movies in this library are added, updated, or deleted.
148
+
149
+ ```typescript
150
+ libraryApi.movies$.subscribe(event => {
151
+ for (const { action, movie } of event.movies) {
152
+ console.log(`Movie ${action}: ${movie.name}`);
153
+ }
154
+ });
155
+ ```
156
+
157
+ #### `people$: Observable<SSEPeopleEvent>`
158
+
159
+ Emits when people in this library are added, updated, or deleted.
160
+
161
+ ```typescript
162
+ libraryApi.people$.subscribe(event => {
163
+ for (const { action, person } of event.people) {
164
+ console.log(`Person ${action}: ${person.name}`);
165
+ }
166
+ });
167
+ ```
168
+
169
+ #### `tags$: Observable<SSETagsEvent>`
170
+
171
+ Emits when tags in this library are added, updated, or deleted.
172
+
173
+ ```typescript
174
+ libraryApi.tags$.subscribe(event => {
175
+ for (const { action, tag } of event.tags) {
176
+ console.log(`Tag ${action}: ${tag.name}`);
177
+ }
178
+ });
179
+ ```
180
+
181
+ #### `libraryStatus$: Observable<SSELibraryStatusEvent>`
182
+
183
+ Emits status updates for this library (e.g., scanning progress).
184
+
185
+ ```typescript
186
+ libraryApi.libraryStatus$.subscribe(event => {
187
+ console.log(`Status: ${event.message} (${event.progress}%)`);
188
+ });
189
+ ```
190
+
191
+ ### Complete SSE Example with LibraryApi
192
+
193
+ ```typescript
194
+ import { RedseatClient, LibraryApi, ServerApi } from '@redseat/api';
195
+ import { Subscription } from 'rxjs';
196
+
197
+ const client = new RedseatClient({
198
+ server: { id: 'server-123', url: 'example.com' },
199
+ getIdToken: async () => await getFirebaseToken()
200
+ });
201
+
202
+ // Connect to SSE first
203
+ await client.connectSSE();
204
+
205
+ // Get library and create LibraryApi
206
+ const serverApi = new ServerApi(client);
207
+ const libraries = await serverApi.getLibraries();
208
+ const library = libraries[0];
209
+ const libraryApi = new LibraryApi(client, library.id!, library);
210
+
211
+ // Track subscriptions
212
+ const subscriptions: Subscription[] = [];
213
+
214
+ // Subscribe to library-specific events
215
+ subscriptions.push(
216
+ libraryApi.medias$.subscribe(event => {
217
+ for (const { action, media } of event.medias) {
218
+ console.log(`[${library.name}] Media ${action}: ${media.name}`);
219
+ }
220
+ })
221
+ );
222
+
223
+ subscriptions.push(
224
+ libraryApi.libraryStatus$.subscribe(event => {
225
+ console.log(`[${library.name}] ${event.message}`);
226
+ })
227
+ );
228
+
229
+ // ... later, cleanup
230
+ subscriptions.forEach(sub => sub.unsubscribe());
231
+ libraryApi.dispose();
232
+ client.disconnectSSE();
233
+ ```
234
+
69
235
  ---
70
236
 
71
237
  ## Tags
@@ -1064,6 +1230,90 @@ if (library.crypt) {
1064
1230
  }
1065
1231
  ```
1066
1232
 
1233
+ ### `uploadGroup(download: RsGroupDownload, options?: { spawn?: boolean }): Promise<IFile[] | { downloading: boolean }>`
1234
+
1235
+ Uploads a group of media files from URLs.
1236
+
1237
+ **Parameters:**
1238
+
1239
+ - `download`: The group download request containing:
1240
+ - `group`: Boolean indicating if files should be grouped
1241
+ - `groupThumbnailUrl?`: Optional thumbnail URL for the group
1242
+ - `groupFilename?`: Optional filename for the group
1243
+ - `groupMime?`: Optional MIME type for the group
1244
+ - `requests`: Array of `RsRequest` objects, each containing:
1245
+ - `url`: The URL to download from
1246
+ - `status`: `RsRequestStatus` (e.g., `NeedParsing`, `Unprocessed`)
1247
+ - `permanent`: Boolean for permanent storage
1248
+ - `method`: `RsRequestMethod` (e.g., `Get`, `Post`)
1249
+ - `ignoreOriginDuplicate`: Boolean to ignore duplicate origins
1250
+ - Optional fields: `headers`, `cookies`, `referer`, `filename`, `mime`, `thumbnailUrl`, `tagsLookup`, `peopleLookup`, `albumsLookup`, etc.
1251
+ - `options`: Optional settings object:
1252
+ - `spawn?`: If true, runs download in background and returns `{ downloading: true }`
1253
+
1254
+ **Returns:** Promise resolving to an array of `IFile` objects when `spawn=false`, or `{ downloading: boolean }` when `spawn=true`
1255
+
1256
+ **Example:**
1257
+
1258
+ ```typescript
1259
+ import { RsRequestStatus, RsRequestMethod } from '@redseat/api';
1260
+
1261
+ // Download a single URL
1262
+ const files = await libraryApi.uploadGroup({
1263
+ group: false,
1264
+ requests: [
1265
+ {
1266
+ url: 'https://example.com/video.mp4',
1267
+ status: RsRequestStatus.Unprocessed,
1268
+ permanent: false,
1269
+ method: RsRequestMethod.Get,
1270
+ ignoreOriginDuplicate: false
1271
+ }
1272
+ ]
1273
+ });
1274
+
1275
+ // Download multiple URLs as a group with parsing
1276
+ const groupedFiles = await libraryApi.uploadGroup({
1277
+ group: true,
1278
+ groupFilename: 'my-collection',
1279
+ requests: [
1280
+ {
1281
+ url: 'https://example.com/video1.mp4',
1282
+ status: RsRequestStatus.NeedParsing,
1283
+ permanent: false,
1284
+ method: RsRequestMethod.Get,
1285
+ ignoreOriginDuplicate: false,
1286
+ tagsLookup: ['vacation', 'beach']
1287
+ },
1288
+ {
1289
+ url: 'https://example.com/video2.mp4',
1290
+ status: RsRequestStatus.NeedParsing,
1291
+ permanent: false,
1292
+ method: RsRequestMethod.Get,
1293
+ ignoreOriginDuplicate: false
1294
+ }
1295
+ ]
1296
+ });
1297
+
1298
+ // Run download in background
1299
+ const result = await libraryApi.uploadGroup(
1300
+ {
1301
+ group: false,
1302
+ requests: [
1303
+ {
1304
+ url: 'https://example.com/large-video.mp4',
1305
+ status: RsRequestStatus.Unprocessed,
1306
+ permanent: false,
1307
+ method: RsRequestMethod.Get,
1308
+ ignoreOriginDuplicate: false
1309
+ }
1310
+ ]
1311
+ },
1312
+ { spawn: true }
1313
+ );
1314
+ // result = { downloading: true }
1315
+ ```
1316
+
1067
1317
  ### `removeMedias(mediaIds: string[]): Promise<void>`
1068
1318
 
1069
1319
  Deletes multiple media files.
package/package.json CHANGED
@@ -1,50 +1,50 @@
1
- {
2
- "name": "@redseat/api",
3
- "version": "0.2.6",
4
- "description": "TypeScript API client library for interacting with Redseat servers",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "module": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
- "exports": {
10
- ".": {
11
- "import": "./dist/index.js",
12
- "types": "./dist/index.d.ts"
13
- }
14
- },
15
- "files": [
16
- "dist/**/*",
17
- "README.md",
18
- "*.md"
19
- ],
20
- "keywords": [
21
- "redseat",
22
- "api",
23
- "client",
24
- "typescript"
25
- ],
26
- "author": "Arnaud JEZEQUEL <arnaud.jezequel@gmail.com>",
27
- "license": "MIT",
28
- "repository": {
29
- "type": "git",
30
- "url": "https://github.com/yourusername/redseat-svelte.git",
31
- "directory": "packages/api"
32
- },
33
- "scripts": {
34
- "build": "tsc",
35
- "test": "vitest run",
36
- "test:watch": "vitest"
37
- },
38
- "dependencies": {
39
- "axios": "^1.11.0",
40
- "rxjs": "^7.8.2"
41
- },
42
- "devDependencies": {
43
- "typescript": "^5.8.3",
44
- "vite": "^7.3.0",
45
- "vitest": "^4.0.16"
46
- },
47
- "publishConfig": {
48
- "access": "public"
49
- }
1
+ {
2
+ "name": "@redseat/api",
3
+ "version": "0.2.8",
4
+ "description": "TypeScript API client library for interacting with Redseat servers",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist/**/*",
17
+ "README.md",
18
+ "*.md"
19
+ ],
20
+ "keywords": [
21
+ "redseat",
22
+ "api",
23
+ "client",
24
+ "typescript"
25
+ ],
26
+ "author": "Arnaud JEZEQUEL <arnaud.jezequel@gmail.com>",
27
+ "license": "MIT",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/yourusername/redseat-svelte.git",
31
+ "directory": "packages/api"
32
+ },
33
+ "scripts": {
34
+ "build": "tsc",
35
+ "test": "vitest run",
36
+ "test:watch": "vitest"
37
+ },
38
+ "dependencies": {
39
+ "axios": "^1.11.0",
40
+ "rxjs": "^7.8.2"
41
+ },
42
+ "devDependencies": {
43
+ "typescript": "^5.8.3",
44
+ "vite": "^7.3.0",
45
+ "vitest": "^4.0.16"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public"
49
+ }
50
50
  }