support caching map data when map_data_fetch_proxy is set true

This commit is contained in:
MaysWind
2026-02-28 18:16:34 +08:00
parent d5dfdc8c05
commit 247181830c
35 changed files with 740 additions and 179 deletions
+65 -3
View File
@@ -1,5 +1,6 @@
import type {
BrowserCacheStatistics
BrowserCacheStatistics,
SWMapCacheConfig
} from '@/core/cache.ts';
import {
@@ -7,10 +8,14 @@ import {
SW_RUNTIME_CACHE_NAME_PREFIX,
SW_ASSETS_CACHE_NAME,
SW_CODE_CACHE_NAME,
SW_MAP_CACHE_NAME
SW_MAP_CACHE_NAME,
SW_MESSAGE_TYPE_UPDATE_MAP_CACHE_CONFIG,
SW_MESSAGE_TYPE_UPDATE_MAP_CACHE_CONFIG_RESPONSE,
MAP_CACHE_MAX_ENTRIES
} from '@/consts/cache.ts';
import { isFunction, isObject, isNumber } from './common.ts';
import services from './services.ts';
import logger from './logger.ts';
function findFirstCacheName(prefix: string): Promise<string> {
@@ -113,6 +118,63 @@ export function loadBrowserCacheStatistics(): Promise<BrowserCacheStatistics> {
});
}
export function updateMapCacheExpiration(expireSeconds: number): Promise<void> {
const config: SWMapCacheConfig = {
enabled: expireSeconds >= 0,
patterns: services.getMapProxyTileImageAndAnnotationImageUrlPatterns(),
maxEntries: MAP_CACHE_MAX_ENTRIES,
maxAgeMilliseconds: expireSeconds * 1000
};
return new Promise((resolve, reject) => {
if (!navigator.serviceWorker || !navigator.serviceWorker.controller) {
reject(new Error('Service worker is not supported or not active'));
return;
}
const controller = navigator.serviceWorker.controller;
navigator.serviceWorker.ready.then(() => {
const messageChannel = new MessageChannel();
messageChannel.port1.onmessage = (event) => {
if (event.data && event.data.type === SW_MESSAGE_TYPE_UPDATE_MAP_CACHE_CONFIG_RESPONSE) {
logger.info('Map cache config updated successfully in service worker: ' + JSON.stringify(event.data.payload));
resolve();
} else {
logger.error('cannot update map cache config, invalid response from service worker', event);
reject(new Error('Invalid response from service worker'));
}
};
controller.postMessage({
type: SW_MESSAGE_TYPE_UPDATE_MAP_CACHE_CONFIG,
payload: config
}, [messageChannel.port2]);
}).catch(error => {
logger.error('failed to update map cache config', error);
reject(error);
});
});
}
export function clearMapDataCache(): Promise<void> {
if (!window.caches) {
logger.error('caches API is not supported in this browser');
return Promise.reject();
}
return window.caches.delete(SW_MAP_CACHE_NAME).then(success => {
if (success) {
logger.info(`cache "${SW_MAP_CACHE_NAME}" cleared successfully`);
} else {
logger.warn(`failed to clear cache "${SW_MAP_CACHE_NAME}"`);
}
}).catch(error => {
logger.error(`failed to clear cache "${SW_MAP_CACHE_NAME}"`, error);
});
}
export function clearAllBrowserCaches(): Promise<void> {
if (!window.caches) {
logger.error('caches API is not supported in this browser');
@@ -142,7 +204,7 @@ export function clearAllBrowserCaches(): Promise<void> {
resolve();
});
}).catch(error => {
logger.warn("failed to clear cache", error);
logger.error("failed to clear cache", error);
reject(error);
});
});
+9 -3
View File
@@ -1,5 +1,11 @@
import { keys, keysIfValueEquals, values } from '@/core/base.ts';
import type { NameValue, TypeAndName, TypeAndDisplayName} from '@/core/base.ts';
import {
type GenericNameValue,
type TypeAndName,
type TypeAndDisplayName,
keys,
keysIfValueEquals,
values
} from '@/core/base.ts';
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
export function isFunction(val: unknown): val is Function {
@@ -285,7 +291,7 @@ export function getItemByKeyValue<T>(src: Record<string, T>[] | Record<string, R
return null;
}
export function findNameByValue(items: NameValue[], value: string): string | null {
export function findNameByValue<T>(items: GenericNameValue<T>[], value: T): string | null {
for (const item of items) {
if (item.value === value) {
return item.name;
+14
View File
@@ -27,6 +27,20 @@ export function initMapProvider(language?: string): void {
}
}
export function isMapProviderUseExternalSDK(): boolean {
const mapProviderType = getMapProvider();
if (mapProviderType === 'googlemap') {
return true;
} else if (mapProviderType === 'baidumap') {
return true;
} else if (mapProviderType === 'amap') {
return true;
} else {
return false;
}
}
export function getMapWebsite(): string {
return mapProvider?.getWebsite() || '';
}
+6
View File
@@ -831,6 +831,12 @@ export default {
generateQrCodeUrl: (qrCodeName: string): string => {
return `${getBasePath()}${BASE_QRCODE_PATH}/${qrCodeName}.png`;
},
getMapProxyTileImageAndAnnotationImageUrlPatterns(): string[] {
return [
`.*${BASE_PROXY_URL_PATH}/map/tile/[^/]+/[^/]+/[^/]+\\.png\\?provider=[^&]+.*$`,
`.*${BASE_PROXY_URL_PATH}/map/annotation/[^/]+/[^/]+/[^/]+\\.png\\?provider=[^&]+.*$`
];
},
generateMapProxyTileImageUrl: (mapProvider: string, language: string): string => {
const token = getCurrentToken();
let url = `${getBasePath()}${BASE_PROXY_URL_PATH}/map/tile/{z}/{x}/{y}.png?provider=${mapProvider}&token=${token}`;