@virtualdisplay.io/client 4.0.0-alpha.26 → 4.0.0-alpha.28
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 +12 -0
- package/dist/index.d.ts +140 -14
- package/dist/virtualdisplay.client.cjs.js +26 -26
- package/dist/virtualdisplay.client.es.js +1398 -1327
- package/dist/virtualdisplay.client.umd.js +15 -15
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.0.0-alpha.28
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
Add a marker toggle button to the viewer action bar for apps set to the `toggle-shown` or `toggle-hidden` annotation mode: the visitor shows or hides the annotation markers themselves, with the starting state you configured. The button only appears when the model has annotations and a toggle mode is active.
|
|
8
|
+
|
|
9
|
+
## 4.0.0-alpha.27
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
Add the per-app annotation visibility modes to the `viewerSettings.annotations` override: `'hide'`, `'show'`, `'toggle-shown'` and `'toggle-hidden'`, besides the existing booleans (`true` maps to `'show'`, `false` to `'hide'`). Markers now follow the mode configured on the app, and an override only speaks up when it differs from that mode.
|
|
14
|
+
|
|
3
15
|
## 4.0.0-alpha.26
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -52,6 +52,29 @@ interface AppResolvedMessage {
|
|
|
52
52
|
readonly slug?: string;
|
|
53
53
|
readonly submit?: AppSubmitSettings$1;
|
|
54
54
|
}
|
|
55
|
+
/** One mesh or material variant in a model, as reported by STATE. */
|
|
56
|
+
interface ModelNodeDto {
|
|
57
|
+
readonly id: string;
|
|
58
|
+
readonly name: string;
|
|
59
|
+
readonly type: string;
|
|
60
|
+
readonly visible: boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* State (viewer → client): the meshes and material variants of one instance,
|
|
64
|
+
* with their current visibility.
|
|
65
|
+
*
|
|
66
|
+
* Its shape used to live in server-core, marked "server-only", while its type
|
|
67
|
+
* value sat in the public MESSAGE_TYPES and the client read it: a public
|
|
68
|
+
* message whose shape only one side declared, which is how two shapes of one
|
|
69
|
+
* thing start to drift.
|
|
70
|
+
*/
|
|
71
|
+
interface StateMessage {
|
|
72
|
+
readonly type: typeof MESSAGE_TYPES.STATE;
|
|
73
|
+
/** Whose meshes and variants these are. */
|
|
74
|
+
readonly instance: string;
|
|
75
|
+
readonly nodes: ModelNodeDto[];
|
|
76
|
+
readonly isInitial: boolean;
|
|
77
|
+
}
|
|
55
78
|
interface MutationDto {
|
|
56
79
|
readonly name: string;
|
|
57
80
|
readonly value: string;
|
|
@@ -75,6 +98,8 @@ interface SyncStateSnapshot {
|
|
|
75
98
|
}
|
|
76
99
|
interface MutationMessage {
|
|
77
100
|
readonly type: typeof MESSAGE_TYPES.MUTATION;
|
|
101
|
+
/** Which instance's attributes these mutations change. */
|
|
102
|
+
readonly instance: string;
|
|
78
103
|
readonly mutations: MutationDto[];
|
|
79
104
|
readonly isInitial: boolean;
|
|
80
105
|
/**
|
|
@@ -117,9 +142,18 @@ interface SyncMessage {
|
|
|
117
142
|
}
|
|
118
143
|
interface MutationResultMessage {
|
|
119
144
|
readonly type: typeof MESSAGE_TYPES.MUTATION;
|
|
145
|
+
/** Which instance these results are for; without it a failure cannot say whose. */
|
|
146
|
+
readonly instance: string;
|
|
120
147
|
readonly results: MutationResult[];
|
|
121
148
|
readonly isInitial: boolean;
|
|
122
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* How a model's annotations present to the Shopper: never (hide), always
|
|
152
|
+
* (show), or under the Shopper's own control via a viewer toggle, starting
|
|
153
|
+
* visible (toggle-shown) or hidden (toggle-hidden). Resolved per app; the
|
|
154
|
+
* backend's `Resolve` owns the `hide` default.
|
|
155
|
+
*/
|
|
156
|
+
type AnnotationVisibility$1 = 'hide' | 'show' | 'toggle-shown' | 'toggle-hidden';
|
|
123
157
|
/**
|
|
124
158
|
* Viewer settings from model metadata (server → client via MAPPING).
|
|
125
159
|
* Customer-configured in the portal.
|
|
@@ -129,7 +163,12 @@ interface ViewerSettings$1 {
|
|
|
129
163
|
readonly fullscreen?: boolean;
|
|
130
164
|
readonly screenshot?: boolean;
|
|
131
165
|
readonly cameraControls?: boolean;
|
|
132
|
-
|
|
166
|
+
/**
|
|
167
|
+
* The resolved per-app annotation mode. Present only when the model has
|
|
168
|
+
* annotations, so a control can never render with nothing to govern;
|
|
169
|
+
* absent means there is nothing to show or toggle.
|
|
170
|
+
*/
|
|
171
|
+
readonly annotations?: AnnotationVisibility$1;
|
|
133
172
|
readonly language?: string;
|
|
134
173
|
/** Where the attribute controls sit: in-frame bottom-left (default) or a docked right panel. */
|
|
135
174
|
readonly configuratorLayout?: 'inframe-bottom-left' | 'sidebar-right' | 'hidden';
|
|
@@ -194,6 +233,12 @@ interface AttributeDefinition {
|
|
|
194
233
|
}
|
|
195
234
|
interface MappingMessage {
|
|
196
235
|
readonly type: typeof MESSAGE_TYPES.MAPPING;
|
|
236
|
+
/**
|
|
237
|
+
* Whose attributes these are. One MAPPING per instance, and an instance with
|
|
238
|
+
* no attributes sends an empty one rather than none: silence would leave the
|
|
239
|
+
* client unable to name it, click it or report its interactions.
|
|
240
|
+
*/
|
|
241
|
+
readonly instance: string;
|
|
197
242
|
readonly attributes: AttributeDefinition[];
|
|
198
243
|
}
|
|
199
244
|
/** Per selector, the values the buyer can still pick right now. */
|
|
@@ -218,11 +263,30 @@ interface SelectableAttribute {
|
|
|
218
263
|
*/
|
|
219
264
|
interface SelectableMessage {
|
|
220
265
|
readonly type: typeof MESSAGE_TYPES.SELECTABLE;
|
|
266
|
+
/** Whose attributes these are, mirroring the MAPPING it follows. */
|
|
267
|
+
readonly instance: string;
|
|
221
268
|
readonly attributes: SelectableAttribute[];
|
|
222
269
|
}
|
|
223
270
|
/**
|
|
224
271
|
* Loading indicator (server → client): progress percentage, phase label, or error.
|
|
225
272
|
* Sent during model download and parse so the client loading indicator can update.
|
|
273
|
+
*
|
|
274
|
+
* This message concerns one model at five of its seven call sites (download
|
|
275
|
+
* progress, a load error, the rendering phase) and is fatal with no model to
|
|
276
|
+
* blame at the other two (no WebGL, the boot-failure path), so by the
|
|
277
|
+
* message-scope rule it takes an instance id optionally.
|
|
278
|
+
*
|
|
279
|
+
* It does not carry one yet, on purpose. `publishLoadingProgress` is the only
|
|
280
|
+
* publisher and knows no instance, so the field would be absent at all seven
|
|
281
|
+
* sites while its documented meaning is "absent means the viewer could not
|
|
282
|
+
* start". An integrator branching on that would read every progress update as
|
|
283
|
+
* a viewer failure, which is worse than no field at all.
|
|
284
|
+
*
|
|
285
|
+
* Nothing is lost by waiting: an optional field is additive, so unlike the
|
|
286
|
+
* required ids in this file it carries no alpha-window pressure. Composition
|
|
287
|
+
* task 10 brings a second model and with it the choice the spec parked, thread
|
|
288
|
+
* the id through the five model sites, or split the fatal case onto its own
|
|
289
|
+
* message. Decide it there, with a real second instance to test against.
|
|
226
290
|
*/
|
|
227
291
|
interface LoadingIndicatorMessage {
|
|
228
292
|
readonly type: typeof MESSAGE_TYPES.LOADING_INDICATOR;
|
|
@@ -284,7 +348,21 @@ interface SessionMessage {
|
|
|
284
348
|
*/
|
|
285
349
|
interface AnnotationToggleMessage {
|
|
286
350
|
readonly type: typeof MESSAGE_TYPES.ANNOTATION_TOGGLE;
|
|
351
|
+
/**
|
|
352
|
+
* Whose pins to show. This looks scene-wide because the client draws one
|
|
353
|
+
* button, and it is not: a pin's position is stored in its model's local
|
|
354
|
+
* space, so it means nothing without the root it belongs to. A client that
|
|
355
|
+
* wants one button loops over the instances, which is a UI decision.
|
|
356
|
+
*/
|
|
357
|
+
readonly instance: string;
|
|
287
358
|
readonly enabled: boolean;
|
|
359
|
+
/**
|
|
360
|
+
* Who sent it: `control` marks the client's own visible toggle button, the
|
|
361
|
+
* only sender that counts as Shopper use in the viewer statistics. Absent
|
|
362
|
+
* means programmatic (the boot-time config echo, an integrator's
|
|
363
|
+
* `client.annotations` call), which must never be measured as interest.
|
|
364
|
+
*/
|
|
365
|
+
readonly origin?: 'control';
|
|
288
366
|
}
|
|
289
367
|
/** Focus actions (client → server). */
|
|
290
368
|
declare const FOCUS_ACTIONS: {
|
|
@@ -306,6 +384,8 @@ type FocusStateValue = (typeof FOCUS_STATES)[keyof typeof FOCUS_STATES];
|
|
|
306
384
|
*/
|
|
307
385
|
interface FocusMessage {
|
|
308
386
|
readonly type: typeof MESSAGE_TYPES.FOCUS;
|
|
387
|
+
/** Which instance the component name resolves inside. */
|
|
388
|
+
readonly instance: string;
|
|
309
389
|
readonly action: FocusAction;
|
|
310
390
|
readonly component?: string;
|
|
311
391
|
}
|
|
@@ -316,6 +396,8 @@ interface FocusMessage {
|
|
|
316
396
|
*/
|
|
317
397
|
interface FocusStateMessage {
|
|
318
398
|
readonly type: typeof MESSAGE_TYPES.FOCUS;
|
|
399
|
+
/** Which instance this state is about. */
|
|
400
|
+
readonly instance: string;
|
|
319
401
|
readonly state: FocusStateValue;
|
|
320
402
|
readonly component?: string;
|
|
321
403
|
readonly attributes?: string[];
|
|
@@ -373,9 +455,16 @@ interface PricingDocument$1 {
|
|
|
373
455
|
*/
|
|
374
456
|
interface PricingMessage {
|
|
375
457
|
readonly type: typeof MESSAGE_TYPES.PRICING;
|
|
458
|
+
/**
|
|
459
|
+
* Which instance is priced. Only one is today, so the id has no alternative
|
|
460
|
+
* value to hold; it carries one anyway, because a rule with a "not needed
|
|
461
|
+
* yet" exception erodes, and a scene of separately priced products needs
|
|
462
|
+
* exactly this field.
|
|
463
|
+
*/
|
|
464
|
+
readonly instance: string;
|
|
376
465
|
readonly pricing: PricingDocument$1;
|
|
377
466
|
}
|
|
378
|
-
type Message = HandshakeMessage | SessionMessage | MutationMessage | MutationResultMessage | CameraCommandMessage | CameraPositionMessage | SnapshotRequestMessage | SnapshotResultMessage | MappingMessage | LoadingIndicatorMessage | ArActivateMessage | FullscreenMessage | ConfigMessage | AnnotationToggleMessage | FocusMessage | FocusStateMessage | PricingMessage | QrShownMessage | SyncMessage | SelectableMessage | AppResolvedMessage;
|
|
467
|
+
type Message = HandshakeMessage | SessionMessage | MutationMessage | MutationResultMessage | CameraCommandMessage | CameraPositionMessage | SnapshotRequestMessage | SnapshotResultMessage | MappingMessage | LoadingIndicatorMessage | ArActivateMessage | FullscreenMessage | ConfigMessage | AnnotationToggleMessage | FocusMessage | FocusStateMessage | PricingMessage | QrShownMessage | SyncMessage | SelectableMessage | AppResolvedMessage | StateMessage;
|
|
379
468
|
type MessageCallback = (message: Message) => void | Promise<void>;
|
|
380
469
|
|
|
381
470
|
/**
|
|
@@ -490,14 +579,6 @@ declare class IframeMessenger {
|
|
|
490
579
|
* Stop listening and clean up all state
|
|
491
580
|
*/
|
|
492
581
|
destroy(): void;
|
|
493
|
-
/**
|
|
494
|
-
* Whether the messenger is ready to send
|
|
495
|
-
*/
|
|
496
|
-
get ready(): boolean;
|
|
497
|
-
/**
|
|
498
|
-
* Number of messages waiting in the outgoing queue
|
|
499
|
-
*/
|
|
500
|
-
get pendingCount(): number;
|
|
501
582
|
private post;
|
|
502
583
|
private routeToHandler;
|
|
503
584
|
}
|
|
@@ -511,7 +592,11 @@ type SendFn$1 = (message: Message) => void;
|
|
|
511
592
|
*/
|
|
512
593
|
declare class Annotations {
|
|
513
594
|
private readonly send;
|
|
514
|
-
|
|
595
|
+
/** Whose pins this facade toggles: a pin lives in one model's local space. */
|
|
596
|
+
private readonly instance;
|
|
597
|
+
constructor(send: SendFn$1,
|
|
598
|
+
/** Whose pins this facade toggles: a pin lives in one model's local space. */
|
|
599
|
+
instance: string);
|
|
515
600
|
setEnabled(enabled: boolean): void;
|
|
516
601
|
}
|
|
517
602
|
|
|
@@ -743,10 +828,14 @@ type DispatchFn = (state: FocusChange) => void;
|
|
|
743
828
|
declare class Focus {
|
|
744
829
|
private readonly send;
|
|
745
830
|
private readonly dispatch;
|
|
831
|
+
/** Which instance this facade addresses; every message it sends carries it. */
|
|
832
|
+
private readonly instance;
|
|
746
833
|
private focused;
|
|
747
834
|
private attributes;
|
|
748
835
|
private readonly changeCallbacks;
|
|
749
|
-
constructor(send: MessageCallback, dispatch: DispatchFn
|
|
836
|
+
constructor(send: MessageCallback, dispatch: DispatchFn,
|
|
837
|
+
/** Which instance this facade addresses; every message it sends carries it. */
|
|
838
|
+
instance: string);
|
|
750
839
|
/** The focused component name, or null in overview. */
|
|
751
840
|
get current(): string | null;
|
|
752
841
|
/**
|
|
@@ -920,6 +1009,15 @@ declare class Attribute {
|
|
|
920
1009
|
private createValues;
|
|
921
1010
|
}
|
|
922
1011
|
|
|
1012
|
+
/**
|
|
1013
|
+
* The integrator-facing viewer settings override. Identical to the wire
|
|
1014
|
+
* `ViewerSettings`, except `annotations` also accepts the legacy booleans:
|
|
1015
|
+
* they normalise before the merge (`true` → `show`, `false` → `hide`), so
|
|
1016
|
+
* existing mounts keep compiling while the package is in alpha.
|
|
1017
|
+
*/
|
|
1018
|
+
type ViewerSettingsOverride = Omit<Partial<ViewerSettings$1>, 'annotations'> & {
|
|
1019
|
+
readonly annotations?: boolean | AnnotationVisibility$1;
|
|
1020
|
+
};
|
|
923
1021
|
/**
|
|
924
1022
|
* Options shared by both address forms.
|
|
925
1023
|
*/
|
|
@@ -940,7 +1038,7 @@ interface ClientOptionsBase {
|
|
|
940
1038
|
* Override viewer settings from metadata. Omitted fields use the metadata value.
|
|
941
1039
|
* A warning is logged when an override differs from the metadata value.
|
|
942
1040
|
*/
|
|
943
|
-
readonly viewerSettings?:
|
|
1041
|
+
readonly viewerSettings?: ViewerSettingsOverride;
|
|
944
1042
|
}
|
|
945
1043
|
/**
|
|
946
1044
|
* How the client addresses what it shows, one of two forms:
|
|
@@ -1122,6 +1220,14 @@ declare class BaseClient {
|
|
|
1122
1220
|
constructor(options: ClientOptions, extensions?: BaseClientExtensions);
|
|
1123
1221
|
/** The configurator UI, every callback bridging it to the facade that owns the action. */
|
|
1124
1222
|
private createStandardInterface;
|
|
1223
|
+
/**
|
|
1224
|
+
* The visible toggle composes its message here, on the internal transport,
|
|
1225
|
+
* because it is the one sender allowed to stamp `origin: 'control'`: the
|
|
1226
|
+
* viewer only counts control-originated flips as Shopper use. The public
|
|
1227
|
+
* `client.annotations` facade stays origin-less on purpose. One send per
|
|
1228
|
+
* member instance once composition lands; today the host is the only one.
|
|
1229
|
+
*/
|
|
1230
|
+
private sendControlAnnotationToggle;
|
|
1125
1231
|
/** Wire the inbound viewer protocol to the facades. */
|
|
1126
1232
|
private wireIncomingMessages;
|
|
1127
1233
|
/** Store the resolved app and notify every registered `onAppResolved` callback. */
|
|
@@ -1145,6 +1251,14 @@ declare class BaseClient {
|
|
|
1145
1251
|
/** Dispatch a bubbling `vd:configuration-submit` event when the CTA is used. */
|
|
1146
1252
|
private dispatchConfigurationSubmit;
|
|
1147
1253
|
private handleConfig;
|
|
1254
|
+
/**
|
|
1255
|
+
* The difference echo: the viewer already applied the app-config mode
|
|
1256
|
+
* itself, so the client only speaks up when the merged mode (config plus
|
|
1257
|
+
* integrator override) differs from what CONFIG announced, in either
|
|
1258
|
+
* direction. Equal modes echo nothing, so a boot without overrides sends
|
|
1259
|
+
* no toggle at all.
|
|
1260
|
+
*/
|
|
1261
|
+
private echoAnnotationsDifference;
|
|
1148
1262
|
/** Tell the viewer the user entered fullscreen, so it records the engagement. */
|
|
1149
1263
|
private trackFullscreen;
|
|
1150
1264
|
private initializeLogging;
|
|
@@ -1241,6 +1355,13 @@ interface AppSubmitSettings {
|
|
|
1241
1355
|
readonly ctaLabel?: string;
|
|
1242
1356
|
readonly privacyUrl?: string;
|
|
1243
1357
|
}
|
|
1358
|
+
/**
|
|
1359
|
+
* How a model's annotations present to the Shopper: never (hide), always
|
|
1360
|
+
* (show), or under the Shopper's own control via a viewer toggle, starting
|
|
1361
|
+
* visible (toggle-shown) or hidden (toggle-hidden). Resolved per app; the
|
|
1362
|
+
* backend's `Resolve` owns the `hide` default.
|
|
1363
|
+
*/
|
|
1364
|
+
type AnnotationVisibility = 'hide' | 'show' | 'toggle-shown' | 'toggle-hidden';
|
|
1244
1365
|
/**
|
|
1245
1366
|
* Viewer settings from model metadata (server → client via MAPPING).
|
|
1246
1367
|
* Customer-configured in the portal.
|
|
@@ -1250,7 +1371,12 @@ interface ViewerSettings {
|
|
|
1250
1371
|
readonly fullscreen?: boolean;
|
|
1251
1372
|
readonly screenshot?: boolean;
|
|
1252
1373
|
readonly cameraControls?: boolean;
|
|
1253
|
-
|
|
1374
|
+
/**
|
|
1375
|
+
* The resolved per-app annotation mode. Present only when the model has
|
|
1376
|
+
* annotations, so a control can never render with nothing to govern;
|
|
1377
|
+
* absent means there is nothing to show or toggle.
|
|
1378
|
+
*/
|
|
1379
|
+
readonly annotations?: AnnotationVisibility;
|
|
1254
1380
|
readonly language?: string;
|
|
1255
1381
|
/** Where the attribute controls sit: in-frame bottom-left (default) or a docked right panel. */
|
|
1256
1382
|
readonly configuratorLayout?: 'inframe-bottom-left' | 'sidebar-right' | 'hidden';
|