Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 3 additions & 29 deletions app/stores/viewer.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// Third party imports
import vtkWSLinkClient, { newInstance } from "@kitware/vtk.js/IO/Core/WSLinkClient";
import _ from "lodash";
// oxlint-disable-next-line no-unassigned-import
import "@kitware/vtk.js/Rendering/OpenGL/Profiles/Geometry";
import SmartConnect from "wslink/src/SmartConnect";
import { connectImageStream } from "@kitware/vtk.js/Rendering/Misc/RemoteView";
import { initWebSocketClient } from "@ogw_internal/utils/ws_client";
import schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";

// Local imports
Expand Down Expand Up @@ -35,7 +34,6 @@ export const useViewerStore = defineStore(
const request_counter = ref(0);
const status = ref(Status.NOT_CONNECTED);
const version = ref("0.0.0");
const busy = ref(0);

const protocol = computed(() => getWebsocketApiProtocol());

Expand Down Expand Up @@ -75,35 +73,11 @@ export const useViewerStore = defineStore(
try {
console.log("VIEWER LOCK GRANTED !", lock);
status.value = Status.CONNECTING;
vtkWSLinkClient.setSmartConnectClass(SmartConnect);

if (_.isEmpty(client.value)) {
client.value = newInstance();
}

client.value.onBusyChange((count) => {
busy.value = count;
});
client.value.onConnectionError((httpReq) => {
const message = httpReq?.response?.error || `Connection error`;
console.error(message);
});
client.value.onConnectionClose((httpReq) => {
const message = httpReq?.response?.error || `Connection close`;
status.value = Status.NOT_CONNECTED;
console.error(message);
});

client.value.beginBusy();
await client.value.connect({
application: "Viewer",
sessionURL: base_url.value,
});
client.value = await initWebSocketClient(base_url.value, client.value);
connectImageStream(client.value.getConnection().getSession());
client.value.endBusy();
const schema = schemas.opengeodeweb_viewer.viewer.reset_visualization;
const timeout = undefined;
await request({ schema, timeout });
await request({ schema });
status.value = Status.CONNECTED;
} catch (error) {
console.error("ws_connect error", error);
Expand Down
7 changes: 6 additions & 1 deletion internal/stores/data_style/mesh/points/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export function useMeshPointsCommonStyle() {
});
}

function mutateMeshPointsVisibility(response) {
return mutateMeshPointsStyle(response.id, { visibility: response.visibility });
}

function meshPointsStyle(id) {
return dataStyleState.getStyle(id).points;
}
Expand All @@ -26,7 +30,8 @@ export function useMeshPointsCommonStyle() {
return {
meshPointsStyle,
meshPointsColoring,
mutateMeshPointsStyle,
mutateMeshPointsColoring,
mutateMeshPointsStyle,
mutateMeshPointsVisibility,
};
}
4 changes: 3 additions & 1 deletion internal/stores/data_style/mesh/points/visibility.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ export function useMeshPointsVisibilityStyle() {
params,
},
{
response_function: () => meshPointsCommonStyle.mutateMeshPointsStyle(id, { visibility }),
response_function(response) {
return meshPointsCommonStyle.mutateMeshPointsVisibility(response);
},
},
);
}
Expand Down
2 changes: 1 addition & 1 deletion internal/utils/api_fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export function api_fetch(
return fetchSchema(
{
schema,
baseURL: microservice.base_url,
params,
baseURL: microservice.base_url,
headers,
max_retry: schema.max_retry,
timeout,
Expand Down
90 changes: 37 additions & 53 deletions internal/utils/viewer_call.js
Original file line number Diff line number Diff line change
@@ -1,65 +1,49 @@
// Third party imports
import pTimeout from "p-timeout";

// Local imports
import { endRequestLog, startRequestLog } from "@ogw_front/utils/log";
import { callSchema } from "@ogw_shared/utils/call_schema";
import { useFeedbackStore } from "@ogw_front/stores/feedback";
import { validate_schema } from "@ogw_shared/utils/validate_schema";

const ERROR_400 = 400;

export function viewer_call(
microservice,
{ schema, params = {}, timeout },
{ request_error_function, response_function, response_error_function } = {},
) {
const feedbackStore = useFeedbackStore();

const { valid, error: schema_error } = validate_schema(schema, params);

if (!valid) {
if (process.env.NODE_ENV !== "production") {
console.log("Bad request", schema_error, schema, params);
}
feedbackStore.add_error(ERROR_400, schema.$id, "Bad request", schema_error);
throw new Error(`${schema.$id}: ${schema_error}`);
}

const { client } = microservice;

async function performCall() {
if (!client.getConnection) {
return;
}
microservice.start_request();
const requestStart = startRequestLog(microservice, schema);
try {
const value = await client.getConnection().getSession().call(schema.$id, [params]);
endRequestLog(microservice, schema, requestStart);
if (response_function) {
await response_function(value);
}
return value;
} catch (error) {
feedbackStore.add_error(error.code, schema.$id, error.message, error.message);
if (request_error_function) {
request_error_function(error);
}
if (response_error_function) {
response_error_function(error);
}
throw error;
} finally {
microservice.stop_request();
}
}

if (timeout > 0) {
return pTimeout(performCall(), {
milliseconds: timeout,
message: `${schema.$id}: Timed out after ${timeout}ms`,
});
}

return performCall();
const requestStartingTime = startRequestLog(microservice, schema);
return callSchema(
{
schema,
params,
client,
timeout,
},
{
request_error_function(error) {
microservice.stop_request();
feedbackStore.add_error(error.code, schema.$id, error.message, error.message);
if (request_error_function) {
request_error_function(error);
}
},
response_function(data) {
endRequestLog(microservice, schema, requestStartingTime);
microservice.stop_request();
if (response_function) {
response_function(data);
}
},
response_error_function(response) {
microservice.stop_request();
feedbackStore.add_error(error.code, schema.$id, error.message, error.message);
if (response_error_function) {
response_error_function(response);
}
},
validation_error_function({ code, name, error }) {
microservice.stop_request();
feedbackStore.add_error(code, schema.$id, name, error);
},
},
);
}
29 changes: 29 additions & 0 deletions internal/utils/ws_client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Third party imports
import vtkWSLinkClient, { newInstance } from "@kitware/vtk.js/IO/Core/WSLinkClient";
import SmartConnect from "wslink/src/SmartConnect";
import _ from "lodash";

async function initWebSocketClient(baseUrl, initialClient = {}) {
vtkWSLinkClient.setSmartConnectClass(SmartConnect);
const client = _.isEmpty(initialClient) ? newInstance() : initialClient;

client.onConnectionError((httpReq) => {
const message = httpReq?.response?.error || `Connection error`;
console.error(message);
});
client.onConnectionClose((httpReq) => {
const message = httpReq?.response?.error || `Connection close`;
status.value = Status.NOT_CONNECTED;
console.error(message);
});

client.beginBusy();
await client.connect({
application: "Viewer",
sessionURL: baseUrl,
});

return client;
}

export { initWebSocketClient };
25 changes: 24 additions & 1 deletion nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,36 @@ export default defineNuxtConfig({
vite: {
optimizeDeps: {
include: [
"@kitware/vtk.js",
"@kitware/vtk.js/Common/Core/Math",
"@kitware/vtk.js/IO/Core/WSLinkClient",
"@kitware/vtk.js/IO/XML/XMLPolyDataReader",
"@kitware/vtk.js/Rendering/Core/Actor",
"@kitware/vtk.js/Rendering/Core/AnnotatedCubeActor",
"@kitware/vtk.js/Rendering/Core/ColorTransferFunction",
"@kitware/vtk.js/Rendering/Core/Mapper",
"@kitware/vtk.js/Rendering/Misc/GenericRenderWindow",
"@kitware/vtk.js/Rendering/Misc/RemoteView",
"@kitware/vtk.js/Rendering/OpenGL/Profiles/Geometry",
"@kitware/vtk.js/Widgets/Core/WidgetManager",
"@kitware/vtk.js/Widgets/Widgets3D/ImplicitPlaneWidget",
"@vue/devtools-core",
"@vue/devtools-kit",
"ajv",
"fast-deep-equal",
"broadcast-channel",
"dexie",
"globalthis",
"h3",
"js-file-download",
"lodash",
"lodash/merge",
"p-timeout",
"seedrandom",
"spark-md5",
"uuid",
"wslink",
"wslink/src/SmartConnect",
"xmlbuilder2",
],
},
},
Expand Down
25 changes: 25 additions & 0 deletions server/utils/server_config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { createServerWsRpcClient } from "./ws_client.js";

const storage = new Map();

function getAppBaseUrl() {
Expand Down Expand Up @@ -25,13 +27,36 @@ function setIsAppReady(isAppReady) {
return storage.set("IS_APP_READY", isAppReady);
}

async function getViewerWebSocketClient() {
const viewerClient = storage.get("VIEWER_CLIENT") ?? undefined;
if (viewerClient?.isOpen()) {
return viewerClient;
}
const viewerBaseUrl = await getViewerBaseUrl();
return setViewerWebSocketClient(viewerBaseUrl);
}

async function setViewerWebSocketClient(baseUrl) {
const client = createServerWsRpcClient(baseUrl);
client.onConnectionClose(() => {
if (viewerClient === client) {
viewerClient = undefined;
}
});
await client.ready;
storage.set("VIEWER_CLIENT", client);
return client;
}

export {
getAppBaseUrl,
getBackBaseUrl,
getIsAppReady,
getViewerBaseUrl,
getViewerWebSocketClient,
setAppBaseUrl,
setBackBaseUrl,
setIsAppReady,
setViewerBaseUrl,
setViewerWebSocketClient,
};
Loading
Loading