@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,432 @@
1
+ /**
2
+ * The shipped 3D {@link SceneStateSyncPort}: a live Cesium `Viewer` bound to the
3
+ * shared scene state.
4
+ *
5
+ * The camera half reuses the adapter's existing conversion
6
+ * (`cameraStateToCesiumView` / `cesiumCameraToSceneState` /
7
+ * `applyCameraStateToCesiumCamera`) rather than re-deriving it, because the
8
+ * renderer-neutral camera *is* a globe pose — there is nothing to project. The
9
+ * slices that a globe expresses differently from a 2D map are declared
10
+ * differently by this port's own `mappings`, so a fidelity claim is always
11
+ * backed by the code that makes it.
12
+ *
13
+ * CesiumJS stays an optional peer: the viewer is duck-typed, and the only
14
+ * reference to the package is a lazy `import("cesium")` performed on the first
15
+ * apply that actually needs a Cesium constructor.
16
+ *
17
+ * @beta Part of the beta `@honua/app-platform/scene-workspace` surface.
18
+ * @module
19
+ */
20
+ import { applyCameraStateToCesiumCamera, cesiumCameraToSceneState } from "./cesium-adapter.js";
21
+ import { applyCesiumClockPlan, cesiumClockPlanWrites, readCesiumClock, restoreCesiumClock, sceneTimelineToCesiumClockPlan, } from "./cesium-time.js";
22
+ import { createPortCore, } from "./state-sync-port-kit.js";
23
+ import { HonuaSceneStateSyncError, } from "./state-sync.js";
24
+ const DEFAULT_PORT_ID = "cesium-state-sync";
25
+ /**
26
+ * Bind a live Cesium viewer to the shared scene state.
27
+ *
28
+ * Camera and selection changes are published automatically where the viewer
29
+ * raises an event for them (`camera.changed`, `camera.moveEnd`,
30
+ * `selectedEntityChanged`); everything else is published by the host. Because a
31
+ * globe's camera event is frame-driven, {@link SceneStateSyncRendererPort.readFromRenderer}
32
+ * is the deterministic pull complement.
33
+ */
34
+ export function createCesiumStateSyncPort(viewer, options) {
35
+ if (viewer === null || typeof viewer !== "object" || viewer.camera === null || typeof viewer.camera !== "object")
36
+ throw new HonuaSceneStateSyncError("invalid-input", "viewer.camera must be a live Cesium camera");
37
+ if (typeof viewer.camera.setView !== "function")
38
+ throw new HonuaSceneStateSyncError("invalid-input", "viewer.camera.setView must be a function");
39
+ if (options === null || typeof options !== "object" || options.identity === undefined)
40
+ throw new HonuaSceneStateSyncError("invalid-input", "options.identity is required");
41
+ const id = options.id ?? DEFAULT_PORT_ID;
42
+ const sourceId = options.sourceId ?? options.identity.sourceId;
43
+ const entitiesCapable = viewer.entities !== undefined && Array.isArray(viewer.entities.values);
44
+ const selectionCapable = entitiesCapable && "selectedEntity" in viewer;
45
+ const clockOwned = viewer.clock !== undefined && viewer.clock !== null && viewer.clockOwnership !== "host";
46
+ const baselineShow = new Map();
47
+ let displacedClock;
48
+ let module = typeof options.cesium === "object" ? options.cesium : undefined;
49
+ // Renderer events raised *during* an apply are echoes by construction. They
50
+ // are deferred rather than dropped so the acknowledgement still reaches the
51
+ // synchronizer (as `loop-suppressed`) once the read-back has been recorded.
52
+ let applyingCamera = false;
53
+ let cameraEventDuringApply = false;
54
+ let applyingSelection = false;
55
+ let selectionEventDuringApply = false;
56
+ const entityIdForTarget = options.entityIdForTarget ??
57
+ ((target) => {
58
+ if (typeof target === "string" || typeof target === "number")
59
+ return String(target);
60
+ const record = target;
61
+ return typeof record.id === "string" || typeof record.id === "number" ? String(record.id) : undefined;
62
+ });
63
+ const targetForEntityId = options.targetForEntityId ?? ((entityId) => ({ sourceId, id: entityId }));
64
+ const entityProperty = options.entityProperty ?? defaultEntityProperty;
65
+ const core = createPortCore({
66
+ id,
67
+ renderer: "cesium",
68
+ identity: options.identity,
69
+ ...(options.now ? { now: options.now } : {}),
70
+ ...(options.onDegraded ? { onDegraded: options.onDegraded } : {}),
71
+ bind: () => {
72
+ const releases = [];
73
+ const publishCamera = () => {
74
+ if (applyingCamera) {
75
+ cameraEventDuringApply = true;
76
+ return;
77
+ }
78
+ core.publish("camera", readCamera());
79
+ };
80
+ releases.push(listen(viewer.camera.changed, publishCamera));
81
+ releases.push(listen(viewer.camera.moveEnd, publishCamera));
82
+ if (selectionCapable) {
83
+ releases.push(listen(viewer.selectedEntityChanged, () => {
84
+ if (applyingSelection) {
85
+ selectionEventDuringApply = true;
86
+ return;
87
+ }
88
+ core.publish("selection", readSelection());
89
+ }));
90
+ }
91
+ return () => {
92
+ for (const release of releases.reverse())
93
+ release();
94
+ };
95
+ },
96
+ });
97
+ async function cesium() {
98
+ if (module)
99
+ return module;
100
+ module =
101
+ typeof options.cesium === "function"
102
+ ? await options.cesium()
103
+ : (await import("cesium"));
104
+ return module;
105
+ }
106
+ function readCamera() {
107
+ return cesiumCameraToSceneState(viewer.camera);
108
+ }
109
+ function readSelection() {
110
+ const entity = viewer.selectedEntity;
111
+ if (!entity || typeof entity.id !== "string")
112
+ return Object.freeze([]);
113
+ const target = targetForEntityId(entity.id);
114
+ return target === undefined ? Object.freeze([]) : Object.freeze([target]);
115
+ }
116
+ function readTime() {
117
+ if (!module || !viewer.clock)
118
+ return Object.freeze({});
119
+ const clock = readCesiumClock(viewer.clock);
120
+ const currentTime = isoFromJulian(module, clock.currentTime);
121
+ const startTime = isoFromJulian(module, clock.startTime);
122
+ const endTime = isoFromJulian(module, clock.stopTime);
123
+ return Object.freeze({
124
+ ...(currentTime === undefined ? {} : { currentTime }),
125
+ ...(startTime === undefined ? {} : { startTime }),
126
+ ...(endTime === undefined ? {} : { endTime }),
127
+ ...(typeof clock.shouldAnimate === "boolean" ? { playing: clock.shouldAnimate } : {}),
128
+ ...(typeof clock.multiplier === "number" && Number.isFinite(clock.multiplier) ? { speed: clock.multiplier } : {}),
129
+ });
130
+ }
131
+ async function applyCamera(camera, revision) {
132
+ if (camera === undefined)
133
+ return;
134
+ const mod = await cesium();
135
+ cameraEventDuringApply = false;
136
+ applyingCamera = true;
137
+ try {
138
+ applyCameraStateToCesiumCamera(viewer.camera, camera, (longitude, latitude, height) => mod.Cartesian3.fromDegrees(longitude, latitude, height));
139
+ }
140
+ finally {
141
+ applyingCamera = false;
142
+ }
143
+ viewer.scene?.requestRender?.();
144
+ core.markApplied("camera", revision, readCamera(), camera);
145
+ if (cameraEventDuringApply) {
146
+ cameraEventDuringApply = false;
147
+ core.publish("camera", readCamera());
148
+ }
149
+ }
150
+ async function applyTime(time, revision) {
151
+ const clock = viewer.clock;
152
+ if (!clock) {
153
+ core.degrade("time", "time-clock-unavailable", "This viewer exposes no clock, so shared time cannot advance it.", {
154
+ revision,
155
+ });
156
+ return;
157
+ }
158
+ if (viewer.clockOwnership === "host") {
159
+ core.degrade("time", "time-clock-host-owned", "This viewer declares host-owned transport, so the port stood down instead of writing the clock.", { revision });
160
+ return;
161
+ }
162
+ // Reuse the scene adapter's clock plan rather than re-deriving the writes:
163
+ // it names what a timeline cannot express, and it orders the extent before
164
+ // the instant so a range-clamped clock accepts the new current time.
165
+ const plan = sceneTimelineToCesiumClockPlan(time);
166
+ if (plan && plan.rejected.length > 0) {
167
+ core.degrade("time", "time-plan-rejected", `Shared time fields were not interpretable: ${plan.rejected.join(", ")}.`, {
168
+ revision,
169
+ });
170
+ }
171
+ if (!cesiumClockPlanWrites(plan) || !plan) {
172
+ core.markApplied("time", revision, readTime(), time);
173
+ return;
174
+ }
175
+ const mod = await cesium();
176
+ const previous = applyCesiumClockPlan(clock, plan, mod);
177
+ displacedClock ??= previous;
178
+ viewer.scene?.requestRender?.();
179
+ core.markApplied("time", revision, readTime(), time);
180
+ }
181
+ function applySelection(targets, revision) {
182
+ if (!selectionCapable)
183
+ return;
184
+ const resolved = [];
185
+ for (const target of targets) {
186
+ const entityId = entityIdForTarget(target);
187
+ const entity = entityId === undefined ? undefined : findEntity(entityId);
188
+ if (!entity) {
189
+ core.degrade("selection", "selection-target-unresolved", `Selection target ${entityId ?? "(unaddressable)"} matches no entity in this scene.`, { revision });
190
+ continue;
191
+ }
192
+ resolved.push(entity);
193
+ }
194
+ if (resolved.length > 1) {
195
+ core.degrade("selection", "selection-not-fully-expressible", "A globe expresses one focused entity; the first resolvable target was applied and the rest were not drawn.", { revision, requested: resolved.length, applied: 1 });
196
+ }
197
+ selectionEventDuringApply = false;
198
+ applyingSelection = true;
199
+ try {
200
+ viewer.selectedEntity = resolved[0];
201
+ }
202
+ finally {
203
+ applyingSelection = false;
204
+ }
205
+ viewer.scene?.requestRender?.();
206
+ core.markApplied("selection", revision, readSelection(), targets);
207
+ if (selectionEventDuringApply) {
208
+ selectionEventDuringApply = false;
209
+ core.publish("selection", readSelection());
210
+ }
211
+ }
212
+ function applyFilters(filters, revision) {
213
+ if (!entitiesCapable || !viewer.entities)
214
+ return;
215
+ const clauses = Object.values(filters).filter((clause) => !clause.appliesTo || clause.appliesTo.length === 0 || clause.appliesTo.includes(sourceId));
216
+ for (const entity of viewer.entities.values) {
217
+ if (!baselineShow.has(entity.id))
218
+ baselineShow.set(entity.id, entity.show);
219
+ if (clauses.length === 0) {
220
+ entity.show = baselineShow.get(entity.id) ?? true;
221
+ continue;
222
+ }
223
+ entity.show = (baselineShow.get(entity.id) ?? true) && clauses.every((clause) => matches(entity, clause));
224
+ }
225
+ viewer.scene?.requestRender?.();
226
+ core.markApplied("filters", revision, filters);
227
+ }
228
+ function matches(entity, clause) {
229
+ const value = entityProperty(entity, clause.field);
230
+ switch (clause.operator) {
231
+ case "=":
232
+ return value === clause.value;
233
+ case "!=":
234
+ return value !== clause.value;
235
+ case "<":
236
+ case "<=":
237
+ case ">":
238
+ case ">=":
239
+ return compare(value, clause.value, clause.operator);
240
+ case "in":
241
+ return Array.isArray(clause.value) && clause.value.includes(value);
242
+ case "not-in":
243
+ return Array.isArray(clause.value) && !clause.value.includes(value);
244
+ case "between":
245
+ return (Array.isArray(clause.value) && compare(value, clause.value[0], ">=") && compare(value, clause.value[1], "<="));
246
+ case "is-null":
247
+ return value === null || value === undefined;
248
+ case "is-not-null":
249
+ return value !== null && value !== undefined;
250
+ case "like":
251
+ return typeof value === "string" && typeof clause.value === "string" && likeMatches(value, clause.value);
252
+ }
253
+ }
254
+ function findEntity(entityId) {
255
+ if (!viewer.entities)
256
+ return undefined;
257
+ if (typeof viewer.entities.getById === "function")
258
+ return viewer.entities.getById(entityId) ?? undefined;
259
+ return viewer.entities.values.find((entity) => entity.id === entityId);
260
+ }
261
+ async function apply(delivery) {
262
+ const { slice, value, revision } = delivery.envelope;
263
+ switch (slice) {
264
+ case "camera":
265
+ await applyCamera(value, revision);
266
+ return;
267
+ case "time":
268
+ await applyTime(value, revision);
269
+ return;
270
+ case "selection":
271
+ applySelection(value, revision);
272
+ return;
273
+ case "filters":
274
+ applyFilters(value, revision);
275
+ return;
276
+ default:
277
+ // `attribution` and `realtime` are credential-free host read models;
278
+ // `detail` never arrives because this port declares it unsupported.
279
+ core.markApplied(slice, revision, value);
280
+ }
281
+ }
282
+ const port = {
283
+ id,
284
+ renderer: "cesium",
285
+ mappings: buildMappings({ selectionCapable, entitiesCapable, clockOwned }),
286
+ subscribe(listener, signal) {
287
+ return core.subscribe(listener, signal);
288
+ },
289
+ apply(delivery) {
290
+ return apply(delivery);
291
+ },
292
+ publish(slice, value) {
293
+ return core.publish(slice, value);
294
+ },
295
+ readFromRenderer(slice) {
296
+ if (slice === "camera")
297
+ return core.publish("camera", readCamera());
298
+ if (slice === "selection" && selectionCapable)
299
+ return core.publish("selection", readSelection());
300
+ if (slice === "time" && viewer.clock !== undefined && module)
301
+ return core.publish("time", readTime());
302
+ return "unsupported";
303
+ },
304
+ get degradations() {
305
+ return core.degradations;
306
+ },
307
+ get disposed() {
308
+ return core.disposed;
309
+ },
310
+ dispose() {
311
+ if (core.disposed)
312
+ return;
313
+ if (displacedClock && viewer.clock) {
314
+ restoreCesiumClock(viewer.clock, displacedClock);
315
+ displacedClock = undefined;
316
+ }
317
+ if (viewer.entities) {
318
+ for (const entity of viewer.entities.values) {
319
+ if (baselineShow.has(entity.id))
320
+ entity.show = baselineShow.get(entity.id) ?? true;
321
+ }
322
+ }
323
+ baselineShow.clear();
324
+ core.dispose();
325
+ },
326
+ };
327
+ return port;
328
+ }
329
+ function buildMappings(capabilities) {
330
+ const mapping = (inbound, outbound, code, message) => Object.freeze({ inbound, outbound, code, message });
331
+ return Object.freeze({
332
+ camera: mapping("exact", "exact", "cesium-3d-camera", "The renderer-neutral camera is a globe pose, so longitude, latitude, height, heading, pitch, and roll all map without projection."),
333
+ selection: capabilities.selectionCapable
334
+ ? mapping("equivalent", "equivalent", "cesium-selected-entity", "A globe expresses one focused entity; the first resolvable target becomes the selected entity and additional targets are reported rather than drawn.")
335
+ : mapping("exact", "unsupported", "cesium-entities-unavailable", "This viewer exposes no entity collection, so shared selection cannot be focused."),
336
+ filters: capabilities.entitiesCapable
337
+ ? mapping("exact", "equivalent", "cesium-entity-visibility-filter", "Protocol-neutral clauses are evaluated against entity properties and applied as entity visibility; the original visibility is restored when the clauses clear.")
338
+ : mapping("exact", "unsupported", "cesium-entities-unavailable", "This viewer exposes no entity collection, so shared filters have nothing to hide."),
339
+ time: capabilities.clockOwned
340
+ ? mapping("exact", "exact", "cesium-clock", "Shared application time maps to the viewer clock's extent, current instant, rate, and transport, through the same clock plan the scene adapter applies.")
341
+ : mapping("exact", "unsupported", "cesium-clock-unbound", "This viewer exposes no clock, or declares host-owned transport, so shared time does not advance the scene."),
342
+ detail: mapping("exact", "unsupported", "cesium-detail-focus-owned-by-selection", "A globe has exactly one focused-entity channel and the selection slice owns it. A detail chosen in this view is shared, but a detail chosen elsewhere is refused rather than double-driving the focus."),
343
+ attribution: mapping("exact", "equivalent", "cesium-attribution-ids", "Credential-free attribution identifiers are shared for the host to render; the globe's own credit display is driven by its providers."),
344
+ realtime: mapping("exact", "equivalent", "cesium-realtime-status", "Realtime status is shared for the host to render; the globe has no realtime surface of its own."),
345
+ });
346
+ }
347
+ function listen(event, listener) {
348
+ if (!event || typeof event.addEventListener !== "function")
349
+ return () => undefined;
350
+ const removed = event.addEventListener(listener);
351
+ let released = false;
352
+ return () => {
353
+ if (released)
354
+ return;
355
+ released = true;
356
+ if (typeof removed === "function") {
357
+ removed();
358
+ return;
359
+ }
360
+ event.removeEventListener?.(listener);
361
+ };
362
+ }
363
+ function defaultEntityProperty(entity, field) {
364
+ const bag = entity.properties;
365
+ if (bag === null || typeof bag !== "object")
366
+ return undefined;
367
+ const property = bag[field];
368
+ if (property === null || property === undefined)
369
+ return property ?? undefined;
370
+ const getValue = property.getValue;
371
+ return typeof getValue === "function" ? getValue.call(property) : property;
372
+ }
373
+ function isoFromJulian(module, value) {
374
+ if (value === null || value === undefined)
375
+ return undefined;
376
+ try {
377
+ const iso = module.JulianDate.toIso8601(value, 3);
378
+ return typeof iso === "string" && new Date(iso).toISOString() === iso ? iso : undefined;
379
+ }
380
+ catch {
381
+ return undefined;
382
+ }
383
+ }
384
+ function compare(left, right, operator) {
385
+ if (typeof left !== "number" || typeof right !== "number")
386
+ return false;
387
+ switch (operator) {
388
+ case "<":
389
+ return left < right;
390
+ case "<=":
391
+ return left <= right;
392
+ case ">":
393
+ return left > right;
394
+ case ">=":
395
+ return left >= right;
396
+ }
397
+ }
398
+ /**
399
+ * SQL `LIKE` with `%`/`_` wildcards, matched without a regular expression so a
400
+ * hostile pattern cannot drive backtracking.
401
+ */
402
+ function likeMatches(value, pattern) {
403
+ const text = value.toLowerCase();
404
+ const needle = pattern.toLowerCase();
405
+ let textIndex = 0;
406
+ let patternIndex = 0;
407
+ let starText = -1;
408
+ let starPattern = -1;
409
+ while (textIndex < text.length) {
410
+ const patternCharacter = needle[patternIndex];
411
+ if (patternIndex < needle.length && (patternCharacter === "_" || patternCharacter === text[textIndex])) {
412
+ textIndex += 1;
413
+ patternIndex += 1;
414
+ }
415
+ else if (patternIndex < needle.length && patternCharacter === "%") {
416
+ starPattern = patternIndex;
417
+ starText = textIndex;
418
+ patternIndex += 1;
419
+ }
420
+ else if (starPattern !== -1) {
421
+ patternIndex = starPattern + 1;
422
+ starText += 1;
423
+ textIndex = starText;
424
+ }
425
+ else {
426
+ return false;
427
+ }
428
+ }
429
+ while (patternIndex < needle.length && needle[patternIndex] === "%")
430
+ patternIndex += 1;
431
+ return patternIndex === needle.length;
432
+ }