@virtualdisplay.io/client 4.0.0-alpha.24 → 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 CHANGED
@@ -1,5 +1,28 @@
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
+
17
+ ## 4.0.0-alpha.25
18
+
19
+ ### Minor Changes
20
+
21
+ Add `onSelectableChange(callback)` and `getSelectable(name)` to follow which
22
+ attribute values the buyer can still pick under the current selection. The
23
+ standard sidebar greys out values the selection rules out. Models without
24
+ exclusions behave exactly as before.
25
+
3
26
  ## 4.0.0-alpha.24
4
27
 
5
28
  ### Patch 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); // Show them again
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 | Type | Effect when `false` |
247
- | ------------------- | --------- | ---------------------------------------------------------------------------------------------- |
248
- | `ar` | `boolean` | Hides the AR button |
249
- | `fullscreen` | `boolean` | Hides the fullscreen button |
250
- | `screenshot` | `boolean` | Hides the screenshot button |
251
- | `cameraControls` | `boolean` | Hides the camera control buttons |
252
- | `annotations` | `boolean` | Hides all annotation markers |
253
- | `language` | `string` | Sets the viewer UI language (BCP 47, e.g. `'nl'`, `'en'`, `'de'`) |
254
- | `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). |
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('Available colours:', values.map(v => v.value));
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; // Where to embed the 3D viewer
310
- license: string; // License key from your Virtualdisplay account
311
- model: string; // Which 3D model to load
312
- debug?: boolean; // Shows console logs for troubleshooting
313
- language?: string; // Viewer language: 'nl', 'en', or 'de'
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
@@ -21,7 +21,37 @@ declare const MESSAGE_TYPES: {
21
21
  readonly PRICING: "pricing";
22
22
  readonly QR_SHOWN: "qr_shown";
23
23
  readonly SYNC: "sync";
24
+ readonly SELECTABLE: "selectable";
25
+ readonly APP_RESOLVED: "app_resolved";
24
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
+ }
25
55
  interface MutationDto {
26
56
  readonly name: string;
27
57
  readonly value: string;
@@ -60,11 +90,19 @@ interface MutationMessage {
60
90
  * authoritative folded family state: the sync module diffs it against the
61
91
  * channel's last-seen state and applies the difference, so a catch-up
62
92
  * (empty `mutations`) or a broadcast the hub dropped still converges the
63
- * subscriber. None of these fields are read by `MutationRouter`.
93
+ * subscriber. None of these fields are read by `MutationPipeline`.
64
94
  */
65
95
  readonly origin?: string;
66
96
  readonly seq?: number;
67
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;
68
106
  }
69
107
  /**
70
108
  * Sync channel status (server → client, ar-session-handoff, sync-channel.md):
@@ -135,15 +173,53 @@ interface SnapshotResultMessage {
135
173
  readonly data?: string;
136
174
  readonly error?: string;
137
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
+ }
138
188
  interface AttributeDefinition {
139
189
  readonly name: string;
140
190
  readonly values: string[];
141
191
  readonly defaultValue?: string;
192
+ /** Present when this attribute is a measurement; see DimensionDescriptor. */
193
+ readonly dimension?: DimensionDescriptor;
142
194
  }
143
195
  interface MappingMessage {
144
196
  readonly type: typeof MESSAGE_TYPES.MAPPING;
145
197
  readonly attributes: AttributeDefinition[];
146
198
  }
199
+ /** Per selector, the values the buyer can still pick right now. */
200
+ interface SelectableAttribute {
201
+ readonly name: string;
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;
210
+ }
211
+ /**
212
+ * Selectability snapshot (server → client): sent after the mapping and after
213
+ * every choice that changes the picture. Always the complete state, never a
214
+ * diff; a value not in its list is not pickable (the client greys it out).
215
+ * The client only renders, it never knows the exclusion rules. Named
216
+ * `selectable`, not availability: that word is taken by pricing
217
+ * (AVAILABILITY, available/view_only).
218
+ */
219
+ interface SelectableMessage {
220
+ readonly type: typeof MESSAGE_TYPES.SELECTABLE;
221
+ readonly attributes: SelectableAttribute[];
222
+ }
147
223
  /**
148
224
  * Loading indicator (server → client): progress percentage, phase label, or error.
149
225
  * Sent during model download and parse so the client loading indicator can update.
@@ -220,8 +296,8 @@ declare const FOCUS_STATES: {
220
296
  readonly FOCUSED: "focused";
221
297
  readonly UNFOCUSED: "unfocused";
222
298
  };
223
- type FocusAction = typeof FOCUS_ACTIONS[keyof typeof FOCUS_ACTIONS];
224
- 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];
225
301
  /**
226
302
  * Focus (client → server): isolate and frame a component, or return to overview.
227
303
  * Programmatic — the API, the (future) component menu, and the portal editors all
@@ -256,7 +332,7 @@ declare const AVAILABILITY$1: {
256
332
  /** Behaves exactly like an unpriced combination: no price, no button. */
257
333
  readonly HIDDEN: "hidden";
258
334
  };
259
- type Availability$1 = typeof AVAILABILITY$1[keyof typeof AVAILABILITY$1];
335
+ type Availability$1 = (typeof AVAILABILITY$1)[keyof typeof AVAILABILITY$1];
260
336
  /**
261
337
  * One pricing rule: a subset of attribute values mapped to a reference + price.
262
338
  * Matches the backend pricing read contract (`GET /api/public/models/.../pricing`).
@@ -299,7 +375,7 @@ interface PricingMessage {
299
375
  readonly type: typeof MESSAGE_TYPES.PRICING;
300
376
  readonly pricing: PricingDocument$1;
301
377
  }
302
- type Message = HandshakeMessage | SessionMessage | MutationMessage | MutationResultMessage | CameraCommandMessage | CameraPositionMessage | SnapshotRequestMessage | SnapshotResultMessage | MappingMessage | LoadingIndicatorMessage | ArActivateMessage | FullscreenMessage | ConfigMessage | AnnotationToggleMessage | FocusMessage | FocusStateMessage | PricingMessage | QrShownMessage | SyncMessage;
378
+ type Message = HandshakeMessage | SessionMessage | MutationMessage | MutationResultMessage | CameraCommandMessage | CameraPositionMessage | SnapshotRequestMessage | SnapshotResultMessage | MappingMessage | LoadingIndicatorMessage | ArActivateMessage | FullscreenMessage | ConfigMessage | AnnotationToggleMessage | FocusMessage | FocusStateMessage | PricingMessage | QrShownMessage | SyncMessage | SelectableMessage | AppResolvedMessage;
303
379
  type MessageCallback = (message: Message) => void | Promise<void>;
304
380
 
305
381
  /**
@@ -439,6 +515,8 @@ declare class Annotations {
439
515
  setEnabled(enabled: boolean): void;
440
516
  }
441
517
 
518
+ type SelectableSnapshot = readonly SelectableAttribute[];
519
+
442
520
  /**
443
521
  * Camera control API for positioning and zoom
444
522
  * Uses chaining pattern for building commands
@@ -843,12 +921,10 @@ declare class Attribute {
843
921
  }
844
922
 
845
923
  /**
846
- * Configuration options for VirtualdisplayClient
924
+ * Options shared by both address forms.
847
925
  */
848
- interface ClientOptions {
926
+ interface ClientOptionsBase {
849
927
  readonly parent: string | HTMLElement;
850
- readonly model: string;
851
- readonly license: string;
852
928
  readonly debug?: boolean | undefined;
853
929
  readonly language?: string | undefined;
854
930
  /** W3C traceparent string to propagate to the viewer iframe for end-to-end tracing. */
@@ -866,6 +942,32 @@ interface ClientOptions {
866
942
  */
867
943
  readonly viewerSettings?: Partial<ViewerSettings$1>;
868
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;
869
971
 
870
972
  /**
871
973
  * The Virtualdisplay client's DOM event names, in one registry.
@@ -893,6 +995,20 @@ interface MutationFailedEvent {
893
995
  readonly attribute: string;
894
996
  readonly value: string;
895
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
+ }
896
1012
  interface VirtualdisplaySelectEvent {
897
1013
  readonly attribute: string;
898
1014
  readonly value: string;
@@ -976,6 +1092,7 @@ interface BaseClientExtensions {
976
1092
  */
977
1093
  declare class BaseClient {
978
1094
  private readonly attributes;
1095
+ private readonly selectableState;
979
1096
  private readonly readyStateTracker;
980
1097
  private readonly messenger;
981
1098
  private readonly cameraApi;
@@ -999,9 +1116,16 @@ declare class BaseClient {
999
1116
  private readonly mutationFailedCallbacks;
1000
1117
  /** The viewer's tracking session id, once the server announces it (SESSION). */
1001
1118
  private viewerSessionId;
1119
+ /** Which app the viewer resolved, once reported (APP_RESOLVED). */
1120
+ private resolvedApp;
1121
+ private readonly appResolvedCallbacks;
1002
1122
  constructor(options: ClientOptions, extensions?: BaseClientExtensions);
1123
+ /** The configurator UI, every callback bridging it to the facade that owns the action. */
1124
+ private createStandardInterface;
1003
1125
  /** Wire the inbound viewer protocol to the facades. */
1004
1126
  private wireIncomingMessages;
1127
+ /** Store the resolved app and notify every registered `onAppResolved` callback. */
1128
+ private handleAppResolved;
1005
1129
  /** Store the tracking session id and hand it to the AR flow, which waits on it for the QR. */
1006
1130
  private handleSession;
1007
1131
  /** Forward a failed mutation to every registered `onMutationFailed` callback. */
@@ -1033,6 +1157,22 @@ declare class BaseClient {
1033
1157
  get isReady(): boolean;
1034
1158
  onReady(callback: (client: this) => void): void;
1035
1159
  onMutationFailed(callback: (event: MutationFailedEvent) => void): void;
1160
+ /**
1161
+ * Subscribe to the viewer's selectability snapshots (kiesbaarheid live):
1162
+ * per attribute, which values the buyer can pick right now. Fires with the
1163
+ * current snapshot immediately when one already arrived. A model without
1164
+ * exclusions never sends one: everything stays selectable and this never
1165
+ * fires.
1166
+ */
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;
1174
+ /** The selectable values for one attribute right now, or null when unrestricted. */
1175
+ getSelectable(name: string): readonly string[] | null;
1036
1176
  /**
1037
1177
  * Trigger the composed AR flow directly (ar-session-handoff task 035): a host
1038
1178
  * page that hides the built-in corner button (`viewerSettings.ar = false`,
@@ -1055,12 +1195,17 @@ declare class BaseClient {
1055
1195
  }
1056
1196
 
1057
1197
  type Attrs = Record<string, unknown> | unknown;
1058
- declare let logger: {
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 {
1059
1203
  debug: (msg: string, attrs?: Attrs) => void;
1060
1204
  info: (msg: string, attrs?: Attrs) => void;
1061
1205
  warn: (msg: string, attrs?: Attrs) => void;
1062
1206
  error: (msg: string, attrs?: Attrs) => void;
1063
- };
1207
+ }
1208
+ declare let logger: ClientLogger;
1064
1209
  declare function enableDebugMode(): void;
1065
1210
  declare function isDebugMode(): boolean;
1066
1211
 
@@ -1082,6 +1227,20 @@ declare class VirtualdisplayClient extends BaseClient {
1082
1227
  onSyncChange(callback: (connected: boolean) => void): void;
1083
1228
  }
1084
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
+ }
1085
1244
  /**
1086
1245
  * Viewer settings from model metadata (server → client via MAPPING).
1087
1246
  * Customer-configured in the portal.
@@ -1108,7 +1267,7 @@ declare const AVAILABILITY: {
1108
1267
  /** Behaves exactly like an unpriced combination: no price, no button. */
1109
1268
  readonly HIDDEN: "hidden";
1110
1269
  };
1111
- type Availability = typeof AVAILABILITY[keyof typeof AVAILABILITY];
1270
+ type Availability = (typeof AVAILABILITY)[keyof typeof AVAILABILITY];
1112
1271
  /**
1113
1272
  * One pricing rule: a subset of attribute values mapped to a reference + price.
1114
1273
  * Matches the backend pricing read contract (`GET /api/public/models/.../pricing`).
@@ -1145,4 +1304,4 @@ interface PricingDocument {
1145
1304
  }
1146
1305
 
1147
1306
  export { Annotations, Attribute, AttributeValue, Camera, Configuration, ERROR_CODES, Focus, Photo, Snapshot, VD_EVENTS, VirtualdisplayClient, VirtualdisplayError, enableDebugMode, isDebugMode, logger };
1148
- 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 };