@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 +23 -0
- package/README.md +50 -16
- package/dist/index.d.ts +172 -13
- package/dist/virtualdisplay.client.cjs.js +119 -26
- package/dist/virtualdisplay.client.es.js +1573 -1194
- package/dist/virtualdisplay.client.umd.js +127 -34
- package/package.json +1 -1
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);
|
|
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
|
@@ -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 `
|
|
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
|
-
*
|
|
924
|
+
* Options shared by both address forms.
|
|
847
925
|
*/
|
|
848
|
-
interface
|
|
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
|
-
|
|
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 };
|