@honua/app-platform 0.1.2-beta.0 → 0.1.4-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 (383) hide show
  1. package/collaboration/client.d.ts.map +1 -1
  2. package/connect-url-safety.d.ts +53 -0
  3. package/connect-url-safety.js +189 -0
  4. package/contract/discovery.d.ts +34 -0
  5. package/contract/discovery.d.ts.map +1 -1
  6. package/contract/index.d.ts +7 -5
  7. package/contract/index.d.ts.map +1 -1
  8. package/contract/index.js +3 -2
  9. package/contract/pmtiles.d.ts +10 -1
  10. package/contract/pmtiles.d.ts.map +1 -1
  11. package/contract/pmtiles.js +10 -2
  12. package/contract/protocol-module.d.ts +84 -9
  13. package/contract/protocol-module.d.ts.map +1 -1
  14. package/contract/query-filter-fes.d.ts +18 -0
  15. package/contract/query-filter-fes.d.ts.map +1 -0
  16. package/contract/query-filter-fes.js +122 -0
  17. package/contract/query-filter.d.ts +300 -0
  18. package/contract/query-filter.d.ts.map +1 -0
  19. package/contract/query-filter.js +883 -0
  20. package/contract/schema.d.ts +12 -0
  21. package/contract/schema.d.ts.map +1 -1
  22. package/contract/schema.js +34 -0
  23. package/contract/source-capability-support.d.ts.map +1 -1
  24. package/contract/source-capability-support.js +15 -3
  25. package/contract/source.d.ts +45 -25
  26. package/contract/source.d.ts.map +1 -1
  27. package/contract/source.js +719 -479
  28. package/contract/types.d.ts +87 -18
  29. package/contract/types.d.ts.map +1 -1
  30. package/contract/widget-source.d.ts.map +1 -1
  31. package/controls/basemap-switcher.d.ts +19 -11
  32. package/controls/basemap-switcher.d.ts.map +1 -1
  33. package/controls/basemap-switcher.js +58 -25
  34. package/controls/catalog.d.ts +105 -0
  35. package/controls/catalog.d.ts.map +1 -0
  36. package/controls/catalog.js +341 -0
  37. package/controls/element-utils.d.ts +9 -0
  38. package/controls/element-utils.d.ts.map +1 -1
  39. package/controls/element-utils.js +17 -0
  40. package/controls/index.d.ts +29 -8
  41. package/controls/index.d.ts.map +1 -1
  42. package/controls/index.js +26 -8
  43. package/controls/layer-list.d.ts +13 -5
  44. package/controls/layer-list.d.ts.map +1 -1
  45. package/controls/layer-list.js +72 -15
  46. package/controls/legend.d.ts +32 -5
  47. package/controls/legend.d.ts.map +1 -1
  48. package/controls/legend.js +95 -25
  49. package/controls/qualification.d.ts +152 -0
  50. package/controls/qualification.d.ts.map +1 -0
  51. package/controls/qualification.js +1265 -0
  52. package/controls/registry.d.ts +104 -0
  53. package/controls/registry.d.ts.map +1 -0
  54. package/controls/registry.js +150 -0
  55. package/controls/swipe-control.d.ts +6 -1
  56. package/controls/swipe-control.d.ts.map +1 -1
  57. package/controls/swipe-control.js +82 -20
  58. package/core/client.d.ts +45 -21
  59. package/core/client.d.ts.map +1 -1
  60. package/core/client.js +224 -46
  61. package/core/error-classifications.d.ts +6 -0
  62. package/core/error-classifications.d.ts.map +1 -1
  63. package/core/error-classifications.js +6 -0
  64. package/core/error-code-registry.d.ts +6 -0
  65. package/core/error-code-registry.d.ts.map +1 -1
  66. package/core/error-code-registry.js +6 -0
  67. package/core/error-envelope.js +2 -0
  68. package/core/errors.d.ts +1 -1
  69. package/core/errors.js +1 -1
  70. package/core/geoparquet-sql.d.ts +68 -4
  71. package/core/geoparquet-sql.d.ts.map +1 -1
  72. package/core/geoparquet-sql.js +325 -8
  73. package/core/odata-write-codec.d.ts.map +1 -1
  74. package/core/odata-write-codec.js +0 -1
  75. package/core/odata.d.ts +6 -0
  76. package/core/odata.d.ts.map +1 -1
  77. package/core/odata.js +6 -1
  78. package/core/ogc-processes.d.ts +182 -25
  79. package/core/ogc-processes.d.ts.map +1 -1
  80. package/core/ogc-processes.js +602 -30
  81. package/core/process-runner.d.ts +8 -1
  82. package/core/process-runner.d.ts.map +1 -1
  83. package/core/process-runner.js +1 -0
  84. package/core/protocol-transport.d.ts +2 -0
  85. package/core/protocol-transport.d.ts.map +1 -1
  86. package/core/stac.d.ts +31 -0
  87. package/core/stac.d.ts.map +1 -1
  88. package/core/stac.js +136 -19
  89. package/core/surfaces.d.ts.map +1 -1
  90. package/core/surfaces.js +273 -68
  91. package/core/types.d.ts +123 -9
  92. package/core/types.d.ts.map +1 -1
  93. package/core/wfs-axis-order.d.ts +18 -0
  94. package/core/wfs-axis-order.d.ts.map +1 -0
  95. package/core/wfs-axis-order.js +108 -0
  96. package/core/wfs-capabilities.d.ts +65 -24
  97. package/core/wfs-capabilities.d.ts.map +1 -1
  98. package/core/wfs-capabilities.js +237 -27
  99. package/core/wfs-filter.d.ts +26 -3
  100. package/core/wfs-filter.d.ts.map +1 -1
  101. package/core/wfs-filter.js +48 -53
  102. package/core/wfs-protocol-error.d.ts +12 -0
  103. package/core/wfs-protocol-error.d.ts.map +1 -0
  104. package/core/wfs-protocol-error.js +13 -0
  105. package/core/wfs.d.ts +53 -1
  106. package/core/wfs.d.ts.map +1 -1
  107. package/core/wfs.js +251 -29
  108. package/core/wms-feature-info.d.ts +92 -0
  109. package/core/wms-feature-info.d.ts.map +1 -0
  110. package/core/wms-feature-info.js +285 -0
  111. package/core/wms.d.ts +9 -0
  112. package/core/wms.d.ts.map +1 -1
  113. package/core/wms.js +17 -5
  114. package/esri-compat/event-bus.d.ts +20 -0
  115. package/esri-compat/event-bus.d.ts.map +1 -1
  116. package/esri-compat/feature-filter.d.ts +46 -1
  117. package/esri-compat/feature-filter.d.ts.map +1 -1
  118. package/esri-compat/feature-filter.js +49 -0
  119. package/esri-compat/geojson-layer.d.ts +4 -2
  120. package/esri-compat/geojson-layer.d.ts.map +1 -1
  121. package/esri-compat/geojson-layer.js +4 -2
  122. package/esri-compat/identity-manager.js +2 -2
  123. package/esri-compat/imagery-layer.d.ts +2 -1
  124. package/esri-compat/imagery-layer.d.ts.map +1 -1
  125. package/esri-compat/imagery-layer.js +2 -1
  126. package/esri-compat/layer-list.d.ts +8 -1
  127. package/esri-compat/layer-list.d.ts.map +1 -1
  128. package/esri-compat/layer-list.js +11 -4
  129. package/esri-compat/legend.d.ts.map +1 -1
  130. package/esri-compat/legend.js +1 -1
  131. package/esri-compat/locator.d.ts +297 -0
  132. package/esri-compat/locator.d.ts.map +1 -0
  133. package/esri-compat/locator.js +579 -0
  134. package/esri-compat/map-image-layer.d.ts.map +1 -1
  135. package/esri-compat/map-view.d.ts.map +1 -1
  136. package/esri-compat/map-view.js +1 -1
  137. package/esri-compat/scene-view.d.ts.map +1 -1
  138. package/esri-compat/time-slider.d.ts +29 -0
  139. package/esri-compat/time-slider.d.ts.map +1 -1
  140. package/esri-compat/time-slider.js +117 -0
  141. package/esri-compat/wfs-layer.d.ts +2 -1
  142. package/esri-compat/wfs-layer.d.ts.map +1 -1
  143. package/esri-compat/wfs-layer.js +2 -1
  144. package/esri-compat/widget-host.d.ts +42 -6
  145. package/esri-compat/widget-host.d.ts.map +1 -1
  146. package/esri-compat/widget-host.js +99 -10
  147. package/generated-app/projection.d.ts.map +1 -1
  148. package/generated-app/runtime.d.ts.map +1 -1
  149. package/map/data-to-map-bridge.d.ts +1 -1
  150. package/map/data-to-map-bridge.d.ts.map +1 -1
  151. package/map/data-to-map-bridge.js +1 -2
  152. package/map/honua-map.d.ts.map +1 -1
  153. package/map/honua-map.js +1 -1
  154. package/map/index.d.ts +2 -0
  155. package/map/index.d.ts.map +1 -1
  156. package/map/index.js +2 -0
  157. package/map/realtime-reconciliation-adapter.d.ts +98 -0
  158. package/map/realtime-reconciliation-adapter.d.ts.map +1 -0
  159. package/map/realtime-reconciliation-adapter.js +84 -0
  160. package/map/temporal-playback.d.ts +25 -0
  161. package/map/temporal-playback.d.ts.map +1 -1
  162. package/map/temporal-playback.js +29 -1
  163. package/operator/workspace/workspace.d.ts.map +1 -1
  164. package/operator/workspace/workspace.js +0 -2
  165. package/package.json +4 -3
  166. package/query-planner/canonical-filter.d.ts +30 -0
  167. package/query-planner/canonical-filter.d.ts.map +1 -0
  168. package/query-planner/canonical-filter.js +30 -0
  169. package/query-planner/columnar-plan.d.ts +63 -0
  170. package/query-planner/columnar-plan.d.ts.map +1 -0
  171. package/query-planner/columnar-plan.js +94 -0
  172. package/query-planner/diagnostics.d.ts +3 -3
  173. package/query-planner/diagnostics.d.ts.map +1 -1
  174. package/query-planner/diagnostics.js +17 -4
  175. package/query-planner/duckdb.d.ts.map +1 -1
  176. package/query-planner/duckdb.js +16 -2
  177. package/query-planner/execution-context.d.ts.map +1 -1
  178. package/query-planner/execution-context.js +3 -1
  179. package/query-planner/executor.d.ts.map +1 -1
  180. package/query-planner/executor.js +7 -1
  181. package/query-planner/geoservices.d.ts.map +1 -1
  182. package/query-planner/geoservices.js +24 -5
  183. package/query-planner/grpc.d.ts.map +1 -1
  184. package/query-planner/grpc.js +29 -5
  185. package/query-planner/index.d.ts +20 -5
  186. package/query-planner/index.d.ts.map +1 -1
  187. package/query-planner/index.js +16 -3
  188. package/query-planner/ir.d.ts +6 -1
  189. package/query-planner/ir.d.ts.map +1 -1
  190. package/query-planner/ir.js +63 -1
  191. package/query-planner/odata-protocol-module.d.ts +54 -0
  192. package/query-planner/odata-protocol-module.d.ts.map +1 -0
  193. package/query-planner/odata-protocol-module.js +199 -0
  194. package/query-planner/odata-v1.d.ts +23 -0
  195. package/query-planner/odata-v1.d.ts.map +1 -0
  196. package/query-planner/odata-v1.js +202 -0
  197. package/query-planner/odata.d.ts +0 -3
  198. package/query-planner/odata.d.ts.map +1 -1
  199. package/query-planner/odata.js +0 -143
  200. package/query-planner/ogc-features.d.ts.map +1 -1
  201. package/query-planner/ogc-features.js +23 -1
  202. package/query-planner/planner.d.ts +2 -2
  203. package/query-planner/planner.d.ts.map +1 -1
  204. package/query-planner/planner.js +146 -27
  205. package/query-planner/representation.d.ts +59 -0
  206. package/query-planner/representation.d.ts.map +1 -0
  207. package/query-planner/representation.js +140 -0
  208. package/query-planner/types.d.ts +153 -3
  209. package/query-planner/types.d.ts.map +1 -1
  210. package/query-planner/wfs-protocol-module.d.ts +57 -0
  211. package/query-planner/wfs-protocol-module.d.ts.map +1 -0
  212. package/query-planner/wfs-protocol-module.js +731 -0
  213. package/query-planner/wfs-v1.d.ts +41 -0
  214. package/query-planner/wfs-v1.d.ts.map +1 -0
  215. package/query-planner/wfs-v1.js +366 -0
  216. package/query-planner/wfs.d.ts +1 -3
  217. package/query-planner/wfs.d.ts.map +1 -1
  218. package/query-planner/wfs.js +1 -70
  219. package/realtime/checkpoint-store.d.ts +206 -0
  220. package/realtime/checkpoint-store.d.ts.map +1 -0
  221. package/realtime/checkpoint-store.js +504 -0
  222. package/realtime/honua-server.d.ts +8 -0
  223. package/realtime/honua-server.d.ts.map +1 -1
  224. package/realtime/honua-server.js +123 -14
  225. package/realtime/index.d.ts +4 -0
  226. package/realtime/index.d.ts.map +1 -1
  227. package/realtime/index.js +2 -0
  228. package/realtime/reconciliation.d.ts +245 -0
  229. package/realtime/reconciliation.d.ts.map +1 -0
  230. package/realtime/reconciliation.js +377 -0
  231. package/realtime/resumable-transport.d.ts.map +1 -1
  232. package/realtime/sse.d.ts.map +1 -1
  233. package/realtime/websocket.d.ts.map +1 -1
  234. package/realtime/wire.d.ts +2 -1
  235. package/realtime/wire.d.ts.map +1 -1
  236. package/realtime/wire.js +24 -8
  237. package/replica-sync/errors.d.ts +19 -1
  238. package/replica-sync/errors.d.ts.map +1 -1
  239. package/replica-sync/errors.js +16 -0
  240. package/replica-sync/geoservices.d.ts +260 -0
  241. package/replica-sync/geoservices.d.ts.map +1 -0
  242. package/replica-sync/geoservices.js +1093 -0
  243. package/replica-sync/index.d.ts +5 -1
  244. package/replica-sync/index.d.ts.map +1 -1
  245. package/replica-sync/index.js +3 -1
  246. package/replica-sync/transport-conformance.d.ts +58 -0
  247. package/replica-sync/transport-conformance.d.ts.map +1 -0
  248. package/replica-sync/transport-conformance.js +265 -0
  249. package/replica-sync/types.d.ts +22 -0
  250. package/replica-sync/types.d.ts.map +1 -1
  251. package/runtime/index.d.ts +6 -2
  252. package/runtime/index.d.ts.map +1 -1
  253. package/runtime/index.js +3 -1
  254. package/runtime/load-package.d.ts +24 -0
  255. package/runtime/load-package.d.ts.map +1 -1
  256. package/runtime/load-package.js +45 -1
  257. package/runtime/maplibre-renderer.d.ts +11 -0
  258. package/runtime/maplibre-renderer.d.ts.map +1 -1
  259. package/runtime/maplibre-renderer.js +32 -7
  260. package/runtime/offline-region-protocol.d.ts +73 -0
  261. package/runtime/offline-region-protocol.d.ts.map +1 -0
  262. package/runtime/offline-region-protocol.js +63 -0
  263. package/runtime/offline-region-style.d.ts +78 -0
  264. package/runtime/offline-region-style.d.ts.map +1 -0
  265. package/runtime/offline-region-style.js +147 -0
  266. package/runtime/pmtiles-protocol.d.ts +7 -8
  267. package/runtime/pmtiles-protocol.d.ts.map +1 -1
  268. package/runtime/pmtiles-protocol.js +19 -66
  269. package/runtime/protocol-registry.d.ts +55 -0
  270. package/runtime/protocol-registry.d.ts.map +1 -0
  271. package/runtime/protocol-registry.js +103 -0
  272. package/runtime/runtime.d.ts +2 -0
  273. package/runtime/runtime.d.ts.map +1 -1
  274. package/runtime/runtime.js +6 -1
  275. package/scene-workspace/analysis-widgets.d.ts +4 -2
  276. package/scene-workspace/analysis-widgets.d.ts.map +1 -1
  277. package/scene-workspace/analysis-widgets.js +4 -2
  278. package/scene-workspace/camera-correspondence.d.ts +151 -0
  279. package/scene-workspace/camera-correspondence.d.ts.map +1 -0
  280. package/scene-workspace/camera-correspondence.js +220 -0
  281. package/scene-workspace/cesium-adapter.d.ts +230 -29
  282. package/scene-workspace/cesium-adapter.d.ts.map +1 -1
  283. package/scene-workspace/cesium-adapter.js +741 -56
  284. package/scene-workspace/cesium-mount.d.ts +205 -0
  285. package/scene-workspace/cesium-mount.d.ts.map +1 -0
  286. package/scene-workspace/cesium-mount.js +392 -0
  287. package/scene-workspace/cesium-scene-owner.d.ts +160 -0
  288. package/scene-workspace/cesium-scene-owner.d.ts.map +1 -0
  289. package/scene-workspace/cesium-scene-owner.js +205 -0
  290. package/scene-workspace/cesium-state-sync.d.ts +101 -0
  291. package/scene-workspace/cesium-state-sync.d.ts.map +1 -0
  292. package/scene-workspace/cesium-state-sync.js +432 -0
  293. package/scene-workspace/cesium-time.d.ts +346 -0
  294. package/scene-workspace/cesium-time.d.ts.map +1 -0
  295. package/scene-workspace/cesium-time.js +403 -0
  296. package/scene-workspace/index.d.ts +42 -10
  297. package/scene-workspace/index.d.ts.map +1 -1
  298. package/scene-workspace/index.js +32 -7
  299. package/scene-workspace/maplibre-state-sync.d.ts +112 -0
  300. package/scene-workspace/maplibre-state-sync.d.ts.map +1 -0
  301. package/scene-workspace/maplibre-state-sync.js +400 -0
  302. package/scene-workspace/primitives.d.ts +237 -3
  303. package/scene-workspace/primitives.d.ts.map +1 -1
  304. package/scene-workspace/primitives.js +1087 -17
  305. package/scene-workspace/scene-discovery.d.ts +5 -2
  306. package/scene-workspace/scene-discovery.d.ts.map +1 -1
  307. package/scene-workspace/scene-discovery.js +5 -2
  308. package/scene-workspace/scene-view.d.ts +5 -2
  309. package/scene-workspace/scene-view.d.ts.map +1 -1
  310. package/scene-workspace/scene-view.js +5 -2
  311. package/scene-workspace/source-to-cesium.d.ts +141 -8
  312. package/scene-workspace/source-to-cesium.d.ts.map +1 -1
  313. package/scene-workspace/source-to-cesium.js +497 -72
  314. package/scene-workspace/state-sync-port-kit.d.ts +156 -0
  315. package/scene-workspace/state-sync-port-kit.d.ts.map +1 -0
  316. package/scene-workspace/state-sync-port-kit.js +319 -0
  317. package/scene-workspace/state-sync.d.ts +34 -1
  318. package/scene-workspace/state-sync.d.ts.map +1 -1
  319. package/scene-workspace/state-sync.js +48 -0
  320. package/scene-workspace/types.d.ts +8 -0
  321. package/scene-workspace/types.d.ts.map +1 -1
  322. package/scene-workspace/types.js +2 -0
  323. package/scene-workspace/workspace.d.ts +12 -1
  324. package/scene-workspace/workspace.d.ts.map +1 -1
  325. package/scene-workspace/workspace.js +13 -0
  326. package/studio/index.d.ts +24 -7
  327. package/studio/index.d.ts.map +1 -1
  328. package/studio/index.js +21 -7
  329. package/studio/lifecycle-client.d.ts +164 -0
  330. package/studio/lifecycle-client.d.ts.map +1 -0
  331. package/studio/lifecycle-client.js +299 -0
  332. package/studio/lifecycle-errors.d.ts +91 -0
  333. package/studio/lifecycle-errors.d.ts.map +1 -0
  334. package/studio/lifecycle-errors.js +77 -0
  335. package/studio/lifecycle-types.d.ts +321 -0
  336. package/studio/lifecycle-types.d.ts.map +1 -0
  337. package/studio/lifecycle-types.js +22 -0
  338. package/web-components/controller.d.ts.map +1 -1
  339. package/web-components/csp-styles.d.ts +6 -0
  340. package/web-components/csp-styles.d.ts.map +1 -0
  341. package/web-components/csp-styles.js +53 -0
  342. package/web-components/elements.d.ts +158 -2
  343. package/web-components/elements.d.ts.map +1 -1
  344. package/web-components/elements.js +1302 -215
  345. package/web-components/export-redaction.d.ts +252 -0
  346. package/web-components/export-redaction.d.ts.map +1 -0
  347. package/web-components/export-redaction.js +588 -0
  348. package/web-components/export.d.ts +417 -0
  349. package/web-components/export.d.ts.map +1 -0
  350. package/web-components/export.js +719 -0
  351. package/web-components/feature-editor-model.d.ts +265 -0
  352. package/web-components/feature-editor-model.d.ts.map +1 -0
  353. package/web-components/feature-editor-model.js +438 -0
  354. package/web-components/feature-editor-sketch.d.ts +125 -0
  355. package/web-components/feature-editor-sketch.d.ts.map +1 -0
  356. package/web-components/feature-editor-sketch.js +194 -0
  357. package/web-components/feature-editor-workflow.d.ts +286 -0
  358. package/web-components/feature-editor-workflow.d.ts.map +1 -0
  359. package/web-components/feature-editor-workflow.js +889 -0
  360. package/web-components/feature-editor.d.ts +83 -0
  361. package/web-components/feature-editor.d.ts.map +1 -0
  362. package/web-components/feature-editor.js +829 -0
  363. package/web-components/feature-table-engine.d.ts +465 -0
  364. package/web-components/feature-table-engine.d.ts.map +1 -0
  365. package/web-components/feature-table-engine.js +1360 -0
  366. package/web-components/feature-table-view.d.ts +95 -0
  367. package/web-components/feature-table-view.d.ts.map +1 -0
  368. package/web-components/feature-table-view.js +343 -0
  369. package/web-components/index.d.ts +34 -3
  370. package/web-components/index.d.ts.map +1 -1
  371. package/web-components/index.js +35 -2
  372. package/web-components/maplibre-renderer.d.ts.map +1 -1
  373. package/web-components/maplibre-renderer.js +13 -4
  374. package/web-components/measurement.d.ts +3 -1
  375. package/web-components/measurement.d.ts.map +1 -1
  376. package/web-components/measurement.js +62 -18
  377. package/web-components/time-slider.d.ts +122 -0
  378. package/web-components/time-slider.d.ts.map +1 -0
  379. package/web-components/time-slider.js +740 -0
  380. package/web-components/types.d.ts +310 -0
  381. package/web-components/types.d.ts.map +1 -1
  382. package/webmap/convert-label.js +0 -1
  383. package/webmap/convert-symbol.d.ts.map +1 -1
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Bounded mount lifecycle for Cesium scene primitives.
3
+ *
4
+ * `applyCesiumScenePrimitives()` is a one-shot projection: it hands back the
5
+ * layer handles it created and forgets them. That is fine for a script and wrong
6
+ * for an application, which must be able to revise the plan, cancel a mount that
7
+ * is still loading, and prove on unmount that nothing survived.
8
+ *
9
+ * {@link mountScenePrimitivesToCesium} adds the missing half — one handle that
10
+ * owns every adapter-created renderer resource for as long as the plan is live:
11
+ *
12
+ * - **Bounded.** A mount owns at most {@link MountScenePrimitivesToCesiumOptions.maxLayers}
13
+ * layer handles. A plan that would exceed the ceiling is rejected before the
14
+ * Cesium peer is even loaded, so the ceiling is a real admission gate rather
15
+ * than a post-hoc count.
16
+ * - **Diffed.** Re-applying a revised plan reuses every primitive whose identity
17
+ * and configuration are unchanged and disposes exactly the ones that left.
18
+ * - **Cancellation-safe.** An `AbortSignal` — the caller's, or the mount's own,
19
+ * fired by `dispose()` — unwinds an in-flight application through the adapter's
20
+ * transactional rollback, so an abandoned mount attaches nothing.
21
+ * - **Provably released.** `dispose()` is idempotent and releases every handle
22
+ * the mount owns exactly once, including after a partially failed application.
23
+ *
24
+ * Diagnostics stay plan-scoped: every application re-diagnoses the whole plan
25
+ * against {@link CESIUM_SCENE_CAPABILITIES}, so a reused primitive still reports
26
+ * its current spatial-reference, terrain, and model findings. The mount adds one
27
+ * lifecycle diagnostic per application describing what it created, reused, and
28
+ * disposed. Plan findings say whether a binding *can* render correctly; mount
29
+ * findings say what the renderer currently owns.
30
+ *
31
+ * Revisions additionally name what they had to cross. Every binding in a
32
+ * revision gets a {@link SceneRebuildBoundaryReport}, and each crossing that was
33
+ * *not* incremental also emits a `scene-mount-rebuild-boundary` diagnostic. A
34
+ * realtime data delta therefore reads as "this binding was rebuilt, for this
35
+ * reason, while these were reused", and a pure time advance reads as a revision
36
+ * with no crossings at all — application time lives in the workspace state, not
37
+ * in the plan, so it is outside the fingerprint the diff runs on.
38
+ *
39
+ * @beta Part of the beta `@honua/app-platform/scene-workspace` surface: the
40
+ * mount handle's shape, its idempotent `dispose()`, and the layer ceiling's
41
+ * fail-closed admission behavior hold through 0.1.x, and mount diagnostic
42
+ * codes grow additively. See the surface tiers table in
43
+ * `docs/standalone-capability-matrix.md`.
44
+ * @module
45
+ */
46
+ import { type CesiumLayerHandle, type CesiumSceneRuntimeTarget } from "./cesium-adapter.js";
47
+ import { type SceneRebuildBoundaryReport } from "./cesium-time.js";
48
+ import { type ScenePrimitiveApplyResult, type ScenePrimitiveDiagnostic, type SceneRuntimePrimitive } from "./primitives.js";
49
+ import type { SceneWorkspaceState } from "./types.js";
50
+ /**
51
+ * Default ceiling on the number of live layer handles one mount may own.
52
+ *
53
+ * Terrain, imagery, tilesets, and models each pin GPU and worker resources for
54
+ * as long as they are attached, so an unbounded plan is an unbounded leak. Sixty
55
+ * four is generous for a hand-authored or server-published scene and small
56
+ * enough that a runaway generated plan fails closed instead of exhausting the
57
+ * renderer. Raise it deliberately with
58
+ * {@link MountScenePrimitivesToCesiumOptions.maxLayers}.
59
+ */
60
+ export declare const DEFAULT_SCENE_MOUNT_LAYER_LIMIT = 64;
61
+ /**
62
+ * Failure codes raised by the scene mount lifecycle. Each one is a fail-closed
63
+ * refusal, never a partially applied plan.
64
+ */
65
+ export type CesiumSceneMountErrorCode = "disposed" | "invalid-option" | "layer-limit-exceeded";
66
+ /**
67
+ * A lifecycle refusal from {@link mountScenePrimitivesToCesium} or
68
+ * {@link MountedCesiumScenePrimitives.apply}. Renderer failures surfacing from
69
+ * Cesium itself keep their own error types; this one is raised only by the
70
+ * mount's own contract.
71
+ */
72
+ export declare class HonuaCesiumSceneMountError extends Error {
73
+ readonly code: CesiumSceneMountErrorCode;
74
+ readonly detail?: Readonly<Record<string, unknown>> | undefined;
75
+ constructor(code: CesiumSceneMountErrorCode, message: string, detail?: Readonly<Record<string, unknown>> | undefined, options?: ErrorOptions);
76
+ }
77
+ /**
78
+ * Lifecycle state of a scene mount.
79
+ *
80
+ * `disposing` is reachable in two ways: transiently, while `dispose()` runs, and
81
+ * durably, when a handle refused to release. The second case keeps the mount
82
+ * retryable — `dispose()` may be called again and will retry only what is still
83
+ * owned — while permanently refusing new applications.
84
+ */
85
+ export type CesiumSceneMountState = "ready" | "applying" | "disposing" | "disposed";
86
+ /** Options for {@link mountScenePrimitivesToCesium}. */
87
+ export interface MountScenePrimitivesToCesiumOptions {
88
+ /**
89
+ * Cancels the initial application. Aborting before or during materialization
90
+ * leaves the scene untouched, releases anything already attached, and rejects
91
+ * the mount promise with the signal's reason.
92
+ */
93
+ readonly signal?: AbortSignal;
94
+ /**
95
+ * Ceiling on the live layer handles this mount may own. Defaults to
96
+ * {@link DEFAULT_SCENE_MOUNT_LAYER_LIMIT}. Must be a positive integer.
97
+ */
98
+ readonly maxLayers?: number;
99
+ /**
100
+ * Workspace state carried alongside the plan, mirroring the adapter's `apply`.
101
+ * Its `timeline` slice drives the target's clock (when the host bound one) and
102
+ * its `realtime` slice is recorded as the application's provenance.
103
+ */
104
+ readonly state?: SceneWorkspaceState;
105
+ }
106
+ /** Options for {@link MountedCesiumScenePrimitives.apply}. */
107
+ export interface ApplyMountedScenePrimitivesOptions {
108
+ /** Cancels this application only; the mount itself stays usable. */
109
+ readonly signal?: AbortSignal;
110
+ /**
111
+ * Workspace state carried alongside the plan, mirroring the adapter's `apply`.
112
+ * Its `timeline` slice drives the target's clock (when the host bound one) and
113
+ * its `realtime` slice is recorded as the application's provenance.
114
+ */
115
+ readonly state?: SceneWorkspaceState;
116
+ }
117
+ /**
118
+ * The result of one application through a mount: the adapter's own apply result
119
+ * plus the diff that produced it.
120
+ */
121
+ export interface MountedScenePrimitiveApplyResult extends ScenePrimitiveApplyResult {
122
+ /** Live layer handles keyed by primitive id, reused and newly created alike. */
123
+ readonly layers: ReadonlyMap<string, CesiumLayerHandle>;
124
+ /** 1 for the initial application, incremented for every revision. */
125
+ readonly revision: number;
126
+ /** Ids whose renderer resource was constructed by this application. */
127
+ readonly created: readonly string[];
128
+ /** Ids whose renderer resource was carried forward untouched. */
129
+ readonly reused: readonly string[];
130
+ /** Ids whose renderer resource was released because the primitive left or changed. */
131
+ readonly disposed: readonly string[];
132
+ /**
133
+ * One entry per binding involved in this update, naming the rebuild boundary
134
+ * it crossed — `"none"` for the bindings applied in place. This is the single
135
+ * list that answers "which parts of this update were incremental, and which
136
+ * forced a rebuild".
137
+ *
138
+ * Empty on the initial application: with no previously mounted plan to
139
+ * compare against, every binding is a construction rather than a crossing,
140
+ * and `created` already reports that.
141
+ */
142
+ readonly rebuildBoundaries: readonly SceneRebuildBoundaryReport[];
143
+ }
144
+ /**
145
+ * One mount of a scene plan against a live Cesium target.
146
+ *
147
+ * The mount owns every layer handle it created. Callers hold the mount, not the
148
+ * handles: a revision goes through {@link apply} and teardown goes through
149
+ * {@link dispose}, so there is never a set of handles the caller must remember
150
+ * to release separately.
151
+ */
152
+ export interface MountedCesiumScenePrimitives {
153
+ readonly renderer: "cesium";
154
+ /** Lifecycle state. See {@link CesiumSceneMountState}. */
155
+ readonly state: CesiumSceneMountState;
156
+ /** Status of the most recent application, summarized from its diagnostics. */
157
+ readonly status: ScenePrimitiveApplyResult["status"];
158
+ /** Diagnostics from the most recent application: plan findings plus the lifecycle finding. */
159
+ readonly diagnostics: readonly ScenePrimitiveDiagnostic[];
160
+ /** Live layer handles keyed by primitive id. Empty once disposed. */
161
+ readonly layers: ReadonlyMap<string, CesiumLayerHandle>;
162
+ /** Rebuild boundaries crossed by the most recent application. */
163
+ readonly rebuildBoundaries: readonly SceneRebuildBoundaryReport[];
164
+ /** The ceiling this mount was created with. */
165
+ readonly layerLimit: number;
166
+ /** 1 after the initial application, incremented for every revision. */
167
+ readonly revision: number;
168
+ /**
169
+ * Apply a revised plan through this mount. Primitives whose identity and
170
+ * configuration are unchanged are reused untouched; primitives that left the
171
+ * plan — or whose configuration changed — are disposed once the revision has
172
+ * landed. A failure rolls the scene back to the previously applied plan.
173
+ *
174
+ * Applications are serialized: a second call queues behind the first rather
175
+ * than interleaving scene mutations.
176
+ *
177
+ * Re-applying the *same* plan with a moved `options.state.timeline` is the
178
+ * incremental time path: nothing is rebuilt, every handle is carried forward
179
+ * by identity, and only the bound clock changes.
180
+ */
181
+ apply(primitives: readonly SceneRuntimePrimitive[], options?: ApplyMountedScenePrimitivesOptions): Promise<MountedScenePrimitiveApplyResult>;
182
+ /**
183
+ * Release every resource this mount owns. Idempotent: the second call is a
184
+ * no-op. Cancels any in-flight application first, so a mount disposed mid-load
185
+ * cannot be completed behind the caller's back.
186
+ *
187
+ * If a handle refuses to release, the failures are aggregated and thrown, the
188
+ * mount stays in `disposing`, and a later `dispose()` retries only what is
189
+ * still owned.
190
+ */
191
+ dispose(): void;
192
+ }
193
+ /**
194
+ * Mount a scene plan against a live Cesium target and return the handle that
195
+ * owns it.
196
+ *
197
+ * The initial plan is applied before the promise resolves, so a resolved mount
198
+ * is a mounted scene. A rejection means nothing was left attached: the adapter's
199
+ * transactional rollback has already run.
200
+ *
201
+ * @param target Live Cesium `Viewer`/`Scene` surface (a `camera`, optionally a `scene`).
202
+ * @param primitives The accepted scene plan.
203
+ */
204
+ export declare function mountScenePrimitivesToCesium(target: CesiumSceneRuntimeTarget, primitives: readonly SceneRuntimePrimitive[], options?: MountScenePrimitivesToCesiumOptions): Promise<MountedCesiumScenePrimitives>;
205
+ //# sourceMappingURL=cesium-mount.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cesium-mount.d.ts","sourceRoot":"","sources":["../../../src/scene-workspace/cesium-mount.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,392 @@
1
+ /**
2
+ * Bounded mount lifecycle for Cesium scene primitives.
3
+ *
4
+ * `applyCesiumScenePrimitives()` is a one-shot projection: it hands back the
5
+ * layer handles it created and forgets them. That is fine for a script and wrong
6
+ * for an application, which must be able to revise the plan, cancel a mount that
7
+ * is still loading, and prove on unmount that nothing survived.
8
+ *
9
+ * {@link mountScenePrimitivesToCesium} adds the missing half — one handle that
10
+ * owns every adapter-created renderer resource for as long as the plan is live:
11
+ *
12
+ * - **Bounded.** A mount owns at most {@link MountScenePrimitivesToCesiumOptions.maxLayers}
13
+ * layer handles. A plan that would exceed the ceiling is rejected before the
14
+ * Cesium peer is even loaded, so the ceiling is a real admission gate rather
15
+ * than a post-hoc count.
16
+ * - **Diffed.** Re-applying a revised plan reuses every primitive whose identity
17
+ * and configuration are unchanged and disposes exactly the ones that left.
18
+ * - **Cancellation-safe.** An `AbortSignal` — the caller's, or the mount's own,
19
+ * fired by `dispose()` — unwinds an in-flight application through the adapter's
20
+ * transactional rollback, so an abandoned mount attaches nothing.
21
+ * - **Provably released.** `dispose()` is idempotent and releases every handle
22
+ * the mount owns exactly once, including after a partially failed application.
23
+ *
24
+ * Diagnostics stay plan-scoped: every application re-diagnoses the whole plan
25
+ * against {@link CESIUM_SCENE_CAPABILITIES}, so a reused primitive still reports
26
+ * its current spatial-reference, terrain, and model findings. The mount adds one
27
+ * lifecycle diagnostic per application describing what it created, reused, and
28
+ * disposed. Plan findings say whether a binding *can* render correctly; mount
29
+ * findings say what the renderer currently owns.
30
+ *
31
+ * Revisions additionally name what they had to cross. Every binding in a
32
+ * revision gets a {@link SceneRebuildBoundaryReport}, and each crossing that was
33
+ * *not* incremental also emits a `scene-mount-rebuild-boundary` diagnostic. A
34
+ * realtime data delta therefore reads as "this binding was rebuilt, for this
35
+ * reason, while these were reused", and a pure time advance reads as a revision
36
+ * with no crossings at all — application time lives in the workspace state, not
37
+ * in the plan, so it is outside the fingerprint the diff runs on.
38
+ *
39
+ * @beta Part of the beta `@honua/app-platform/scene-workspace` surface: the
40
+ * mount handle's shape, its idempotent `dispose()`, and the layer ceiling's
41
+ * fail-closed admission behavior hold through 0.1.x, and mount diagnostic
42
+ * codes grow additively. See the surface tiers table in
43
+ * `docs/standalone-capability-matrix.md`.
44
+ * @module
45
+ */
46
+ import { CESIUM_SCENE_CAPABILITIES, applyCesiumScenePrimitivesInternal, scenePrimitiveFingerprint, scenePrimitiveMountKey, } from "./cesium-adapter.js";
47
+ import { sceneRebuildBoundaryReport, } from "./cesium-time.js";
48
+ import { summarizeDiagnosticStatus, } from "./primitives.js";
49
+ /**
50
+ * Default ceiling on the number of live layer handles one mount may own.
51
+ *
52
+ * Terrain, imagery, tilesets, and models each pin GPU and worker resources for
53
+ * as long as they are attached, so an unbounded plan is an unbounded leak. Sixty
54
+ * four is generous for a hand-authored or server-published scene and small
55
+ * enough that a runaway generated plan fails closed instead of exhausting the
56
+ * renderer. Raise it deliberately with
57
+ * {@link MountScenePrimitivesToCesiumOptions.maxLayers}.
58
+ */
59
+ export const DEFAULT_SCENE_MOUNT_LAYER_LIMIT = 64;
60
+ /**
61
+ * A lifecycle refusal from {@link mountScenePrimitivesToCesium} or
62
+ * {@link MountedCesiumScenePrimitives.apply}. Renderer failures surfacing from
63
+ * Cesium itself keep their own error types; this one is raised only by the
64
+ * mount's own contract.
65
+ */
66
+ export class HonuaCesiumSceneMountError extends Error {
67
+ code;
68
+ detail;
69
+ constructor(code, message, detail, options) {
70
+ super(message, options);
71
+ this.code = code;
72
+ this.detail = detail;
73
+ this.name = "HonuaCesiumSceneMountError";
74
+ }
75
+ }
76
+ /**
77
+ * Mount a scene plan against a live Cesium target and return the handle that
78
+ * owns it.
79
+ *
80
+ * The initial plan is applied before the promise resolves, so a resolved mount
81
+ * is a mounted scene. A rejection means nothing was left attached: the adapter's
82
+ * transactional rollback has already run.
83
+ *
84
+ * @param target Live Cesium `Viewer`/`Scene` surface (a `camera`, optionally a `scene`).
85
+ * @param primitives The accepted scene plan.
86
+ */
87
+ export async function mountScenePrimitivesToCesium(target, primitives, options = {}) {
88
+ const layerLimit = resolveLayerLimit(options.maxLayers);
89
+ const lifecycle = new AbortController();
90
+ let entries = new Map();
91
+ let orphans = [];
92
+ let diagnostics = [];
93
+ let rebuildBoundaries = Object.freeze([]);
94
+ let status = "supported";
95
+ let state = "ready";
96
+ let revision = 0;
97
+ let applyTail = Promise.resolve();
98
+ let disposeActive = false;
99
+ const runApply = async (plan, applyOptions) => {
100
+ if (state === "disposing" || state === "disposed") {
101
+ throw new HonuaCesiumSceneMountError("disposed", "Cannot apply a plan through a disposed Cesium scene mount.");
102
+ }
103
+ assertWithinLayerLimit(plan, layerLimit);
104
+ const signal = combineSignals([lifecycle.signal, applyOptions.signal]);
105
+ signal.throwIfAborted();
106
+ // Identity + configuration diff against what is already mounted. A primitive
107
+ // with no fingerprint is treated as changed, never as unchanged.
108
+ //
109
+ // The same walk names the rebuild boundary each binding crosses, so the
110
+ // reuse decision and the diagnostic that explains it can never disagree.
111
+ // Boundaries are only meaningful against a previously mounted plan, so the
112
+ // initial application reports none.
113
+ const isRevision = revision > 0;
114
+ const boundaries = [];
115
+ const reuse = new Map();
116
+ const planEntries = [];
117
+ for (const primitive of plan) {
118
+ const key = scenePrimitiveMountKey(primitive);
119
+ const fingerprint = scenePrimitiveFingerprint(primitive);
120
+ const previous = entries.get(key);
121
+ const unchanged = previous !== undefined && fingerprint !== undefined && previous.fingerprint === fingerprint;
122
+ if (unchanged)
123
+ reuse.set(key, previous.handle);
124
+ if (isRevision) {
125
+ boundaries.push(sceneRebuildBoundaryReport(primitive.id, primitive.kind, boundaryFor(previous, fingerprint)));
126
+ }
127
+ planEntries.push({ key, id: primitive.id, kind: primitive.kind, fingerprint, handle: undefined });
128
+ }
129
+ state = "applying";
130
+ let application;
131
+ try {
132
+ application = await applyCesiumScenePrimitivesInternal(target, plan, {
133
+ signal,
134
+ reuse,
135
+ ...(applyOptions.state ? { state: applyOptions.state } : {}),
136
+ });
137
+ }
138
+ finally {
139
+ if (state === "applying")
140
+ state = "ready";
141
+ }
142
+ if (lifecycle.signal.aborted) {
143
+ // Disposal won the race with a materialization that had no checkpoint left
144
+ // to hit. Release what this application built rather than committing it
145
+ // into a mount the host has already torn down.
146
+ releaseHandles(collectCreatedHandles(application.mounted, reuse));
147
+ throw lifecycle.signal.reason;
148
+ }
149
+ // Only now that the revision has landed is it safe to release what it
150
+ // displaced. Disposing earlier would make a mid-application failure
151
+ // unrecoverable.
152
+ const nextEntries = new Map();
153
+ for (const entry of planEntries) {
154
+ nextEntries.set(entry.key, { ...entry, handle: application.mounted.get(entry.key) });
155
+ }
156
+ const disposed = [];
157
+ const disposalFailures = [];
158
+ for (const entry of [...entries.values()].reverse()) {
159
+ if (reuse.has(entry.key) || !entry.handle)
160
+ continue;
161
+ try {
162
+ entry.handle.remove();
163
+ disposed.push(entry.id);
164
+ }
165
+ catch (error) {
166
+ disposalFailures.push(error);
167
+ // Still owned, so still this mount's problem: `dispose()` retries it.
168
+ orphans.push(entry.handle);
169
+ }
170
+ }
171
+ // A binding that left the plan entirely crosses its own boundary; it is not
172
+ // in `plan`, so the diff walk above could not have reported it.
173
+ if (isRevision) {
174
+ for (const entry of entries.values()) {
175
+ if (nextEntries.has(entry.key))
176
+ continue;
177
+ boundaries.push(sceneRebuildBoundaryReport(entry.id, entry.kind, "plan-membership"));
178
+ }
179
+ }
180
+ entries = nextEntries;
181
+ revision += 1;
182
+ rebuildBoundaries = Object.freeze([...boundaries]);
183
+ const crossed = rebuildBoundaries.filter((report) => !report.incremental);
184
+ const lifecycleDiagnostics = [
185
+ appliedDiagnostic(revision, application.created, application.reused, disposed, layerLimit, entries.size, applyOptions.state?.realtime, application.time.applied),
186
+ ...crossed.map((report) => rebuildBoundaryDiagnostic(revision, report)),
187
+ ...(disposalFailures.length > 0 ? [disposalIncompleteDiagnostic(disposalFailures)] : []),
188
+ ];
189
+ diagnostics = Object.freeze([...application.diagnostics, ...lifecycleDiagnostics]);
190
+ status = summarizeDiagnosticStatus(diagnostics);
191
+ return {
192
+ status,
193
+ diagnostics,
194
+ layers: application.layers,
195
+ revision,
196
+ created: Object.freeze([...application.created]),
197
+ reused: Object.freeze([...application.reused]),
198
+ disposed: Object.freeze(disposed),
199
+ rebuildBoundaries,
200
+ };
201
+ };
202
+ const enqueueApply = (plan, applyOptions) => {
203
+ const value = applyTail.then(() => runApply(plan, applyOptions));
204
+ applyTail = value.then(() => undefined, () => undefined);
205
+ return value;
206
+ };
207
+ await runApply(primitives, {
208
+ ...(options.signal ? { signal: options.signal } : {}),
209
+ ...(options.state ? { state: options.state } : {}),
210
+ });
211
+ return {
212
+ renderer: "cesium",
213
+ get state() {
214
+ return state;
215
+ },
216
+ get status() {
217
+ return status;
218
+ },
219
+ get diagnostics() {
220
+ return diagnostics;
221
+ },
222
+ get rebuildBoundaries() {
223
+ return rebuildBoundaries;
224
+ },
225
+ get layers() {
226
+ const live = new Map();
227
+ for (const entry of entries.values())
228
+ if (entry.handle)
229
+ live.set(entry.id, entry.handle);
230
+ return live;
231
+ },
232
+ layerLimit,
233
+ get revision() {
234
+ return revision;
235
+ },
236
+ apply(plan, applyOptions = {}) {
237
+ return enqueueApply(plan, applyOptions);
238
+ },
239
+ dispose() {
240
+ if (state === "disposed" || disposeActive)
241
+ return;
242
+ disposeActive = true;
243
+ if (!lifecycle.signal.aborted) {
244
+ lifecycle.abort(new DOMException("Cesium scene mount disposed", "AbortError"));
245
+ }
246
+ state = "disposing";
247
+ try {
248
+ // Reverse construction order, orphaned handles from an earlier failure
249
+ // first, so a retry drains the backlog before the current plan.
250
+ const owned = [...entries.values()]
251
+ .reverse()
252
+ .map((entry) => entry.handle)
253
+ .filter((handle) => handle !== undefined);
254
+ const pending = [...orphans, ...owned];
255
+ orphans = [];
256
+ entries = new Map();
257
+ const failures = releaseHandles(pending);
258
+ orphans = failures.retained;
259
+ if (failures.errors.length > 0) {
260
+ throw new AggregateError(failures.errors, "Cesium scene mount disposal is incomplete and may be retried.");
261
+ }
262
+ state = "disposed";
263
+ }
264
+ finally {
265
+ disposeActive = false;
266
+ }
267
+ },
268
+ };
269
+ }
270
+ function collectCreatedHandles(mountedHandles, reuse) {
271
+ const handles = [];
272
+ for (const [key, handle] of mountedHandles) {
273
+ if (handle && !reuse.has(key))
274
+ handles.push(handle);
275
+ }
276
+ return handles.reverse();
277
+ }
278
+ function releaseHandles(handles) {
279
+ const errors = [];
280
+ const retained = [];
281
+ for (const handle of handles) {
282
+ try {
283
+ handle.remove();
284
+ }
285
+ catch (error) {
286
+ errors.push(error);
287
+ retained.push(handle);
288
+ }
289
+ }
290
+ return { errors, retained };
291
+ }
292
+ /**
293
+ * Reject an over-budget plan before the Cesium peer loads.
294
+ *
295
+ * The count is of primitives that would each materialize one adapter-owned layer
296
+ * handle. Camera, ground, extrusion, and scene-layer-metadata primitives own no
297
+ * renderer resource on this adapter and are not counted; an unsupported binding
298
+ * is counted, because refusing a plan must not depend on which of its bindings
299
+ * happen to be renderable today.
300
+ */
301
+ function assertWithinLayerLimit(primitives, layerLimit) {
302
+ const layerCount = primitives.filter((primitive) => primitive.kind === "elevation-source" || primitive.kind === "imagery-layer" || primitive.kind === "model-layer").length;
303
+ if (layerCount > layerLimit) {
304
+ throw new HonuaCesiumSceneMountError("layer-limit-exceeded", `Scene plan declares ${layerCount} renderer layers, exceeding the mount ceiling ${layerLimit}.`, { layerCount, layerLimit });
305
+ }
306
+ }
307
+ function resolveLayerLimit(maxLayers) {
308
+ if (maxLayers === undefined)
309
+ return DEFAULT_SCENE_MOUNT_LAYER_LIMIT;
310
+ if (!Number.isSafeInteger(maxLayers) || maxLayers <= 0) {
311
+ throw new HonuaCesiumSceneMountError("invalid-option", "maxLayers must be a positive integer.", { maxLayers });
312
+ }
313
+ return maxLayers;
314
+ }
315
+ /**
316
+ * Classify one plan binding against what this mount already owns.
317
+ *
318
+ * The order matters: a binding the mount has never seen is an identity
319
+ * crossing regardless of whether it can be fingerprinted, and an
320
+ * unfingerprintable revision is called out as such rather than being reported as
321
+ * a configuration change nobody made.
322
+ */
323
+ function boundaryFor(previous, fingerprint) {
324
+ if (previous === undefined)
325
+ return "primitive-identity";
326
+ if (fingerprint === undefined)
327
+ return "unfingerprintable";
328
+ return previous.fingerprint === fingerprint ? "none" : "primitive-configuration";
329
+ }
330
+ function appliedDiagnostic(revision, created, reused, disposed, layerLimit, mountedPrimitiveCount, realtime, timeApplied) {
331
+ return {
332
+ code: "scene-mount-applied",
333
+ severity: "info",
334
+ status: "supported",
335
+ renderer: CESIUM_SCENE_CAPABILITIES.renderer,
336
+ message: `Applied scene plan revision ${revision}: created ${created.length}, reused ${reused.length}, disposed ${disposed.length}.`,
337
+ context: {
338
+ revision,
339
+ created: [...created],
340
+ reused: [...reused],
341
+ disposed: [...disposed],
342
+ layerLimit,
343
+ mountedPrimitiveCount,
344
+ // Whether this revision also moved application time, so a time-only
345
+ // revision is legible as one rather than as an application that did
346
+ // nothing.
347
+ timeApplied,
348
+ // Provenance for a revision driven by a live feed: which feed state the
349
+ // delta arrived under, so a rebuild can be read against a reconnect or a
350
+ // stale window rather than in isolation.
351
+ ...(realtime
352
+ ? {
353
+ realtime: {
354
+ status: realtime.status,
355
+ ...(realtime.cursor === undefined ? {} : { cursor: realtime.cursor }),
356
+ ...(realtime.staleSince === undefined ? {} : { staleSince: realtime.staleSince }),
357
+ },
358
+ }
359
+ : {}),
360
+ },
361
+ };
362
+ }
363
+ function rebuildBoundaryDiagnostic(revision, report) {
364
+ return {
365
+ code: "scene-mount-rebuild-boundary",
366
+ severity: "info",
367
+ status: "supported",
368
+ primitiveId: report.id,
369
+ primitiveKind: report.kind,
370
+ renderer: CESIUM_SCENE_CAPABILITIES.renderer,
371
+ message: `Revision ${revision} could not update ${report.id} in place: ${report.reason}`,
372
+ context: { revision, rebuildBoundary: report.boundary, incremental: report.incremental },
373
+ };
374
+ }
375
+ function disposalIncompleteDiagnostic(failures) {
376
+ return {
377
+ code: "scene-mount-disposal-incomplete",
378
+ severity: "error",
379
+ status: "degraded",
380
+ renderer: CESIUM_SCENE_CAPABILITIES.renderer,
381
+ message: `${failures.length} displaced layer handle(s) refused to release; the revised plan is mounted and the handles remain owned.`,
382
+ fallback: "Call dispose() to retry releasing the retained handles.",
383
+ context: {
384
+ retainedHandleCount: failures.length,
385
+ failures: failures.map((failure) => (failure instanceof Error ? failure.message : String(failure))),
386
+ },
387
+ };
388
+ }
389
+ function combineSignals(signals) {
390
+ const available = signals.filter((signal) => signal !== undefined);
391
+ return available.length === 1 ? available[0] : AbortSignal.any(available);
392
+ }