@geode/opengeodeweb-front 10.3.0 → 10.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/app/assets/geode_objects.js +1 -3
  3. package/app/components/Carousel.vue +7 -4
  4. package/app/components/CrsSelector.vue +5 -6
  5. package/app/components/DragAndDrop.vue +18 -8
  6. package/app/components/ExtensionSelector.vue +9 -17
  7. package/app/components/FeedBack/ErrorBanner.vue +1 -1
  8. package/app/components/FeedBack/Snackers.vue +4 -1
  9. package/app/components/FileSelector.vue +21 -10
  10. package/app/components/FileUploader.vue +15 -32
  11. package/app/components/HybridRenderingView.vue +5 -3
  12. package/app/components/Inspector/InspectionButton.vue +2 -2
  13. package/app/components/Inspector/ResultPanel.vue +4 -4
  14. package/app/components/Launcher.vue +1 -1
  15. package/app/components/Loading.vue +6 -6
  16. package/app/components/MissingFilesSelector.vue +23 -29
  17. package/app/components/ObjectSelector.vue +11 -10
  18. package/app/components/OptionCard.vue +1 -1
  19. package/app/components/PackagesVersions.vue +5 -3
  20. package/app/components/Recaptcha.vue +6 -4
  21. package/app/components/RemoteRenderingView.vue +4 -3
  22. package/app/components/Screenshot.vue +4 -4
  23. package/app/components/Step.vue +7 -7
  24. package/app/components/VeaseViewToolbar.vue +3 -3
  25. package/app/components/Viewer/BreadCrumb.vue +2 -4
  26. package/app/components/Viewer/ContextMenu.vue +77 -45
  27. package/app/components/Viewer/ContextMenuItem.vue +42 -33
  28. package/app/components/Viewer/EdgedCurve/PointsOptions.vue +3 -3
  29. package/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue +5 -5
  30. package/app/components/Viewer/Generic/Mesh/CellsOptions.vue +6 -6
  31. package/app/components/Viewer/Generic/Mesh/EdgesOptions.vue +5 -5
  32. package/app/components/Viewer/Generic/Mesh/PointsOptions.vue +5 -5
  33. package/app/components/Viewer/Generic/Mesh/PolygonsOptions.vue +6 -7
  34. package/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue +6 -6
  35. package/app/components/Viewer/Generic/Model/EdgesOptions.vue +3 -3
  36. package/app/components/Viewer/Generic/Model/PointsOptions.vue +4 -4
  37. package/app/components/Viewer/Grid/2D/CellsOptions.vue +3 -3
  38. package/app/components/Viewer/Grid/2D/EdgesOptions.vue +3 -3
  39. package/app/components/Viewer/Grid/2D/PointsOptions.vue +3 -3
  40. package/app/components/Viewer/Grid/3D/CellsOptions.vue +3 -3
  41. package/app/components/Viewer/Grid/3D/EdgesOptions.vue +3 -3
  42. package/app/components/Viewer/Grid/3D/FacetsOptions.vue +3 -3
  43. package/app/components/Viewer/Grid/3D/PointsOptions.vue +3 -3
  44. package/app/components/Viewer/HybridSolid/EdgesOptions.vue +3 -3
  45. package/app/components/Viewer/HybridSolid/PointsOptions.vue +3 -3
  46. package/app/components/Viewer/HybridSolid/PolygonsOptions.vue +3 -3
  47. package/app/components/Viewer/HybridSolid/PolyhedraOptions.vue +3 -3
  48. package/app/components/Viewer/Options/CellAttributeSelector.vue +23 -20
  49. package/app/components/Viewer/Options/ColorMapList.vue +75 -50
  50. package/app/components/Viewer/Options/ColorMapPicker.vue +38 -32
  51. package/app/components/Viewer/Options/ColorPicker.vue +3 -3
  52. package/app/components/Viewer/Options/ColoringTypeSelector.vue +29 -21
  53. package/app/components/Viewer/Options/EdgeAttributeSelector.vue +7 -7
  54. package/app/components/Viewer/Options/PolygonAttributeSelector.vue +7 -7
  55. package/app/components/Viewer/Options/PolyhedronAttributeSelector.vue +7 -7
  56. package/app/components/Viewer/Options/TextureItem.vue +5 -5
  57. package/app/components/Viewer/Options/TexturesSelector.vue +5 -5
  58. package/app/components/Viewer/Options/VertexAttributeSelector.vue +7 -7
  59. package/app/components/Viewer/PointSet/SpecificPointsOptions.vue +5 -5
  60. package/app/components/Viewer/PolygonalSurface/EdgesOptions.vue +3 -3
  61. package/app/components/Viewer/PolygonalSurface/PointsOptions.vue +3 -3
  62. package/app/components/Viewer/PolygonalSurface/SpecificPolygonsOptions.vue +6 -6
  63. package/app/components/Viewer/Solid/EdgesOptions.vue +3 -3
  64. package/app/components/Viewer/Solid/PointsOptions.vue +3 -3
  65. package/app/components/Viewer/Solid/PolygonsOptions.vue +3 -3
  66. package/app/components/Viewer/Solid/SpecificPolyhedraOptions.vue +6 -6
  67. package/app/components/Viewer/TetrahedralSolid/TetrahedraOptions.vue +3 -3
  68. package/app/components/Viewer/TetrahedralSolid/TrianglesOptions.vue +3 -3
  69. package/app/components/Viewer/Tree/ObjectTree.vue +7 -9
  70. package/app/components/Viewer/TreeComponent.vue +9 -13
  71. package/app/components/Viewer/TreeObject.vue +8 -9
  72. package/app/components/Viewer/TriangulatedSurface/EdgesOptions.vue +3 -3
  73. package/app/components/Viewer/TriangulatedSurface/PointsOptions.vue +3 -3
  74. package/app/components/Viewer/TriangulatedSurface/TrianglesOptions.vue +3 -3
  75. package/app/components/Wrapper.vue +1 -2
  76. package/app/components/ZScaling.vue +1 -1
  77. package/app/composables/project_manager.js +6 -6
  78. package/app/plugins/auto_store_register.js +1 -1
  79. package/app/stores/app.js +45 -41
  80. package/app/stores/data.js +52 -51
  81. package/app/stores/data_style.js +12 -11
  82. package/app/stores/feedback.js +5 -1
  83. package/app/stores/geode.js +16 -13
  84. package/app/stores/hybrid_viewer.js +72 -44
  85. package/app/stores/infra.js +18 -16
  86. package/app/stores/lambda.js +1 -9
  87. package/app/stores/menu.js +13 -13
  88. package/app/stores/treeview.js +15 -13
  89. package/app/stores/viewer.js +39 -33
  90. package/app/utils/app_mode.js +4 -3
  91. package/app/utils/default_styles.js +55 -47
  92. package/app/utils/file_import_workflow.js +4 -17
  93. package/app/utils/local.js +195 -184
  94. package/app/utils/upload_file.js +1 -2
  95. package/eslint.config.js +2 -2
  96. package/internal/database/database.js +17 -32
  97. package/internal/database/extended_database.js +25 -0
  98. package/internal/stores/data_style/mesh/cells/cell.js +3 -3
  99. package/internal/stores/data_style/mesh/cells/color.js +1 -1
  100. package/internal/stores/data_style/mesh/cells/index.js +7 -7
  101. package/internal/stores/data_style/mesh/cells/textures.js +1 -1
  102. package/internal/stores/data_style/mesh/cells/vertex.js +3 -3
  103. package/internal/stores/data_style/mesh/cells/visibility.js +1 -1
  104. package/internal/stores/data_style/mesh/edges/color.js +1 -1
  105. package/internal/stores/data_style/mesh/edges/edge.js +22 -22
  106. package/internal/stores/data_style/mesh/edges/index.js +7 -7
  107. package/internal/stores/data_style/mesh/edges/vertex.js +3 -3
  108. package/internal/stores/data_style/mesh/edges/visibility.js +1 -1
  109. package/internal/stores/data_style/mesh/edges/width.js +1 -1
  110. package/internal/stores/data_style/mesh/index.js +4 -5
  111. package/internal/stores/data_style/mesh/points/color.js +1 -1
  112. package/internal/stores/data_style/mesh/points/index.js +6 -6
  113. package/internal/stores/data_style/mesh/points/size.js +1 -1
  114. package/internal/stores/data_style/mesh/points/vertex.js +3 -3
  115. package/internal/stores/data_style/mesh/points/visibility.js +1 -1
  116. package/internal/stores/data_style/mesh/polygons/color.js +1 -1
  117. package/internal/stores/data_style/mesh/polygons/index.js +7 -7
  118. package/internal/stores/data_style/mesh/polygons/polygon.js +3 -3
  119. package/internal/stores/data_style/mesh/polygons/textures.js +1 -1
  120. package/internal/stores/data_style/mesh/polygons/vertex.js +3 -3
  121. package/internal/stores/data_style/mesh/polygons/visibility.js +1 -1
  122. package/internal/stores/data_style/mesh/polyhedra/color.js +1 -1
  123. package/internal/stores/data_style/mesh/polyhedra/index.js +6 -6
  124. package/internal/stores/data_style/mesh/polyhedra/polyhedron.js +3 -3
  125. package/internal/stores/data_style/mesh/polyhedra/vertex.js +3 -3
  126. package/internal/stores/data_style/mesh/polyhedra/visibility.js +1 -1
  127. package/internal/stores/data_style/model/edges.js +1 -1
  128. package/internal/stores/data_style/model/index.js +32 -22
  129. package/internal/utils/api_fetch.js +8 -5
  130. package/internal/utils/viewer_call.js +42 -46
  131. package/nuxt.config.js +3 -3
  132. package/package.json +1 -1
  133. package/scripts/generate_geode_objects.js +8 -7
  134. package/tests/integration/setup.js +28 -21
  135. package/tests/integration/stores/data_style/mesh/cells.nuxt.test.js +18 -10
  136. package/tests/integration/stores/data_style/mesh/edges.nuxt.test.js +18 -10
  137. package/tests/integration/stores/data_style/mesh/index.nuxt.test.js +9 -5
  138. package/tests/integration/stores/data_style/mesh/points.nuxt.test.js +17 -10
  139. package/tests/integration/stores/data_style/mesh/polygons.nuxt.test.js +18 -10
  140. package/tests/integration/stores/data_style/mesh/polyhedra.nuxt.test.js +18 -10
  141. package/tests/integration/stores/data_style/model/blocks.nuxt.test.js +10 -6
  142. package/tests/integration/stores/data_style/model/corners.nuxt.test.js +10 -6
  143. package/tests/integration/stores/data_style/model/edges.nuxt.test.js +9 -5
  144. package/tests/integration/stores/data_style/model/index.nuxt.test.js +9 -5
  145. package/tests/integration/stores/data_style/model/lines.nuxt.test.js +10 -6
  146. package/tests/integration/stores/data_style/model/points.nuxt.test.js +9 -5
  147. package/tests/integration/stores/data_style/model/surfaces.nuxt.test.js +10 -6
  148. package/tests/integration/stores/viewer.nuxt.test.js +55 -39
  149. package/tests/setup_indexeddb.js +1 -0
  150. package/tests/unit/components/CrsSelector.nuxt.test.js +18 -19
  151. package/tests/unit/components/ExtensionSelector.nuxt.test.js +24 -19
  152. package/tests/unit/components/FeedBack/ErrorsBanner.nuxt.test.js +23 -36
  153. package/tests/unit/components/FeedBack/Snackers.nuxt.test.js +20 -25
  154. package/tests/unit/components/FileSelector.nuxt.test.js +27 -27
  155. package/tests/unit/components/FileUploader.nuxt.test.js +18 -17
  156. package/tests/unit/components/Inspector/InspectionButton.nuxt.test.js +9 -16
  157. package/tests/unit/components/Inspector/ResultPanel.nuxt.test.js +8 -6
  158. package/tests/unit/components/Launcher.nuxt.test.js +12 -17
  159. package/tests/unit/components/MissingFilesSelector.nuxt.test.js +16 -19
  160. package/tests/unit/components/ObjectSelector.nuxt.test.js +30 -34
  161. package/tests/unit/components/PackagesVersions.nuxt.test.js +8 -11
  162. package/tests/unit/components/Step.nuxt.test.js +8 -7
  163. package/tests/unit/components/Stepper.nuxt.test.js +14 -12
  164. package/tests/unit/composables/ProjectManager.nuxt.test.js +142 -100
  165. package/tests/unit/composables/api_fetch.nuxt.test.js +12 -39
  166. package/tests/unit/composables/run_function_when_microservices_connected.nuxt.test.js +36 -61
  167. package/tests/unit/composables/upload_file.nuxt.test.js +21 -25
  168. package/tests/unit/plugins/project_load.nuxt.test.js +22 -21
  169. package/tests/unit/stores/App.nuxt.test.js +45 -43
  170. package/tests/unit/stores/Feedback.nuxt.test.js +16 -18
  171. package/tests/unit/stores/Geode.nuxt.test.js +135 -137
  172. package/tests/unit/stores/Infra.nuxt.test.js +20 -26
  173. package/tests/unit/stores/Lambda.nuxt.test.js +30 -31
  174. package/tests/unit/stores/Treeview.nuxt.test.js +53 -55
  175. package/tests/unit/stores/Viewer.nuxt.test.js +16 -23
  176. package/tests/unit/utils/validate_schema.nuxt.test.js +18 -18
  177. package/tests/utils.js +15 -2
  178. package/tests/vitest.config.js +6 -2
@@ -1,19 +1,23 @@
1
- // Node.js imports
2
- import fs from "fs"
3
- import path from "path"
4
- import child_process from "child_process"
5
- import WebSocket from "ws"
1
+ import { on, once } from "node:events"
2
+ import child_process from "node:child_process"
3
+ import fs from "node:fs"
4
+ import path from "node:path"
6
5
 
7
6
  // Third party imports
7
+ import { WebSocket } from "ws"
8
+ import back_schemas from "@geode/opengeodeweb-back/opengeodeweb_back_schemas.json" with { type: "json" }
8
9
  import { getPort } from "get-port-please"
9
10
  import isElectron from "is-electron"
10
11
  import pTimeout from "p-timeout"
11
- import back_schemas from "@geode/opengeodeweb-back/opengeodeweb_back_schemas.json" with { type: "json" }
12
12
  import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json" with { type: "json" }
13
13
 
14
+ const MAX_DELETE_FOLDER_RETRIES = 5
15
+ const DEFAULT_TIMEOUT_SECONDS = 30
16
+ const MILLISECONDS_PER_SECOND = 1000
17
+
14
18
  function venv_script_path(root_path, microservice_path) {
15
19
  const venv_path = path.join(root_path, microservice_path, "venv")
16
- var script_path
20
+ let script_path = ""
17
21
  if (process.platform === "win32") {
18
22
  script_path = path.join(venv_path, "Scripts")
19
23
  } else {
@@ -37,7 +41,7 @@ async function executable_path(microservice_path) {
37
41
 
38
42
  function executable_name(name) {
39
43
  if (process.platform === "win32") {
40
- return name + ".exe"
44
+ return `${name}.exe`
41
45
  }
42
46
  return name
43
47
  }
@@ -65,119 +69,108 @@ function commandExistsSync(executable_name) {
65
69
  })
66
70
  }
67
71
 
72
+ async function wait_for_ready(child, expected_response) {
73
+ for await (const [data] of on(child.stdout, "data")) {
74
+ if (data.toString().includes(expected_response)) {
75
+ return child
76
+ }
77
+ }
78
+ throw new Error("Process closed before signal")
79
+ }
80
+
68
81
  async function run_script(
69
82
  executable_name,
70
83
  executable_path,
71
84
  args,
72
85
  expected_response,
73
- timeout_seconds = 30,
86
+ timeout_seconds = DEFAULT_TIMEOUT_SECONDS,
74
87
  ) {
75
- return new Promise((resolve, reject) => {
76
- setTimeout(() => {
77
- reject("Timed out after " + timeout_seconds + " seconds")
78
- }, timeout_seconds * 1000)
88
+ const command = commandExistsSync(executable_name)
89
+ ? executable_name
90
+ : path.join(executable_path, executable_name)
91
+ console.log("run_script", command, args)
92
+ const child = child_process.spawn(command, args, {
93
+ encoding: "utf8",
94
+ shell: true,
95
+ })
79
96
 
80
- const command = commandExistsSync(executable_name)
81
- ? executable_name
82
- : path.join(executable_path, executable_name)
83
- console.log("run_script", command, args)
84
- const child = child_process.spawn(command, args, {
85
- encoding: "utf8",
86
- shell: true,
87
- })
97
+ child.stdout.on("data", (data) => console.log(data.toString()))
88
98
 
89
- // You can also use a variable to save the output for when the script closes later
90
- child.stderr.setEncoding("utf8")
91
- child.on("error", async (error) => {
92
- const electron = await import("electron")
93
- electron.dialog.showMessageBox({
94
- title: "Title",
95
- type: "warning",
96
- message: "Error occured.\r\n" + error,
97
- })
98
- })
99
- child.stdout.setEncoding("utf8")
100
- child.stdout.on("data", (data) => {
101
- //Here is the output
102
- data = data.toString()
103
- if (data.includes(expected_response)) {
104
- resolve(child)
105
- }
106
- console.log(data)
99
+ child.on("error", async (error) => {
100
+ const electron = await import("electron")
101
+ electron.dialog.showMessageBox({
102
+ title: "Title",
103
+ type: "warning",
104
+ message: `Error occured.\r\n${error}`,
107
105
  })
106
+ })
108
107
 
109
- child.stderr.on("data", (data) => {
110
- console.log(data)
111
- })
108
+ child.on("close", (code) =>
109
+ console.log(`Child Process exited with code ${code}`),
110
+ )
111
+ child.on("kill", () => {
112
+ console.log("Child Process killed")
113
+ })
114
+ child.name = command.replace(/^.*[\\/]/, "")
112
115
 
113
- child.on("close", (_code) => {
114
- //Here you can get the exit code of the script
115
- console.log("Child Process exited with code " + _code)
116
- })
117
- child.on("kill", () => {
118
- console.log("Child Process killed")
116
+ try {
117
+ return await pTimeout(wait_for_ready(child, expected_response), {
118
+ milliseconds: timeout_seconds * MILLISECONDS_PER_SECOND,
119
+ message: `Timed out after ${timeout_seconds} seconds`,
119
120
  })
120
- child.name = command.replace(/^.*[\\/]/, "")
121
- return child
122
- })
121
+ } catch (error) {
122
+ child.kill()
123
+ throw error
124
+ }
123
125
  }
124
126
 
125
- async function run_back(
126
- executable_name,
127
- executable_path,
128
- args = {
129
- project_folder_path,
130
- upload_folder_path: undefined,
131
- },
132
- ) {
133
- return new Promise(async (resolve, reject) => {
134
- let upload_folder_path = args.upload_folder_path
135
- if (!args.upload_folder_path) {
136
- upload_folder_path = path.join(args.project_folder_path, "uploads")
137
- }
138
- const port = await get_available_port()
139
- const back_args = [
140
- "--port " + port,
141
- "--data_folder_path " + args.project_folder_path,
142
- "--upload_folder_path " + upload_folder_path,
143
- "--allowed_origin http://localhost:*",
144
- "--timeout " + 0,
145
- ]
146
- if (process.env.NODE_ENV === "development" || !process.env.NODE_ENV) {
147
- back_args.push("--debug")
148
- }
149
- console.log("run_back", executable_name, executable_path, back_args)
150
- await run_script(
151
- executable_name,
152
- executable_path,
153
- back_args,
154
- "Serving Flask app",
155
- )
156
- resolve(port)
157
- })
127
+ async function run_back(executable_name, executable_path, args = {}) {
128
+ let { project_folder_path, upload_folder_path } = args
129
+ if (!project_folder_path) {
130
+ throw new Error("project_folder_path is required")
131
+ }
132
+ if (!upload_folder_path) {
133
+ upload_folder_path = path.join(project_folder_path, "uploads")
134
+ }
135
+ const port = await get_available_port()
136
+ const back_args = [
137
+ `--port ${port}`,
138
+ `--data_folder_path ${project_folder_path}`,
139
+ `--upload_folder_path ${upload_folder_path}`,
140
+ `--allowed_origin http://localhost:*`,
141
+ `--timeout ${0}`,
142
+ ]
143
+ if (process.env.NODE_ENV === "development" || !process.env.NODE_ENV) {
144
+ back_args.push("--debug")
145
+ }
146
+ console.log("run_back", executable_name, executable_path, back_args)
147
+ await run_script(
148
+ executable_name,
149
+ executable_path,
150
+ back_args,
151
+ "Serving Flask app",
152
+ )
153
+ return port
158
154
  }
159
155
 
160
- async function run_viewer(
161
- executable_name,
162
- executable_path,
163
- args = { project_folder_path },
164
- ) {
165
- return new Promise(async (resolve, reject) => {
166
- const port = await get_available_port()
167
- const viewer_args = [
168
- "--port " + port,
169
- "--data_folder_path " + args.project_folder_path,
170
- "--timeout " + 0,
171
- ]
172
- console.log("run_viewer", executable_name, executable_path, viewer_args)
173
- await run_script(
174
- executable_name,
175
- executable_path,
176
- viewer_args,
177
- "Starting factory",
178
- )
179
- resolve(port)
180
- })
156
+ async function run_viewer(executable_name, executable_path, args = {}) {
157
+ if (!args.project_folder_path) {
158
+ throw new Error("project_folder_path is required")
159
+ }
160
+ const port = await get_available_port()
161
+ const viewer_args = [
162
+ `--port ${port}`,
163
+ `--data_folder_path ${args.project_folder_path}`,
164
+ `--timeout ${0}`,
165
+ ]
166
+ console.log("run_viewer", executable_name, executable_path, viewer_args)
167
+ await run_script(
168
+ executable_name,
169
+ executable_path,
170
+ viewer_args,
171
+ "Starting factory",
172
+ )
173
+ return port
181
174
  }
182
175
 
183
176
  function delete_folder_recursive(data_folder_path) {
@@ -186,60 +179,52 @@ function delete_folder_recursive(data_folder_path) {
186
179
  return
187
180
  }
188
181
  try {
189
- for (const i = 0; i <= 5; i++) {
182
+ for (let i = 0; i <= MAX_DELETE_FOLDER_RETRIES; i += 1) {
190
183
  console.log(`Deleting folder: ${data_folder_path}`)
191
184
  fs.rmSync(data_folder_path, { recursive: true, force: true })
192
185
  console.log(`Deleted folder: ${data_folder_path}`)
193
186
  return
194
187
  }
195
- } catch (err) {
196
- console.error(`Error deleting folder ${data_folder_path}:`, err)
188
+ } catch (error) {
189
+ console.error(`Error deleting folder ${data_folder_path}:`, error)
197
190
  }
198
191
  }
199
192
 
200
193
  function kill_back(back_port) {
201
- return pTimeout(
202
- new Promise((resolve, reject) => {
203
- fetch(
204
- "http://localhost:" +
205
- back_port +
206
- "/" +
207
- back_schemas.opengeodeweb_back.kill.$id,
194
+ async function do_kill() {
195
+ try {
196
+ await fetch(
197
+ `http://localhost:${back_port}/${back_schemas.opengeodeweb_back.kill.$id}`,
208
198
  {
209
199
  method: back_schemas.opengeodeweb_back.kill.methods[0],
210
200
  },
211
201
  )
212
- .then(() => {
213
- console.log("Failed to kill back")
214
- reject()
215
- })
216
- .catch(() => {
217
- console.log("Back closed")
218
- resolve()
219
- })
220
- }),
221
- {
222
- milliseconds: 500,
223
- message: "Failed to kill back",
224
- },
225
- )
202
+ throw new Error("Failed to kill back")
203
+ } catch (error) {
204
+ console.log("Back closed", error)
205
+ }
206
+ }
207
+ return pTimeout(do_kill(), {
208
+ milliseconds: 500,
209
+ message: "Failed to kill back",
210
+ })
226
211
  }
227
212
 
228
213
  function kill_viewer(viewer_port) {
229
- return pTimeout(
230
- new Promise((resolve) => {
231
- const socket = new WebSocket("ws://localhost:" + viewer_port + "/ws")
232
- socket.on("open", () => {
233
- console.log("Connected to WebSocket server")
234
- socket.send(
235
- JSON.stringify({
236
- id: "system:hello",
237
- method: "wslink.hello",
238
- args: [{ secret: "wslink-secret" }],
239
- }),
240
- )
241
- })
242
- socket.on("message", (data) => {
214
+ async function do_kill() {
215
+ const socket = new WebSocket(`ws://localhost:${viewer_port}/ws`)
216
+ try {
217
+ await once(socket, "open")
218
+ console.log("Connected to WebSocket server")
219
+ socket.send(
220
+ JSON.stringify({
221
+ id: "system:hello",
222
+ method: "wslink.hello",
223
+ args: [{ secret: "wslink-secret" }],
224
+ }),
225
+ )
226
+
227
+ for await (const [data] of on(socket, "message")) {
243
228
  const message = data.toString()
244
229
  console.log("Received from server:", message)
245
230
 
@@ -250,48 +235,89 @@ function kill_viewer(viewer_port) {
250
235
  method: viewer_schemas.opengeodeweb_viewer.kill.$id,
251
236
  }),
252
237
  )
253
- resolve()
238
+ break
254
239
  }
255
- })
256
- socket.on("close", () => {
257
- console.log("Disconnected from WebSocket server")
258
- resolve()
259
- })
260
- socket.on("error", (error) => {
261
- console.error("WebSocket error:", error)
262
- resolve()
263
- })
264
- }),
265
- {
266
- milliseconds: 500,
267
- message: "Failed to kill viewer",
268
- },
269
- )
240
+ }
241
+ await once(socket, "close")
242
+ console.log("Disconnected from WebSocket server")
243
+ } catch (error) {
244
+ console.error("WebSocket error:", error)
245
+ } finally {
246
+ if (socket.readyState === WebSocket.OPEN) {
247
+ socket.close()
248
+ }
249
+ }
250
+ }
251
+
252
+ return pTimeout(do_kill(), {
253
+ milliseconds: 500,
254
+ message: "Failed to kill viewer",
255
+ })
256
+ }
257
+
258
+ async function wait_nuxt(nuxt_process, back_port, viewer_port) {
259
+ for await (const [data] of on(nuxt_process.stdout, "data")) {
260
+ const output = data.toString()
261
+ const portMatch = output.match(
262
+ /Accepting connections at http:\/\/localhost:(\d+)/,
263
+ )
264
+ console.log("Nuxt:", output)
265
+ if (portMatch) {
266
+ const [, nuxt_port] = portMatch
267
+ process.env.NUXT_PORT = nuxt_port
268
+ return { geode_port: back_port, viewer_port, nuxt_port }
269
+ }
270
+ }
271
+ throw new Error("Nuxt process closed without accepting connections")
270
272
  }
271
273
 
272
274
  async function run_browser(
273
275
  script_name,
274
276
  microservices_options = {
275
- back: { executable_name, executable_path, args: { project_folder_path } },
276
- viewer: { executable_name, executable_path, args: { project_folder_path } },
277
+ back: {
278
+ executable_name: executable_name("opengeodeweb-back"),
279
+ executable_path: "",
280
+ args: { project_folder_path: "" },
281
+ },
282
+ viewer: {
283
+ executable_name: executable_name("opengeodeweb-viewer"),
284
+ executable_path: "",
285
+ args: { project_folder_path: "" },
286
+ },
277
287
  },
278
288
  ) {
279
- console.log("microservices_options", microservices_options)
289
+ if (
290
+ microservices_options.back.executable_path === "" ||
291
+ microservices_options.back.args.project_folder_path === ""
292
+ ) {
293
+ const microservices_path = "microservices"
294
+ microservices_options.back.executable_path =
295
+ await executable_path(microservices_path)
296
+ microservices_options.back.args.project_folder_path = create_path(
297
+ path.join(process.cwd(), "data"),
298
+ )
299
+ }
300
+ if (
301
+ microservices_options.viewer.executable_path === "" ||
302
+ microservices_options.viewer.args.project_folder_path === ""
303
+ ) {
304
+ const microservices_path = "microservices"
305
+ microservices_options.viewer.executable_path =
306
+ await executable_path(microservices_path)
307
+ microservices_options.viewer.args.project_folder_path =
308
+ microservices_options.back.args.project_folder_path
309
+ }
280
310
  const back_promise = run_back(
281
311
  microservices_options.back.executable_name,
282
312
  microservices_options.back.executable_path,
283
- {
284
- ...microservices_options.back.args,
285
- },
313
+ { ...microservices_options.back.args },
286
314
  )
287
315
  console.log("back_promise", back_promise)
288
316
 
289
317
  const viewer_promise = run_viewer(
290
318
  microservices_options.viewer.executable_name,
291
319
  microservices_options.viewer.executable_path,
292
- {
293
- ...microservices_options.viewer.args,
294
- },
320
+ { ...microservices_options.viewer.args },
295
321
  )
296
322
  console.log("viewer_promise", viewer_promise)
297
323
 
@@ -316,22 +342,7 @@ async function run_browser(
316
342
  shell: true,
317
343
  FORCE_COLOR: true,
318
344
  })
319
-
320
- return new Promise((resolve) => {
321
- nuxt_process.stdout.on("data", function (data) {
322
- const output = data.toString()
323
- const portMatch = output.match(
324
- /Accepting\ connections\ at\ http:\/\/localhost:(\d+)/,
325
- )
326
- console.log("Nuxt: ", output)
327
- if (portMatch) {
328
- const nuxt_port = portMatch[1]
329
- process.env.NUXT_PORT = nuxt_port
330
- resolve({ geode_port: back_port, viewer_port, nuxt_port })
331
- return
332
- }
333
- })
334
- })
345
+ return wait_nuxt(nuxt_process, back_port, viewer_port)
335
346
  }
336
347
 
337
348
  export {
@@ -1,5 +1,5 @@
1
- import { useGeodeStore } from "@ogw_front/stores/geode"
2
1
  import { useFeedbackStore } from "@ogw_front/stores/feedback"
2
+ import { useGeodeStore } from "@ogw_front/stores/geode"
3
3
 
4
4
  export async function upload_file(
5
5
  { route, file },
@@ -18,7 +18,6 @@ export async function upload_file(
18
18
  method: "PUT",
19
19
  body: body,
20
20
  }
21
-
22
21
  geodeStore.start_request()
23
22
  return $fetch(route, {
24
23
  baseURL: geodeStore.base_url,
package/eslint.config.js CHANGED
@@ -1,7 +1,8 @@
1
+ import nuxt from "eslint-plugin-nuxt"
1
2
  import vue from "eslint-plugin-vue"
2
3
  import vuetify from "eslint-plugin-vuetify"
3
- import nuxt from "eslint-plugin-nuxt"
4
4
 
5
+ // oxlint-disable-next-line import/no-anonymous-default-export
5
6
  export default [
6
7
  {
7
8
  files: ["**/*.{js,ts,vue}"],
@@ -11,7 +12,6 @@ export default [
11
12
  globals: {
12
13
  window: "readonly",
13
14
  document: "readonly",
14
- // ajoute d'autres globals si nécessaire
15
15
  },
16
16
  },
17
17
  plugins: {
@@ -1,8 +1,9 @@
1
- import Dexie from "dexie"
1
+ import { Dexie } from "dexie"
2
+ import { ExtendedDatabase } from "./extended_database"
2
3
  import { dataTable } from "./tables/data_table"
3
4
  import { modelComponentsTable } from "./tables/model_components"
4
5
 
5
- export class Database extends Dexie {
6
+ class Database extends Dexie {
6
7
  constructor() {
7
8
  super("Database")
8
9
 
@@ -16,50 +17,34 @@ export class Database extends Dexie {
16
17
  const tempDb = new Database()
17
18
  await tempDb.open()
18
19
 
19
- if (tempDb.tables.some((t) => t.name === tableName)) {
20
- console.warn(`Table "${tableName}" already exists`)
20
+ if (tempDb.tables.some((table) => table.name === tableName)) {
21
21
  tempDb.close()
22
22
  return tempDb
23
23
  }
24
24
 
25
25
  const currentVersion = tempDb.verno
26
-
27
26
  const currentStores = {}
28
- tempDb.tables.forEach((table) => {
27
+
28
+ for (const table of tempDb.tables) {
29
29
  const keyPath = table.schema.primKey.src
30
- const indexes = table.schema.indexes.map((idx) => idx.src)
30
+ const indexes = table.schema.indexes.map((index) => index.src)
31
31
  currentStores[table.name] = [keyPath, ...indexes].join(",")
32
- })
32
+ }
33
33
 
34
34
  tempDb.close()
35
35
 
36
- class ExtendedDatabase extends Dexie {
37
- constructor() {
38
- super("Database")
39
-
40
- for (let v = 1; v <= currentVersion; v++) {
41
- if (v === 1) {
42
- this.version(1).stores({
43
- [dataTable.name]: dataTable.schema,
44
- [modelComponentsTable.name]: modelComponentsTable.schema,
45
- })
46
- } else {
47
- this.version(v).stores(currentStores)
48
- }
49
- }
50
-
51
- this.version(currentVersion + 1).stores({
52
- ...currentStores,
53
- [tableName]: schemaDefinition,
54
- })
55
- }
56
- }
57
-
58
- const newDb = new ExtendedDatabase()
36
+ const newDb = new ExtendedDatabase(
37
+ currentVersion,
38
+ currentStores,
39
+ tableName,
40
+ schemaDefinition,
41
+ )
59
42
  await newDb.open()
60
43
 
61
44
  return newDb
62
45
  }
63
46
  }
64
47
 
65
- export const database = new Database()
48
+ const database = new Database()
49
+
50
+ export { Database, database }
@@ -0,0 +1,25 @@
1
+ import { Dexie } from "dexie"
2
+ import { dataTable } from "./tables/data_table"
3
+ import { modelComponentsTable } from "./tables/model_components"
4
+
5
+ export class ExtendedDatabase extends Dexie {
6
+ constructor(currentVersion, currentStores, tableName, schemaDefinition) {
7
+ super("Database")
8
+
9
+ for (let version = 1; version <= currentVersion; version += 1) {
10
+ if (version === 1) {
11
+ this.version(1).stores({
12
+ [dataTable.name]: dataTable.schema,
13
+ [modelComponentsTable.name]: modelComponentsTable.schema,
14
+ })
15
+ } else {
16
+ this.version(version).stores(currentStores)
17
+ }
18
+ }
19
+
20
+ this.version(currentVersion + 1).stores({
21
+ ...currentStores,
22
+ [tableName]: schemaDefinition,
23
+ })
24
+ }
25
+ }
@@ -2,9 +2,9 @@
2
2
  import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json"
3
3
 
4
4
  // Local imports
5
- import { useViewerStore } from "@ogw_front/stores/viewer"
6
5
  import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap"
7
6
  import { useMeshCellsCommonStyle } from "./common"
7
+ import { useViewerStore } from "@ogw_front/stores/viewer"
8
8
 
9
9
  // Local constants
10
10
  const meshCellsCellAttributeSchemas =
@@ -30,7 +30,7 @@ export function useMeshCellsCellAttributeStyle() {
30
30
  }
31
31
 
32
32
  function meshCellsCellAttributeStoredConfig(id, name) {
33
- const storedConfigs = meshCellsCellAttribute(id).storedConfigs
33
+ const { storedConfigs } = meshCellsCellAttribute(id)
34
34
  if (name in storedConfigs) {
35
35
  return storedConfigs[name]
36
36
  }
@@ -46,7 +46,7 @@ export function useMeshCellsCellAttributeStyle() {
46
46
  name,
47
47
  { minimum, maximum, colorMap },
48
48
  ) {
49
- const storedConfigs = meshCellsCellAttribute(id).storedConfigs
49
+ const { storedConfigs } = meshCellsCellAttribute(id)
50
50
  storedConfigs[name] = { minimum, maximum, colorMap }
51
51
  return storedConfigs[name]
52
52
  }
@@ -2,8 +2,8 @@
2
2
  import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json"
3
3
 
4
4
  // Local imports
5
- import { useViewerStore } from "@ogw_front/stores/viewer"
6
5
  import { useMeshCellsCommonStyle } from "./common"
6
+ import { useViewerStore } from "@ogw_front/stores/viewer"
7
7
 
8
8
  // Local constants
9
9
  const meshCellsColorSchemas =