@geode/opengeodeweb-front 10.34.0-rc.8 → 10.34.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 (282) hide show
  1. package/{server → .build/server}/utils/app_config.js +10 -9
  2. package/{server → .build/server}/utils/cleanup.js +31 -17
  3. package/{server → .build/server}/utils/cloud.js +1 -4
  4. package/{server → .build/server}/utils/microservices.js +21 -9
  5. package/{server → .build/server}/utils/path.js +4 -4
  6. package/{server → .build/server}/utils/scripts.js +9 -9
  7. package/.build/server/utils/server_config.js +51 -0
  8. package/.build/server/utils/stream.js +6 -0
  9. package/{server → .build/server}/utils/ws_client.js +18 -3
  10. package/{shared → .build/shared}/scripts.js +10 -10
  11. package/.build/shared/utils/call_raw.js +31 -0
  12. package/{shared → .build/shared}/utils/call_schema.js +2 -2
  13. package/.build/shared/utils/fetch_raw.js +52 -0
  14. package/{shared → .build/shared}/utils/fetch_schema.js +2 -2
  15. package/{shared → .build/shared}/utils/file.js +3 -1
  16. package/{shared → .build/shared}/utils/response_handlers/load.js +10 -7
  17. package/{shared → .build/shared}/utils/validate_schema.js +1 -1
  18. package/app/components/ActionButton.vue +6 -6
  19. package/app/components/CameraManager/List.vue +5 -5
  20. package/app/components/CameraManager/Saver.vue +3 -5
  21. package/app/components/CameraManager.vue +6 -4
  22. package/app/components/CameraOrientation.vue +12 -12
  23. package/app/components/ClippingPlaneCard.vue +4 -2
  24. package/app/components/ClippingPlanes.vue +8 -8
  25. package/app/components/CrsSelector.vue +9 -10
  26. package/app/components/DeleteDialog.vue +4 -2
  27. package/app/components/DragAndDrop.vue +10 -12
  28. package/app/components/DragAndDropInternal/DragAndDropInline.vue +4 -2
  29. package/app/components/ExtensionSelector.vue +4 -4
  30. package/app/components/FeedBack/ErrorBanner.vue +3 -1
  31. package/app/components/FeedBack/Snackers.vue +4 -3
  32. package/app/components/FileSelector.vue +10 -8
  33. package/app/components/FileUploader.vue +11 -11
  34. package/app/components/GlassCard.vue +1 -1
  35. package/app/components/HybridRenderingView.vue +7 -5
  36. package/app/components/HybridViewerTooltip.vue +7 -7
  37. package/app/components/Launcher.vue +1 -1
  38. package/app/components/Loading/EcoMessages.vue +9 -3
  39. package/app/components/Loading.vue +2 -2
  40. package/app/components/MissingFilesSelector.vue +12 -10
  41. package/app/components/ObjectSelector.vue +10 -9
  42. package/app/components/PackagesVersions.vue +6 -5
  43. package/app/components/Recaptcha.vue +3 -3
  44. package/app/components/RemoteRenderingView.vue +6 -7
  45. package/app/components/Ruler.vue +3 -3
  46. package/app/components/Screenshot.vue +6 -6
  47. package/app/components/SearchBar.vue +4 -2
  48. package/app/components/ShrinkFilter.vue +7 -7
  49. package/app/components/Step.vue +6 -5
  50. package/app/components/Stepper.vue +4 -3
  51. package/app/components/ToolPanel.vue +6 -3
  52. package/app/components/ViewToolbar.vue +25 -28
  53. package/app/components/Viewer/ContextMenu/CenterButton.vue +7 -5
  54. package/app/components/Viewer/ContextMenu/CircularItems.vue +3 -3
  55. package/app/components/Viewer/ContextMenu/ContextMenu.vue +22 -19
  56. package/app/components/Viewer/ContextMenu/ContextMenuItem.vue +10 -8
  57. package/app/components/Viewer/ContextMenu/InfoCard.vue +11 -12
  58. package/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue +13 -17
  59. package/app/components/Viewer/Generic/Mesh/CellsOptions.vue +11 -15
  60. package/app/components/Viewer/Generic/Mesh/EdgesOptions.vue +12 -16
  61. package/app/components/Viewer/Generic/Mesh/PointsOptions.vue +8 -12
  62. package/app/components/Viewer/Generic/Mesh/PolygonsOptions.vue +11 -15
  63. package/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue +11 -15
  64. package/app/components/Viewer/Generic/Model/BlocksOptions.vue +67 -38
  65. package/app/components/Viewer/Generic/Model/CornersOptions.vue +53 -23
  66. package/app/components/Viewer/Generic/Model/EdgesOptions.vue +1 -3
  67. package/app/components/Viewer/Generic/Model/LinesOptions.vue +67 -38
  68. package/app/components/Viewer/Generic/Model/ModelStyleCard.vue +31 -15
  69. package/app/components/Viewer/Generic/Model/ModelStyleOptions.vue +2 -3
  70. package/app/components/Viewer/Generic/Model/PointsOptions.vue +6 -6
  71. package/app/components/Viewer/Generic/Model/SurfacesOptions.vue +69 -38
  72. package/app/components/Viewer/ObjectTree/Base/CommonTreeView.vue +64 -46
  73. package/app/components/Viewer/ObjectTree/Base/Controls.vue +5 -5
  74. package/app/components/Viewer/ObjectTree/Base/ItemLabel.vue +13 -9
  75. package/app/components/Viewer/ObjectTree/Base/StickyHeader.vue +5 -5
  76. package/app/components/Viewer/ObjectTree/Base/TreeRow.vue +10 -10
  77. package/app/components/Viewer/ObjectTree/Box.vue +6 -4
  78. package/app/components/Viewer/ObjectTree/Layout.vue +23 -21
  79. package/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue +14 -14
  80. package/app/components/Viewer/ObjectTree/Views/{ModelCollections.vue → ModelTree.vue} +59 -24
  81. package/app/components/Viewer/Options/AttributeColorBar.vue +4 -2
  82. package/app/components/Viewer/Options/AttributeRangeSelector.vue +4 -2
  83. package/app/components/Viewer/Options/AttributeSelector.vue +7 -9
  84. package/app/components/Viewer/Options/ColorMapList.vue +15 -13
  85. package/app/components/Viewer/Options/ColorMapPicker.vue +4 -4
  86. package/app/components/Viewer/Options/ColorPicker.vue +223 -41
  87. package/app/components/Viewer/Options/ColoringTypeSelector.vue +16 -16
  88. package/app/components/Viewer/Options/ColormapQuickPicker.vue +7 -5
  89. package/app/components/Viewer/Options/OptionsSection.vue +1 -1
  90. package/app/components/Viewer/Options/TextureItem.vue +8 -6
  91. package/app/components/Viewer/Options/TexturesSelector.vue +1 -1
  92. package/app/components/Viewer/OverlappingObjectsPicker.vue +8 -9
  93. package/app/components/Viewer/PointSet/SpecificPointsOptions.vue +2 -6
  94. package/app/components/Viewer/Solid/SpecificPolyhedraOptions.vue +12 -16
  95. package/app/components/Viewer/Surface/PolygonsOptions.vue +12 -16
  96. package/app/components/Viewer/Ui.vue +2 -2
  97. package/app/components/Wrapper.vue +1 -4
  98. package/app/components/ZScaling.vue +5 -3
  99. package/app/components/csv-preview/CsvPreviewer.vue +38 -37
  100. package/app/components/csv-preview/CsvSettings.vue +6 -4
  101. package/app/components/csv-preview/CsvTable.vue +1 -1
  102. package/app/composables/batch_style.ts +5 -6
  103. package/app/composables/clipping_planes_widget.ts +73 -181
  104. package/app/composables/clipping_planes_widget_entries.ts +189 -0
  105. package/app/composables/copy_to_clipboard.ts +7 -0
  106. package/app/composables/global_attribute_style.ts +163 -83
  107. package/app/composables/hover_highlight.ts +46 -14
  108. package/app/composables/model_collections.ts +26 -13
  109. package/app/composables/model_components.ts +26 -13
  110. package/app/composables/project_manager.ts +76 -19
  111. package/app/composables/responsive_middle_truncate.ts +13 -13
  112. package/app/composables/stepper_tree.ts +34 -11
  113. package/app/composables/tree_filter.ts +66 -44
  114. package/app/composables/tree_keyboard_nav.ts +25 -11
  115. package/app/composables/tree_scroll.ts +44 -14
  116. package/app/composables/use_adaptive_styles.ts +66 -23
  117. package/app/composables/use_overlapping_picker.ts +66 -16
  118. package/app/composables/use_quick_colormap.ts +16 -5
  119. package/app/composables/virtual_tree.ts +75 -43
  120. package/app/composables/vtk_implicit_plane_widget.d.ts +2 -0
  121. package/app/plugins/auto_store_register.ts +2 -7
  122. package/app/plugins/click_outside_ignore_snackbars.client.ts +39 -0
  123. package/app/stores/app.ts +57 -192
  124. package/app/stores/app_helpers/extension.ts +179 -0
  125. package/app/stores/back.ts +37 -21
  126. package/app/stores/camera_manager.ts +22 -20
  127. package/app/stores/cloud.ts +17 -13
  128. package/app/stores/data.ts +88 -47
  129. package/app/stores/data_helpers/collections.ts +36 -38
  130. package/app/stores/data_helpers/mesh.ts +45 -36
  131. package/app/stores/data_style.ts +50 -28
  132. package/app/stores/feedback.ts +6 -6
  133. package/app/stores/hybrid_viewer.ts +41 -52
  134. package/app/stores/infra.ts +39 -37
  135. package/app/stores/menu.ts +23 -14
  136. package/app/stores/treeview.ts +72 -42
  137. package/app/stores/viewer.ts +39 -27
  138. package/app/utils/attributes.ts +3 -3
  139. package/app/utils/clipping_planes.ts +111 -14
  140. package/app/utils/color_picker.ts +57 -0
  141. package/app/utils/colormap.ts +58 -35
  142. package/app/utils/default_styles/index.ts +2 -2
  143. package/app/utils/default_styles/meshes.ts +107 -13
  144. package/app/utils/default_styles/models.ts +83 -14
  145. package/app/utils/extension.ts +47 -20
  146. package/app/utils/import_workflow.ts +21 -13
  147. package/app/utils/name_cleaner.ts +1 -1
  148. package/app/utils/string.ts +1 -1
  149. package/app/utils/treeview.ts +2 -2
  150. package/internal/database/base_database.ts +7 -3
  151. package/internal/database/database.ts +36 -26
  152. package/internal/database/extended_database.ts +1 -1
  153. package/internal/stores/data_style/mesh/cells/cell.ts +70 -34
  154. package/internal/stores/data_style/mesh/cells/color.ts +12 -6
  155. package/internal/stores/data_style/mesh/cells/common.ts +18 -8
  156. package/internal/stores/data_style/mesh/cells/index.ts +122 -42
  157. package/internal/stores/data_style/mesh/cells/textures.ts +12 -6
  158. package/internal/stores/data_style/mesh/cells/vertex.ts +75 -34
  159. package/internal/stores/data_style/mesh/cells/visibility.ts +15 -4
  160. package/internal/stores/data_style/mesh/edges/color.ts +12 -6
  161. package/internal/stores/data_style/mesh/edges/common.ts +14 -6
  162. package/internal/stores/data_style/mesh/edges/edge.ts +71 -39
  163. package/internal/stores/data_style/mesh/edges/index.ts +117 -42
  164. package/internal/stores/data_style/mesh/edges/vertex.ts +76 -39
  165. package/internal/stores/data_style/mesh/edges/visibility.ts +15 -4
  166. package/internal/stores/data_style/mesh/edges/width.ts +12 -4
  167. package/internal/stores/data_style/mesh/index.ts +30 -11
  168. package/internal/stores/data_style/mesh/points/color.ts +12 -6
  169. package/internal/stores/data_style/mesh/points/common.ts +21 -8
  170. package/internal/stores/data_style/mesh/points/index.ts +101 -50
  171. package/internal/stores/data_style/mesh/points/size.ts +12 -4
  172. package/internal/stores/data_style/mesh/points/vertex.ts +75 -34
  173. package/internal/stores/data_style/mesh/points/visibility.ts +17 -7
  174. package/internal/stores/data_style/mesh/polygons/color.ts +12 -6
  175. package/internal/stores/data_style/mesh/polygons/common.ts +23 -6
  176. package/internal/stores/data_style/mesh/polygons/index.ts +130 -70
  177. package/internal/stores/data_style/mesh/polygons/polygon.ts +77 -43
  178. package/internal/stores/data_style/mesh/polygons/textures.ts +12 -6
  179. package/internal/stores/data_style/mesh/polygons/vertex.ts +79 -39
  180. package/internal/stores/data_style/mesh/polygons/visibility.ts +16 -6
  181. package/internal/stores/data_style/mesh/polyhedra/color.ts +12 -6
  182. package/internal/stores/data_style/mesh/polyhedra/common.ts +14 -6
  183. package/internal/stores/data_style/mesh/polyhedra/index.ts +115 -56
  184. package/internal/stores/data_style/mesh/polyhedra/polyhedron.ts +80 -39
  185. package/internal/stores/data_style/mesh/polyhedra/vertex.ts +79 -39
  186. package/internal/stores/data_style/mesh/polyhedra/visibility.ts +16 -6
  187. package/internal/stores/data_style/model/blocks/color.ts +43 -13
  188. package/internal/stores/data_style/model/blocks/common.ts +21 -6
  189. package/internal/stores/data_style/model/blocks/index.ts +89 -59
  190. package/internal/stores/data_style/model/blocks/polyhedron.ts +101 -44
  191. package/internal/stores/data_style/model/blocks/vertex.ts +107 -42
  192. package/internal/stores/data_style/model/blocks/visibility.ts +17 -4
  193. package/internal/stores/data_style/model/color.ts +171 -83
  194. package/internal/stores/data_style/model/common.ts +70 -21
  195. package/internal/stores/data_style/model/corners/color.ts +43 -11
  196. package/internal/stores/data_style/model/corners/common.ts +25 -6
  197. package/internal/stores/data_style/model/corners/index.ts +66 -41
  198. package/internal/stores/data_style/model/corners/vertex.ts +105 -74
  199. package/internal/stores/data_style/model/corners/visibility.ts +19 -4
  200. package/internal/stores/data_style/model/edges/common.ts +12 -4
  201. package/internal/stores/data_style/model/edges/index.ts +2 -1
  202. package/internal/stores/data_style/model/edges/visibility.ts +24 -7
  203. package/internal/stores/data_style/model/index.ts +24 -11
  204. package/internal/stores/data_style/model/lines/color.ts +41 -11
  205. package/internal/stores/data_style/model/lines/common.ts +17 -6
  206. package/internal/stores/data_style/model/lines/edge.ts +105 -42
  207. package/internal/stores/data_style/model/lines/index.ts +86 -59
  208. package/internal/stores/data_style/model/lines/vertex.ts +105 -42
  209. package/internal/stores/data_style/model/lines/visibility.ts +17 -4
  210. package/internal/stores/data_style/model/points/common.ts +8 -4
  211. package/internal/stores/data_style/model/points/index.ts +10 -3
  212. package/internal/stores/data_style/model/points/size.ts +12 -4
  213. package/internal/stores/data_style/model/points/visibility.ts +16 -6
  214. package/internal/stores/data_style/model/selection.ts +80 -58
  215. package/internal/stores/data_style/model/surfaces/color.ts +41 -11
  216. package/internal/stores/data_style/model/surfaces/common.ts +23 -6
  217. package/internal/stores/data_style/model/surfaces/index.ts +89 -59
  218. package/internal/stores/data_style/model/surfaces/polygon.ts +107 -67
  219. package/internal/stores/data_style/model/surfaces/vertex.ts +111 -67
  220. package/internal/stores/data_style/model/surfaces/visibility.ts +18 -5
  221. package/internal/stores/data_style/model/visibility.ts +82 -20
  222. package/internal/stores/data_style/state.ts +77 -65
  223. package/internal/stores/hybrid_viewer/brightness.ts +49 -31
  224. package/internal/stores/hybrid_viewer/camera.ts +191 -177
  225. package/internal/stores/hybrid_viewer/camera_animation.ts +11 -10
  226. package/internal/stores/hybrid_viewer/core.ts +64 -0
  227. package/internal/stores/hybrid_viewer/filters.ts +10 -16
  228. package/internal/stores/hybrid_viewer/highlight.ts +91 -130
  229. package/internal/stores/hybrid_viewer/ruler.ts +24 -15
  230. package/internal/stores/hybrid_viewer/scene.ts +96 -117
  231. package/internal/stores/hybrid_viewer/viewport.ts +74 -65
  232. package/internal/stores/hybrid_viewer/vtk_types.ts +13 -29
  233. package/internal/utils/api_fetch.ts +54 -23
  234. package/internal/utils/upload_file.ts +74 -53
  235. package/internal/utils/viewer_call.ts +22 -13
  236. package/internal/utils/ws_client.ts +24 -13
  237. package/nuxt.config.ts +58 -1
  238. package/package.json +20 -8
  239. package/server/api/cloud/extensions/run.post.ts +6 -10
  240. package/server/api/local/app/project_folder_path.post.ts +4 -4
  241. package/server/api/local/app/run_back.post.ts +5 -7
  242. package/server/api/local/app/run_viewer.post.ts +5 -7
  243. package/server/api/local/extensions/kill.post.ts +4 -3
  244. package/server/api/local/extensions/run.post.ts +7 -10
  245. package/server/api/local/extensions/upload.put.ts +44 -54
  246. package/server/api/microservice/app/get_is_app_ready.get.ts +4 -5
  247. package/server/api/microservice/app/set_app_base_url.post.ts +5 -6
  248. package/server/api/microservice/app/set_back_base_url.post.ts +5 -6
  249. package/server/api/microservice/app/set_is_app_ready.post.ts +5 -6
  250. package/server/api/microservice/app/set_viewer_base_url.post.ts +5 -6
  251. package/server/api/microservice/extensions/download.post.ts +5 -4
  252. package/server/api/serverless/run_cloud.post.ts +53 -11
  253. package/server/utils/app_config.ts +29 -22
  254. package/server/utils/cleanup.ts +60 -30
  255. package/server/utils/cloud.ts +9 -8
  256. package/server/utils/extension.ts +23 -9
  257. package/server/utils/microservices.ts +33 -24
  258. package/server/utils/path.ts +4 -4
  259. package/server/utils/scripts.ts +26 -23
  260. package/server/utils/server.ts +2 -2
  261. package/server/utils/server_config.ts +41 -27
  262. package/server/utils/stream.ts +6 -0
  263. package/server/utils/ws_client.ts +42 -8
  264. package/shared/scripts.ts +15 -10
  265. package/shared/utils/call_raw.ts +23 -16
  266. package/shared/utils/call_schema.ts +5 -8
  267. package/shared/utils/fetch_raw.ts +87 -47
  268. package/shared/utils/fetch_schema.ts +6 -9
  269. package/shared/utils/file.ts +8 -2
  270. package/shared/utils/response_handlers/load.ts +26 -11
  271. package/shared/utils/types.ts +9 -9
  272. package/shared/utils/validate_schema.ts +1 -1
  273. package/app/components/Viewer/ObjectTree/Views/ModelComponents.vue +0 -276
  274. package/server/types/vendor.d.ts +0 -64
  275. package/server/utils/server_config.js +0 -43
  276. package/shared/utils/call_raw.js +0 -30
  277. package/shared/utils/fetch_raw.js +0 -40
  278. /package/{opengeodeweb_front_schemas.js → .build/opengeodeweb_front_schemas.js} +0 -0
  279. /package/{server → .build/server}/utils/server.js +0 -0
  280. /package/{shared → .build/shared}/app_mode.js +0 -0
  281. /package/{shared → .build/shared}/utils/parse_boolean.js +0 -0
  282. /package/{shared → .build/shared}/utils/types.js +0 -0
@@ -1,51 +1,52 @@
1
- // Not auto-fixable (eslint's sort-imports core rule has no autofixer) and this file's import order doesn't match its syntax-kind-then-alphabetical requirement - left as-is rather than manually reordered across the codebase for a purely cosmetic rule.
2
- // oxlint-disable eslint/sort-imports
3
- import type { Ref } from "vue";
1
+ import type { Vector3, ViewStreamLike } from "./vtk_types";
2
+ import { centerCameraOnPosition, useHybridViewerCamera } from "./camera";
4
3
  import { Status } from "@ogw_front/utils/status";
5
4
  import { WHEEL_TIME_OUT_MS } from "./constants";
6
- import { centerCameraOnPosition } from "./camera";
7
- import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
5
+ import { useHybridViewerCore } from "./core";
6
+ import { useHybridViewerHighlight } from "./highlight";
8
7
  import { useViewerStore } from "@ogw_front/stores/viewer";
9
8
  import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
10
- import type { HybridViewerStorePublic, Vector3 } from "./vtk_types";
11
9
 
12
10
  type ContainerRef = Ref<{ $el: HTMLElement } | undefined>;
13
11
 
14
- // The image stream object returned by vtk.js's ImageStream.createViewStream(); vtk.js's own vtkViewStream type declares `onImageReady` with a zero-arg callback, which doesn't match how it's actually invoked at runtime (with the decoded image), so this describes the shape as it's actually used here.
15
- interface ViewStreamLike {
16
- setSize: (width: number, height: number) => void;
17
- onImageReady: (callback: (event: { image: unknown }) => void) => void;
12
+ interface HybridViewerViewport {
13
+ setContainer: (container: ContainerRef | undefined) => void;
14
+ resize: (width: number, height: number) => Promise<void>;
15
+ viewStream: Ref<ViewStreamLike | undefined>;
18
16
  }
19
17
 
20
- async function performResize(width: number, height: number): Promise<void> {
21
- const hybridViewerStore = useHybridViewerStore();
22
- const { genericRenderWindow, remoteRender } =
23
- hybridViewerStore as unknown as HybridViewerStorePublic;
24
- const { status, viewStream } = storeToRefs(hybridViewerStore) as unknown as {
25
- status: Ref<string>;
26
- viewStream: Ref<{ setSize: (width: number, height: number) => void } | undefined>;
27
- };
18
+ async function resize(width: number, height: number): Promise<void> {
19
+ const { genericRenderWindow, remoteRender, status, viewStream } = useHybridViewerCore();
28
20
  const viewerStore = useViewerStore();
29
21
  if (viewerStore.status !== Status.CONNECTED || status.value !== Status.CREATED) {
30
22
  return;
31
23
  }
32
- const webGLRenderWindow = genericRenderWindow.value!.getApiSpecificRenderWindow();
33
- const canvas = webGLRenderWindow.getCanvas();
24
+ const renderWindow = genericRenderWindow.value;
25
+ if (!renderWindow) {
26
+ return;
27
+ }
28
+ // oxlint-disable-next-line no-unsafe-assignment -- vtk.js has no types for getApiSpecificRenderWindow(); narrowed below.
29
+ const webGLRenderWindow = renderWindow.getApiSpecificRenderWindow();
30
+ // oxlint-disable-next-line no-unsafe-type-assertion -- trusted vtk.js OpenGL render window API boundary.
31
+ const openGLRenderWindow = webGLRenderWindow as unknown as {
32
+ getCanvas: () => HTMLCanvasElement;
33
+ setSize: (width: number, height: number) => void;
34
+ };
35
+ const canvas = openGLRenderWindow.getCanvas();
34
36
  canvas.width = width;
35
37
  canvas.height = height;
36
38
  await nextTick();
37
- webGLRenderWindow.setSize(width, height);
39
+ openGLRenderWindow.setSize(width, height);
38
40
  if (viewStream.value) {
39
41
  viewStream.value.setSize(width, height);
40
42
  }
41
- const renderWindow = genericRenderWindow.value!.getRenderWindow();
42
- renderWindow.render();
43
+ renderWindow.getRenderWindow().render();
43
44
  await remoteRender();
44
45
  }
45
46
 
46
47
  function performClickPicking(event: MouseEvent, containerElement: HTMLElement): void {
47
- const { genericRenderWindow, syncRemoteCamera } =
48
- useHybridViewerStore() as unknown as HybridViewerStorePublic;
48
+ const { genericRenderWindow } = useHybridViewerCore();
49
+ const { syncRemoteCamera } = useHybridViewerCamera();
49
50
  const viewerStore = useViewerStore();
50
51
  const rect = containerElement.getBoundingClientRect();
51
52
  const schema = viewer_schemas.opengeodeweb_viewer.viewer.get_point_position;
@@ -53,53 +54,58 @@ function performClickPicking(event: MouseEvent, containerElement: HTMLElement):
53
54
  x: Math.round(event.clientX - rect.left),
54
55
  y: Math.round(rect.height - (event.clientY - rect.top)),
55
56
  };
56
- viewerStore.request(
57
+ void viewerStore.request(
57
58
  {
58
59
  schema,
59
60
  params,
60
61
  },
61
62
  {
62
63
  response_function: (response: unknown) => {
64
+ // oxlint-disable-next-line no-unsafe-type-assertion -- response shape is defined by the get_point_position schema.
63
65
  const { x, y, z } = response as { x: number; y: number; z: number };
64
66
  const pickedPos: Vector3 = [x, y, z];
65
- if (pickedPos.some((val) => val !== 0)) {
66
- const renderer = genericRenderWindow.value!.getRenderer();
67
- const camera = renderer.getActiveCamera();
68
- centerCameraOnPosition(camera, pickedPos);
69
- const renderWindow = genericRenderWindow.value!.getRenderWindow();
70
- renderWindow.render();
71
- syncRemoteCamera();
67
+ if (!genericRenderWindow.value || !pickedPos.some((val) => val !== 0)) {
68
+ return;
72
69
  }
70
+ const renderer = genericRenderWindow.value.getRenderer();
71
+ const camera = renderer.getActiveCamera();
72
+ centerCameraOnPosition(camera, pickedPos);
73
+ genericRenderWindow.value.getRenderWindow().render();
74
+ syncRemoteCamera();
73
75
  },
74
76
  },
75
77
  );
76
78
  }
77
79
 
78
- function performSetContainer(container: ContainerRef | undefined): void {
80
+ function setContainer(container: ContainerRef | undefined): void {
79
81
  if (!container || !container.value) {
80
82
  return;
81
83
  }
82
- const hybridViewerStore = useHybridViewerStore();
83
- const { genericRenderWindow, syncRemoteCamera, hoverHighlight } =
84
- hybridViewerStore as unknown as HybridViewerStorePublic;
85
- const { is_picking, is_moving } = storeToRefs(hybridViewerStore) as unknown as {
86
- is_picking: Ref<boolean>;
87
- is_moving: Ref<boolean>;
84
+ const containerElement = container.value.$el;
85
+ const { genericRenderWindow, is_picking, is_moving } = useHybridViewerCore();
86
+ const { syncRemoteCamera } = useHybridViewerCamera();
87
+ const { hoverHighlight } = useHybridViewerHighlight();
88
+ if (!genericRenderWindow.value) {
89
+ return;
90
+ }
91
+ genericRenderWindow.value.setContainer(containerElement);
92
+ // oxlint-disable-next-line no-unsafe-assignment -- vtk.js has no types for getApiSpecificRenderWindow(); narrowed below.
93
+ const webGLRenderWindow = genericRenderWindow.value.getApiSpecificRenderWindow();
94
+ // oxlint-disable-next-line no-unsafe-type-assertion -- trusted vtk.js OpenGL render window API boundary.
95
+ const openGLRenderWindow = webGLRenderWindow as unknown as {
96
+ setUseBackgroundImage: (value: boolean) => void;
97
+ getReferenceByName: (name: string) => { style: CSSStyleDeclaration } | undefined;
88
98
  };
89
- genericRenderWindow.value!.setContainer(container.value.$el);
90
- const webGLRenderWindow = genericRenderWindow.value!.getApiSpecificRenderWindow();
91
- webGLRenderWindow.setUseBackgroundImage(true);
92
- const imageStyle = webGLRenderWindow.getReferenceByName("bgImage")?.style as
93
- | CSSStyleDeclaration
94
- | undefined;
99
+ openGLRenderWindow.setUseBackgroundImage(true);
100
+ const imageStyle = openGLRenderWindow.getReferenceByName("bgImage")?.style;
95
101
  Object.assign(imageStyle ?? {}, {
96
102
  transition: "opacity 0.1s ease-in",
97
103
  zIndex: 1,
98
104
  });
99
- performResize(container.value.$el.offsetWidth, container.value.$el.offsetHeight);
105
+ void resize(containerElement.offsetWidth, containerElement.offsetHeight);
100
106
  let has_dragged = false;
101
107
  useMousePressed({
102
- target: container as never,
108
+ target: containerElement,
103
109
  onPressed: (event: MouseEvent | TouchEvent | DragEvent) => {
104
110
  if (!(event instanceof MouseEvent)) {
105
111
  return;
@@ -108,7 +114,7 @@ function performSetContainer(container: ContainerRef | undefined): void {
108
114
  return;
109
115
  }
110
116
  if (event.button === 0 && is_picking.value) {
111
- performClickPicking(event, container.value!.$el);
117
+ performClickPicking(event, containerElement);
112
118
  is_picking.value = false;
113
119
  return;
114
120
  }
@@ -118,25 +124,31 @@ function performSetContainer(container: ContainerRef | undefined): void {
118
124
  },
119
125
  onReleased: () => {
120
126
  is_moving.value = false;
121
- if (has_dragged) {
122
- const renderer = genericRenderWindow.value!.getRenderer();
127
+ if (has_dragged && genericRenderWindow.value) {
128
+ const renderer = genericRenderWindow.value.getRenderer();
123
129
  renderer.resetCameraClippingRange();
124
130
  syncRemoteCamera();
125
131
  }
126
132
  has_dragged = false;
127
133
  },
128
134
  });
129
- useEventListener(container as never, "mousemove", (event: MouseEvent) => {
135
+ useEventListener(containerElement, "mousemove", (event: MouseEvent) => {
130
136
  if (is_moving.value) {
131
137
  has_dragged = true;
132
138
  if (imageStyle) {
133
139
  imageStyle.opacity = "0";
134
140
  }
135
141
  }
136
- hoverHighlight(event);
142
+ void (async (): Promise<void> => {
143
+ try {
144
+ await hoverHighlight(event);
145
+ } catch {
146
+ // Ignore hover highlight failures
147
+ }
148
+ })();
137
149
  });
138
150
  let wheelEventEndTimeout: ReturnType<typeof setTimeout> | undefined = undefined;
139
- useEventListener(container as never, "wheel", () => {
151
+ useEventListener(containerElement, "wheel", () => {
140
152
  is_moving.value = true;
141
153
  if (imageStyle) {
142
154
  imageStyle.opacity = "0";
@@ -144,25 +156,22 @@ function performSetContainer(container: ContainerRef | undefined): void {
144
156
  clearTimeout(wheelEventEndTimeout);
145
157
  wheelEventEndTimeout = setTimeout(() => {
146
158
  is_moving.value = false;
147
- const renderer = genericRenderWindow.value!.getRenderer();
159
+ if (!genericRenderWindow.value) {
160
+ return;
161
+ }
162
+ const renderer = genericRenderWindow.value.getRenderer();
148
163
  renderer.resetCameraClippingRange();
149
164
  syncRemoteCamera();
150
165
  }, WHEEL_TIME_OUT_MS);
151
166
  });
152
167
  }
153
- function useHybridViewerViewport() {
154
- const viewStream = ref<ViewStreamLike | undefined>(undefined);
155
- function setContainer(container: ContainerRef | undefined): void {
156
- performSetContainer(container);
157
- }
158
- async function resize(width: number, height: number): Promise<void> {
159
- await performResize(width, height);
160
- }
168
+ function useHybridViewerViewport(): HybridViewerViewport {
169
+ const { viewStream } = useHybridViewerCore();
161
170
  return {
162
171
  setContainer,
163
172
  resize,
164
173
  viewStream,
165
174
  };
166
175
  }
167
- export { performClickPicking, performResize, performSetContainer, useHybridViewerViewport };
168
- export type { ViewStreamLike };
176
+ export { performClickPicking, useHybridViewerViewport };
177
+ export type { ViewStreamLike } from "./vtk_types";
@@ -1,14 +1,5 @@
1
- // Not auto-fixable (eslint's sort-imports core rule has no autofixer) and this file's import order doesn't match its syntax-kind-then-alphabetical requirement - left as-is rather than manually reordered across the codebase for a purely cosmetic rule.
2
- // This file's imported vtk.js types are also used locally (CameraOptions, HybridDbEntry, HybridViewerStorePublic reference them directly), not just re-exported, so they can't become pure `export ... from "...";` re-exports without losing the local binding these interfaces need.
3
- // oxlint-disable eslint/sort-imports, unicorn/prefer-export-from
4
- // Re-exports of vtk.js's own (real, shipped) TypeScript types for the objects the hybrid viewer store composables interact with, plus the handful of shapes that are specific to this codebase (CameraOptions' snake_case wire format, the local hybridDb map, hover highlight data, ...).
5
- import type { vtkCamera } from "@kitware/vtk.js/Rendering/Core/Camera";
6
- import type { vtkRenderer } from "@kitware/vtk.js/Rendering/Core/Renderer";
7
- import type { vtkRenderWindow } from "@kitware/vtk.js/Rendering/Core/RenderWindow";
8
- import type { vtkGenericRenderWindow } from "@kitware/vtk.js/Rendering/Misc/GenericRenderWindow";
9
- import type { vtkOpenGLRenderWindow } from "@kitware/vtk.js/Rendering/OpenGL/RenderWindow";
10
- import type vtkActor from "@kitware/vtk.js/Rendering/Core/Actor";
11
1
  import type { Vector3 } from "@kitware/vtk.js/types";
2
+ import type vtkActor from "@kitware/vtk.js/Rendering/Core/Actor";
12
3
 
13
4
  // The camera state as exchanged with the viewer microservice (snake_case field names, plain arrays) - distinct from vtk.js's own vtkCamera object.
14
5
  interface CameraOptions {
@@ -44,31 +35,24 @@ interface HoverData {
44
35
  attributes: Record<string, unknown>;
45
36
  }
46
37
 
47
- // The parent Pinia store (app/stores/hybrid_viewer.ts) assembles these composables via `...spread` and is converted/typed separately from this directory, so its exact inferred return type isn't reliable to build on here. This describes just the slice of its returned (already-unwrapped) state and actions that the composables in this folder read or call directly (i.e. not through `storeToRefs`, which callers type separately at each destructuring site).
48
- interface HybridViewerStorePublic {
49
- genericRenderWindow: { value: vtkGenericRenderWindow | undefined };
50
- hybridDb: HybridDb;
51
- camera_options: Record<string, unknown>;
52
- remoteRender: () => Promise<void> | void;
53
- clearHoverHighlight: () => void;
54
- syncRemoteCamera: () => void;
55
- hoverHighlight: (event: MouseEvent) => void;
56
- setZScaling: (value: number) => Promise<void>;
57
- setCamera: (options: CameraOptions) => void;
38
+ // The image stream object returned by vtk.js's ImageStream.createViewStream(); vtk.js's own vtkViewStream type declares `onImageReady` with a zero-arg callback, which doesn't match how it's actually invoked at runtime (with the decoded image), so this describes the shape as it's actually used here.
39
+ interface ViewStreamLike {
40
+ setSize: (width: number, height: number) => void;
41
+ onImageReady: (callback: (event: { image: unknown }) => void) => void;
58
42
  }
59
43
 
44
+ export type { Vector3 } from "@kitware/vtk.js/types";
45
+ export type { default as vtkActor } from "@kitware/vtk.js/Rendering/Core/Actor";
46
+ export type { vtkCamera } from "@kitware/vtk.js/Rendering/Core/Camera";
47
+ export type { vtkGenericRenderWindow } from "@kitware/vtk.js/Rendering/Misc/GenericRenderWindow";
48
+ export type { vtkOpenGLRenderWindow } from "@kitware/vtk.js/Rendering/OpenGL/RenderWindow";
49
+ export type { vtkRenderWindow } from "@kitware/vtk.js/Rendering/Core/RenderWindow";
50
+ export type { vtkRenderer } from "@kitware/vtk.js/Rendering/Core/Renderer";
60
51
  export type {
61
- vtkCamera,
62
- vtkRenderer,
63
- vtkRenderWindow,
64
- vtkGenericRenderWindow,
65
- vtkOpenGLRenderWindow,
66
- vtkActor,
67
- Vector3,
68
52
  CameraOptions,
69
53
  HybridDbEntry,
70
54
  HybridDb,
71
55
  HoverComponentInfo,
72
56
  HoverData,
73
- HybridViewerStorePublic,
57
+ ViewStreamLike,
74
58
  };
@@ -1,9 +1,7 @@
1
- // Not auto-fixable (eslint's sort-imports core rule has no autofixer) and this file's import order doesn't match its syntax-kind-then-alphabetical requirement - left as-is rather than manually reordered across the codebase for a purely cosmetic rule.
2
- // oxlint-disable eslint/sort-imports
1
+ import type { JsonRpcSchema, RequestHandlersWithValidation } from "@ogw_shared/utils/types.js";
3
2
  import { endRequestLog, startRequestLog } from "@ogw_front/utils/log";
4
3
  import { fetchSchema } from "@ogw_shared/utils/fetch_schema";
5
4
  import { useFeedbackStore } from "@ogw_front/stores/feedback";
6
- import type { JsonRpcSchema, RequestHandlersWithValidation } from "@ogw_shared/utils/types.js";
7
5
 
8
6
  // The microservice-backed Pinia stores (back/app/...) all expose this shape; only the slice actually used here needs to be declared.
9
7
  interface Microservice {
@@ -33,7 +31,34 @@ interface FetchErrorResponseLike {
33
31
  description?: string;
34
32
  }
35
33
 
36
- function api_fetch(
34
+ function isRecord(value: unknown): value is Record<string, unknown> {
35
+ return typeof value === "object" && value !== null;
36
+ }
37
+
38
+ function toFetchErrorLike(error: unknown): FetchErrorLike {
39
+ if (!isRecord(error)) {
40
+ return {};
41
+ }
42
+ return {
43
+ code: typeof error.code === "number" ? error.code : undefined,
44
+ message: typeof error.message === "string" ? error.message : undefined,
45
+ stack: typeof error.stack === "string" ? error.stack : undefined,
46
+ };
47
+ }
48
+
49
+ function toFetchErrorResponseLike(response: unknown): FetchErrorResponseLike {
50
+ if (!isRecord(response)) {
51
+ return {};
52
+ }
53
+ return {
54
+ status: typeof response.status === "number" ? response.status : undefined,
55
+ name: typeof response.name === "string" ? response.name : undefined,
56
+ description: typeof response.description === "string" ? response.description : undefined,
57
+ };
58
+ }
59
+
60
+ // oxlint-disable-next-line max-lines-per-function
61
+ async function api_fetch(
37
62
  microservice: Microservice,
38
63
  { schema, params = {}, headers = {} }: ApiFetchParams,
39
64
  {
@@ -41,14 +66,15 @@ function api_fetch(
41
66
  response_function,
42
67
  response_error_function,
43
68
  timeout,
44
- }: RequestHandlersWithValidation & { timeout?: number } = {},
45
- ) {
69
+ skip_feedback_error,
70
+ }: RequestHandlersWithValidation & { timeout?: number; skip_feedback_error?: boolean } = {},
71
+ ): Promise<unknown> {
46
72
  console.log("[API] Fetching", microservice.base_url);
47
73
  const feedbackStore = useFeedbackStore();
48
74
  microservice.start_request();
49
75
 
50
76
  const requestStartingTime = startRequestLog(microservice, schema);
51
- return fetchSchema(
77
+ const result = await fetchSchema(
52
78
  {
53
79
  schema,
54
80
  params,
@@ -59,15 +85,17 @@ function api_fetch(
59
85
  {
60
86
  request_error_function(error: unknown) {
61
87
  microservice.stop_request();
62
- const typedError = error as FetchErrorLike;
63
- feedbackStore.add_error(
64
- typedError.code ?? 0,
65
- schema.$id,
66
- typedError.message ?? "",
67
- typedError.stack ?? "",
68
- );
88
+ const typedError = toFetchErrorLike(error);
89
+ if (skip_feedback_error !== true) {
90
+ feedbackStore.add_error(
91
+ typedError.code ?? 0,
92
+ schema.$id,
93
+ typedError.message ?? "",
94
+ typedError.stack ?? "",
95
+ );
96
+ }
69
97
  if (request_error_function) {
70
- request_error_function(error);
98
+ void request_error_function(error);
71
99
  }
72
100
  },
73
101
  response_function(data: unknown) {
@@ -79,15 +107,17 @@ function api_fetch(
79
107
  },
80
108
  response_error_function(response: unknown) {
81
109
  microservice.stop_request();
82
- const typedResponse = response as FetchErrorResponseLike;
83
- feedbackStore.add_error(
84
- typedResponse.status ?? 0,
85
- schema.$id,
86
- typedResponse.name ?? "",
87
- typedResponse.description ?? "",
88
- );
110
+ const typedResponse = toFetchErrorResponseLike(response);
111
+ if (skip_feedback_error !== true) {
112
+ feedbackStore.add_error(
113
+ typedResponse.status ?? 0,
114
+ schema.$id,
115
+ typedResponse.name ?? "",
116
+ typedResponse.description ?? "",
117
+ );
118
+ }
89
119
  if (response_error_function) {
90
- response_error_function(response);
120
+ void response_error_function(response);
91
121
  }
92
122
  },
93
123
  validation_error_function({ code, name, error }) {
@@ -96,6 +126,7 @@ function api_fetch(
96
126
  },
97
127
  },
98
128
  );
129
+ return result;
99
130
  }
100
131
 
101
132
  export { api_fetch };
@@ -1,16 +1,15 @@
1
- // Not auto-fixable (eslint's sort-imports core rule has no autofixer) and this file's import order doesn't match its syntax-kind-then-alphabetical requirement - left as-is rather than manually reordered across the codebase for a purely cosmetic rule.
2
- // oxlint-disable eslint/sort-imports
3
- import { fetchRaw } from "@ogw_shared/utils/fetch_raw.js";
4
- import { useFeedbackStore } from "@ogw_front/stores/feedback.js";
5
1
  import type { JsonRpcSchema, RequestHandlers } from "@ogw_shared/utils/types.js";
2
+ import { CHUNK_SIZE_BYTES } from "@ogw_shared/utils/file.js";
6
3
  import type { Microservice } from "./api_fetch.js";
4
+ import { fetchRaw } from "@ogw_shared/utils/fetch_raw.js";
5
+ import { useFeedbackStore } from "@ogw_front/stores/feedback.js";
7
6
 
8
7
  interface UploadFileParams {
9
8
  // Always forwarded to fetchRaw via schema.methods, which is only ever set on
10
9
  // HTTP-flavored ("front"/"back") schemas.
11
10
  schema: JsonRpcSchema & { methods: string[] };
12
11
  file: File;
13
- params?: Record<string, string | Blob>;
12
+ params?: Record<string, string>;
14
13
  }
15
14
 
16
15
  // Loosely-typed shapes for the dynamic error/response values reported by fetchRaw.
@@ -26,69 +25,91 @@ interface FetchErrorResponseLike {
26
25
  description?: string;
27
26
  }
28
27
 
29
- function upload_file(
28
+ function isFetchErrorLike(value: unknown): value is FetchErrorLike {
29
+ return typeof value === "object" && value !== null;
30
+ }
31
+
32
+ function isFetchErrorResponseLike(value: unknown): value is FetchErrorResponseLike {
33
+ return typeof value === "object" && value !== null;
34
+ }
35
+
36
+ async function upload_file(
30
37
  microservice: Microservice,
31
38
  { schema, file, params = {} }: UploadFileParams,
32
39
  { request_error_function, response_function, response_error_function }: RequestHandlers = {},
33
- ) {
40
+ ): Promise<unknown> {
34
41
  console.log("[UPLOAD_FILE] Uploading file", { schema, file });
35
42
  const feedbackStore = useFeedbackStore();
36
43
 
37
44
  if (!(file instanceof File)) {
38
- return Promise.reject(new Error("file must be an instance of File"));
45
+ throw new Error("file must be an instance of File");
39
46
  }
40
47
 
41
- const body = new FormData();
42
- for (const [key, value] of Object.entries(params)) {
43
- body.append(key, value);
48
+ const route = schema.$id;
49
+ const method = schema.methods.find((candidate) => candidate !== "OPTIONS");
50
+ const totalChunks = Math.max(1, Math.ceil(file.size / CHUNK_SIZE_BYTES));
51
+
52
+ function onRequestError(error: unknown): void {
53
+ microservice.stop_request();
54
+ const typedError = isFetchErrorLike(error) ? error : {};
55
+ feedbackStore.add_error(
56
+ typedError.code ?? 0,
57
+ route,
58
+ typedError.message ?? "",
59
+ typedError.stack ?? "",
60
+ );
61
+ if (request_error_function) {
62
+ void request_error_function(error);
63
+ }
64
+ }
65
+
66
+ function onResponseError(response: unknown): void {
67
+ microservice.stop_request();
68
+ const typedResponse = isFetchErrorResponseLike(response) ? response : {};
69
+ feedbackStore.add_error(
70
+ typedResponse.status ?? 0,
71
+ route,
72
+ typedResponse.name ?? "",
73
+ typedResponse.description ?? "",
74
+ );
75
+ if (response_error_function) {
76
+ void response_error_function(response);
77
+ }
44
78
  }
45
- body.append("file", file);
46
79
 
47
80
  microservice.start_request();
48
- const route = schema.$id;
49
81
 
50
- return fetchRaw(
51
- {
52
- route,
53
- method: schema.methods.find((method) => method !== "OPTIONS"),
54
- params: body,
55
- baseURL: microservice.base_url,
56
- },
57
- {
58
- request_error_function(error: unknown) {
59
- microservice.stop_request();
60
- const typedError = error as FetchErrorLike;
61
- feedbackStore.add_error(
62
- typedError.code ?? 0,
63
- route,
64
- typedError.message ?? "",
65
- typedError.stack ?? "",
66
- );
67
- if (request_error_function) {
68
- request_error_function(error);
69
- }
70
- },
71
- response_function(data: unknown) {
72
- microservice.stop_request();
73
- if (response_function) {
74
- response_function(data);
75
- }
82
+ let result: unknown = undefined;
83
+ for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex += 1) {
84
+ const start = chunkIndex * CHUNK_SIZE_BYTES;
85
+ const chunk = file.slice(start, start + CHUNK_SIZE_BYTES);
86
+ const query = new URLSearchParams({
87
+ ...params,
88
+ filename: file.name,
89
+ chunk_index: String(chunkIndex),
90
+ total_chunks: String(totalChunks),
91
+ });
92
+
93
+ // oxlint-disable-next-line no-await-in-loop -- chunks must be sent in order; the server appends each one to the file as it arrives.
94
+ result = await fetchRaw(
95
+ {
96
+ route: `${route}?${query.toString()}`,
97
+ method,
98
+ params: chunk,
99
+ baseURL: microservice.base_url,
76
100
  },
77
- response_error_function(response: unknown) {
78
- microservice.stop_request();
79
- const typedResponse = response as FetchErrorResponseLike;
80
- feedbackStore.add_error(
81
- typedResponse.status ?? 0,
82
- route,
83
- typedResponse.name ?? "",
84
- typedResponse.description ?? "",
85
- );
86
- if (response_error_function) {
87
- response_error_function(response);
88
- }
101
+ {
102
+ request_error_function: onRequestError,
103
+ response_error_function: onResponseError,
89
104
  },
90
- },
91
- );
105
+ );
106
+ }
107
+
108
+ microservice.stop_request();
109
+ if (response_function) {
110
+ response_function(result);
111
+ }
112
+ return result;
92
113
  }
93
114
 
94
115
  export { upload_file };