@honua/app-platform 0.1.2-beta.0 → 0.1.7-beta.0

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.
Files changed (400) hide show
  1. package/app/index.d.ts.map +1 -1
  2. package/app/index.js +4 -0
  3. package/collaboration/client.d.ts.map +1 -1
  4. package/connect-url-safety.d.ts +53 -0
  5. package/connect-url-safety.js +189 -0
  6. package/contract/discovery.d.ts +34 -0
  7. package/contract/discovery.d.ts.map +1 -1
  8. package/contract/index.d.ts +7 -5
  9. package/contract/index.d.ts.map +1 -1
  10. package/contract/index.js +3 -2
  11. package/contract/pmtiles.d.ts +10 -1
  12. package/contract/pmtiles.d.ts.map +1 -1
  13. package/contract/pmtiles.js +10 -2
  14. package/contract/protocol-module.d.ts +84 -9
  15. package/contract/protocol-module.d.ts.map +1 -1
  16. package/contract/query-filter-fes.d.ts +18 -0
  17. package/contract/query-filter-fes.d.ts.map +1 -0
  18. package/contract/query-filter-fes.js +122 -0
  19. package/contract/query-filter.d.ts +300 -0
  20. package/contract/query-filter.d.ts.map +1 -0
  21. package/contract/query-filter.js +883 -0
  22. package/contract/schema.d.ts +12 -0
  23. package/contract/schema.d.ts.map +1 -1
  24. package/contract/schema.js +34 -0
  25. package/contract/source-capability-support.d.ts.map +1 -1
  26. package/contract/source-capability-support.js +15 -3
  27. package/contract/source.d.ts +45 -25
  28. package/contract/source.d.ts.map +1 -1
  29. package/contract/source.js +719 -479
  30. package/contract/types.d.ts +88 -19
  31. package/contract/types.d.ts.map +1 -1
  32. package/contract/types.js +4 -0
  33. package/contract/widget-source.d.ts.map +1 -1
  34. package/controls/basemap-switcher.d.ts +19 -11
  35. package/controls/basemap-switcher.d.ts.map +1 -1
  36. package/controls/basemap-switcher.js +58 -25
  37. package/controls/catalog.d.ts +105 -0
  38. package/controls/catalog.d.ts.map +1 -0
  39. package/controls/catalog.js +341 -0
  40. package/controls/element-utils.d.ts +9 -0
  41. package/controls/element-utils.d.ts.map +1 -1
  42. package/controls/element-utils.js +17 -0
  43. package/controls/index.d.ts +29 -8
  44. package/controls/index.d.ts.map +1 -1
  45. package/controls/index.js +26 -8
  46. package/controls/layer-list.d.ts +13 -5
  47. package/controls/layer-list.d.ts.map +1 -1
  48. package/controls/layer-list.js +72 -15
  49. package/controls/legend.d.ts +32 -5
  50. package/controls/legend.d.ts.map +1 -1
  51. package/controls/legend.js +95 -25
  52. package/controls/qualification.d.ts +152 -0
  53. package/controls/qualification.d.ts.map +1 -0
  54. package/controls/qualification.js +1265 -0
  55. package/controls/registry.d.ts +104 -0
  56. package/controls/registry.d.ts.map +1 -0
  57. package/controls/registry.js +150 -0
  58. package/controls/swipe-control.d.ts +6 -1
  59. package/controls/swipe-control.d.ts.map +1 -1
  60. package/controls/swipe-control.js +82 -20
  61. package/core/client.d.ts +51 -21
  62. package/core/client.d.ts.map +1 -1
  63. package/core/client.js +234 -54
  64. package/core/error-classifications.d.ts +23 -0
  65. package/core/error-classifications.d.ts.map +1 -1
  66. package/core/error-classifications.js +23 -0
  67. package/core/error-code-registry.d.ts +24 -1
  68. package/core/error-code-registry.d.ts.map +1 -1
  69. package/core/error-code-registry.js +23 -0
  70. package/core/error-envelope.js +2 -0
  71. package/core/errors.d.ts +2 -2
  72. package/core/errors.d.ts.map +1 -1
  73. package/core/errors.js +1 -1
  74. package/core/geoparquet-sql.d.ts +69 -5
  75. package/core/geoparquet-sql.d.ts.map +1 -1
  76. package/core/geoparquet-sql.js +327 -10
  77. package/core/odata-write-codec.d.ts.map +1 -1
  78. package/core/odata-write-codec.js +0 -1
  79. package/core/odata.d.ts +6 -0
  80. package/core/odata.d.ts.map +1 -1
  81. package/core/odata.js +6 -1
  82. package/core/ogc-processes.d.ts +182 -25
  83. package/core/ogc-processes.d.ts.map +1 -1
  84. package/core/ogc-processes.js +602 -30
  85. package/core/process-runner.d.ts +8 -1
  86. package/core/process-runner.d.ts.map +1 -1
  87. package/core/process-runner.js +1 -0
  88. package/core/protocol-transport.d.ts +2 -0
  89. package/core/protocol-transport.d.ts.map +1 -1
  90. package/core/stac.d.ts +32 -0
  91. package/core/stac.d.ts.map +1 -1
  92. package/core/stac.js +158 -23
  93. package/core/surfaces.d.ts.map +1 -1
  94. package/core/surfaces.js +273 -68
  95. package/core/types.d.ts +138 -11
  96. package/core/types.d.ts.map +1 -1
  97. package/core/wfs-axis-order.d.ts +18 -0
  98. package/core/wfs-axis-order.d.ts.map +1 -0
  99. package/core/wfs-axis-order.js +108 -0
  100. package/core/wfs-capabilities.d.ts +65 -24
  101. package/core/wfs-capabilities.d.ts.map +1 -1
  102. package/core/wfs-capabilities.js +237 -27
  103. package/core/wfs-filter.d.ts +26 -3
  104. package/core/wfs-filter.d.ts.map +1 -1
  105. package/core/wfs-filter.js +48 -53
  106. package/core/wfs-protocol-error.d.ts +12 -0
  107. package/core/wfs-protocol-error.d.ts.map +1 -0
  108. package/core/wfs-protocol-error.js +13 -0
  109. package/core/wfs.d.ts +53 -1
  110. package/core/wfs.d.ts.map +1 -1
  111. package/core/wfs.js +251 -29
  112. package/core/wms-feature-info.d.ts +92 -0
  113. package/core/wms-feature-info.d.ts.map +1 -0
  114. package/core/wms-feature-info.js +285 -0
  115. package/core/wms.d.ts +9 -0
  116. package/core/wms.d.ts.map +1 -1
  117. package/core/wms.js +17 -5
  118. package/esri-compat/event-bus.d.ts +20 -0
  119. package/esri-compat/event-bus.d.ts.map +1 -1
  120. package/esri-compat/feature-filter.d.ts +46 -1
  121. package/esri-compat/feature-filter.d.ts.map +1 -1
  122. package/esri-compat/feature-filter.js +49 -0
  123. package/esri-compat/geojson-layer.d.ts +4 -2
  124. package/esri-compat/geojson-layer.d.ts.map +1 -1
  125. package/esri-compat/geojson-layer.js +4 -2
  126. package/esri-compat/identity-manager.js +2 -2
  127. package/esri-compat/imagery-layer.d.ts +2 -1
  128. package/esri-compat/imagery-layer.d.ts.map +1 -1
  129. package/esri-compat/imagery-layer.js +2 -1
  130. package/esri-compat/layer-list.d.ts +8 -1
  131. package/esri-compat/layer-list.d.ts.map +1 -1
  132. package/esri-compat/layer-list.js +11 -4
  133. package/esri-compat/legend.d.ts.map +1 -1
  134. package/esri-compat/legend.js +1 -1
  135. package/esri-compat/locator.d.ts +297 -0
  136. package/esri-compat/locator.d.ts.map +1 -0
  137. package/esri-compat/locator.js +579 -0
  138. package/esri-compat/map-image-layer.d.ts.map +1 -1
  139. package/esri-compat/map-view.d.ts.map +1 -1
  140. package/esri-compat/map-view.js +1 -1
  141. package/esri-compat/scene-view.d.ts.map +1 -1
  142. package/esri-compat/time-slider.d.ts +29 -0
  143. package/esri-compat/time-slider.d.ts.map +1 -1
  144. package/esri-compat/time-slider.js +117 -0
  145. package/esri-compat/wfs-layer.d.ts +2 -1
  146. package/esri-compat/wfs-layer.d.ts.map +1 -1
  147. package/esri-compat/wfs-layer.js +2 -1
  148. package/esri-compat/widget-host.d.ts +42 -6
  149. package/esri-compat/widget-host.d.ts.map +1 -1
  150. package/esri-compat/widget-host.js +99 -10
  151. package/generated-app/projection.d.ts.map +1 -1
  152. package/generated-app/runtime.d.ts.map +1 -1
  153. package/interactions/declarative-contract.d.ts +149 -0
  154. package/interactions/declarative-contract.d.ts.map +1 -0
  155. package/interactions/declarative-contract.js +293 -0
  156. package/interactions/declarative.d.ts +198 -0
  157. package/interactions/declarative.d.ts.map +1 -0
  158. package/interactions/declarative.js +470 -0
  159. package/interactions/feature-state.d.ts +7 -0
  160. package/interactions/feature-state.d.ts.map +1 -1
  161. package/interactions/feature-state.js +10 -2
  162. package/map/data-to-map-bridge.d.ts +1 -1
  163. package/map/data-to-map-bridge.d.ts.map +1 -1
  164. package/map/data-to-map-bridge.js +1 -2
  165. package/map/honua-map.d.ts.map +1 -1
  166. package/map/honua-map.js +1 -1
  167. package/map/index.d.ts +2 -0
  168. package/map/index.d.ts.map +1 -1
  169. package/map/index.js +2 -0
  170. package/map/maplibre-target.js +1 -1
  171. package/map/realtime-reconciliation-adapter.d.ts +98 -0
  172. package/map/realtime-reconciliation-adapter.d.ts.map +1 -0
  173. package/map/realtime-reconciliation-adapter.js +84 -0
  174. package/map/temporal-playback.d.ts +25 -0
  175. package/map/temporal-playback.d.ts.map +1 -1
  176. package/map/temporal-playback.js +29 -1
  177. package/operator/workspace/workspace.d.ts.map +1 -1
  178. package/operator/workspace/workspace.js +0 -2
  179. package/package.json +4 -3
  180. package/query-planner/canonical-filter.d.ts +30 -0
  181. package/query-planner/canonical-filter.d.ts.map +1 -0
  182. package/query-planner/canonical-filter.js +30 -0
  183. package/query-planner/columnar-plan.d.ts +63 -0
  184. package/query-planner/columnar-plan.d.ts.map +1 -0
  185. package/query-planner/columnar-plan.js +94 -0
  186. package/query-planner/diagnostics.d.ts +3 -3
  187. package/query-planner/diagnostics.d.ts.map +1 -1
  188. package/query-planner/diagnostics.js +17 -4
  189. package/query-planner/duckdb.d.ts.map +1 -1
  190. package/query-planner/duckdb.js +16 -2
  191. package/query-planner/execution-context.d.ts.map +1 -1
  192. package/query-planner/execution-context.js +3 -1
  193. package/query-planner/executor.d.ts.map +1 -1
  194. package/query-planner/executor.js +7 -1
  195. package/query-planner/geoservices.d.ts.map +1 -1
  196. package/query-planner/geoservices.js +24 -5
  197. package/query-planner/grpc.d.ts.map +1 -1
  198. package/query-planner/grpc.js +29 -5
  199. package/query-planner/index.d.ts +20 -5
  200. package/query-planner/index.d.ts.map +1 -1
  201. package/query-planner/index.js +16 -3
  202. package/query-planner/ir.d.ts +6 -1
  203. package/query-planner/ir.d.ts.map +1 -1
  204. package/query-planner/ir.js +63 -1
  205. package/query-planner/odata-protocol-module.d.ts +54 -0
  206. package/query-planner/odata-protocol-module.d.ts.map +1 -0
  207. package/query-planner/odata-protocol-module.js +199 -0
  208. package/query-planner/odata-v1.d.ts +23 -0
  209. package/query-planner/odata-v1.d.ts.map +1 -0
  210. package/query-planner/odata-v1.js +202 -0
  211. package/query-planner/odata.d.ts +0 -3
  212. package/query-planner/odata.d.ts.map +1 -1
  213. package/query-planner/odata.js +0 -143
  214. package/query-planner/ogc-features.d.ts.map +1 -1
  215. package/query-planner/ogc-features.js +23 -1
  216. package/query-planner/planner.d.ts +2 -2
  217. package/query-planner/planner.d.ts.map +1 -1
  218. package/query-planner/planner.js +146 -27
  219. package/query-planner/representation.d.ts +59 -0
  220. package/query-planner/representation.d.ts.map +1 -0
  221. package/query-planner/representation.js +140 -0
  222. package/query-planner/types.d.ts +153 -3
  223. package/query-planner/types.d.ts.map +1 -1
  224. package/query-planner/wfs-protocol-module.d.ts +57 -0
  225. package/query-planner/wfs-protocol-module.d.ts.map +1 -0
  226. package/query-planner/wfs-protocol-module.js +731 -0
  227. package/query-planner/wfs-v1.d.ts +41 -0
  228. package/query-planner/wfs-v1.d.ts.map +1 -0
  229. package/query-planner/wfs-v1.js +366 -0
  230. package/query-planner/wfs.d.ts +1 -3
  231. package/query-planner/wfs.d.ts.map +1 -1
  232. package/query-planner/wfs.js +1 -70
  233. package/realtime/checkpoint-store.d.ts +206 -0
  234. package/realtime/checkpoint-store.d.ts.map +1 -0
  235. package/realtime/checkpoint-store.js +504 -0
  236. package/realtime/honua-server.d.ts +8 -0
  237. package/realtime/honua-server.d.ts.map +1 -1
  238. package/realtime/honua-server.js +123 -14
  239. package/realtime/index.d.ts +4 -0
  240. package/realtime/index.d.ts.map +1 -1
  241. package/realtime/index.js +2 -0
  242. package/realtime/reconciliation.d.ts +245 -0
  243. package/realtime/reconciliation.d.ts.map +1 -0
  244. package/realtime/reconciliation.js +377 -0
  245. package/realtime/resumable-transport.d.ts.map +1 -1
  246. package/realtime/sse.d.ts.map +1 -1
  247. package/realtime/sse.js +7 -1
  248. package/realtime/websocket.d.ts.map +1 -1
  249. package/realtime/wire.d.ts +2 -1
  250. package/realtime/wire.d.ts.map +1 -1
  251. package/realtime/wire.js +24 -8
  252. package/replica-sync/errors.d.ts +19 -1
  253. package/replica-sync/errors.d.ts.map +1 -1
  254. package/replica-sync/errors.js +16 -0
  255. package/replica-sync/geoservices.d.ts +260 -0
  256. package/replica-sync/geoservices.d.ts.map +1 -0
  257. package/replica-sync/geoservices.js +1093 -0
  258. package/replica-sync/index.d.ts +5 -1
  259. package/replica-sync/index.d.ts.map +1 -1
  260. package/replica-sync/index.js +3 -1
  261. package/replica-sync/transport-conformance.d.ts +58 -0
  262. package/replica-sync/transport-conformance.d.ts.map +1 -0
  263. package/replica-sync/transport-conformance.js +265 -0
  264. package/replica-sync/types.d.ts +22 -0
  265. package/replica-sync/types.d.ts.map +1 -1
  266. package/runtime/index.d.ts +6 -2
  267. package/runtime/index.d.ts.map +1 -1
  268. package/runtime/index.js +3 -1
  269. package/runtime/load-package.d.ts +24 -0
  270. package/runtime/load-package.d.ts.map +1 -1
  271. package/runtime/load-package.js +45 -1
  272. package/runtime/maplibre-renderer.d.ts +11 -0
  273. package/runtime/maplibre-renderer.d.ts.map +1 -1
  274. package/runtime/maplibre-renderer.js +32 -7
  275. package/runtime/offline-region-protocol.d.ts +73 -0
  276. package/runtime/offline-region-protocol.d.ts.map +1 -0
  277. package/runtime/offline-region-protocol.js +63 -0
  278. package/runtime/offline-region-style.d.ts +78 -0
  279. package/runtime/offline-region-style.d.ts.map +1 -0
  280. package/runtime/offline-region-style.js +147 -0
  281. package/runtime/pmtiles-protocol.d.ts +7 -8
  282. package/runtime/pmtiles-protocol.d.ts.map +1 -1
  283. package/runtime/pmtiles-protocol.js +19 -66
  284. package/runtime/protocol-registry.d.ts +55 -0
  285. package/runtime/protocol-registry.d.ts.map +1 -0
  286. package/runtime/protocol-registry.js +103 -0
  287. package/runtime/runtime.d.ts +2 -0
  288. package/runtime/runtime.d.ts.map +1 -1
  289. package/runtime/runtime.js +6 -1
  290. package/runtime/style-compose.d.ts.map +1 -1
  291. package/runtime/style-compose.js +78 -9
  292. package/scene-workspace/analysis-widgets.d.ts +4 -2
  293. package/scene-workspace/analysis-widgets.d.ts.map +1 -1
  294. package/scene-workspace/analysis-widgets.js +4 -2
  295. package/scene-workspace/camera-correspondence.d.ts +151 -0
  296. package/scene-workspace/camera-correspondence.d.ts.map +1 -0
  297. package/scene-workspace/camera-correspondence.js +220 -0
  298. package/scene-workspace/cesium-adapter.d.ts +230 -29
  299. package/scene-workspace/cesium-adapter.d.ts.map +1 -1
  300. package/scene-workspace/cesium-adapter.js +741 -56
  301. package/scene-workspace/cesium-mount.d.ts +205 -0
  302. package/scene-workspace/cesium-mount.d.ts.map +1 -0
  303. package/scene-workspace/cesium-mount.js +392 -0
  304. package/scene-workspace/cesium-scene-owner.d.ts +160 -0
  305. package/scene-workspace/cesium-scene-owner.d.ts.map +1 -0
  306. package/scene-workspace/cesium-scene-owner.js +205 -0
  307. package/scene-workspace/cesium-state-sync.d.ts +101 -0
  308. package/scene-workspace/cesium-state-sync.d.ts.map +1 -0
  309. package/scene-workspace/cesium-state-sync.js +432 -0
  310. package/scene-workspace/cesium-time.d.ts +346 -0
  311. package/scene-workspace/cesium-time.d.ts.map +1 -0
  312. package/scene-workspace/cesium-time.js +403 -0
  313. package/scene-workspace/index.d.ts +42 -10
  314. package/scene-workspace/index.d.ts.map +1 -1
  315. package/scene-workspace/index.js +32 -7
  316. package/scene-workspace/maplibre-state-sync.d.ts +112 -0
  317. package/scene-workspace/maplibre-state-sync.d.ts.map +1 -0
  318. package/scene-workspace/maplibre-state-sync.js +400 -0
  319. package/scene-workspace/primitives.d.ts +237 -3
  320. package/scene-workspace/primitives.d.ts.map +1 -1
  321. package/scene-workspace/primitives.js +1087 -17
  322. package/scene-workspace/scene-discovery.d.ts +5 -2
  323. package/scene-workspace/scene-discovery.d.ts.map +1 -1
  324. package/scene-workspace/scene-discovery.js +5 -2
  325. package/scene-workspace/scene-view.d.ts +5 -2
  326. package/scene-workspace/scene-view.d.ts.map +1 -1
  327. package/scene-workspace/scene-view.js +5 -2
  328. package/scene-workspace/source-to-cesium.d.ts +141 -8
  329. package/scene-workspace/source-to-cesium.d.ts.map +1 -1
  330. package/scene-workspace/source-to-cesium.js +497 -72
  331. package/scene-workspace/state-sync-port-kit.d.ts +156 -0
  332. package/scene-workspace/state-sync-port-kit.d.ts.map +1 -0
  333. package/scene-workspace/state-sync-port-kit.js +319 -0
  334. package/scene-workspace/state-sync.d.ts +34 -1
  335. package/scene-workspace/state-sync.d.ts.map +1 -1
  336. package/scene-workspace/state-sync.js +48 -0
  337. package/scene-workspace/types.d.ts +8 -0
  338. package/scene-workspace/types.d.ts.map +1 -1
  339. package/scene-workspace/types.js +2 -0
  340. package/scene-workspace/workspace.d.ts +12 -1
  341. package/scene-workspace/workspace.d.ts.map +1 -1
  342. package/scene-workspace/workspace.js +13 -0
  343. package/studio/index.d.ts +24 -7
  344. package/studio/index.d.ts.map +1 -1
  345. package/studio/index.js +21 -7
  346. package/studio/lifecycle-client.d.ts +164 -0
  347. package/studio/lifecycle-client.d.ts.map +1 -0
  348. package/studio/lifecycle-client.js +299 -0
  349. package/studio/lifecycle-errors.d.ts +91 -0
  350. package/studio/lifecycle-errors.d.ts.map +1 -0
  351. package/studio/lifecycle-errors.js +77 -0
  352. package/studio/lifecycle-types.d.ts +321 -0
  353. package/studio/lifecycle-types.d.ts.map +1 -0
  354. package/studio/lifecycle-types.js +22 -0
  355. package/web-components/controller.d.ts.map +1 -1
  356. package/web-components/csp-styles.d.ts +6 -0
  357. package/web-components/csp-styles.d.ts.map +1 -0
  358. package/web-components/csp-styles.js +53 -0
  359. package/web-components/elements.d.ts +158 -2
  360. package/web-components/elements.d.ts.map +1 -1
  361. package/web-components/elements.js +1302 -215
  362. package/web-components/export-redaction.d.ts +252 -0
  363. package/web-components/export-redaction.d.ts.map +1 -0
  364. package/web-components/export-redaction.js +588 -0
  365. package/web-components/export.d.ts +417 -0
  366. package/web-components/export.d.ts.map +1 -0
  367. package/web-components/export.js +719 -0
  368. package/web-components/feature-editor-model.d.ts +265 -0
  369. package/web-components/feature-editor-model.d.ts.map +1 -0
  370. package/web-components/feature-editor-model.js +438 -0
  371. package/web-components/feature-editor-sketch.d.ts +125 -0
  372. package/web-components/feature-editor-sketch.d.ts.map +1 -0
  373. package/web-components/feature-editor-sketch.js +194 -0
  374. package/web-components/feature-editor-workflow.d.ts +286 -0
  375. package/web-components/feature-editor-workflow.d.ts.map +1 -0
  376. package/web-components/feature-editor-workflow.js +889 -0
  377. package/web-components/feature-editor.d.ts +83 -0
  378. package/web-components/feature-editor.d.ts.map +1 -0
  379. package/web-components/feature-editor.js +829 -0
  380. package/web-components/feature-table-engine.d.ts +465 -0
  381. package/web-components/feature-table-engine.d.ts.map +1 -0
  382. package/web-components/feature-table-engine.js +1360 -0
  383. package/web-components/feature-table-view.d.ts +95 -0
  384. package/web-components/feature-table-view.d.ts.map +1 -0
  385. package/web-components/feature-table-view.js +343 -0
  386. package/web-components/index.d.ts +34 -3
  387. package/web-components/index.d.ts.map +1 -1
  388. package/web-components/index.js +35 -2
  389. package/web-components/maplibre-renderer.d.ts.map +1 -1
  390. package/web-components/maplibre-renderer.js +13 -4
  391. package/web-components/measurement.d.ts +3 -1
  392. package/web-components/measurement.d.ts.map +1 -1
  393. package/web-components/measurement.js +62 -18
  394. package/web-components/time-slider.d.ts +122 -0
  395. package/web-components/time-slider.d.ts.map +1 -0
  396. package/web-components/time-slider.js +740 -0
  397. package/web-components/types.d.ts +310 -0
  398. package/web-components/types.d.ts.map +1 -1
  399. package/webmap/convert-label.js +0 -1
  400. package/webmap/convert-symbol.d.ts.map +1 -1
@@ -11,6 +11,8 @@ import { createDataset } from "../contract/index.js";
11
11
  import { HonuaMap } from "../map/honua-map.js";
12
12
  import { HonuaMapPackageError } from "./errors.js";
13
13
  import { HONUA_MAP_PACKAGE_FORMAT_V1 } from "./map-package.js";
14
+ import { OFFLINE_REGION_PROTOCOL_SCHEME, ensureOfflineRegionProtocol, styleUsesOfflineRegion, } from "./offline-region-protocol.js";
15
+ import { rewriteStyleTilesForOfflineRegion } from "./offline-region-style.js";
14
16
  import { createOgcStyleRefResolver } from "./ogc-styles.js";
15
17
  import { ensurePmtilesProtocol, styleUsesPmtiles } from "./pmtiles-protocol.js";
16
18
  import { HonuaMapRuntime, } from "./runtime.js";
@@ -18,6 +20,29 @@ import { projectSourceBindings, toHonuaSourceSpec } from "./source-bridge.js";
18
20
  import { composeStyle } from "./style-compose.js";
19
21
  import { throwRuntimeDiagnostics } from "./style-interactions.js";
20
22
  import { prepareRuntimeStyleSpecValidation } from "./style-spec-validation.js";
23
+ /**
24
+ * Point the named sources at the region, or fail the load.
25
+ *
26
+ * A refusal is fatal here on purpose: the caller named these sources precisely
27
+ * because they must come from storage, so leaving one on its network template
28
+ * would render live tiles while the application believed it was offline-backed.
29
+ */
30
+ function bindOfflineRegionStyle(style, packageId, region) {
31
+ if (!region?.sourceIds || region.sourceIds.length === 0)
32
+ return style;
33
+ const rewrite = rewriteStyleTilesForOfflineRegion(style, {
34
+ sourceIds: region.sourceIds,
35
+ ...(region.tileMatrixSetId !== undefined ? { tileMatrixSetId: region.tileMatrixSetId } : {}),
36
+ });
37
+ if (rewrite.refusals.length > 0) {
38
+ throw new HonuaMapPackageError("offline-region style binding refused a source it cannot rewrite exactly", {
39
+ ...(packageId === undefined ? {} : { packageId }),
40
+ stage: "style-compose",
41
+ detail: { refusals: rewrite.refusals },
42
+ });
43
+ }
44
+ return rewrite.style;
45
+ }
21
46
  /**
22
47
  * Load a `MapPackage` onto a caller-provided `MaplibreMap`. Returns a
23
48
  * runtime handle that exposes the operational API. Throws
@@ -121,10 +146,11 @@ export async function loadMapPackage(pkg, map, options) {
121
146
  if (!honuaMap.hasLayer(layer.id))
122
147
  honuaMap.addLayer(layer);
123
148
  }
124
- const composed = await composeStyle(target, preComposed, {
149
+ const styled = await composeStyle(target, preComposed, {
125
150
  resolveStyleRef: styleRefResolver,
126
151
  resolveTheme: options.resolveTheme,
127
152
  });
153
+ const composed = bindOfflineRegionStyle(styled, target.mapPackageId, options.offlineRegion);
128
154
  // Auto-register the MapLibre `pmtiles://` protocol before the caller (or
129
155
  // `runtime.reload`) hands this style to `map.setStyle`, so PMTiles-backed
130
156
  // sources render with no manual `addProtocol` wiring. Idempotent across
@@ -132,6 +158,24 @@ export async function loadMapPackage(pkg, map, options) {
132
158
  if (styleUsesPmtiles(composed)) {
133
159
  await ensurePmtilesProtocol();
134
160
  }
161
+ // Same contract for a persisted offline region: register on the evidence of
162
+ // the composed style, and refuse to hand MapLibre a style that addresses a
163
+ // region without the handler that can answer it — a missing handler renders
164
+ // blank tiles instead of failing.
165
+ if (styleUsesOfflineRegion(composed)) {
166
+ const region = options.offlineRegion;
167
+ if (!region) {
168
+ throw new HonuaMapPackageError("the composed style addresses an offline region but no offlineRegion tile handler was supplied", {
169
+ packageId: target.mapPackageId,
170
+ stage: "style-compose",
171
+ detail: { scheme: OFFLINE_REGION_PROTOCOL_SCHEME },
172
+ });
173
+ }
174
+ await ensureOfflineRegionProtocol({
175
+ tileHandler: region.tileHandler,
176
+ ...(region.maplibre ? { maplibre: region.maplibre } : {}),
177
+ });
178
+ }
135
179
  return { composed, dataset, honuaMap, failedSources };
136
180
  };
137
181
  try {
@@ -1,5 +1,6 @@
1
1
  import type { RendererAdapter } from "../kernel/renderer.js";
2
2
  import { type ExplainAutomaticMapLibreOptions, type SourceToMapLibreMap } from "../map/index.js";
3
+ import { type OfflineRegionTileHandler } from "./offline-region-protocol.js";
3
4
  import type { PmtilesProtocolModuleLike } from "./pmtiles-protocol.js";
4
5
  /** MapLibre module slice consumed from the caller-injected optional peer. */
5
6
  export interface MapLibreRendererPeer {
@@ -30,6 +31,16 @@ export interface MapLibreRendererOptions extends Omit<ExplainAutomaticMapLibreOp
30
31
  readonly mapOptions?: Readonly<Record<string, unknown>>;
31
32
  /** Defaults to `render`, the first frame that can contain the mounted layer. */
32
33
  readonly firstFrameEvent?: "render" | "idle";
34
+ /**
35
+ * Tile handler for a style that addresses a persisted offline region.
36
+ *
37
+ * Registered before an owned map is constructed, but only when the style
38
+ * actually references the `offline-region://` scheme. A style that references
39
+ * it without a handler fails construction instead of rendering blank tiles.
40
+ */
41
+ readonly offlineRegion?: {
42
+ readonly tileHandler: OfflineRegionTileHandler;
43
+ };
33
44
  }
34
45
  /**
35
46
  * Create an executable MapLibre adapter without importing `maplibre-gl`.
@@ -1 +1 @@
1
- {"version":3,"file":"maplibre-renderer.d.ts","sourceRoot":"","sources":["../../../src/runtime/maplibre-renderer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EAKhB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,+BAA+B,EAEpC,KAAK,mBAAmB,EAGzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAGvE,6EAA6E;AAC7E,MAAM,WAAW,oBAAoB;IACnC,0FAA0F;IAC1F,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAQD,yFAAyF;AACzF,MAAM,WAAW,mBAAoB,SAAQ,mBAAmB;IAC9D,MAAM,CAAC,IAAI,OAAO,CAAC;IACnB,kFAAkF;IAClF,aAAa,CAAC,IAAI,OAAO,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,IAAI,OAAO,CAAC;IACrB,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;IACpD,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;IACnD,cAAc,CAAC,IAAI,IAAI,CAAC;IACxB,MAAM,CAAC,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,8BAA8B;IAC7C,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,CAAC,EAAE,yBAAyB,CAAC;CAC9C;AAED,qEAAqE;AACrE,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CAAC,+BAA+B,EAAE,WAAW,CAAC;IACjG,sGAAsG;IACtG,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,gFAAgF;IAChF,QAAQ,CAAC,eAAe,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;CAC9C;AAQD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,oBAAoB,EAC1B,OAAO,GAAE,8BAAmC,GAC3C,eAAe,CAAC,UAAU,EAAE,mBAAmB,EAAE,uBAAuB,CAAC,CA6G3E"}
1
+ {"version":3,"file":"maplibre-renderer.d.ts","sourceRoot":"","sources":["../../../src/runtime/maplibre-renderer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EAKhB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,+BAA+B,EAEpC,KAAK,mBAAmB,EAGzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,wBAAwB,EAG9B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAA6B,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAGlG,6EAA6E;AAC7E,MAAM,WAAW,oBAAoB;IACnC,0FAA0F;IAC1F,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAQD,yFAAyF;AACzF,MAAM,WAAW,mBAAoB,SAAQ,mBAAmB;IAC9D,MAAM,CAAC,IAAI,OAAO,CAAC;IACnB,kFAAkF;IAClF,aAAa,CAAC,IAAI,OAAO,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,IAAI,OAAO,CAAC;IACrB,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;IACpD,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;IACnD,cAAc,CAAC,IAAI,IAAI,CAAC;IACxB,MAAM,CAAC,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,8BAA8B;IAC7C,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,CAAC,EAAE,yBAAyB,CAAC;CAC9C;AAED,qEAAqE;AACrE,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CAAC,+BAA+B,EAAE,WAAW,CAAC;IACjG,sGAAsG;IACtG,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,gFAAgF;IAChF,QAAQ,CAAC,eAAe,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC7C;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,EAAE,wBAAwB,CAAA;KAAE,CAAC;CAC7E;AAQD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,oBAAoB,EAC1B,OAAO,GAAE,8BAAmC,GAC3C,eAAe,CAAC,UAAU,EAAE,mBAAmB,EAAE,uBAAuB,CAAC,CAwH3E"}
@@ -1,5 +1,6 @@
1
1
  import { HonuaAbortError } from "../core/errors.js";
2
2
  import { HonuaAutomaticMapLibreStrategyError, explainAutomaticSourceToMapLibre, mountAutomaticSourceToMapLibre, } from "../map/index.js";
3
+ import { ensureOfflineRegionProtocol, styleUsesOfflineRegion, } from "./offline-region-protocol.js";
3
4
  import { ensurePmtilesProtocol } from "./pmtiles-protocol.js";
4
5
  const EMPTY_STYLE = Object.freeze({
5
6
  version: 8,
@@ -24,6 +25,20 @@ export function maplibreRenderer(peer, options = {}) {
24
25
  },
25
26
  async mount(target, request) {
26
27
  const rendererOptions = request.rendererOptions ?? {};
28
+ // A style that addresses a persisted region needs its protocol before the
29
+ // map is constructed with it; registration is driven by the style's own
30
+ // evidence, and a style that names the scheme without a handler fails here
31
+ // rather than rendering blank tiles.
32
+ if (styleUsesOfflineRegion(request.style)) {
33
+ const registrar = protocolRegistrar(maplibre);
34
+ if (rendererOptions.offlineRegion === undefined || registrar === undefined) {
35
+ throw new TypeError("Rendering an offline-region style requires caller-injected MapLibre and a rendererOptions.offlineRegion tile handler.");
36
+ }
37
+ await ensureOfflineRegionProtocol({
38
+ tileHandler: rendererOptions.offlineRegion.tileHandler,
39
+ maplibre: registrar,
40
+ });
41
+ }
27
42
  const host = resolveMapHost(maplibre, target, request, rendererOptions);
28
43
  const map = host.map;
29
44
  try {
@@ -50,15 +65,10 @@ export function maplibreRenderer(peer, options = {}) {
50
65
  });
51
66
  }
52
67
  if (plan.selected?.strategy.startsWith("pmtiles")) {
53
- if (pmtiles === undefined || typeof maplibre.addProtocol !== "function") {
68
+ const registrar = protocolRegistrar(maplibre);
69
+ if (pmtiles === undefined || registrar === undefined) {
54
70
  throw new HonuaAutomaticMapLibreStrategyError("no-eligible-strategy", "PMTiles mounting requires caller-injected MapLibre and PMTiles protocol peers.");
55
71
  }
56
- const registrar = {
57
- addProtocol: (scheme, handler) => maplibre.addProtocol(scheme, handler),
58
- ...(typeof maplibre.removeProtocol === "function"
59
- ? { removeProtocol: (scheme) => maplibre.removeProtocol(scheme) }
60
- : {}),
61
- };
62
72
  await ensurePmtilesProtocol({ maplibre: registrar, pmtilesModule: pmtiles });
63
73
  }
64
74
  const mounted = await mountAutomaticSourceToMapLibre(map, request.source, plan, {
@@ -131,6 +141,21 @@ function maplibrePeer(value) {
131
141
  : {}),
132
142
  });
133
143
  }
144
+ /**
145
+ * Adapt the injected peer to the shared protocol registrar, or report that it
146
+ * cannot register protocols. This adapter never imports `maplibre-gl` itself, so
147
+ * an absent `addProtocol` is a caller-visible failure rather than a lazy import.
148
+ */
149
+ function protocolRegistrar(peer) {
150
+ const addProtocol = peer.addProtocol;
151
+ if (typeof addProtocol !== "function")
152
+ return undefined;
153
+ const removeProtocol = peer.removeProtocol;
154
+ return {
155
+ addProtocol: (scheme, handler) => addProtocol(scheme, handler),
156
+ ...(typeof removeProtocol === "function" ? { removeProtocol: (scheme) => removeProtocol(scheme) } : {}),
157
+ };
158
+ }
134
159
  function resolveMapHost(peer, target, request, options) {
135
160
  if (isMapHost(target)) {
136
161
  if (request.style !== undefined) {
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Auto-registration of the MapLibre `offline-region://` protocol.
3
+ *
4
+ * A style whose tile sources address a persisted offline region renders through
5
+ * a protocol handler built by `@honua/sdk-js/offline`
6
+ * (`createOfflineRegionTileProtocol`). This module registers that handler on
7
+ * MapLibre once, through the same shared registry `pmtiles://` uses.
8
+ *
9
+ * The runtime deliberately does **not** import `@honua/sdk-js/offline` and does
10
+ * not build the handler itself. A handler is bound to one region manifest, one
11
+ * store, and one authorization scope, none of which the runtime can invent —
12
+ * so the caller supplies the handler and the runtime decides only *when* it must
13
+ * be registered. That also keeps the offline module graph out of every map that
14
+ * never reads from a region.
15
+ *
16
+ * Registration is triggered by evidence, never by import: `loadMapPackage`
17
+ * registers when the composed style actually references the scheme, and fails
18
+ * closed when it does but no handler was supplied — because a missing handler
19
+ * renders blank tiles rather than an error.
20
+ *
21
+ * @module
22
+ */
23
+ import { type MaplibreProtocolRegistrar } from "./protocol-registry.js";
24
+ /** The MapLibre protocol scheme persisted offline regions are addressed under. */
25
+ export declare const OFFLINE_REGION_PROTOCOL_SCHEME = "offline-region";
26
+ /**
27
+ * The handler shape `createOfflineRegionTileProtocol()` returns.
28
+ *
29
+ * Declared structurally so the runtime never imports the offline entrypoint; it
30
+ * is the same shape MapLibre itself expects from `addProtocol`.
31
+ */
32
+ export type OfflineRegionTileHandler = (request: {
33
+ readonly url: string;
34
+ }, abortController?: AbortController) => Promise<{
35
+ readonly data: ArrayBuffer;
36
+ readonly cacheControl?: string;
37
+ readonly expires?: string;
38
+ }>;
39
+ /** Injectable dependencies for {@link ensureOfflineRegionProtocol}. */
40
+ export interface EnsureOfflineRegionProtocolDeps {
41
+ /** Handler from `@honua/sdk-js/offline`'s `createOfflineRegionTileProtocol()`. */
42
+ readonly tileHandler: OfflineRegionTileHandler;
43
+ /** Override the lazily-imported MapLibre `addProtocol` registrar. */
44
+ readonly maplibre?: MaplibreProtocolRegistrar;
45
+ /** Protocol scheme to register. Defaults to `"offline-region"`. */
46
+ readonly scheme?: string;
47
+ }
48
+ /**
49
+ * Register the `offline-region://` protocol on MapLibre if it is not registered
50
+ * already. Idempotent per scheme, exactly like the PMTiles registration: several
51
+ * maps loading the same region concurrently share one registration.
52
+ *
53
+ * Because MapLibre's protocol table is process-global, the *first* handler wins
54
+ * for a given scheme. A host that needs to serve a different region on the same
55
+ * scheme must {@link resetOfflineRegionProtocol} first, or register the second
56
+ * region under its own scheme.
57
+ */
58
+ export declare function ensureOfflineRegionProtocol(deps: EnsureOfflineRegionProtocolDeps): Promise<void>;
59
+ /** Whether the `offline-region://` protocol (or `scheme`) is currently registered. */
60
+ export declare function isOfflineRegionProtocolRegistered(scheme?: string): boolean;
61
+ /**
62
+ * Release a prior {@link ensureOfflineRegionProtocol} registration, so a later
63
+ * call can bind a different region's handler to the same scheme.
64
+ */
65
+ export declare function resetOfflineRegionProtocol(scheme?: string): void;
66
+ /**
67
+ * Whether a composed MapLibre style references at least one `offline-region://`
68
+ * source. This is the evidence `loadMapPackage` registers on.
69
+ */
70
+ export declare function styleUsesOfflineRegion(style: {
71
+ sources?: Record<string, unknown>;
72
+ } | null | undefined, scheme?: string): boolean;
73
+ //# sourceMappingURL=offline-region-protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline-region-protocol.d.ts","sourceRoot":"","sources":["../../../src/runtime/offline-region-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,KAAK,yBAAyB,EAK/B,MAAM,wBAAwB,CAAC;AAEhC,kFAAkF;AAClF,eAAO,MAAM,8BAA8B,mBAAmB,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,MAAM,wBAAwB,GAAG,CACrC,OAAO,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACjC,eAAe,CAAC,EAAE,eAAe,KAC9B,OAAO,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAExG,uEAAuE;AACvE,MAAM,WAAW,+BAA+B;IAC9C,kFAAkF;IAClF,QAAQ,CAAC,WAAW,EAAE,wBAAwB,CAAC;IAC/C,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IAC9C,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,+BAA+B,GAAG,OAAO,CAAC,IAAI,CAAC,CAWtG;AAED,sFAAsF;AACtF,wBAAgB,iCAAiC,CAAC,MAAM,GAAE,MAAuC,GAAG,OAAO,CAE1G;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,GAAE,MAAuC,GAAG,IAAI,CAEhG;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,EAC/D,MAAM,GAAE,MAAuC,GAC9C,OAAO,CAET"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Auto-registration of the MapLibre `offline-region://` protocol.
3
+ *
4
+ * A style whose tile sources address a persisted offline region renders through
5
+ * a protocol handler built by `@honua/sdk-js/offline`
6
+ * (`createOfflineRegionTileProtocol`). This module registers that handler on
7
+ * MapLibre once, through the same shared registry `pmtiles://` uses.
8
+ *
9
+ * The runtime deliberately does **not** import `@honua/sdk-js/offline` and does
10
+ * not build the handler itself. A handler is bound to one region manifest, one
11
+ * store, and one authorization scope, none of which the runtime can invent —
12
+ * so the caller supplies the handler and the runtime decides only *when* it must
13
+ * be registered. That also keeps the offline module graph out of every map that
14
+ * never reads from a region.
15
+ *
16
+ * Registration is triggered by evidence, never by import: `loadMapPackage`
17
+ * registers when the composed style actually references the scheme, and fails
18
+ * closed when it does but no handler was supplied — because a missing handler
19
+ * renders blank tiles rather than an error.
20
+ *
21
+ * @module
22
+ */
23
+ import { ensureMaplibreProtocol, isMaplibreProtocolRegistered, resetMaplibreProtocol, styleUsesProtocolScheme, } from "./protocol-registry.js";
24
+ /** The MapLibre protocol scheme persisted offline regions are addressed under. */
25
+ export const OFFLINE_REGION_PROTOCOL_SCHEME = "offline-region";
26
+ /**
27
+ * Register the `offline-region://` protocol on MapLibre if it is not registered
28
+ * already. Idempotent per scheme, exactly like the PMTiles registration: several
29
+ * maps loading the same region concurrently share one registration.
30
+ *
31
+ * Because MapLibre's protocol table is process-global, the *first* handler wins
32
+ * for a given scheme. A host that needs to serve a different region on the same
33
+ * scheme must {@link resetOfflineRegionProtocol} first, or register the second
34
+ * region under its own scheme.
35
+ */
36
+ export async function ensureOfflineRegionProtocol(deps) {
37
+ if (typeof deps?.tileHandler !== "function") {
38
+ throw new TypeError("An offline-region tile handler is required; build one with createOfflineRegionTileProtocol() from @honua/sdk-js/offline.");
39
+ }
40
+ await ensureMaplibreProtocol({
41
+ scheme: deps.scheme ?? OFFLINE_REGION_PROTOCOL_SCHEME,
42
+ ...(deps.maplibre ? { maplibre: deps.maplibre } : {}),
43
+ createHandler: () => deps.tileHandler,
44
+ });
45
+ }
46
+ /** Whether the `offline-region://` protocol (or `scheme`) is currently registered. */
47
+ export function isOfflineRegionProtocolRegistered(scheme = OFFLINE_REGION_PROTOCOL_SCHEME) {
48
+ return isMaplibreProtocolRegistered(scheme);
49
+ }
50
+ /**
51
+ * Release a prior {@link ensureOfflineRegionProtocol} registration, so a later
52
+ * call can bind a different region's handler to the same scheme.
53
+ */
54
+ export function resetOfflineRegionProtocol(scheme = OFFLINE_REGION_PROTOCOL_SCHEME) {
55
+ resetMaplibreProtocol(scheme);
56
+ }
57
+ /**
58
+ * Whether a composed MapLibre style references at least one `offline-region://`
59
+ * source. This is the evidence `loadMapPackage` registers on.
60
+ */
61
+ export function styleUsesOfflineRegion(style, scheme = OFFLINE_REGION_PROTOCOL_SCHEME) {
62
+ return styleUsesProtocolScheme(style, scheme);
63
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Rewriting a style's tile templates onto the `offline-region://` scheme.
3
+ *
4
+ * A persisted region can only answer what it was addressed for, so pointing a
5
+ * style at one is a narrow, mechanical edit: replace a source's single XYZ tile
6
+ * template with `offline-region://<tileMatrixSetId>/{z}/{x}/{y}`. Everything
7
+ * else — TileJSON `url` members, GeoJSON `data`, sprites, glyphs, layer paint —
8
+ * is left exactly as authored.
9
+ *
10
+ * The rewrite is lossless and reversible: it returns a new style plus a record of
11
+ * every replacement, and {@link revertOfflineRegionStyleRewrite} restores the
12
+ * original byte-for-byte. Anything it cannot rewrite *exactly* is refused with a
13
+ * reason rather than guessed at, because a style that silently kept its network
14
+ * template would render live tiles while the application believed it was reading
15
+ * from a region.
16
+ *
17
+ * @module
18
+ */
19
+ export type OfflineRegionStyleRefusalReason =
20
+ /** No source with this id exists in the style. */
21
+ "unknown-source"
22
+ /** The source is not a tile source (`geojson`, `image`, `video`, …). */
23
+ | "not-a-tile-source"
24
+ /** The source addresses tiles only through a TileJSON `url`, which a region does not serve. */
25
+ | "tilejson-url-only"
26
+ /** The source carries both `url` and `tiles`; which one MapLibre uses is not ours to decide. */
27
+ | "ambiguous-tile-source"
28
+ /** The source has no single tile template to replace. */
29
+ | "multiple-tile-templates"
30
+ /** The template is not a plain `{z}/{x}/{y}` address. */
31
+ | "unsupported-tile-template"
32
+ /** The template already addresses the offline scheme. */
33
+ | "already-rewritten";
34
+ export interface OfflineRegionStyleRefusalV1 {
35
+ readonly sourceId: string;
36
+ readonly reason: OfflineRegionStyleRefusalReason;
37
+ readonly detail: string;
38
+ }
39
+ /** One replacement, carrying exactly what is needed to undo it. */
40
+ export interface OfflineRegionStyleRewriteEntryV1 {
41
+ readonly sourceId: string;
42
+ readonly member: "tiles";
43
+ readonly index: number;
44
+ readonly from: string;
45
+ readonly to: string;
46
+ }
47
+ export interface OfflineRegionStyleRewriteV1<TStyle = unknown> {
48
+ /** A new style. The input is never mutated. */
49
+ readonly style: TStyle;
50
+ readonly rewrites: readonly OfflineRegionStyleRewriteEntryV1[];
51
+ readonly refusals: readonly OfflineRegionStyleRefusalV1[];
52
+ }
53
+ export interface RewriteStyleTilesForOfflineRegionOptions {
54
+ /** Style source ids to serve from the region. Only these are considered. */
55
+ readonly sourceIds: readonly string[];
56
+ /** Tile-matrix-set segment of the rewritten URL. Defaults to `"default"`. */
57
+ readonly tileMatrixSetId?: string;
58
+ /** Protocol scheme. Defaults to `"offline-region"`. */
59
+ readonly scheme?: string;
60
+ }
61
+ /**
62
+ * Point the named tile sources at a persisted offline region.
63
+ *
64
+ * Rewrites only `sources[id].tiles[0]`, and only when that source is a
65
+ * `vector`, `raster`, or `raster-dem` source whose single template is a plain
66
+ * `{z}`/`{x}`/`{y}` address. Every other shape is refused; the caller decides
67
+ * whether a refusal is fatal.
68
+ */
69
+ export declare function rewriteStyleTilesForOfflineRegion<TStyle>(style: TStyle, options: RewriteStyleTilesForOfflineRegionOptions): OfflineRegionStyleRewriteV1<TStyle>;
70
+ /**
71
+ * Undo a rewrite, restoring every original template exactly.
72
+ *
73
+ * Applying this to the style a rewrite produced yields a style deep-equal to the
74
+ * one that went in, which is what makes the offline binding safe to apply to a
75
+ * package a host still owns.
76
+ */
77
+ export declare function revertOfflineRegionStyleRewrite<TStyle>(style: TStyle, rewrite: Pick<OfflineRegionStyleRewriteV1, "rewrites">): TStyle;
78
+ //# sourceMappingURL=offline-region-style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline-region-style.d.ts","sourceRoot":"","sources":["../../../src/runtime/offline-region-style.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAUH,MAAM,MAAM,+BAA+B;AACzC,kDAAkD;AAChD,gBAAgB;AAClB,wEAAwE;GACtE,mBAAmB;AACrB,+FAA+F;GAC7F,mBAAmB;AACrB,gGAAgG;GAC9F,uBAAuB;AACzB,yDAAyD;GACvD,yBAAyB;AAC3B,yDAAyD;GACvD,2BAA2B;AAC7B,yDAAyD;GACvD,mBAAmB,CAAC;AAExB,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,+BAA+B,CAAC;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,mEAAmE;AACnE,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,2BAA2B,CAAC,MAAM,GAAG,OAAO;IAC3D,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS,gCAAgC,EAAE,CAAC;IAC/D,QAAQ,CAAC,QAAQ,EAAE,SAAS,2BAA2B,EAAE,CAAC;CAC3D;AAED,MAAM,WAAW,wCAAwC;IACvD,4EAA4E;IAC5E,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,6EAA6E;IAC7E,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,uDAAuD;IACvD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAOD;;;;;;;GAOG;AACH,wBAAgB,iCAAiC,CAAC,MAAM,EACtD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,wCAAwC,GAChD,2BAA2B,CAAC,MAAM,CAAC,CAmCrC;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,MAAM,EACpD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,IAAI,CAAC,2BAA2B,EAAE,UAAU,CAAC,GACrD,MAAM,CAqBR"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Rewriting a style's tile templates onto the `offline-region://` scheme.
3
+ *
4
+ * A persisted region can only answer what it was addressed for, so pointing a
5
+ * style at one is a narrow, mechanical edit: replace a source's single XYZ tile
6
+ * template with `offline-region://<tileMatrixSetId>/{z}/{x}/{y}`. Everything
7
+ * else — TileJSON `url` members, GeoJSON `data`, sprites, glyphs, layer paint —
8
+ * is left exactly as authored.
9
+ *
10
+ * The rewrite is lossless and reversible: it returns a new style plus a record of
11
+ * every replacement, and {@link revertOfflineRegionStyleRewrite} restores the
12
+ * original byte-for-byte. Anything it cannot rewrite *exactly* is refused with a
13
+ * reason rather than guessed at, because a style that silently kept its network
14
+ * template would render live tiles while the application believed it was reading
15
+ * from a region.
16
+ *
17
+ * @module
18
+ */
19
+ import { OFFLINE_REGION_PROTOCOL_SCHEME } from "./offline-region-protocol.js";
20
+ /** Source types whose `tiles` templates address XYZ tiles. */
21
+ const TILE_SOURCE_TYPES = new Set(["vector", "raster", "raster-dem"]);
22
+ /** Placeholders the offline tile handler can answer. Anything else is refused. */
23
+ const SUPPORTED_PLACEHOLDERS = new Set(["z", "x", "y"]);
24
+ /**
25
+ * Point the named tile sources at a persisted offline region.
26
+ *
27
+ * Rewrites only `sources[id].tiles[0]`, and only when that source is a
28
+ * `vector`, `raster`, or `raster-dem` source whose single template is a plain
29
+ * `{z}`/`{x}`/`{y}` address. Every other shape is refused; the caller decides
30
+ * whether a refusal is fatal.
31
+ */
32
+ export function rewriteStyleTilesForOfflineRegion(style, options) {
33
+ const sourceIds = options?.sourceIds;
34
+ if (!Array.isArray(sourceIds) || sourceIds.length === 0) {
35
+ throw new TypeError("rewriteStyleTilesForOfflineRegion requires at least one style source id.");
36
+ }
37
+ const scheme = options.scheme ?? OFFLINE_REGION_PROTOCOL_SCHEME;
38
+ const tileMatrixSetId = options.tileMatrixSetId ?? "default";
39
+ if (tileMatrixSetId.length === 0 || tileMatrixSetId.includes("/")) {
40
+ throw new TypeError("tileMatrixSetId must be a non-empty path segment.");
41
+ }
42
+ const target = `${scheme}://${tileMatrixSetId}/{z}/{x}/{y}`;
43
+ const sources = style?.sources;
44
+ const rewrites = [];
45
+ const refusals = [];
46
+ const replacements = new Map();
47
+ for (const sourceId of sourceIds) {
48
+ const source = sources && typeof sources === "object" ? sources[sourceId] : undefined;
49
+ const refusal = classify(sourceId, source, scheme);
50
+ if (refusal) {
51
+ refusals.push(refusal);
52
+ continue;
53
+ }
54
+ const record = source;
55
+ rewrites.push({ sourceId, member: "tiles", index: 0, from: record.tiles[0], to: target });
56
+ replacements.set(sourceId, { ...record, tiles: [target] });
57
+ }
58
+ if (replacements.size === 0) {
59
+ return { style, rewrites, refusals };
60
+ }
61
+ const nextSources = { ...sources };
62
+ for (const [sourceId, source] of replacements)
63
+ nextSources[sourceId] = source;
64
+ return { style: { ...style, sources: nextSources }, rewrites, refusals };
65
+ }
66
+ /**
67
+ * Undo a rewrite, restoring every original template exactly.
68
+ *
69
+ * Applying this to the style a rewrite produced yields a style deep-equal to the
70
+ * one that went in, which is what makes the offline binding safe to apply to a
71
+ * package a host still owns.
72
+ */
73
+ export function revertOfflineRegionStyleRewrite(style, rewrite) {
74
+ const entries = rewrite?.rewrites ?? [];
75
+ if (entries.length === 0)
76
+ return style;
77
+ const sources = style?.sources;
78
+ if (!sources || typeof sources !== "object") {
79
+ throw new TypeError("Cannot revert an offline-region rewrite against a style without sources.");
80
+ }
81
+ const nextSources = { ...sources };
82
+ for (const entry of entries) {
83
+ const source = nextSources[entry.sourceId];
84
+ const current = source?.tiles?.[entry.index];
85
+ if (current !== entry.to) {
86
+ throw new TypeError(`Style source "${entry.sourceId}" no longer carries the rewritten tile template; refusing a partial revert.`);
87
+ }
88
+ const tiles = [...(source?.tiles ?? [])];
89
+ tiles[entry.index] = entry.from;
90
+ nextSources[entry.sourceId] = { ...source, tiles };
91
+ }
92
+ return { ...style, sources: nextSources };
93
+ }
94
+ function classify(sourceId, source, scheme) {
95
+ if (!source || typeof source !== "object") {
96
+ return refuse(sourceId, "unknown-source", "The style declares no source with this id.");
97
+ }
98
+ const record = source;
99
+ if (typeof record.type !== "string" || !TILE_SOURCE_TYPES.has(record.type)) {
100
+ return refuse(sourceId, "not-a-tile-source", `Only vector, raster, and raster-dem sources address tiles; this source is "${String(record.type)}".`);
101
+ }
102
+ const hasTiles = Array.isArray(record.tiles);
103
+ if (record.url !== undefined && hasTiles) {
104
+ return refuse(sourceId, "ambiguous-tile-source", "The source carries both a TileJSON url and a tiles array; remove one before binding it to a region.");
105
+ }
106
+ if (!hasTiles) {
107
+ return refuse(sourceId, "tilejson-url-only", "The source addresses tiles through a TileJSON url, which a persisted region does not serve.");
108
+ }
109
+ const tiles = record.tiles;
110
+ if (tiles.length !== 1 || typeof tiles[0] !== "string") {
111
+ return refuse(sourceId, "multiple-tile-templates", `Exactly one string tile template can be bound to a region; this source declares ${tiles.length}.`);
112
+ }
113
+ const template = tiles[0];
114
+ if (template.startsWith(`${scheme}://`)) {
115
+ return refuse(sourceId, "already-rewritten", "The source already addresses the offline-region scheme.");
116
+ }
117
+ const placeholders = collectPlaceholders(template);
118
+ const missing = ["z", "x", "y"].filter((name) => !placeholders.has(name));
119
+ if (missing.length > 0) {
120
+ return refuse(sourceId, "unsupported-tile-template", `The template is missing the ${missing.join(", ")} placeholder(s) a region addresses tiles by.`);
121
+ }
122
+ for (const placeholder of placeholders) {
123
+ if (!SUPPORTED_PLACEHOLDERS.has(placeholder)) {
124
+ return refuse(sourceId, "unsupported-tile-template", `The template uses the {${placeholder}} placeholder, which a persisted region cannot address.`);
125
+ }
126
+ }
127
+ return undefined;
128
+ }
129
+ /** Bounded linear scan for `{name}` placeholders; deliberately not a regex. */
130
+ function collectPlaceholders(template) {
131
+ const found = new Set();
132
+ let index = 0;
133
+ while (index < template.length) {
134
+ const open = template.indexOf("{", index);
135
+ if (open < 0)
136
+ break;
137
+ const close = template.indexOf("}", open + 1);
138
+ if (close < 0)
139
+ break;
140
+ found.add(template.slice(open + 1, close));
141
+ index = close + 1;
142
+ }
143
+ return found;
144
+ }
145
+ function refuse(sourceId, reason, detail) {
146
+ return { sourceId, reason, detail };
147
+ }
@@ -16,16 +16,15 @@
16
16
  * PMTiles source to a live map through `runtime.addSource` is synchronous — call
17
17
  * {@link ensurePmtilesProtocol} yourself beforehand in that case.
18
18
  *
19
- * The `maplibre-gl` / `pmtiles` slices are injectable so the wiring is
20
- * unit-testable without either real package.
19
+ * The registration bookkeeping itself lives in `protocol-registry.ts`, shared
20
+ * with every other scheme the runtime registers; this module owns only the
21
+ * PMTiles policy. The `maplibre-gl` / `pmtiles` slices are injectable so the
22
+ * wiring is unit-testable without either real package.
21
23
  *
22
24
  * @module
23
25
  */
24
- /** The MapLibre `addProtocol` / `removeProtocol` surface this module drives. */
25
- export interface MaplibreProtocolRegistrar {
26
- addProtocol(scheme: string, handler: unknown): void;
27
- removeProtocol?(scheme: string): void;
28
- }
26
+ import { type MaplibreProtocolRegistrar } from "./protocol-registry.js";
27
+ export type { MaplibreProtocolRegistrar };
29
28
  /** The `pmtiles.Protocol` surface this module drives. */
30
29
  export interface PmtilesProtocolLike {
31
30
  readonly tile: unknown;
@@ -65,7 +64,7 @@ export declare function isPmtilesProtocolRegistered(scheme?: string): boolean;
65
64
  * useful if a host wants to fully release the protocol. Best-effort — a
66
65
  * registrar without `removeProtocol` just clears the local record.
67
66
  */
68
- export declare function resetPmtilesProtocol(): void;
67
+ export declare function resetPmtilesProtocol(scheme?: string): void;
69
68
  /**
70
69
  * Whether a composed MapLibre style references at least one `pmtiles://` source.
71
70
  * Used by `loadMapPackage` to decide whether the protocol must be registered
@@ -1 +1 @@
1
- {"version":3,"file":"pmtiles-protocol.d.ts","sourceRoot":"","sources":["../../../src/runtime/pmtiles-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,gFAAgF;AAChF,MAAM,WAAW,yBAAyB;IACxC,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACpD,cAAc,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC;AAED,yDAAyD;AACzD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,0EAA0E;AAC1E,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,KAAK,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,mBAAmB,CAAC;CACvG;AAED,8EAA8E;AAC9E,MAAM,WAAW,yBAAyB;IACxC,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IAC9C,qDAAqD;IACrD,QAAQ,CAAC,aAAa,CAAC,EAAE,yBAAyB,CAAC;IACnD,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,YAAY,CAAC;AAmCjD;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,GAAE,yBAA8B,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB/F;AAED,+EAA+E;AAC/E,wBAAgB,2BAA2B,CAAC,MAAM,GAAE,MAAgC,GAAG,OAAO,CAE7F;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAM3C;AAcD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,EAC/D,MAAM,GAAE,MAAgC,GACvC,OAAO,CAOT"}
1
+ {"version":3,"file":"pmtiles-protocol.d.ts","sourceRoot":"","sources":["../../../src/runtime/pmtiles-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EACL,KAAK,yBAAyB,EAK/B,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,yBAAyB,EAAE,CAAC;AAE1C,yDAAyD;AACzD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,0EAA0E;AAC1E,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,KAAK,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,mBAAmB,CAAC;CACvG;AAED,8EAA8E;AAC9E,MAAM,WAAW,yBAAyB;IACxC,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IAC9C,qDAAqD;IACrD,QAAQ,CAAC,aAAa,CAAC,EAAE,yBAAyB,CAAC;IACnD,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,YAAY,CAAC;AAMjD;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,GAAE,yBAA8B,GAAG,OAAO,CAAC,IAAI,CAAC,CAY/F;AAED,+EAA+E;AAC/E,wBAAgB,2BAA2B,CAAC,MAAM,GAAE,MAAgC,GAAG,OAAO,CAE7F;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,GAAE,MAAgC,GAAG,IAAI,CAEnF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,EAC/D,MAAM,GAAE,MAAgC,GACvC,OAAO,CAET"}