7
This commit is contained in:
@@ -17,14 +17,34 @@ export const getAssetFromVersion = (currentVersion, assetType) => {
|
||||
return getAssetFromGroup(currentVersion.assets, assetType);
|
||||
};
|
||||
|
||||
export const resolveDocumentAssetUrl = (doc, type, { ensureAssetUrl, getAsset, ensureOptions } = {}) => {
|
||||
if (!doc || !type) {
|
||||
return null;
|
||||
}
|
||||
const asset = typeof getAsset === 'function' ? getAsset(doc, type) : null;
|
||||
if (!asset) {
|
||||
return null;
|
||||
}
|
||||
const now = Date.now();
|
||||
const expiresAt = typeof asset.expiresAt === 'number' ? asset.expiresAt : null;
|
||||
const hasFreshUrl = asset.url && (!expiresAt || expiresAt > now);
|
||||
if (hasFreshUrl) {
|
||||
return asset.url;
|
||||
}
|
||||
if (doc.id && asset.id && typeof ensureAssetUrl === 'function') {
|
||||
const force = Boolean(asset.url && expiresAt && expiresAt <= now);
|
||||
const options = ensureOptions ? { ...ensureOptions, force } : { force };
|
||||
ensureAssetUrl(doc.id, asset, options).catch(() => {});
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
class AssetManager {
|
||||
constructor({ api, assetPresignTtlMs }) {
|
||||
this.api = api;
|
||||
this.assetPresignTtlMs = assetPresignTtlMs;
|
||||
this.assetCache = new Map();
|
||||
this.assetInflight = new Map();
|
||||
this.previewCache = new Map();
|
||||
this.previewInflight = new Map();
|
||||
}
|
||||
|
||||
setApi(api) {
|
||||
@@ -197,60 +217,9 @@ class AssetManager {
|
||||
return request;
|
||||
}
|
||||
|
||||
ensurePreview(documentId, { force = false } = {}) {
|
||||
if (!documentId) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
const cached = this.previewCache.get(documentId);
|
||||
const now = Date.now();
|
||||
if (!force && cached && (!cached.expiresAt || cached.expiresAt > now)) {
|
||||
return Promise.resolve(cached);
|
||||
}
|
||||
|
||||
if (!force && this.previewInflight.has(documentId)) {
|
||||
return this.previewInflight.get(documentId);
|
||||
}
|
||||
|
||||
if (!this.api) {
|
||||
return Promise.reject(new Error('AssetManager API client is not configured.'));
|
||||
}
|
||||
|
||||
const request = this.api
|
||||
.get(`/documents/${documentId}/download`)
|
||||
.then(({ data }) => {
|
||||
const ttl = data.expires_in ? Math.max(data.expires_in - 60, 30) * 1000 : 5 * 60 * 1000;
|
||||
const entry = {
|
||||
url: data.url,
|
||||
contentType: data.content_type || null,
|
||||
filename: data.filename,
|
||||
expiresAt: Date.now() + ttl,
|
||||
};
|
||||
this.previewCache.set(documentId, entry);
|
||||
return entry;
|
||||
})
|
||||
.finally(() => {
|
||||
this.previewInflight.delete(documentId);
|
||||
});
|
||||
|
||||
this.previewInflight.set(documentId, request);
|
||||
return request;
|
||||
}
|
||||
|
||||
getPreview(documentId) {
|
||||
return this.previewCache.get(documentId) || null;
|
||||
}
|
||||
|
||||
deleteDocument(documentId) {
|
||||
if (!documentId) return;
|
||||
this.previewCache.delete(documentId);
|
||||
this.previewInflight.delete(documentId);
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.assetCache.clear();
|
||||
this.assetInflight.clear();
|
||||
this.previewCache.clear();
|
||||
this.previewInflight.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user