@geode/opengeodeweb-front 10.36.0 → 10.37.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.
- package/app/components/Screenshot.vue +6 -4
- package/app/components/ViewToolbar.vue +4 -2
- package/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue +7 -4
- package/app/components/Viewer/Generic/Mesh/CellsOptions.vue +10 -4
- package/app/components/Viewer/Generic/Mesh/EdgesOptions.vue +7 -4
- package/app/components/Viewer/Generic/Mesh/PointsOptions.vue +5 -2
- package/app/components/Viewer/Generic/Mesh/PolygonsOptions.vue +10 -6
- package/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue +7 -6
- package/app/components/Viewer/Generic/Model/BlocksOptions.vue +9 -18
- package/app/components/Viewer/Generic/Model/CornersOptions.vue +5 -10
- package/app/components/Viewer/Generic/Model/EdgesOptions.vue +3 -0
- package/app/components/Viewer/Generic/Model/LinesOptions.vue +9 -17
- package/app/components/Viewer/Generic/Model/SurfacesOptions.vue +8 -18
- package/app/components/Viewer/ObjectTree/Views/ModelTree.vue +1 -5
- package/app/components/Viewer/PointSet/SpecificPointsOptions.vue +11 -2
- package/app/components/Viewer/Solid/SpecificPolyhedraOptions.vue +7 -6
- package/app/components/Viewer/Surface/PolygonsOptions.vue +10 -6
- package/app/composables/hover_highlight.ts +5 -4
- package/app/composables/project_manager.ts +1 -1
- package/app/composables/use_overlapping_picker.ts +4 -73
- package/app/composables/use_quick_colormap.ts +4 -14
- package/app/stores/back.ts +4 -10
- package/app/stores/camera_manager.ts +1 -1
- package/app/stores/data.ts +1 -1
- package/app/stores/viewer.ts +33 -19
- package/internal/stores/data_style/mesh/cells/cell.ts +26 -23
- package/internal/stores/data_style/mesh/cells/color.ts +8 -6
- package/internal/stores/data_style/mesh/cells/index.ts +13 -6
- package/internal/stores/data_style/mesh/cells/textures.ts +17 -6
- package/internal/stores/data_style/mesh/cells/vertex.ts +29 -23
- package/internal/stores/data_style/mesh/cells/visibility.ts +3 -6
- package/internal/stores/data_style/mesh/edges/color.ts +8 -6
- package/internal/stores/data_style/mesh/edges/edge.ts +26 -23
- package/internal/stores/data_style/mesh/edges/index.ts +13 -3
- package/internal/stores/data_style/mesh/edges/vertex.ts +29 -23
- package/internal/stores/data_style/mesh/edges/visibility.ts +3 -6
- package/internal/stores/data_style/mesh/edges/width.ts +3 -3
- package/internal/stores/data_style/mesh/index.ts +24 -11
- package/internal/stores/data_style/mesh/points/color.ts +8 -6
- package/internal/stores/data_style/mesh/points/index.ts +13 -6
- package/internal/stores/data_style/mesh/points/size.ts +3 -3
- package/internal/stores/data_style/mesh/points/vertex.ts +29 -23
- package/internal/stores/data_style/mesh/points/visibility.ts +5 -11
- package/internal/stores/data_style/mesh/polygons/color.ts +8 -6
- package/internal/stores/data_style/mesh/polygons/index.ts +13 -9
- package/internal/stores/data_style/mesh/polygons/polygon.ts +26 -23
- package/internal/stores/data_style/mesh/polygons/textures.ts +17 -6
- package/internal/stores/data_style/mesh/polygons/vertex.ts +26 -23
- package/internal/stores/data_style/mesh/polygons/visibility.ts +3 -6
- package/internal/stores/data_style/mesh/polyhedra/color.ts +8 -6
- package/internal/stores/data_style/mesh/polyhedra/index.ts +9 -5
- package/internal/stores/data_style/mesh/polyhedra/polyhedron.ts +28 -23
- package/internal/stores/data_style/mesh/polyhedra/vertex.ts +26 -23
- package/internal/stores/data_style/mesh/polyhedra/visibility.ts +3 -6
- package/internal/stores/data_style/model/blocks/color.ts +8 -6
- package/internal/stores/data_style/model/blocks/index.ts +9 -22
- package/internal/stores/data_style/model/blocks/polyhedron.ts +28 -23
- package/internal/stores/data_style/model/blocks/vertex.ts +26 -23
- package/internal/stores/data_style/model/blocks/visibility.ts +3 -3
- package/internal/stores/data_style/model/color.ts +10 -7
- package/internal/stores/data_style/model/common.ts +36 -20
- package/internal/stores/data_style/model/corners/color.ts +8 -6
- package/internal/stores/data_style/model/corners/index.ts +8 -14
- package/internal/stores/data_style/model/corners/vertex.ts +26 -23
- package/internal/stores/data_style/model/corners/visibility.ts +3 -3
- package/internal/stores/data_style/model/edges/visibility.ts +8 -8
- package/internal/stores/data_style/model/lines/color.ts +8 -6
- package/internal/stores/data_style/model/lines/edge.ts +26 -23
- package/internal/stores/data_style/model/lines/index.ts +9 -22
- package/internal/stores/data_style/model/lines/vertex.ts +26 -23
- package/internal/stores/data_style/model/lines/visibility.ts +3 -3
- package/internal/stores/data_style/model/points/index.ts +14 -4
- package/internal/stores/data_style/model/points/size.ts +3 -3
- package/internal/stores/data_style/model/points/visibility.ts +3 -6
- package/internal/stores/data_style/model/surfaces/color.ts +8 -6
- package/internal/stores/data_style/model/surfaces/index.ts +9 -22
- package/internal/stores/data_style/model/surfaces/polygon.ts +29 -23
- package/internal/stores/data_style/model/surfaces/vertex.ts +26 -23
- package/internal/stores/data_style/model/surfaces/visibility.ts +3 -3
- package/internal/stores/data_style/model/visibility.ts +1 -1
- package/internal/stores/data_style/when_defined.ts +13 -0
- package/internal/stores/hybrid_viewer/camera.ts +14 -15
- package/internal/stores/hybrid_viewer/core.ts +1 -1
- package/internal/stores/hybrid_viewer/filters.ts +12 -6
- package/internal/stores/hybrid_viewer/highlight.ts +9 -18
- package/internal/stores/hybrid_viewer/ruler.ts +10 -13
- package/internal/stores/hybrid_viewer/scene.ts +1 -1
- package/internal/utils/viewer_call.ts +1 -1
- package/package.json +1 -1
- package/server/utils/ws_client.ts +4 -4
- package/shared/utils/call_raw.ts +3 -3
- package/shared/utils/call_schema.ts +10 -8
- package/shared/utils/types.ts +6 -0
|
@@ -9,7 +9,7 @@ import { requireRenderWindow, useHybridViewerCore } from "./core";
|
|
|
9
9
|
import { dot } from "@kitware/vtk.js/Common/Core/Math";
|
|
10
10
|
import { useHybridViewerScene } from "./scene";
|
|
11
11
|
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
12
|
-
import viewer_schemas from "@geode/opengeodeweb-viewer/
|
|
12
|
+
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_typed_schemas.js";
|
|
13
13
|
|
|
14
14
|
const BUMP_MULTIPLIER = 0.2;
|
|
15
15
|
const ALIGNMENT_THRESHOLD = 0.9;
|
|
@@ -210,25 +210,24 @@ const useHybridViewerCamera = createSharedComposable(() => {
|
|
|
210
210
|
syncRemoteCamera();
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
async function performFocusCameraOnObject(id: string, block_ids:
|
|
213
|
+
async function performFocusCameraOnObject(id: string, block_ids: number[] = []): Promise<void> {
|
|
214
214
|
const { genericRenderWindow } = useHybridViewerCore();
|
|
215
215
|
const { hybridDb } = useHybridViewerScene();
|
|
216
216
|
if (!hybridDb[id]) {
|
|
217
217
|
return;
|
|
218
218
|
}
|
|
219
219
|
const viewerStore = useViewerStore();
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
: hybridDb[id].actor.getBounds();
|
|
220
|
+
let bounds: [number, number, number, number, number, number] = hybridDb[id].actor.getBounds();
|
|
221
|
+
if (block_ids.length > 0) {
|
|
222
|
+
const response = await viewerStore.request({
|
|
223
|
+
schema: viewer_schemas.opengeodeweb_viewer.model.get_blocks_bounds,
|
|
224
|
+
params: {
|
|
225
|
+
id,
|
|
226
|
+
block_ids,
|
|
227
|
+
},
|
|
228
|
+
});
|
|
229
|
+
bounds = toBounds(response.bounds);
|
|
230
|
+
}
|
|
232
231
|
const renderer = requireRenderWindow(genericRenderWindow).getRenderer();
|
|
233
232
|
const camera = renderer.getActiveCamera();
|
|
234
233
|
const startOptions = getCameraOptions(camera);
|
|
@@ -238,7 +237,7 @@ const useHybridViewerCamera = createSharedComposable(() => {
|
|
|
238
237
|
performSetCamera(targetOptions);
|
|
239
238
|
}
|
|
240
239
|
|
|
241
|
-
async function focusCameraOnObject(id: string, block_ids:
|
|
240
|
+
async function focusCameraOnObject(id: string, block_ids: number[] = []): Promise<void> {
|
|
242
241
|
await performFocusCameraOnObject(id, block_ids);
|
|
243
242
|
}
|
|
244
243
|
|
|
@@ -2,7 +2,7 @@ import { Status } from "@ogw_front/utils/status";
|
|
|
2
2
|
import type { ViewStreamLike } from "./vtk_types";
|
|
3
3
|
import type { vtkGenericRenderWindow as VtkGenericRenderWindow } from "@kitware/vtk.js/Rendering/Misc/GenericRenderWindow";
|
|
4
4
|
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
5
|
-
import viewer_schemas from "@geode/opengeodeweb-viewer/
|
|
5
|
+
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_typed_schemas.js";
|
|
6
6
|
|
|
7
7
|
interface GenericRenderWindowHolder {
|
|
8
8
|
value?: VtkGenericRenderWindow;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import viewer_schemas, {
|
|
2
|
+
type ViewerClippingPlanesParams,
|
|
3
|
+
} from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_typed_schemas.js";
|
|
1
4
|
import type { SliceAxis } from "@ogw_front/utils/slice";
|
|
2
5
|
import { useHybridViewerCore } from "./core";
|
|
3
6
|
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
4
|
-
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
|
|
5
7
|
|
|
6
|
-
async function setClippingPlanes(
|
|
8
|
+
async function setClippingPlanes(
|
|
9
|
+
ids: string[],
|
|
10
|
+
planes: ViewerClippingPlanesParams["planes"],
|
|
11
|
+
): Promise<void> {
|
|
7
12
|
const viewerStore = useViewerStore();
|
|
8
13
|
const { remoteRender } = useHybridViewerCore();
|
|
9
14
|
const schema = viewer_schemas.opengeodeweb_viewer.viewer.clipping_planes;
|
|
@@ -42,13 +47,14 @@ async function setSlice(
|
|
|
42
47
|
ids,
|
|
43
48
|
slices,
|
|
44
49
|
};
|
|
45
|
-
const
|
|
50
|
+
const {
|
|
51
|
+
max_indices: [max_i = 0, max_j = 0, max_k = 0],
|
|
52
|
+
} = await viewerStore.request({
|
|
46
53
|
schema,
|
|
47
54
|
params,
|
|
48
55
|
});
|
|
49
56
|
await remoteRender();
|
|
50
|
-
|
|
51
|
-
return (response as { max_indices: [number, number, number] }).max_indices;
|
|
57
|
+
return [max_i, max_j, max_k];
|
|
52
58
|
}
|
|
53
59
|
interface ThresholdAttribute {
|
|
54
60
|
name: string;
|
|
@@ -72,7 +78,7 @@ async function setThreshold(ids: string[], attribute?: ThresholdAttribute): Prom
|
|
|
72
78
|
await remoteRender();
|
|
73
79
|
}
|
|
74
80
|
function useHybridViewerFilters(): {
|
|
75
|
-
setClippingPlanes: (ids: string[], planes:
|
|
81
|
+
setClippingPlanes: (ids: string[], planes: ViewerClippingPlanesParams["planes"]) => Promise<void>;
|
|
76
82
|
setShrink: (ids: string[], shrink_factor: number) => Promise<void>;
|
|
77
83
|
setSlice: (
|
|
78
84
|
ids: string[],
|
|
@@ -1,25 +1,19 @@
|
|
|
1
1
|
import { HOVER_DEBOUNCE_MS, HOVER_TIMEOUT_MS } from "./constants";
|
|
2
2
|
import type { HoverComponentInfo, HoverData } from "./vtk_types";
|
|
3
|
+
import viewer_schemas, {
|
|
4
|
+
type PickedFieldType,
|
|
5
|
+
type ViewerHighlightResponse,
|
|
6
|
+
} from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_typed_schemas.js";
|
|
3
7
|
import type { IndexableType } from "dexie";
|
|
4
8
|
import { database } from "@ogw_internal/database/database.js";
|
|
5
9
|
import { useHybridViewerCore } from "./core";
|
|
6
10
|
import { useHybridViewerScene } from "./scene";
|
|
7
11
|
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
8
|
-
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
|
|
9
|
-
|
|
10
|
-
// The dynamic/RPC-shaped payload of the viewer's "highlight" schema response.
|
|
11
|
-
interface HighlightResponse {
|
|
12
|
-
id?: string;
|
|
13
|
-
picked_id?: number;
|
|
14
|
-
field_type?: string;
|
|
15
|
-
geode_id?: string | null;
|
|
16
|
-
attributes?: Record<string, unknown>;
|
|
17
|
-
}
|
|
18
12
|
|
|
19
13
|
// Shared via createSharedComposable (rather than merged into the parent hybridViewer store) so sibling slices, e.g. ruler.ts and viewport.ts, can read hover state/clearHoverHighlight/hoverHighlight directly without importing the parent store and creating a cycle. A Pinia store would work too but its $id/$patch/... properties would leak into the composed store's spread and collapse its inferred type.
|
|
20
14
|
const useHybridViewerHighlight = createSharedComposable(() => {
|
|
21
15
|
const is_hover_highlight = ref(false);
|
|
22
|
-
const hover_highlight_field_type = ref("CELL");
|
|
16
|
+
const hover_highlight_field_type = ref<PickedFieldType>("CELL");
|
|
23
17
|
const hoverData = ref<HoverData | undefined>(undefined);
|
|
24
18
|
const hoverPosition = ref({
|
|
25
19
|
x: 0,
|
|
@@ -39,7 +33,7 @@ const useHybridViewerHighlight = createSharedComposable(() => {
|
|
|
39
33
|
|
|
40
34
|
function requestHoverHighlight(
|
|
41
35
|
event: MouseEvent,
|
|
42
|
-
onResponse: (response:
|
|
36
|
+
onResponse: (response: ViewerHighlightResponse) => void | Promise<void>,
|
|
43
37
|
): void {
|
|
44
38
|
if (!is_hover_highlight.value) {
|
|
45
39
|
return;
|
|
@@ -85,12 +79,9 @@ const useHybridViewerHighlight = createSharedComposable(() => {
|
|
|
85
79
|
x: event.clientX,
|
|
86
80
|
y: event.clientY,
|
|
87
81
|
};
|
|
88
|
-
requestHoverHighlight(event, async (
|
|
89
|
-
// oxlint-disable-next-line no-unsafe-type-assertion -- trusted viewer RPC response boundary.
|
|
90
|
-
const response = rawResponse as HighlightResponse | undefined;
|
|
82
|
+
requestHoverHighlight(event, async (response) => {
|
|
91
83
|
if (
|
|
92
84
|
!is_hover_highlight.value ||
|
|
93
|
-
response === undefined ||
|
|
94
85
|
response.id === undefined ||
|
|
95
86
|
response.picked_id === undefined ||
|
|
96
87
|
response.picked_id === -1
|
|
@@ -115,7 +106,7 @@ const useHybridViewerHighlight = createSharedComposable(() => {
|
|
|
115
106
|
modelName = modelRecord.name;
|
|
116
107
|
}
|
|
117
108
|
const modelComponentsTable = database.model_components;
|
|
118
|
-
if (response.geode_id !== undefined &&
|
|
109
|
+
if (response.geode_id !== undefined && modelComponentsTable) {
|
|
119
110
|
const components = modelComponentsTable.where("[id+geode_id]");
|
|
120
111
|
const query = components.equals([response.id, response.geode_id] as IndexableType);
|
|
121
112
|
const component = (await query.first()) as
|
|
@@ -132,7 +123,7 @@ const useHybridViewerHighlight = createSharedComposable(() => {
|
|
|
132
123
|
const newHoverData: HoverData = {
|
|
133
124
|
modelId: response.id,
|
|
134
125
|
modelName,
|
|
135
|
-
blockName: response.geode_id
|
|
126
|
+
blockName: response.geode_id,
|
|
136
127
|
pickedId: response.picked_id,
|
|
137
128
|
fieldType: response.field_type,
|
|
138
129
|
component: componentInfo,
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import viewer_schemas, {
|
|
2
|
+
type PickedFieldType,
|
|
3
|
+
} from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_typed_schemas.js";
|
|
1
4
|
import { useHybridViewerCore } from "./core";
|
|
2
5
|
import { useHybridViewerHighlight } from "./highlight";
|
|
3
6
|
import { useHybridViewerScene } from "./scene";
|
|
4
7
|
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
5
|
-
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
|
|
6
8
|
|
|
7
9
|
interface RulerHoverState {
|
|
8
10
|
active: boolean;
|
|
9
|
-
fieldType:
|
|
11
|
+
fieldType: PickedFieldType;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
function useHybridViewerRuler(): {
|
|
@@ -63,11 +65,8 @@ function useHybridViewerRuler(): {
|
|
|
63
65
|
const { remoteRender } = useHybridViewerCore();
|
|
64
66
|
const viewerStore = useViewerStore();
|
|
65
67
|
const schema = viewer_schemas.opengeodeweb_viewer.viewer.ruler;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
distance?: number;
|
|
69
|
-
};
|
|
70
|
-
ruler_distance.value = response.distance;
|
|
68
|
+
const { distance } = await viewerStore.request({ schema, params: { points } });
|
|
69
|
+
ruler_distance.value = distance;
|
|
71
70
|
await remoteRender();
|
|
72
71
|
}
|
|
73
72
|
|
|
@@ -80,14 +79,12 @@ function useHybridViewerRuler(): {
|
|
|
80
79
|
const params = {
|
|
81
80
|
x: Math.round(x),
|
|
82
81
|
y: Math.round(y),
|
|
83
|
-
field_type: "POINT",
|
|
82
|
+
field_type: "POINT" as const,
|
|
84
83
|
ids: Object.keys(hybridDb),
|
|
85
84
|
};
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
};
|
|
90
|
-
coords = response.attributes?.coordinates;
|
|
85
|
+
const { attributes } = await viewerStore.request({ schema, params });
|
|
86
|
+
const coordinates = attributes?.coordinates;
|
|
87
|
+
coords = Array.isArray(coordinates) ? coordinates : undefined;
|
|
91
88
|
} else {
|
|
92
89
|
coords = await viewerStore.pick_world_position(x, y);
|
|
93
90
|
}
|
|
@@ -4,7 +4,7 @@ import { ACTOR_COLOR } from "./constants";
|
|
|
4
4
|
import { base64ToArrayBuffer } from "./base64";
|
|
5
5
|
import { useDataStore } from "@ogw_front/stores/data";
|
|
6
6
|
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
7
|
-
import viewer_schemas from "@geode/opengeodeweb-viewer/
|
|
7
|
+
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_typed_schemas.js";
|
|
8
8
|
import { newInstance as vtkActor } from "@kitware/vtk.js/Rendering/Core/Actor";
|
|
9
9
|
import { newInstance as vtkMapper } from "@kitware/vtk.js/Rendering/Core/Mapper";
|
|
10
10
|
import type vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
|
package/package.json
CHANGED
|
@@ -34,11 +34,11 @@ function rawDataToString(raw: WebSocket.RawData): string {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
interface ServerWsRpcClient {
|
|
37
|
-
call: (rpc: string, params?:
|
|
37
|
+
call: (rpc: string, params?: object) => Promise<unknown>;
|
|
38
38
|
close: () => void;
|
|
39
39
|
getConnection: () => {
|
|
40
40
|
getSession: () => {
|
|
41
|
-
call: (rpc: string, params: readonly [
|
|
41
|
+
call: (rpc: string, params: readonly [object]) => Promise<unknown>;
|
|
42
42
|
};
|
|
43
43
|
};
|
|
44
44
|
isOpen: () => boolean;
|
|
@@ -114,7 +114,7 @@ function createServerWsRpcClient(baseUrl: string): ServerWsRpcClient {
|
|
|
114
114
|
});
|
|
115
115
|
});
|
|
116
116
|
|
|
117
|
-
async function call(rpc: string, params:
|
|
117
|
+
async function call(rpc: string, params: object = {}): Promise<unknown> {
|
|
118
118
|
await ready;
|
|
119
119
|
const id = uuidv4();
|
|
120
120
|
//oxlint-disable-next-line promise/avoid-new
|
|
@@ -139,7 +139,7 @@ function createServerWsRpcClient(baseUrl: string): ServerWsRpcClient {
|
|
|
139
139
|
function getConnection(): ReturnType<ServerWsRpcClient["getConnection"]> {
|
|
140
140
|
return {
|
|
141
141
|
getSession: () => ({
|
|
142
|
-
call: async (rpc: string, [params]: readonly [
|
|
142
|
+
call: async (rpc: string, [params]: readonly [object]) => {
|
|
143
143
|
const result = await call(rpc, params);
|
|
144
144
|
return result;
|
|
145
145
|
},
|
package/shared/utils/call_raw.ts
CHANGED
|
@@ -6,19 +6,19 @@ import pTimeout from "p-timeout";
|
|
|
6
6
|
import type { RequestHandlers } from "./types.js";
|
|
7
7
|
|
|
8
8
|
interface RpcSession {
|
|
9
|
-
readonly call: (rpc: string, params: readonly [
|
|
9
|
+
readonly call: (rpc: string, params: readonly [object]) => Promise<unknown>;
|
|
10
10
|
}
|
|
11
11
|
interface RpcConnection {
|
|
12
12
|
readonly getSession: () => RpcSession;
|
|
13
13
|
}
|
|
14
14
|
interface RpcClient {
|
|
15
|
-
readonly call: (rpc: string, params:
|
|
15
|
+
readonly call: (rpc: string, params: object) => Promise<unknown>;
|
|
16
16
|
readonly getConnection: () => RpcConnection;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
interface CallClientOptions {
|
|
20
20
|
rpc: string;
|
|
21
|
-
params?:
|
|
21
|
+
params?: object;
|
|
22
22
|
client: RpcClient;
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
// Third party imports
|
|
2
2
|
|
|
3
3
|
// Local imports
|
|
4
|
-
import type { JsonRpcSchema, RequestHandlersWithValidation } from "./types.js";
|
|
4
|
+
import type { JsonRpcSchema, RequestHandlersWithValidation, ResponseOf } from "./types.js";
|
|
5
5
|
import { type RpcClient, callRaw } from "./call_raw.js";
|
|
6
6
|
import { consola } from "consola";
|
|
7
7
|
import { validateSchema } from "./validate_schema.js";
|
|
8
8
|
|
|
9
9
|
const ERROR_400 = 400;
|
|
10
10
|
|
|
11
|
-
interface CallSchemaOptions {
|
|
12
|
-
schema:
|
|
13
|
-
params?:
|
|
11
|
+
interface CallSchemaOptions<Schema extends JsonRpcSchema> {
|
|
12
|
+
schema: Schema;
|
|
13
|
+
params?: object;
|
|
14
14
|
client: RpcClient;
|
|
15
15
|
timeout?: number;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
async function callSchema(
|
|
19
|
-
{ schema, params = {}, client, timeout }: CallSchemaOptions
|
|
18
|
+
async function callSchema<Schema extends JsonRpcSchema>(
|
|
19
|
+
{ schema, params = {}, client, timeout }: CallSchemaOptions<Schema>,
|
|
20
20
|
{
|
|
21
21
|
request_error_function,
|
|
22
22
|
response_function,
|
|
23
23
|
response_error_function,
|
|
24
24
|
validation_error_function,
|
|
25
25
|
}: RequestHandlersWithValidation = {},
|
|
26
|
-
): Promise<
|
|
26
|
+
): Promise<ResponseOf<Schema>> {
|
|
27
27
|
const { valid, error: schema_error } = validateSchema(schema, params);
|
|
28
28
|
|
|
29
29
|
if (!valid) {
|
|
@@ -49,7 +49,9 @@ async function callSchema(
|
|
|
49
49
|
response_error_function,
|
|
50
50
|
},
|
|
51
51
|
);
|
|
52
|
-
|
|
52
|
+
// The microservice validates its responses against the schema `response` it was generated from.
|
|
53
|
+
// oxlint-disable-next-line typescript/no-unsafe-type-assertion
|
|
54
|
+
return result as ResponseOf<Schema>;
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
export { callSchema };
|
package/shared/utils/types.ts
CHANGED
|
@@ -21,6 +21,11 @@ type ParamsOf<Schema> = Schema extends { readonly __params?: infer Params }
|
|
|
21
21
|
? Params
|
|
22
22
|
: Record<string, unknown>;
|
|
23
23
|
|
|
24
|
+
// Any microservice's `microservice_version` schema, whatever the package that generated it.
|
|
25
|
+
type MicroserviceVersionSchema = JsonRpcSchema & {
|
|
26
|
+
readonly __response?: { microservice_version: string };
|
|
27
|
+
};
|
|
28
|
+
|
|
24
29
|
interface RequestHandlers<Response = unknown> {
|
|
25
30
|
readonly request_error_function?: (error: unknown) => void | Promise<void>;
|
|
26
31
|
// Return value is intentionally untyped: callers commonly return the Promise of a downstream call (e.g. a Dexie `.put()`, which resolves to a primary key) that this code chains/awaits but never inspects the resolved value of.
|
|
@@ -34,6 +39,7 @@ interface RequestHandlersWithValidation extends RequestHandlers {
|
|
|
34
39
|
|
|
35
40
|
export type {
|
|
36
41
|
JsonRpcSchema,
|
|
42
|
+
MicroserviceVersionSchema,
|
|
37
43
|
ParamsOf,
|
|
38
44
|
RequestHandlers,
|
|
39
45
|
RequestHandlersWithValidation,
|