@caoguo/maplibre 0.0.1

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.
@@ -0,0 +1,300 @@
1
+ import { AddProtocolAction } from 'maplibre-gl';
2
+
3
+ /**
4
+ * 离线瓦片存储抽象层(F-1.4)。
5
+ *
6
+ * 设计:存储后端可插拔。浏览器用 IndexedDB(idb),Node/测试用内存实现。
7
+ * 瓦片 key 统一为 `${sourceId}:${z}:${x}:${y}`,value 为原始字节 + 过期时间。
8
+ */
9
+ type TileFormat = 'pbf' | 'geojson' | 'png' | 'mvt' | 'json';
10
+ interface StoredTile {
11
+ data: ArrayBuffer | Uint8Array;
12
+ format: TileFormat;
13
+ /** 过期时间戳(ms);0 表示永不过期 */
14
+ expires: number;
15
+ }
16
+ interface TileStoreBackend {
17
+ get(key: string): Promise<StoredTile | undefined>;
18
+ put(key: string, tile: StoredTile): Promise<void>;
19
+ has(key: string): Promise<boolean>;
20
+ delete(key: string): Promise<void>;
21
+ clear(prefix?: string): Promise<void>;
22
+ size(): Promise<number>;
23
+ }
24
+ /** 内存实现(测试 / 无 IndexedDB 环境) */
25
+ declare class MemoryTileStore implements TileStoreBackend {
26
+ private map;
27
+ get(key: string): Promise<StoredTile | undefined>;
28
+ put(key: string, tile: StoredTile): Promise<void>;
29
+ has(key: string): Promise<boolean>;
30
+ delete(key: string): Promise<void>;
31
+ clear(prefix?: string): Promise<void>;
32
+ size(): Promise<number>;
33
+ }
34
+ declare function tileKey(sourceId: string, z: number, x: number, y: number): string;
35
+ /** 离线协议名(caoguo-offline://...)。集中定义,供 protocol 与 serviceWorker 共用。 */
36
+ declare const OFFLINE_PROTOCOL = "caoguo-offline";
37
+ /**
38
+ * 解析离线协议 URL:`caoguo-offline://{sourceId}/{z}/{x}/{y}`
39
+ * 返回 sourceId 与瓦片坐标,便于 ProtocolHandler 取瓦片。
40
+ */
41
+ declare function parseOfflineUrl(url: string): {
42
+ sourceId: string;
43
+ z: number;
44
+ x: number;
45
+ y: number;
46
+ } | null;
47
+
48
+ /**
49
+ * 离线协议加载器(F-1.4)。
50
+ *
51
+ * 通过 MapLibre `addProtocol('caoguo-offline', loader)` 注册自定义协议,
52
+ * 瓦片源可声明 `tiles: ['caoguo-offline://{sourceId}/{z}/{x}/{y}']`,
53
+ * 引擎即从离线存储读取瓦片,实现「空气隔离」离线底图。
54
+ *
55
+ * MapLibre v4 的 protocol handler 签名:
56
+ * (requestParameters, abortController) => Promise<{ data: ArrayBuffer }>
57
+ */
58
+
59
+ interface OfflineProtocolContext {
60
+ store: TileStoreBackend;
61
+ }
62
+ /** 构造离线协议 URL(供 source.tiles 使用) */
63
+ declare function offlineTileUrl(sourceId: string, z: number, x: number, y: number): string;
64
+ /** 生成离线栅格/矢量源的 tiles 数组 */
65
+ declare function offlineSourceTiles(sourceId: string): string[];
66
+ /**
67
+ * 创建离线协议 loader(返回可直接传给 addProtocol 的异步函数)。
68
+ * 未命中瓦片时 reject,由 MapLibre 回退到线上源(若配置)。
69
+ */
70
+ declare function createOfflineLoader(ctx: OfflineProtocolContext): AddProtocolAction;
71
+ /** 在指定地图实例上注册离线协议 */
72
+ declare function registerOfflineProtocol(maplibregl: {
73
+ addProtocol: (name: string, action: AddProtocolAction) => void;
74
+ }, ctx: OfflineProtocolContext): void;
75
+
76
+ /**
77
+ * 离线瓦片打包器(F-1.4)。
78
+ *
79
+ * 把本地瓦片导入离线存储:
80
+ * - 原始 {z}/{x}/{y}.pbf|png 目录结构
81
+ * - 单张 GeoJSON(按 z/x/y 网格切片为矢量瓦片缓冲,供 `caoguo-offline` 协议读取)
82
+ *
83
+ * 这里的「切片」为简化实现:GeoJSON 按瓦片网格空间包含关系分桶,
84
+ * 仅把要素写入对应瓦片(不做 MVT 编码),存储为 UTF-8 JSON,
85
+ * 由 protocol loader 以 `geojson` 格式返回,source type 用 geojson。
86
+ * 生产级 MVT 编码(tippecanoe / @mapbox/vector-tile)可后续接入。
87
+ */
88
+
89
+ interface PackGeoJSONOptions {
90
+ sourceId: string;
91
+ geojson: {
92
+ type: 'FeatureCollection';
93
+ features: Array<{
94
+ geometry: {
95
+ type: string;
96
+ coordinates: unknown;
97
+ };
98
+ properties: Record<string, unknown>;
99
+ }>;
100
+ };
101
+ maxZoom?: number;
102
+ /** 过期时间(ms 时间戳),0=永不过期 */
103
+ expires?: number;
104
+ onProgress?: (done: number, total: number) => void;
105
+ }
106
+ /**
107
+ * 将 GeoJSON 按瓦片网格分桶写入离线存储。
108
+ * 返回写入的瓦片数量。
109
+ */
110
+ declare function packGeoJSONToStore(store: TileStoreBackend, opts: PackGeoJSONOptions): Promise<number>;
111
+ /**
112
+ * 由离线存储构造一个 geojson 源(用于 MapLibre source.tiles)。
113
+ * 注意:geojson 协议瓦片由 protocol loader 直接返回 FeatureCollection。
114
+ */
115
+ declare function offlineGeoJSONSource(sourceId: string): {
116
+ type: 'geojson';
117
+ data: never;
118
+ } & {
119
+ tiles: string[];
120
+ _caoguoOffline: true;
121
+ _sourceId: string;
122
+ };
123
+
124
+ /**
125
+ * Service Worker 离线拦截(T5 / F-1.6)。
126
+ *
127
+ * 目标:在 T4 离线瓦片(IndexedDB + caoguo-offline 协议)之上,增加一层
128
+ * **网络级二级缓存**——用 Cache API 缓存线上请求的瓦片(天地图等),并在
129
+ * 「空气隔离(air-gap)」模式下拦截所有请求、用 Cache/离线存储兜底,
130
+ * 实现断网后地图仍可平移缩放。
131
+ *
132
+ * 设计:
133
+ * - `resolveCacheKey` / `shouldCache` / `resolveResponse` 是**纯函数 core**,
134
+ * 不依赖真实 ServiceWorker 全局,可在 Node/vitest 中直接测试。
135
+ * - `createFetchHandler` 把 core 包装成标准 `fetch` 事件处理器(注入 cache 与 store)。
136
+ * - 浏览器侧用 `registerServiceWorker` 注册脚本,并通过 postMessage 切换空气隔离模式。
137
+ *
138
+ * 与 T4 的边界:T4 负责「业务离线瓦片 → IndexedDB → maplibre 协议」,
139
+ * 本模块负责「线上瓦片请求 → Cache API 二级缓存 + 空气隔离拦截」,
140
+ * 二者互补:T4 命中时根本不发网络请求(协议层短路),未命中时才走到 SW 缓存。
141
+ */
142
+
143
+ /** 需要二级缓存的瓦片来源(host 白名单,避免缓存无关资源) */
144
+ declare const CACHEABLE_HOSTS: string[];
145
+ /** 缓存名称(版本化,便于失效升级) */
146
+ declare const CACHE_NAME = "caoguo-offline-tiles-v1";
147
+ /** 空气隔离模式消息协议 */
148
+ declare const MSG_AIRGAP: "caoguo:airgap";
149
+ interface AirgapMessage {
150
+ type: typeof MSG_AIRGAP;
151
+ /** true=开启空气隔离(断网模式),false=恢复在线优先 */
152
+ enabled: boolean;
153
+ }
154
+ /**
155
+ * 判断请求是否应进入离线二级缓存。
156
+ * 只缓存 GET 请求 & 白名单 host & 图片/瓦片类型(保守策略)。
157
+ */
158
+ declare function shouldCache(request: {
159
+ method: string;
160
+ url: string;
161
+ }): boolean;
162
+ /**
163
+ * 计算 Cache Storage 的 key。优先用 URL(含 query,token 不同视为不同资源),
164
+ * 否则回退到 request 对象本身。
165
+ */
166
+ declare function resolveCacheKey(request: {
167
+ url: string;
168
+ }): string;
169
+ /**
170
+ * 从存储(IndexedDB/T4 离线)尝试取得瓦片兜底。
171
+ * 用于空气隔离模式下网络不可达时返回上次离线打包的瓦片。
172
+ */
173
+ declare function resolveFromStore(store: TileStoreBackend | undefined, request: {
174
+ url: string;
175
+ }): Promise<{
176
+ data: ArrayBuffer;
177
+ contentType: string;
178
+ } | undefined>;
179
+ interface ResolveResponseDeps {
180
+ /** 实际的 fetch 实现(浏览器为全局 fetch,测试可注入) */
181
+ fetchImpl: (input: string) => Promise<{
182
+ ok: boolean;
183
+ status: number;
184
+ arrayBuffer: () => Promise<ArrayBuffer>;
185
+ headers: {
186
+ get: (k: string) => string | null;
187
+ };
188
+ }>;
189
+ /** Cache 接口(浏览器为全局 caches,测试可注入内存实现) */
190
+ cache: {
191
+ match: (key: string) => Promise<CacheEntry | undefined>;
192
+ put: (key: string, resp: unknown) => Promise<void>;
193
+ };
194
+ /** 空气隔离开关(闭包状态,由消息控制) */
195
+ airgap: {
196
+ enabled: boolean;
197
+ };
198
+ /** T4 离线存储(可选,空气隔离兜底) */
199
+ store?: TileStoreBackend;
200
+ }
201
+ interface CacheEntry {
202
+ ok: boolean;
203
+ status: number;
204
+ arrayBuffer: () => Promise<ArrayBuffer>;
205
+ headers: {
206
+ get: (k: string) => string | null;
207
+ };
208
+ }
209
+ interface ResolvedResponse {
210
+ /** 最终响应主体 */
211
+ data: ArrayBuffer;
212
+ /** 内容类型 */
213
+ contentType: string;
214
+ /** 来源:cache=命中缓存 / network=线上最新 / store=离线存储兜底 */
215
+ source: 'cache' | 'network' | 'store';
216
+ /** 该响应是否应写回缓存 */
217
+ cacheable: boolean;
218
+ }
219
+ /**
220
+ * 核心解析逻辑(纯函数,可测试)。
221
+ * 两种模式:
222
+ * - 在线优先(airgap=false):cache → network(写回 cache) → store 兜底
223
+ * - 空气隔离(airgap=true):cache → store 兜底(不发网络请求)
224
+ */
225
+ declare function resolveResponse(request: {
226
+ method: string;
227
+ url: string;
228
+ }, deps: ResolveResponseDeps): Promise<ResolvedResponse | null>;
229
+ /**
230
+ * 包装为 Service Worker 的 fetch 事件处理器。
231
+ * 注入真实的 caches / fetch / store。在浏览器 SW 全局中调用:
232
+ * self.addEventListener('fetch', createFetchHandler({ store }));
233
+ */
234
+ declare function createFetchHandler(opts: {
235
+ store?: TileStoreBackend;
236
+ airgap?: {
237
+ enabled: boolean;
238
+ };
239
+ }): (event: {
240
+ request: {
241
+ method: string;
242
+ url: string;
243
+ };
244
+ respondWith: (r: Promise<Response> | Response) => void;
245
+ }) => void;
246
+ /**
247
+ * 在 Service Worker 全局上安装离线拦截逻辑(浏览器 SW 脚本入口)。
248
+ * 处理 install/activate 生命周期、airgap 消息、fetch 拦截。
249
+ */
250
+ declare function installServiceWorker(sw: {
251
+ addEventListener: (type: string, handler: (ev: unknown) => void) => void;
252
+ caches: unknown;
253
+ store?: TileStoreBackend;
254
+ }): {
255
+ airgap: {
256
+ enabled: boolean;
257
+ };
258
+ };
259
+ /**
260
+ * 浏览器端注册离线 Service Worker(主线程调用)。
261
+ * 需要项目提供 SW 脚本文件(见 `sw-template` 注释),并部署到与地图同域根路径。
262
+ *
263
+ * @param scriptUrl SW 脚本 URL(如 '/caoguo-sw.js'),需调用方自行构建/放置
264
+ * @returns 注册成功的 ServiceWorker 实例;不支持时返回 null
265
+ */
266
+ declare function registerOfflineServiceWorker(scriptUrl: string): Promise<ServiceWorkerRegistration | null>;
267
+ /**
268
+ * 向已注册的 Service Worker 发送消息,切换「空气隔离」模式。
269
+ * enabled=true 时地图进入断网可用状态(仅用 Cache + T4 离线存储)。
270
+ */
271
+ declare function setAirgap(registration: ServiceWorkerRegistration, enabled: boolean): void;
272
+ /**
273
+ * SW 脚本模板(供调用方写入部署文件,如 public/caoguo-sw.js)。
274
+ * 该脚本通过 importScripts 复用本包编译产物,或直接内联 installServiceWorker。
275
+ *
276
+ * ```js
277
+ * // caoguo-sw.js
278
+ * importScripts('/caoguo-offline-sw.bundle.js'); // 含 installServiceWorker
279
+ * installServiceWorker(self);
280
+ * ```
281
+ */
282
+ declare const SW_TEMPLATE_HINT = "importScripts('caoguo-offline-sw.bundle.js'); installServiceWorker(self);";
283
+
284
+ /**
285
+ * IndexedDB 离线瓦片后端(浏览器环境,F-1.4)。
286
+ * 延迟依赖 idb;仅当运行在浏览器时加载,避免 Node/测试环境报错。
287
+ */
288
+
289
+ declare class IdbTileStore implements TileStoreBackend {
290
+ get(key: string): Promise<StoredTile | undefined>;
291
+ put(key: string, tile: StoredTile): Promise<void>;
292
+ has(key: string): Promise<boolean>;
293
+ delete(key: string): Promise<void>;
294
+ clear(prefix?: string): Promise<void>;
295
+ size(): Promise<number>;
296
+ }
297
+ /** 浏览器环境默认用 IndexedDB,否则回退内存 */
298
+ declare function createDefaultStore(): TileStoreBackend;
299
+
300
+ export { type AirgapMessage, CACHEABLE_HOSTS, CACHE_NAME, IdbTileStore, MSG_AIRGAP, MemoryTileStore, OFFLINE_PROTOCOL, type OfflineProtocolContext, type PackGeoJSONOptions, type ResolveResponseDeps, type ResolvedResponse, SW_TEMPLATE_HINT, type StoredTile, type TileFormat, type TileStoreBackend, createDefaultStore, createFetchHandler, createOfflineLoader, installServiceWorker, offlineGeoJSONSource, offlineSourceTiles, offlineTileUrl, packGeoJSONToStore, parseOfflineUrl, registerOfflineProtocol, registerOfflineServiceWorker, resolveCacheKey, resolveFromStore, resolveResponse, setAirgap, shouldCache, tileKey };
@@ -0,0 +1,300 @@
1
+ import { AddProtocolAction } from 'maplibre-gl';
2
+
3
+ /**
4
+ * 离线瓦片存储抽象层(F-1.4)。
5
+ *
6
+ * 设计:存储后端可插拔。浏览器用 IndexedDB(idb),Node/测试用内存实现。
7
+ * 瓦片 key 统一为 `${sourceId}:${z}:${x}:${y}`,value 为原始字节 + 过期时间。
8
+ */
9
+ type TileFormat = 'pbf' | 'geojson' | 'png' | 'mvt' | 'json';
10
+ interface StoredTile {
11
+ data: ArrayBuffer | Uint8Array;
12
+ format: TileFormat;
13
+ /** 过期时间戳(ms);0 表示永不过期 */
14
+ expires: number;
15
+ }
16
+ interface TileStoreBackend {
17
+ get(key: string): Promise<StoredTile | undefined>;
18
+ put(key: string, tile: StoredTile): Promise<void>;
19
+ has(key: string): Promise<boolean>;
20
+ delete(key: string): Promise<void>;
21
+ clear(prefix?: string): Promise<void>;
22
+ size(): Promise<number>;
23
+ }
24
+ /** 内存实现(测试 / 无 IndexedDB 环境) */
25
+ declare class MemoryTileStore implements TileStoreBackend {
26
+ private map;
27
+ get(key: string): Promise<StoredTile | undefined>;
28
+ put(key: string, tile: StoredTile): Promise<void>;
29
+ has(key: string): Promise<boolean>;
30
+ delete(key: string): Promise<void>;
31
+ clear(prefix?: string): Promise<void>;
32
+ size(): Promise<number>;
33
+ }
34
+ declare function tileKey(sourceId: string, z: number, x: number, y: number): string;
35
+ /** 离线协议名(caoguo-offline://...)。集中定义,供 protocol 与 serviceWorker 共用。 */
36
+ declare const OFFLINE_PROTOCOL = "caoguo-offline";
37
+ /**
38
+ * 解析离线协议 URL:`caoguo-offline://{sourceId}/{z}/{x}/{y}`
39
+ * 返回 sourceId 与瓦片坐标,便于 ProtocolHandler 取瓦片。
40
+ */
41
+ declare function parseOfflineUrl(url: string): {
42
+ sourceId: string;
43
+ z: number;
44
+ x: number;
45
+ y: number;
46
+ } | null;
47
+
48
+ /**
49
+ * 离线协议加载器(F-1.4)。
50
+ *
51
+ * 通过 MapLibre `addProtocol('caoguo-offline', loader)` 注册自定义协议,
52
+ * 瓦片源可声明 `tiles: ['caoguo-offline://{sourceId}/{z}/{x}/{y}']`,
53
+ * 引擎即从离线存储读取瓦片,实现「空气隔离」离线底图。
54
+ *
55
+ * MapLibre v4 的 protocol handler 签名:
56
+ * (requestParameters, abortController) => Promise<{ data: ArrayBuffer }>
57
+ */
58
+
59
+ interface OfflineProtocolContext {
60
+ store: TileStoreBackend;
61
+ }
62
+ /** 构造离线协议 URL(供 source.tiles 使用) */
63
+ declare function offlineTileUrl(sourceId: string, z: number, x: number, y: number): string;
64
+ /** 生成离线栅格/矢量源的 tiles 数组 */
65
+ declare function offlineSourceTiles(sourceId: string): string[];
66
+ /**
67
+ * 创建离线协议 loader(返回可直接传给 addProtocol 的异步函数)。
68
+ * 未命中瓦片时 reject,由 MapLibre 回退到线上源(若配置)。
69
+ */
70
+ declare function createOfflineLoader(ctx: OfflineProtocolContext): AddProtocolAction;
71
+ /** 在指定地图实例上注册离线协议 */
72
+ declare function registerOfflineProtocol(maplibregl: {
73
+ addProtocol: (name: string, action: AddProtocolAction) => void;
74
+ }, ctx: OfflineProtocolContext): void;
75
+
76
+ /**
77
+ * 离线瓦片打包器(F-1.4)。
78
+ *
79
+ * 把本地瓦片导入离线存储:
80
+ * - 原始 {z}/{x}/{y}.pbf|png 目录结构
81
+ * - 单张 GeoJSON(按 z/x/y 网格切片为矢量瓦片缓冲,供 `caoguo-offline` 协议读取)
82
+ *
83
+ * 这里的「切片」为简化实现:GeoJSON 按瓦片网格空间包含关系分桶,
84
+ * 仅把要素写入对应瓦片(不做 MVT 编码),存储为 UTF-8 JSON,
85
+ * 由 protocol loader 以 `geojson` 格式返回,source type 用 geojson。
86
+ * 生产级 MVT 编码(tippecanoe / @mapbox/vector-tile)可后续接入。
87
+ */
88
+
89
+ interface PackGeoJSONOptions {
90
+ sourceId: string;
91
+ geojson: {
92
+ type: 'FeatureCollection';
93
+ features: Array<{
94
+ geometry: {
95
+ type: string;
96
+ coordinates: unknown;
97
+ };
98
+ properties: Record<string, unknown>;
99
+ }>;
100
+ };
101
+ maxZoom?: number;
102
+ /** 过期时间(ms 时间戳),0=永不过期 */
103
+ expires?: number;
104
+ onProgress?: (done: number, total: number) => void;
105
+ }
106
+ /**
107
+ * 将 GeoJSON 按瓦片网格分桶写入离线存储。
108
+ * 返回写入的瓦片数量。
109
+ */
110
+ declare function packGeoJSONToStore(store: TileStoreBackend, opts: PackGeoJSONOptions): Promise<number>;
111
+ /**
112
+ * 由离线存储构造一个 geojson 源(用于 MapLibre source.tiles)。
113
+ * 注意:geojson 协议瓦片由 protocol loader 直接返回 FeatureCollection。
114
+ */
115
+ declare function offlineGeoJSONSource(sourceId: string): {
116
+ type: 'geojson';
117
+ data: never;
118
+ } & {
119
+ tiles: string[];
120
+ _caoguoOffline: true;
121
+ _sourceId: string;
122
+ };
123
+
124
+ /**
125
+ * Service Worker 离线拦截(T5 / F-1.6)。
126
+ *
127
+ * 目标:在 T4 离线瓦片(IndexedDB + caoguo-offline 协议)之上,增加一层
128
+ * **网络级二级缓存**——用 Cache API 缓存线上请求的瓦片(天地图等),并在
129
+ * 「空气隔离(air-gap)」模式下拦截所有请求、用 Cache/离线存储兜底,
130
+ * 实现断网后地图仍可平移缩放。
131
+ *
132
+ * 设计:
133
+ * - `resolveCacheKey` / `shouldCache` / `resolveResponse` 是**纯函数 core**,
134
+ * 不依赖真实 ServiceWorker 全局,可在 Node/vitest 中直接测试。
135
+ * - `createFetchHandler` 把 core 包装成标准 `fetch` 事件处理器(注入 cache 与 store)。
136
+ * - 浏览器侧用 `registerServiceWorker` 注册脚本,并通过 postMessage 切换空气隔离模式。
137
+ *
138
+ * 与 T4 的边界:T4 负责「业务离线瓦片 → IndexedDB → maplibre 协议」,
139
+ * 本模块负责「线上瓦片请求 → Cache API 二级缓存 + 空气隔离拦截」,
140
+ * 二者互补:T4 命中时根本不发网络请求(协议层短路),未命中时才走到 SW 缓存。
141
+ */
142
+
143
+ /** 需要二级缓存的瓦片来源(host 白名单,避免缓存无关资源) */
144
+ declare const CACHEABLE_HOSTS: string[];
145
+ /** 缓存名称(版本化,便于失效升级) */
146
+ declare const CACHE_NAME = "caoguo-offline-tiles-v1";
147
+ /** 空气隔离模式消息协议 */
148
+ declare const MSG_AIRGAP: "caoguo:airgap";
149
+ interface AirgapMessage {
150
+ type: typeof MSG_AIRGAP;
151
+ /** true=开启空气隔离(断网模式),false=恢复在线优先 */
152
+ enabled: boolean;
153
+ }
154
+ /**
155
+ * 判断请求是否应进入离线二级缓存。
156
+ * 只缓存 GET 请求 & 白名单 host & 图片/瓦片类型(保守策略)。
157
+ */
158
+ declare function shouldCache(request: {
159
+ method: string;
160
+ url: string;
161
+ }): boolean;
162
+ /**
163
+ * 计算 Cache Storage 的 key。优先用 URL(含 query,token 不同视为不同资源),
164
+ * 否则回退到 request 对象本身。
165
+ */
166
+ declare function resolveCacheKey(request: {
167
+ url: string;
168
+ }): string;
169
+ /**
170
+ * 从存储(IndexedDB/T4 离线)尝试取得瓦片兜底。
171
+ * 用于空气隔离模式下网络不可达时返回上次离线打包的瓦片。
172
+ */
173
+ declare function resolveFromStore(store: TileStoreBackend | undefined, request: {
174
+ url: string;
175
+ }): Promise<{
176
+ data: ArrayBuffer;
177
+ contentType: string;
178
+ } | undefined>;
179
+ interface ResolveResponseDeps {
180
+ /** 实际的 fetch 实现(浏览器为全局 fetch,测试可注入) */
181
+ fetchImpl: (input: string) => Promise<{
182
+ ok: boolean;
183
+ status: number;
184
+ arrayBuffer: () => Promise<ArrayBuffer>;
185
+ headers: {
186
+ get: (k: string) => string | null;
187
+ };
188
+ }>;
189
+ /** Cache 接口(浏览器为全局 caches,测试可注入内存实现) */
190
+ cache: {
191
+ match: (key: string) => Promise<CacheEntry | undefined>;
192
+ put: (key: string, resp: unknown) => Promise<void>;
193
+ };
194
+ /** 空气隔离开关(闭包状态,由消息控制) */
195
+ airgap: {
196
+ enabled: boolean;
197
+ };
198
+ /** T4 离线存储(可选,空气隔离兜底) */
199
+ store?: TileStoreBackend;
200
+ }
201
+ interface CacheEntry {
202
+ ok: boolean;
203
+ status: number;
204
+ arrayBuffer: () => Promise<ArrayBuffer>;
205
+ headers: {
206
+ get: (k: string) => string | null;
207
+ };
208
+ }
209
+ interface ResolvedResponse {
210
+ /** 最终响应主体 */
211
+ data: ArrayBuffer;
212
+ /** 内容类型 */
213
+ contentType: string;
214
+ /** 来源:cache=命中缓存 / network=线上最新 / store=离线存储兜底 */
215
+ source: 'cache' | 'network' | 'store';
216
+ /** 该响应是否应写回缓存 */
217
+ cacheable: boolean;
218
+ }
219
+ /**
220
+ * 核心解析逻辑(纯函数,可测试)。
221
+ * 两种模式:
222
+ * - 在线优先(airgap=false):cache → network(写回 cache) → store 兜底
223
+ * - 空气隔离(airgap=true):cache → store 兜底(不发网络请求)
224
+ */
225
+ declare function resolveResponse(request: {
226
+ method: string;
227
+ url: string;
228
+ }, deps: ResolveResponseDeps): Promise<ResolvedResponse | null>;
229
+ /**
230
+ * 包装为 Service Worker 的 fetch 事件处理器。
231
+ * 注入真实的 caches / fetch / store。在浏览器 SW 全局中调用:
232
+ * self.addEventListener('fetch', createFetchHandler({ store }));
233
+ */
234
+ declare function createFetchHandler(opts: {
235
+ store?: TileStoreBackend;
236
+ airgap?: {
237
+ enabled: boolean;
238
+ };
239
+ }): (event: {
240
+ request: {
241
+ method: string;
242
+ url: string;
243
+ };
244
+ respondWith: (r: Promise<Response> | Response) => void;
245
+ }) => void;
246
+ /**
247
+ * 在 Service Worker 全局上安装离线拦截逻辑(浏览器 SW 脚本入口)。
248
+ * 处理 install/activate 生命周期、airgap 消息、fetch 拦截。
249
+ */
250
+ declare function installServiceWorker(sw: {
251
+ addEventListener: (type: string, handler: (ev: unknown) => void) => void;
252
+ caches: unknown;
253
+ store?: TileStoreBackend;
254
+ }): {
255
+ airgap: {
256
+ enabled: boolean;
257
+ };
258
+ };
259
+ /**
260
+ * 浏览器端注册离线 Service Worker(主线程调用)。
261
+ * 需要项目提供 SW 脚本文件(见 `sw-template` 注释),并部署到与地图同域根路径。
262
+ *
263
+ * @param scriptUrl SW 脚本 URL(如 '/caoguo-sw.js'),需调用方自行构建/放置
264
+ * @returns 注册成功的 ServiceWorker 实例;不支持时返回 null
265
+ */
266
+ declare function registerOfflineServiceWorker(scriptUrl: string): Promise<ServiceWorkerRegistration | null>;
267
+ /**
268
+ * 向已注册的 Service Worker 发送消息,切换「空气隔离」模式。
269
+ * enabled=true 时地图进入断网可用状态(仅用 Cache + T4 离线存储)。
270
+ */
271
+ declare function setAirgap(registration: ServiceWorkerRegistration, enabled: boolean): void;
272
+ /**
273
+ * SW 脚本模板(供调用方写入部署文件,如 public/caoguo-sw.js)。
274
+ * 该脚本通过 importScripts 复用本包编译产物,或直接内联 installServiceWorker。
275
+ *
276
+ * ```js
277
+ * // caoguo-sw.js
278
+ * importScripts('/caoguo-offline-sw.bundle.js'); // 含 installServiceWorker
279
+ * installServiceWorker(self);
280
+ * ```
281
+ */
282
+ declare const SW_TEMPLATE_HINT = "importScripts('caoguo-offline-sw.bundle.js'); installServiceWorker(self);";
283
+
284
+ /**
285
+ * IndexedDB 离线瓦片后端(浏览器环境,F-1.4)。
286
+ * 延迟依赖 idb;仅当运行在浏览器时加载,避免 Node/测试环境报错。
287
+ */
288
+
289
+ declare class IdbTileStore implements TileStoreBackend {
290
+ get(key: string): Promise<StoredTile | undefined>;
291
+ put(key: string, tile: StoredTile): Promise<void>;
292
+ has(key: string): Promise<boolean>;
293
+ delete(key: string): Promise<void>;
294
+ clear(prefix?: string): Promise<void>;
295
+ size(): Promise<number>;
296
+ }
297
+ /** 浏览器环境默认用 IndexedDB,否则回退内存 */
298
+ declare function createDefaultStore(): TileStoreBackend;
299
+
300
+ export { type AirgapMessage, CACHEABLE_HOSTS, CACHE_NAME, IdbTileStore, MSG_AIRGAP, MemoryTileStore, OFFLINE_PROTOCOL, type OfflineProtocolContext, type PackGeoJSONOptions, type ResolveResponseDeps, type ResolvedResponse, SW_TEMPLATE_HINT, type StoredTile, type TileFormat, type TileStoreBackend, createDefaultStore, createFetchHandler, createOfflineLoader, installServiceWorker, offlineGeoJSONSource, offlineSourceTiles, offlineTileUrl, packGeoJSONToStore, parseOfflineUrl, registerOfflineProtocol, registerOfflineServiceWorker, resolveCacheKey, resolveFromStore, resolveResponse, setAirgap, shouldCache, tileKey };
@@ -0,0 +1,3 @@
1
+ export { CACHEABLE_HOSTS, CACHE_NAME, IdbTileStore, MSG_AIRGAP, MemoryTileStore, OFFLINE_PROTOCOL, SW_TEMPLATE_HINT, createDefaultStore, createFetchHandler, createOfflineLoader, installServiceWorker, offlineGeoJSONSource, offlineSourceTiles, offlineTileUrl, packGeoJSONToStore, parseOfflineUrl, registerOfflineProtocol, registerOfflineServiceWorker, resolveCacheKey, resolveFromStore, resolveResponse, setAirgap, shouldCache, tileKey } from '../chunk-MNUQZUQA.js';
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}