fixed cors issue
This commit is contained in:
parent
f8c3bb4a07
commit
ef137199ec
@ -18,10 +18,8 @@ import {
|
|||||||
extractStoragePath,
|
extractStoragePath,
|
||||||
queuePresignedUrls,
|
queuePresignedUrls,
|
||||||
isRelativeStoragePath,
|
isRelativeStoragePath,
|
||||||
markPresignedUrlFailed,
|
|
||||||
markPresignedUrlsVerified,
|
markPresignedUrlsVerified,
|
||||||
isPresignedUrl,
|
isPresignedUrl,
|
||||||
buildProxyUrl,
|
|
||||||
} from '../lib/assetUrl';
|
} from '../lib/assetUrl';
|
||||||
import { logger } from '../lib/logger';
|
import { logger } from '../lib/logger';
|
||||||
import type { BlobUrlReadyEvent } from '../types/offline';
|
import type { BlobUrlReadyEvent } from '../types/offline';
|
||||||
@ -173,7 +171,7 @@ export function usePreloadOrchestrator(
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Use DownloadManager for unified download and blob URL creation
|
// Use DownloadManager for unified download and blob URL creation
|
||||||
// Mark presigned URL as verified if download succeeds
|
// DownloadManager automatically handles presigned URL → proxy fallback
|
||||||
downloadManager
|
downloadManager
|
||||||
.addJob({
|
.addJob({
|
||||||
assetId: item.id,
|
assetId: item.id,
|
||||||
@ -192,44 +190,11 @@ export function usePreloadOrchestrator(
|
|||||||
markPresignedUrlsVerified();
|
markPresignedUrlsVerified();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(async (err) => {
|
.catch((err) => {
|
||||||
logger.error('[PRELOAD] Download failed', {
|
logger.error('[PRELOAD] Download failed', {
|
||||||
url: item.url.slice(-50),
|
url: item.url.slice(-50),
|
||||||
error: err?.message,
|
error: err?.message,
|
||||||
});
|
});
|
||||||
|
|
||||||
// If presigned URL failed (e.g., CORS), retry with proxy URL
|
|
||||||
if (storageKey && isPresignedUrl(item.url)) {
|
|
||||||
markPresignedUrlFailed(storageKey);
|
|
||||||
const proxyUrl = buildProxyUrl(storageKey);
|
|
||||||
logger.info('[PRELOAD] Retrying with proxy URL', {
|
|
||||||
storageKey: storageKey.slice(-50),
|
|
||||||
proxyUrl: proxyUrl.slice(-60),
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await downloadManager.addJob({
|
|
||||||
assetId: item.id,
|
|
||||||
projectId: '',
|
|
||||||
url: proxyUrl,
|
|
||||||
filename: storageKey.split('/').pop() || 'asset',
|
|
||||||
variantType: 'original',
|
|
||||||
assetType: mapAssetType(item.assetType),
|
|
||||||
priority: item.priority,
|
|
||||||
storageKey,
|
|
||||||
createBlobUrl: true,
|
|
||||||
persist: false,
|
|
||||||
});
|
|
||||||
logger.info('[PRELOAD] Proxy download complete', {
|
|
||||||
url: proxyUrl.slice(-60),
|
|
||||||
});
|
|
||||||
} catch (retryErr) {
|
|
||||||
logger.error('[PRELOAD] Proxy download also failed', {
|
|
||||||
url: proxyUrl.slice(-60),
|
|
||||||
error: retryErr instanceof Error ? retryErr.message : 'unknown',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
preloadedUrls.add(storageKey);
|
preloadedUrls.add(storageKey);
|
||||||
@ -582,6 +547,7 @@ export function usePreloadOrchestrator(
|
|||||||
// Partial downloads (video/audio/transition) use presigned URL directly for playback
|
// Partial downloads (video/audio/transition) use presigned URL directly for playback
|
||||||
const createBlobUrl = assetType === 'image' || maxBytes === undefined;
|
const createBlobUrl = assetType === 'image' || maxBytes === undefined;
|
||||||
|
|
||||||
|
// DownloadManager automatically handles presigned URL → proxy fallback
|
||||||
return downloadManager
|
return downloadManager
|
||||||
.addJob({
|
.addJob({
|
||||||
assetId: id,
|
assetId: id,
|
||||||
@ -601,33 +567,11 @@ export function usePreloadOrchestrator(
|
|||||||
markPresignedUrlsVerified();
|
markPresignedUrlsVerified();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(async (err) => {
|
.catch((err) => {
|
||||||
logger.error('[PRELOAD] Download failed', {
|
logger.error('[PRELOAD] Download failed', {
|
||||||
url: resolvedUrl.slice(-50),
|
url: resolvedUrl.slice(-50),
|
||||||
error: err?.message,
|
error: err?.message,
|
||||||
});
|
});
|
||||||
// Retry with proxy if presigned URL failed
|
|
||||||
if (isPresignedUrl(resolvedUrl)) {
|
|
||||||
markPresignedUrlFailed(normalizedKey);
|
|
||||||
const proxyUrl = buildProxyUrl(normalizedKey);
|
|
||||||
try {
|
|
||||||
await downloadManager.addJob({
|
|
||||||
assetId: id,
|
|
||||||
projectId: '',
|
|
||||||
url: proxyUrl,
|
|
||||||
filename: normalizedKey.split('/').pop() || 'asset',
|
|
||||||
variantType: 'original',
|
|
||||||
assetType: mapAssetType(assetType),
|
|
||||||
priority,
|
|
||||||
storageKey: normalizedKey,
|
|
||||||
createBlobUrl,
|
|
||||||
persist: false,
|
|
||||||
maxBytes, // Preserve partial preload behavior for retry
|
|
||||||
});
|
|
||||||
} catch {
|
|
||||||
// Ignore retry failures
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,12 @@ import { OFFLINE_CONFIG } from '../../config/offline.config';
|
|||||||
import { downloadEventBus } from './DownloadEventBus';
|
import { downloadEventBus } from './DownloadEventBus';
|
||||||
import { StorageManager } from './StorageManager';
|
import { StorageManager } from './StorageManager';
|
||||||
import { OfflineDbManager } from '../offlineDb/OfflineDbManager';
|
import { OfflineDbManager } from '../offlineDb/OfflineDbManager';
|
||||||
import { extractStoragePath } from '../assetUrl';
|
import {
|
||||||
|
extractStoragePath,
|
||||||
|
isPresignedUrl,
|
||||||
|
markPresignedUrlFailed,
|
||||||
|
buildProxyUrl,
|
||||||
|
} from '../assetUrl';
|
||||||
import { logger } from '../logger';
|
import { logger } from '../logger';
|
||||||
import type {
|
import type {
|
||||||
PreloadJobStatus,
|
PreloadJobStatus,
|
||||||
@ -39,6 +44,7 @@ interface DownloadJob {
|
|||||||
persist?: boolean; // Persist to IndexedDB for resume (default: true)
|
persist?: boolean; // Persist to IndexedDB for resume (default: true)
|
||||||
maxBytes?: number; // Partial download limit (undefined = full download)
|
maxBytes?: number; // Partial download limit (undefined = full download)
|
||||||
isPartial?: boolean; // Whether this was a partial download (for tracking)
|
isPartial?: boolean; // Whether this was a partial download (for tracking)
|
||||||
|
usedProxyFallback?: boolean; // Whether we've already tried proxy URL fallback
|
||||||
abortController?: AbortController;
|
abortController?: AbortController;
|
||||||
resolve?: () => void;
|
resolve?: () => void;
|
||||||
reject?: (error: Error) => void;
|
reject?: (error: Error) => void;
|
||||||
@ -402,10 +408,35 @@ class DownloadManagerClass {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
job.retryCount++;
|
|
||||||
const errorMessage =
|
const errorMessage =
|
||||||
error instanceof Error ? error.message : 'Unknown error';
|
error instanceof Error ? error.message : 'Unknown error';
|
||||||
|
|
||||||
|
// If presigned URL failed and we haven't tried proxy yet, fall back to proxy
|
||||||
|
if (isPresignedUrl(job.url) && !job.usedProxyFallback) {
|
||||||
|
markPresignedUrlFailed(job.storageKey);
|
||||||
|
const proxyUrl = buildProxyUrl(job.storageKey);
|
||||||
|
|
||||||
|
logger.info('[DownloadManager] Presigned URL failed, retrying with proxy', {
|
||||||
|
storageKey: job.storageKey.slice(-50),
|
||||||
|
error: errorMessage,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update job to use proxy URL and retry immediately
|
||||||
|
job.url = proxyUrl;
|
||||||
|
job.usedProxyFallback = true;
|
||||||
|
job.retryCount = 0; // Reset retry count for proxy attempt
|
||||||
|
job.bytesLoaded = 0;
|
||||||
|
job.progress = 0;
|
||||||
|
job.status = 'queued';
|
||||||
|
|
||||||
|
// Retry immediately with proxy URL
|
||||||
|
this.queue.unshift(job);
|
||||||
|
this.processQueue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
job.retryCount++;
|
||||||
|
|
||||||
if (job.retryCount < this.config.maxRetries) {
|
if (job.retryCount < this.config.maxRetries) {
|
||||||
// Retry with backoff
|
// Retry with backoff
|
||||||
job.status = 'queued';
|
job.status = 'queued';
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user