@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/{agents.md → AGENTS.md} +275 -275
- package/CLAUDE.md +2 -0
- package/README.md +132 -132
- package/client.md +614 -318
- package/dist/client.d.ts +71 -0
- package/dist/client.js +285 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/interfaces.d.ts +9 -31
- package/dist/library.d.ts +34 -9
- package/dist/library.js +30 -10
- package/dist/sse-types.d.ts +121 -0
- package/dist/sse-types.js +1 -0
- package/encryption.md +533 -533
- package/firebase.md +602 -602
- package/libraries.md +250 -0
- package/package.json +49 -49
- package/server.md +196 -196
- package/test.md +291 -291
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.
|
|
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
|
}
|