@vidtreo/recorder 1.7.1 → 1.7.2

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/index.d.ts CHANGED
@@ -1,3 +1,9 @@
1
+ export type RecoverPendingUploadOptions = {
2
+ match: PendingUploadMatch;
3
+ onProgress?: (progress: number) => void;
4
+ };
5
+ export declare function recoverPendingUpload(options: RecoverPendingUploadOptions): Promise<VideoUploadResult | null>;
6
+
1
7
  export type VideoUploadOptions = {
2
8
  apiKey: string;
3
9
  backendUrl: string;
@@ -35,6 +41,10 @@ type UploadCallbacks = {
35
41
  onUploadComplete?: (id: string, result: VideoUploadResult) => void;
36
42
  onUploadError?: (id: string, error: Error) => void;
37
43
  };
44
+ export type PendingUploadMatch = {
45
+ metadata?: Record<string, unknown>;
46
+ userMetadata?: Record<string, unknown>;
47
+ };
38
48
  export declare class UploadQueueManager {
39
49
  private readonly storageService;
40
50
  private readonly uploadService;
@@ -50,6 +60,7 @@ export declare class UploadQueueManager {
50
60
  queueUpload(upload: Omit<PendingUpload, "id" | "createdAt" | "updatedAt" | "status" | "retryCount">): Promise<string>;
51
61
  processQueue(): Promise<void>;
52
62
  getPendingUploads(): Promise<PendingUpload[]>;
63
+ processMatchingUpload(match: PendingUploadMatch): Promise<VideoUploadResult | null>;
53
64
  getStats(): Promise<{
54
65
  pending: number;
55
66
  uploading: number;
@@ -58,6 +69,10 @@ export declare class UploadQueueManager {
58
69
  }>;
59
70
  private getOldestUpload;
60
71
  private getOldestFailedUpload;
72
+ private recoverStaleUploads;
73
+ private getOldestMatchingUpload;
74
+ private canProcessMatchingUpload;
75
+ private matchesMetadata;
61
76
  private processUpload;
62
77
  private calculateRetryDelay;
63
78
  private scheduleRetry;
package/dist/index.js CHANGED
@@ -6305,7 +6305,7 @@ function resolveDeviceError(input) {
6305
6305
  // package.json
6306
6306
  var package_default = {
6307
6307
  name: "@vidtreo/recorder",
6308
- version: "1.7.1",
6308
+ version: "1.7.2",
6309
6309
  type: "module",
6310
6310
  description: "Vidtreo SDK for browser-based video recording and transcoding. Features include camera/screen recording, real-time MP4 transcoding, audio level analysis, mute/pause controls, source switching, device selection, and automatic backend uploads. Similar to Ziggeo and Addpipe, Vidtreo provides enterprise-grade video processing capabilities for web applications.",
6311
6311
  main: "./dist/index.js",
@@ -7056,13 +7056,7 @@ class UploadQueueManager {
7056
7056
  if (!this.storageService.isInitialized()) {
7057
7057
  throw new Error("Database not initialized");
7058
7058
  }
7059
- if (!this.hasRecoveredStaleUploads) {
7060
- const staleUploads = await this.storageService.getPendingUploads("uploading");
7061
- await Promise.all(staleUploads.map((upload) => this.storageService.updateUploadStatus(upload.id, {
7062
- status: "pending"
7063
- })));
7064
- this.hasRecoveredStaleUploads = true;
7065
- }
7059
+ await this.recoverStaleUploads();
7066
7060
  const pendingUploads = await this.storageService.getPendingUploads("pending");
7067
7061
  if (pendingUploads.length > 0) {
7068
7062
  const upload = this.getOldestUpload(pendingUploads);
@@ -7096,6 +7090,27 @@ class UploadQueueManager {
7096
7090
  getPendingUploads() {
7097
7091
  return this.storageService.getPendingUploads();
7098
7092
  }
7093
+ async processMatchingUpload(match) {
7094
+ if (this.isProcessing) {
7095
+ return null;
7096
+ }
7097
+ this.isProcessing = true;
7098
+ try {
7099
+ await this.recoverStaleUploads();
7100
+ const uploads = await this.storageService.getPendingUploads();
7101
+ const matchingUpload = this.getOldestMatchingUpload(uploads, match);
7102
+ if (!matchingUpload) {
7103
+ this.isProcessing = false;
7104
+ return null;
7105
+ }
7106
+ const result = await this.processUpload(matchingUpload, true);
7107
+ this.isProcessing = false;
7108
+ return result;
7109
+ } catch (error) {
7110
+ this.isProcessing = false;
7111
+ throw new Error(`Error processing matching upload: ${extractErrorMessage(error)}`);
7112
+ }
7113
+ }
7099
7114
  async getStats() {
7100
7115
  const all = await this.storageService.getPendingUploads();
7101
7116
  const stats = {
@@ -7127,7 +7142,45 @@ class UploadQueueManager {
7127
7142
  }
7128
7143
  return uploads.sort((a, b) => a.updatedAt - b.updatedAt)[0];
7129
7144
  }
7130
- async processUpload(upload) {
7145
+ async recoverStaleUploads() {
7146
+ if (this.hasRecoveredStaleUploads) {
7147
+ return;
7148
+ }
7149
+ const staleUploads = await this.storageService.getPendingUploads("uploading");
7150
+ await Promise.all(staleUploads.map((upload) => this.storageService.updateUploadStatus(upload.id, {
7151
+ status: "pending"
7152
+ })));
7153
+ this.hasRecoveredStaleUploads = true;
7154
+ }
7155
+ getOldestMatchingUpload(uploads, match) {
7156
+ const matchingUploads = uploads.filter((upload) => this.canProcessMatchingUpload(upload, match));
7157
+ if (matchingUploads.length === 0) {
7158
+ return null;
7159
+ }
7160
+ return matchingUploads.sort((a, b) => a.createdAt - b.createdAt)[0];
7161
+ }
7162
+ canProcessMatchingUpload(upload, match) {
7163
+ if (upload.status === "completed") {
7164
+ return false;
7165
+ }
7166
+ if (upload.status === "failed" && upload.retryCount >= MAX_RETRIES2) {
7167
+ return false;
7168
+ }
7169
+ if (!this.matchesMetadata(upload.metadata, match.metadata)) {
7170
+ return false;
7171
+ }
7172
+ return this.matchesMetadata(upload.userMetadata, match.userMetadata);
7173
+ }
7174
+ matchesMetadata(actual, expected) {
7175
+ if (!expected || Object.keys(expected).length === 0) {
7176
+ return true;
7177
+ }
7178
+ if (!actual) {
7179
+ return false;
7180
+ }
7181
+ return Object.entries(expected).every(([key, value]) => actual[key] === value);
7182
+ }
7183
+ async processUpload(upload, shouldThrowOnError = false) {
7131
7184
  try {
7132
7185
  await this.storageService.updateUploadStatus(upload.id, {
7133
7186
  status: "uploading"
@@ -7145,6 +7198,7 @@ class UploadQueueManager {
7145
7198
  });
7146
7199
  await this.storageService.deleteUpload(upload.id);
7147
7200
  this.callbacks.onUploadComplete?.(upload.id, result);
7201
+ return result;
7148
7202
  } catch (error) {
7149
7203
  const errorMessage = extractErrorMessage(error);
7150
7204
  const retryCount = upload.retryCount + 1;
@@ -7159,6 +7213,10 @@ class UploadQueueManager {
7159
7213
  const delay2 = this.calculateRetryDelay(retryCount);
7160
7214
  this.scheduleRetry(delay2);
7161
7215
  }
7216
+ if (shouldThrowOnError) {
7217
+ throw new Error(errorMessage);
7218
+ }
7219
+ return null;
7162
7220
  }
7163
7221
  }
7164
7222
  calculateRetryDelay(retryCount) {
@@ -23899,6 +23957,23 @@ class QuotaManager {
23899
23957
  return quota.percentage >= threshold;
23900
23958
  }
23901
23959
  }
23960
+ // src/core/upload/pending-upload-recovery.ts
23961
+ async function recoverPendingUpload(options) {
23962
+ const storageService = new VideoStorageService;
23963
+ await storageService.init();
23964
+ const uploadService = new VideoUploadService;
23965
+ const uploadQueueManager = new UploadQueueManager(storageService, uploadService);
23966
+ uploadQueueManager.setCallbacks({
23967
+ onUploadProgress: (_id, progress) => {
23968
+ options.onProgress?.(progress);
23969
+ }
23970
+ });
23971
+ try {
23972
+ return await uploadQueueManager.processMatchingUpload(options.match);
23973
+ } finally {
23974
+ uploadQueueManager.destroy();
23975
+ }
23976
+ }
23902
23977
  // src/core/utils/audio-utils.ts
23903
23978
  function calculateBarColor(position) {
23904
23979
  if (position < 0.25) {
@@ -24294,6 +24369,7 @@ export {
24294
24369
  requireInitialized,
24295
24370
  requireDefined,
24296
24371
  requireActive,
24372
+ recoverPendingUpload,
24297
24373
  parseBrowserErrorLinkContent,
24298
24374
  mapPresetToConfig,
24299
24375
  logger,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vidtreo/recorder",
3
- "version": "1.7.1",
3
+ "version": "1.7.2",
4
4
  "type": "module",
5
5
  "description": "Vidtreo SDK for browser-based video recording and transcoding. Features include camera/screen recording, real-time MP4 transcoding, audio level analysis, mute/pause controls, source switching, device selection, and automatic backend uploads. Similar to Ziggeo and Addpipe, Vidtreo provides enterprise-grade video processing capabilities for web applications.",
6
6
  "main": "./dist/index.js",