Skip to content

Commit 6acc6f4

Browse files
authored
feat: use indexedDB instead of caches to cache sdf (#2839)
Co-authored-by: HGX_GEO <2307864143@qq.ocm> sdf持久化存储修改,使用indexedDB取代caches API,因为测试中发现caches API只支持https和localhost,不支持http
1 parent 9872288 commit 6acc6f4

File tree

1 file changed

+83
-25
lines changed

1 file changed

+83
-25
lines changed

packages/vt/src/packer/GlyphRequestor.js

Lines changed: 83 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,72 @@ const MAX_CONCURRENT_REQUESTS = 6;
1717
let activeRequests = 0;
1818
const requestQueue = [];
1919

20+
21+
// --- IndexedDB persistent cache (works on HTTP & HTTPS) ---
22+
const SDF_DB_NAME = 'maptalks-sdf-cache';
23+
const SDF_STORE_NAME = 'sdf';
24+
const SDF_DB_VERSION = 1;
25+
let _sdfDB = null;
26+
let _sdfDBReady = null; // shared promise
27+
28+
function _getCacheKey(url) {
29+
// Strip query parameters so tokens/timestamps don't break matching
30+
try {
31+
const u = new URL(url, typeof location !== 'undefined' ? location.href : undefined);
32+
return u.origin + u.pathname;
33+
} catch (e) {
34+
return url.split('?')[0];
35+
}
36+
}
37+
38+
function _openSdfDB() {
39+
if (_sdfDBReady) return _sdfDBReady;
40+
_sdfDBReady = new Promise((resolve, reject) => {
41+
if (typeof indexedDB === 'undefined') {
42+
reject(new Error('IndexedDB not available'));
43+
return;
44+
}
45+
const req = indexedDB.open(SDF_DB_NAME, SDF_DB_VERSION);
46+
req.onupgradeneeded = () => {
47+
const db = req.result;
48+
if (!db.objectStoreNames.contains(SDF_STORE_NAME)) {
49+
db.createObjectStore(SDF_STORE_NAME);
50+
}
51+
};
52+
req.onsuccess = () => {
53+
_sdfDB = req.result;
54+
resolve(_sdfDB);
55+
};
56+
req.onerror = () => reject(req.error);
57+
});
58+
return _sdfDBReady;
59+
}
60+
61+
function _idbGet(key) {
62+
return _openSdfDB().then(db => {
63+
return new Promise((resolve, reject) => {
64+
const tx = db.transaction(SDF_STORE_NAME, 'readonly');
65+
const store = tx.objectStore(SDF_STORE_NAME);
66+
const req = store.get(key);
67+
req.onsuccess = () => resolve(req.result); // ArrayBuffer or undefined
68+
req.onerror = () => reject(req.error);
69+
});
70+
});
71+
}
72+
73+
function _idbPut(key, value) {
74+
return _openSdfDB().then(db => {
75+
return new Promise((resolve, reject) => {
76+
const tx = db.transaction(SDF_STORE_NAME, 'readwrite');
77+
const store = tx.objectStore(SDF_STORE_NAME);
78+
const req = store.put(value, key);
79+
req.onsuccess = () => resolve();
80+
req.onerror = () => reject(req.error);
81+
});
82+
});
83+
}
84+
// -------------------------------------------------------
85+
2086
function enqueueSDFRequest(url, resolve, reject) {
2187
if (activeRequests < MAX_CONCURRENT_REQUESTS) {
2288
executeSDFRequest(url, resolve, reject);
@@ -40,41 +106,33 @@ function executeSDFRequest(url, resolve, reject) {
40106
processNextSDFRequest();
41107
};
42108

43-
if (typeof caches !== 'undefined') {
44-
caches.match(url).then(cachedResponse => {
45-
if (cachedResponse) {
46-
return cachedResponse.arrayBuffer().then(buffer => {
47-
resolve(buffer);
48-
onComplete();
49-
});
50-
} else {
51-
fetchAndCacheSDF(url, resolve, reject, onComplete);
52-
}
53-
}).catch(() => {
54-
fetchAndCacheSDF(url, resolve, reject, onComplete);
55-
});
56-
} else {
57-
fetchAndCacheSDF(url, resolve, reject, onComplete);
58-
}
109+
const cacheKey = _getCacheKey(url);
110+
111+
_idbGet(cacheKey).then(buffer => {
112+
if (buffer) {
113+
// Cache hit — return a copy so the buffer can be transferred
114+
resolve(buffer instanceof ArrayBuffer ? buffer.slice(0) : buffer);
115+
onComplete();
116+
} else {
117+
fetchAndCacheSDF(url, cacheKey, resolve, reject, onComplete);
118+
}
119+
}).catch(() => {
120+
// IndexedDB unavailable or error — fall back to network
121+
fetchAndCacheSDF(url, cacheKey, resolve, reject, onComplete);
122+
});
59123
}
60124

61-
function fetchAndCacheSDF(url, resolve, reject, onComplete) {
125+
function fetchAndCacheSDF(url, cacheKey, resolve, reject, onComplete) {
62126
fetch(url)
63127
.then(response => {
64128
if (!response.ok) {
65129
throw new Error(`HTTP ${response.status}`);
66130
}
67-
if (typeof caches !== 'undefined') {
68-
const clone = response.clone();
69-
caches.open('maptalks-sdf-cache').then(cache => {
70-
cache.put(url, clone);
71-
}).catch(e => {
72-
console.warn('Failed to cache SDF in caches API:', e);
73-
});
74-
}
75131
return response.arrayBuffer();
76132
})
77133
.then(buffer => {
134+
// Store in IndexedDB (fire-and-forget)
135+
_idbPut(cacheKey, buffer.slice(0)).catch(() => { });
78136
resolve(buffer);
79137
onComplete();
80138
})

0 commit comments

Comments
 (0)