@virtualdisplay.io/client 4.0.0-alpha.25 → 4.0.0-alpha.26
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/CHANGELOG.md +14 -0
- package/README.md +50 -16
- package/dist/index.d.ts +141 -13
- package/dist/virtualdisplay.client.cjs.js +103 -12
- package/dist/virtualdisplay.client.es.js +1500 -1203
- package/dist/virtualdisplay.client.umd.js +111 -20
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.0.0-alpha.26
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
Add `app` option to `ClientOptions` as an alternative to the `license` and `model` pair, mounting one specific app by its link key. The pair keeps working unchanged; when both are supplied, `app` wins and a warning is logged that the pair was ignored.
|
|
8
|
+
|
|
9
|
+
Add `AppType` with the known app types. `ResolvedAppInfo.appType` is typed as a plain string so an app type newer than your bundle still reaches `onAppResolved` for explicit handling.
|
|
10
|
+
|
|
11
|
+
Add a measurement slider for size attributes. A model that offers a size (width, depth, diameter) now renders it as a slider with the formatted value and unit beside it, and the model follows the drag live while only the released value counts as the chosen size.
|
|
12
|
+
|
|
13
|
+
Add `slug` to the `onAppResolved` callback payload: the resolved app's public slug, so a host page can address the app it embeds without knowing the slug in advance.
|
|
14
|
+
|
|
15
|
+
Add `onAppResolved(callback)`. The viewer reports which app it resolved (`appType`, `name`, and public submit settings as `ResolvedAppInfo`), and the callback fires immediately when the report already arrived.
|
|
16
|
+
|
|
3
17
|
## 4.0.0-alpha.25
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -55,6 +55,26 @@ The server defines which attributes and values are available for each model.
|
|
|
55
55
|
The client receives this configuration automatically via postMessage. No
|
|
56
56
|
manual mapping required.
|
|
57
57
|
|
|
58
|
+
### Mounting a specific app
|
|
59
|
+
|
|
60
|
+
A model can have several apps (a plain viewer, a configurator), each with its
|
|
61
|
+
own link and its own configuration. Pass the app's link key as `app` to mount
|
|
62
|
+
that exact app:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { VirtualdisplayClient } from '@virtualdisplay.io/client';
|
|
66
|
+
|
|
67
|
+
const client = new VirtualdisplayClient({
|
|
68
|
+
parent: '#product-container',
|
|
69
|
+
app: 'sofa-deluxe-k3f9dm',
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`license` + `model` keeps working unchanged and shows the model's default
|
|
74
|
+
viewer. If both forms are supplied, `app` wins and a warning is logged that the
|
|
75
|
+
pair was ignored, so adding `app` to an existing integration is additive. One
|
|
76
|
+
of the two forms is required; supplying neither is a compile error.
|
|
77
|
+
|
|
58
78
|
## How it works
|
|
59
79
|
|
|
60
80
|
The 3D server hosts the viewer in an iframe, keeping WebGL complexity isolated
|
|
@@ -229,7 +249,7 @@ exposes an API to toggle their visibility.
|
|
|
229
249
|
|
|
230
250
|
```typescript
|
|
231
251
|
client.annotations.setEnabled(false); // Hide all markers
|
|
232
|
-
client.annotations.setEnabled(true);
|
|
252
|
+
client.annotations.setEnabled(true); // Show them again
|
|
233
253
|
```
|
|
234
254
|
|
|
235
255
|
Visibility can also be controlled via `viewerSettings.annotations` (see below).
|
|
@@ -243,15 +263,15 @@ settings configured in the Virtualdisplay portal.
|
|
|
243
263
|
|
|
244
264
|
### Available settings
|
|
245
265
|
|
|
246
|
-
| Field
|
|
247
|
-
|
|
|
248
|
-
| `ar`
|
|
249
|
-
| `fullscreen`
|
|
250
|
-
| `screenshot`
|
|
251
|
-
| `cameraControls`
|
|
252
|
-
| `annotations`
|
|
253
|
-
| `language`
|
|
254
|
-
| `configuratorLayout
|
|
266
|
+
| Field | Type | Effect when `false` |
|
|
267
|
+
| -------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
268
|
+
| `ar` | `boolean` | Hides the AR button |
|
|
269
|
+
| `fullscreen` | `boolean` | Hides the fullscreen button |
|
|
270
|
+
| `screenshot` | `boolean` | Hides the screenshot button |
|
|
271
|
+
| `cameraControls` | `boolean` | Hides the camera control buttons |
|
|
272
|
+
| `annotations` | `boolean` | Hides all annotation markers |
|
|
273
|
+
| `language` | `string` | Sets the viewer UI language (BCP 47, e.g. `'nl'`, `'en'`, `'de'`) |
|
|
274
|
+
| `configuratorLayout` | `string` | Where the attribute controls sit, or whether they show: `'inframe-bottom-left'` (default), `'sidebar-right'` (a docked, scrollable right-hand panel), or `'hidden'` (no built-in selector, `client.select()` and `client.onChange()` keep working). |
|
|
255
275
|
|
|
256
276
|
### Overriding settings
|
|
257
277
|
|
|
@@ -290,7 +310,10 @@ automatically.
|
|
|
290
310
|
```typescript
|
|
291
311
|
client.onReady(() => {
|
|
292
312
|
const values = client.getValues('Color');
|
|
293
|
-
console.log(
|
|
313
|
+
console.log(
|
|
314
|
+
'Available colours:',
|
|
315
|
+
values.map((v) => v.value)
|
|
316
|
+
);
|
|
294
317
|
});
|
|
295
318
|
```
|
|
296
319
|
|
|
@@ -306,15 +329,26 @@ client.destroy();
|
|
|
306
329
|
import type { ViewerSettings } from '@virtualdisplay.io/client';
|
|
307
330
|
|
|
308
331
|
interface ClientOptions {
|
|
309
|
-
parent: string | HTMLElement;
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
332
|
+
parent: string | HTMLElement; // Where to embed the 3D viewer
|
|
333
|
+
app?: string; // An app's link key: the alternative to license + model (see Mounting a specific app)
|
|
334
|
+
license: string; // License key from your Virtualdisplay account; with model, the classic address form
|
|
335
|
+
model: string; // Which 3D model to load
|
|
336
|
+
debug?: boolean; // Shows console logs for troubleshooting
|
|
337
|
+
language?: string; // Viewer language: 'nl', 'en', or 'de'
|
|
314
338
|
viewerSettings?: Partial<ViewerSettings>; // Override fields from model metadata (see Standard interface)
|
|
315
339
|
}
|
|
316
340
|
```
|
|
317
341
|
|
|
342
|
+
One of the two address forms is required: `app`, or `license` + `model`. The
|
|
343
|
+
real type is a union that enforces this at compile time; the block above is the
|
|
344
|
+
flattened reference.
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
type ClientAddress =
|
|
348
|
+
| { app: string } // an app's link key
|
|
349
|
+
| { license: string; model: string }; // the classic address form
|
|
350
|
+
```
|
|
351
|
+
|
|
318
352
|
## Error codes
|
|
319
353
|
|
|
320
354
|
The client throws `VirtualdisplayError` for known error conditions:
|
package/dist/index.d.ts
CHANGED
|
@@ -22,7 +22,36 @@ declare const MESSAGE_TYPES: {
|
|
|
22
22
|
readonly QR_SHOWN: "qr_shown";
|
|
23
23
|
readonly SYNC: "sync";
|
|
24
24
|
readonly SELECTABLE: "selectable";
|
|
25
|
+
readonly APP_RESOLVED: "app_resolved";
|
|
25
26
|
};
|
|
27
|
+
/** The public submit settings of a configurator-type app, as the form renders
|
|
28
|
+
* them. Never the recipient: that section is removed in SQL on the public
|
|
29
|
+
* read and cannot ride any message. Sparse like every config section: an
|
|
30
|
+
* absent field means the renderer's default (the backend stores the section
|
|
31
|
+
* as written and omits empty keys), so nothing here is guaranteed present. */
|
|
32
|
+
interface AppSubmitSettings$1 {
|
|
33
|
+
readonly fields?: string[];
|
|
34
|
+
readonly ctaLabel?: string;
|
|
35
|
+
readonly privacyUrl?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Viewer -> client: which app this viewer resolved, reported up so the parent
|
|
39
|
+
* (the embed host) can load the matching shell without its own resolve (the
|
|
40
|
+
* apps spec's one-read inversion). Sent once, after the resolve, before or
|
|
41
|
+
* with MAPPING.
|
|
42
|
+
*/
|
|
43
|
+
interface AppResolvedMessage {
|
|
44
|
+
readonly type: typeof MESSAGE_TYPES.APP_RESOLVED;
|
|
45
|
+
/** Known values: {@link AppType}. An unknown value means a newer server; the host reports it, never downgrades. */
|
|
46
|
+
readonly appType: string;
|
|
47
|
+
readonly name: string;
|
|
48
|
+
/** The app's public slug, the address a submit POSTs to. Optional on the
|
|
49
|
+
* wire: a pre-task-60 server does not send it, and the pair-form host has
|
|
50
|
+
* no other way to learn it, so the shell treats absence as "submit
|
|
51
|
+
* unavailable" rather than the guard dropping the whole report. */
|
|
52
|
+
readonly slug?: string;
|
|
53
|
+
readonly submit?: AppSubmitSettings$1;
|
|
54
|
+
}
|
|
26
55
|
interface MutationDto {
|
|
27
56
|
readonly name: string;
|
|
28
57
|
readonly value: string;
|
|
@@ -61,11 +90,19 @@ interface MutationMessage {
|
|
|
61
90
|
* authoritative folded family state: the sync module diffs it against the
|
|
62
91
|
* channel's last-seen state and applies the difference, so a catch-up
|
|
63
92
|
* (empty `mutations`) or a broadcast the hub dropped still converges the
|
|
64
|
-
* subscriber. None of these fields are read by `
|
|
93
|
+
* subscriber. None of these fields are read by `MutationPipeline`.
|
|
65
94
|
*/
|
|
66
95
|
readonly origin?: string;
|
|
67
96
|
readonly seq?: number;
|
|
68
97
|
readonly state?: SyncStateSnapshot;
|
|
98
|
+
/**
|
|
99
|
+
* A drag's intermediate step (parametric dimensions): the viewer applies it
|
|
100
|
+
* so the model follows the hand, but never tracks it, the settled value is
|
|
101
|
+
* the one recorded choice and it arrives as an ordinary mutation without
|
|
102
|
+
* this flag. Only the client knows when a drag settles, which is why this
|
|
103
|
+
* travels on the message instead of being guessed viewer-side.
|
|
104
|
+
*/
|
|
105
|
+
readonly transient?: boolean;
|
|
69
106
|
}
|
|
70
107
|
/**
|
|
71
108
|
* Sync channel status (server → client, ar-session-handoff, sync-channel.md):
|
|
@@ -136,10 +173,24 @@ interface SnapshotResultMessage {
|
|
|
136
173
|
readonly data?: string;
|
|
137
174
|
readonly error?: string;
|
|
138
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Marks an attribute as a measurement (a parametric dimension): the values
|
|
178
|
+
* are millimetre integer strings, and this carries what a client needs to
|
|
179
|
+
* render a measurement control and format the unit. Absent for ordinary
|
|
180
|
+
* attributes; a client that ignores it still renders the value list.
|
|
181
|
+
*/
|
|
182
|
+
interface DimensionDescriptor {
|
|
183
|
+
readonly displayUnit: 'mm' | 'cm' | 'm' | 'in';
|
|
184
|
+
readonly minMm: number;
|
|
185
|
+
readonly maxMm: number;
|
|
186
|
+
readonly stepMm: number;
|
|
187
|
+
}
|
|
139
188
|
interface AttributeDefinition {
|
|
140
189
|
readonly name: string;
|
|
141
190
|
readonly values: string[];
|
|
142
191
|
readonly defaultValue?: string;
|
|
192
|
+
/** Present when this attribute is a measurement; see DimensionDescriptor. */
|
|
193
|
+
readonly dimension?: DimensionDescriptor;
|
|
143
194
|
}
|
|
144
195
|
interface MappingMessage {
|
|
145
196
|
readonly type: typeof MESSAGE_TYPES.MAPPING;
|
|
@@ -149,6 +200,13 @@ interface MappingMessage {
|
|
|
149
200
|
interface SelectableAttribute {
|
|
150
201
|
readonly name: string;
|
|
151
202
|
readonly selectable: string[];
|
|
203
|
+
/**
|
|
204
|
+
* The control should not render at all: a dimension whose component is
|
|
205
|
+
* currently hidden by its show-when conditions (parametric dimensions).
|
|
206
|
+
* Different from an empty `selectable`, which greys values out but keeps
|
|
207
|
+
* the control visible. Absent means visible.
|
|
208
|
+
*/
|
|
209
|
+
readonly hidden?: boolean;
|
|
152
210
|
}
|
|
153
211
|
/**
|
|
154
212
|
* Selectability snapshot (server → client): sent after the mapping and after
|
|
@@ -238,8 +296,8 @@ declare const FOCUS_STATES: {
|
|
|
238
296
|
readonly FOCUSED: "focused";
|
|
239
297
|
readonly UNFOCUSED: "unfocused";
|
|
240
298
|
};
|
|
241
|
-
type FocusAction = typeof FOCUS_ACTIONS[keyof typeof FOCUS_ACTIONS];
|
|
242
|
-
type FocusStateValue = typeof FOCUS_STATES[keyof typeof FOCUS_STATES];
|
|
299
|
+
type FocusAction = (typeof FOCUS_ACTIONS)[keyof typeof FOCUS_ACTIONS];
|
|
300
|
+
type FocusStateValue = (typeof FOCUS_STATES)[keyof typeof FOCUS_STATES];
|
|
243
301
|
/**
|
|
244
302
|
* Focus (client → server): isolate and frame a component, or return to overview.
|
|
245
303
|
* Programmatic — the API, the (future) component menu, and the portal editors all
|
|
@@ -274,7 +332,7 @@ declare const AVAILABILITY$1: {
|
|
|
274
332
|
/** Behaves exactly like an unpriced combination: no price, no button. */
|
|
275
333
|
readonly HIDDEN: "hidden";
|
|
276
334
|
};
|
|
277
|
-
type Availability$1 = typeof AVAILABILITY$1[keyof typeof AVAILABILITY$1];
|
|
335
|
+
type Availability$1 = (typeof AVAILABILITY$1)[keyof typeof AVAILABILITY$1];
|
|
278
336
|
/**
|
|
279
337
|
* One pricing rule: a subset of attribute values mapped to a reference + price.
|
|
280
338
|
* Matches the backend pricing read contract (`GET /api/public/models/.../pricing`).
|
|
@@ -317,7 +375,7 @@ interface PricingMessage {
|
|
|
317
375
|
readonly type: typeof MESSAGE_TYPES.PRICING;
|
|
318
376
|
readonly pricing: PricingDocument$1;
|
|
319
377
|
}
|
|
320
|
-
type Message = HandshakeMessage | SessionMessage | MutationMessage | MutationResultMessage | CameraCommandMessage | CameraPositionMessage | SnapshotRequestMessage | SnapshotResultMessage | MappingMessage | LoadingIndicatorMessage | ArActivateMessage | FullscreenMessage | ConfigMessage | AnnotationToggleMessage | FocusMessage | FocusStateMessage | PricingMessage | QrShownMessage | SyncMessage | SelectableMessage;
|
|
378
|
+
type Message = HandshakeMessage | SessionMessage | MutationMessage | MutationResultMessage | CameraCommandMessage | CameraPositionMessage | SnapshotRequestMessage | SnapshotResultMessage | MappingMessage | LoadingIndicatorMessage | ArActivateMessage | FullscreenMessage | ConfigMessage | AnnotationToggleMessage | FocusMessage | FocusStateMessage | PricingMessage | QrShownMessage | SyncMessage | SelectableMessage | AppResolvedMessage;
|
|
321
379
|
type MessageCallback = (message: Message) => void | Promise<void>;
|
|
322
380
|
|
|
323
381
|
/**
|
|
@@ -863,12 +921,10 @@ declare class Attribute {
|
|
|
863
921
|
}
|
|
864
922
|
|
|
865
923
|
/**
|
|
866
|
-
*
|
|
924
|
+
* Options shared by both address forms.
|
|
867
925
|
*/
|
|
868
|
-
interface
|
|
926
|
+
interface ClientOptionsBase {
|
|
869
927
|
readonly parent: string | HTMLElement;
|
|
870
|
-
readonly model: string;
|
|
871
|
-
readonly license: string;
|
|
872
928
|
readonly debug?: boolean | undefined;
|
|
873
929
|
readonly language?: string | undefined;
|
|
874
930
|
/** W3C traceparent string to propagate to the viewer iframe for end-to-end tracing. */
|
|
@@ -886,6 +942,32 @@ interface ClientOptions {
|
|
|
886
942
|
*/
|
|
887
943
|
readonly viewerSettings?: Partial<ViewerSettings$1>;
|
|
888
944
|
}
|
|
945
|
+
/**
|
|
946
|
+
* How the client addresses what it shows, one of two forms:
|
|
947
|
+
*
|
|
948
|
+
* - `{ app }`: an app's public link key (the slug in its URL). The viewer
|
|
949
|
+
* resolves that app and renders it with its own configuration.
|
|
950
|
+
* - `{ license, model }`: the classic pair, which resolves to the model's
|
|
951
|
+
* default app. Every existing integration keeps working unchanged.
|
|
952
|
+
*
|
|
953
|
+
* Supplying both is allowed so a migration is additive (add `app`, done):
|
|
954
|
+
* `app` wins and a warning is logged that the pair was ignored. Supplying
|
|
955
|
+
* neither is a compile error, which is the guarantee this union buys over a
|
|
956
|
+
* bag of three optional fields.
|
|
957
|
+
*/
|
|
958
|
+
type ClientAddress = {
|
|
959
|
+
readonly app: string;
|
|
960
|
+
readonly license?: string | undefined;
|
|
961
|
+
readonly model?: string | undefined;
|
|
962
|
+
} | {
|
|
963
|
+
readonly license: string;
|
|
964
|
+
readonly model: string;
|
|
965
|
+
readonly app?: undefined;
|
|
966
|
+
};
|
|
967
|
+
/**
|
|
968
|
+
* Configuration options for VirtualdisplayClient
|
|
969
|
+
*/
|
|
970
|
+
type ClientOptions = ClientOptionsBase & ClientAddress;
|
|
889
971
|
|
|
890
972
|
/**
|
|
891
973
|
* The Virtualdisplay client's DOM event names, in one registry.
|
|
@@ -913,6 +995,20 @@ interface MutationFailedEvent {
|
|
|
913
995
|
readonly attribute: string;
|
|
914
996
|
readonly value: string;
|
|
915
997
|
}
|
|
998
|
+
/**
|
|
999
|
+
* Which app this viewer resolved (the apps spec's one-read inversion): the
|
|
1000
|
+
* `onAppResolved` callback payload. The protocol message minus its wire
|
|
1001
|
+
* discriminator; only the parent-safe submit settings ride along, never the
|
|
1002
|
+
* delivery recipient (removed in SQL on the public read).
|
|
1003
|
+
*/
|
|
1004
|
+
interface ResolvedAppInfo {
|
|
1005
|
+
/** Known values: `AppType`. An unknown value means a newer server; report it, never downgrade to a viewer. */
|
|
1006
|
+
readonly appType: string;
|
|
1007
|
+
readonly name: string;
|
|
1008
|
+
/** The app's public slug (the address a submit POSTs to). Absent from a pre-slug server. */
|
|
1009
|
+
readonly slug?: string;
|
|
1010
|
+
readonly submit?: AppSubmitSettings$1;
|
|
1011
|
+
}
|
|
916
1012
|
interface VirtualdisplaySelectEvent {
|
|
917
1013
|
readonly attribute: string;
|
|
918
1014
|
readonly value: string;
|
|
@@ -1020,9 +1116,16 @@ declare class BaseClient {
|
|
|
1020
1116
|
private readonly mutationFailedCallbacks;
|
|
1021
1117
|
/** The viewer's tracking session id, once the server announces it (SESSION). */
|
|
1022
1118
|
private viewerSessionId;
|
|
1119
|
+
/** Which app the viewer resolved, once reported (APP_RESOLVED). */
|
|
1120
|
+
private resolvedApp;
|
|
1121
|
+
private readonly appResolvedCallbacks;
|
|
1023
1122
|
constructor(options: ClientOptions, extensions?: BaseClientExtensions);
|
|
1123
|
+
/** The configurator UI, every callback bridging it to the facade that owns the action. */
|
|
1124
|
+
private createStandardInterface;
|
|
1024
1125
|
/** Wire the inbound viewer protocol to the facades. */
|
|
1025
1126
|
private wireIncomingMessages;
|
|
1127
|
+
/** Store the resolved app and notify every registered `onAppResolved` callback. */
|
|
1128
|
+
private handleAppResolved;
|
|
1026
1129
|
/** Store the tracking session id and hand it to the AR flow, which waits on it for the QR. */
|
|
1027
1130
|
private handleSession;
|
|
1028
1131
|
/** Forward a failed mutation to every registered `onMutationFailed` callback. */
|
|
@@ -1062,6 +1165,12 @@ declare class BaseClient {
|
|
|
1062
1165
|
* fires.
|
|
1063
1166
|
*/
|
|
1064
1167
|
onSelectableChange(callback: (snapshot: SelectableSnapshot) => void): void;
|
|
1168
|
+
/**
|
|
1169
|
+
* Subscribe to which app this viewer resolved (type, name, public submit
|
|
1170
|
+
* settings). Reported once by the viewer after its resolve; fires immediately
|
|
1171
|
+
* when the report already arrived, so registration order does not matter.
|
|
1172
|
+
*/
|
|
1173
|
+
onAppResolved(callback: (app: ResolvedAppInfo) => void): void;
|
|
1065
1174
|
/** The selectable values for one attribute right now, or null when unrestricted. */
|
|
1066
1175
|
getSelectable(name: string): readonly string[] | null;
|
|
1067
1176
|
/**
|
|
@@ -1086,12 +1195,17 @@ declare class BaseClient {
|
|
|
1086
1195
|
}
|
|
1087
1196
|
|
|
1088
1197
|
type Attrs = Record<string, unknown> | unknown;
|
|
1089
|
-
|
|
1198
|
+
/**
|
|
1199
|
+
* The logger the client exposes: the same four levels as the base logger, but
|
|
1200
|
+
* accepting any value as attributes so callers can pass an Error or a bare value.
|
|
1201
|
+
*/
|
|
1202
|
+
interface ClientLogger {
|
|
1090
1203
|
debug: (msg: string, attrs?: Attrs) => void;
|
|
1091
1204
|
info: (msg: string, attrs?: Attrs) => void;
|
|
1092
1205
|
warn: (msg: string, attrs?: Attrs) => void;
|
|
1093
1206
|
error: (msg: string, attrs?: Attrs) => void;
|
|
1094
|
-
}
|
|
1207
|
+
}
|
|
1208
|
+
declare let logger: ClientLogger;
|
|
1095
1209
|
declare function enableDebugMode(): void;
|
|
1096
1210
|
declare function isDebugMode(): boolean;
|
|
1097
1211
|
|
|
@@ -1113,6 +1227,20 @@ declare class VirtualdisplayClient extends BaseClient {
|
|
|
1113
1227
|
onSyncChange(callback: (connected: boolean) => void): void;
|
|
1114
1228
|
}
|
|
1115
1229
|
|
|
1230
|
+
/** The app types this protocol version knows. The wire field stays a plain
|
|
1231
|
+
* string on purpose: a newer viewer may report a type this bundle predates,
|
|
1232
|
+
* and the host must receive it to fail visibly (never a quiet downgrade). */
|
|
1233
|
+
type AppType = 'viewer' | 'configurator';
|
|
1234
|
+
/** The public submit settings of a configurator-type app, as the form renders
|
|
1235
|
+
* them. Never the recipient: that section is removed in SQL on the public
|
|
1236
|
+
* read and cannot ride any message. Sparse like every config section: an
|
|
1237
|
+
* absent field means the renderer's default (the backend stores the section
|
|
1238
|
+
* as written and omits empty keys), so nothing here is guaranteed present. */
|
|
1239
|
+
interface AppSubmitSettings {
|
|
1240
|
+
readonly fields?: string[];
|
|
1241
|
+
readonly ctaLabel?: string;
|
|
1242
|
+
readonly privacyUrl?: string;
|
|
1243
|
+
}
|
|
1116
1244
|
/**
|
|
1117
1245
|
* Viewer settings from model metadata (server → client via MAPPING).
|
|
1118
1246
|
* Customer-configured in the portal.
|
|
@@ -1139,7 +1267,7 @@ declare const AVAILABILITY: {
|
|
|
1139
1267
|
/** Behaves exactly like an unpriced combination: no price, no button. */
|
|
1140
1268
|
readonly HIDDEN: "hidden";
|
|
1141
1269
|
};
|
|
1142
|
-
type Availability = typeof AVAILABILITY[keyof typeof AVAILABILITY];
|
|
1270
|
+
type Availability = (typeof AVAILABILITY)[keyof typeof AVAILABILITY];
|
|
1143
1271
|
/**
|
|
1144
1272
|
* One pricing rule: a subset of attribute values mapped to a reference + price.
|
|
1145
1273
|
* Matches the backend pricing read contract (`GET /api/public/models/.../pricing`).
|
|
@@ -1176,4 +1304,4 @@ interface PricingDocument {
|
|
|
1176
1304
|
}
|
|
1177
1305
|
|
|
1178
1306
|
export { Annotations, Attribute, AttributeValue, Camera, Configuration, ERROR_CODES, Focus, Photo, Snapshot, VD_EVENTS, VirtualdisplayClient, VirtualdisplayError, enableDebugMode, isDebugMode, logger };
|
|
1179
|
-
export type { Availability, ClientOptions, ErrorCode, FocusState, MutationFailedEvent, PhotoData, PricingDocument, PricingRule, ResolvedConfiguration, SubmitOptions, SubmittedConfiguration, VdEvent, ViewerSettings, VirtualdisplaySelectEvent, VirtualdisplaySelectedEvent, VirtualdisplayUiEventMap, VirtualdisplayUiEventType };
|
|
1307
|
+
export type { AppSubmitSettings, AppType, Availability, ClientOptions, ErrorCode, FocusState, MutationFailedEvent, PhotoData, PricingDocument, PricingRule, ResolvedAppInfo, ResolvedConfiguration, SubmitOptions, SubmittedConfiguration, VdEvent, ViewerSettings, VirtualdisplaySelectEvent, VirtualdisplaySelectedEvent, VirtualdisplayUiEventMap, VirtualdisplayUiEventType };
|