@virtualdisplay.io/client 4.0.0-alpha.3 → 4.0.0-alpha.32

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.
Files changed (49) hide show
  1. package/CHANGELOG.md +254 -1
  2. package/README.md +127 -156
  3. package/dist/browser-7qZ1KQYo.cjs +8 -0
  4. package/dist/browser-B8yql1bQ.js +1226 -0
  5. package/dist/index.d.ts +672 -0
  6. package/dist/rolldown-runtime-5iZMYShA.cjs +1 -0
  7. package/dist/rolldown-runtime-CYdcPHCu.js +12 -0
  8. package/dist/virtualdisplay.client.cjs.js +691 -1
  9. package/dist/virtualdisplay.client.es.js +3142 -458
  10. package/dist/virtualdisplay.client.umd.js +698 -1
  11. package/package.json +3 -3
  12. package/dist/src/attributes/attribute.d.ts +0 -38
  13. package/dist/src/attributes/attribute.d.ts.map +0 -1
  14. package/dist/src/attributes/attributes.d.ts +0 -43
  15. package/dist/src/attributes/attributes.d.ts.map +0 -1
  16. package/dist/src/attributes/selections.d.ts +0 -16
  17. package/dist/src/attributes/selections.d.ts.map +0 -1
  18. package/dist/src/attributes/value.d.ts +0 -13
  19. package/dist/src/attributes/value.d.ts.map +0 -1
  20. package/dist/src/camera/camera.d.ts +0 -40
  21. package/dist/src/camera/camera.d.ts.map +0 -1
  22. package/dist/src/camera/index.d.ts +0 -4
  23. package/dist/src/camera/index.d.ts.map +0 -1
  24. package/dist/src/camera/position.d.ts +0 -43
  25. package/dist/src/camera/position.d.ts.map +0 -1
  26. package/dist/src/client/client.d.ts +0 -83
  27. package/dist/src/client/client.d.ts.map +0 -1
  28. package/dist/src/client/error.d.ts +0 -26
  29. package/dist/src/client/error.d.ts.map +0 -1
  30. package/dist/src/client/iframe-builder.d.ts +0 -25
  31. package/dist/src/client/iframe-builder.d.ts.map +0 -1
  32. package/dist/src/client/options.d.ts +0 -17
  33. package/dist/src/client/options.d.ts.map +0 -1
  34. package/dist/src/client/ready-state-tracker.d.ts +0 -26
  35. package/dist/src/client/ready-state-tracker.d.ts.map +0 -1
  36. package/dist/src/client/types.d.ts +0 -5
  37. package/dist/src/client/types.d.ts.map +0 -1
  38. package/dist/src/index.d.ts +0 -11
  39. package/dist/src/index.d.ts.map +0 -1
  40. package/dist/src/snapshot/index.d.ts +0 -3
  41. package/dist/src/snapshot/index.d.ts.map +0 -1
  42. package/dist/src/snapshot/photo.d.ts +0 -47
  43. package/dist/src/snapshot/photo.d.ts.map +0 -1
  44. package/dist/src/snapshot/snapshot.d.ts +0 -30
  45. package/dist/src/snapshot/snapshot.d.ts.map +0 -1
  46. package/dist/src/ui/viewer-config.d.ts +0 -63
  47. package/dist/src/ui/viewer-config.d.ts.map +0 -1
  48. package/dist/src/utils/logger.d.ts +0 -11
  49. package/dist/src/utils/logger.d.ts.map +0 -1
@@ -0,0 +1,672 @@
1
+ /** The app types this protocol version knows. The wire field stays a plain
2
+ * string on purpose: a newer viewer may report a type this bundle predates,
3
+ * and the host must receive it to fail visibly (never a quiet downgrade). */
4
+ type AppType = 'viewer' | 'configurator';
5
+ /** What a configurator app's submit form renders. Any field may be absent; an
6
+ * absent field means the form's own default. */
7
+ interface AppSubmitSettings {
8
+ readonly fields?: string[];
9
+ readonly ctaLabel?: string;
10
+ readonly privacyUrl?: string;
11
+ }
12
+ /**
13
+ * How a model's annotations present to the visitor: never (hide), always
14
+ * (show), or under their own control via a viewer toggle, starting visible
15
+ * (toggle-shown) or hidden (toggle-hidden). Resolved per app, defaulting to
16
+ * hide.
17
+ */
18
+ type AnnotationVisibility = 'hide' | 'show' | 'toggle-shown' | 'toggle-hidden';
19
+ /**
20
+ * Which viewer controls the model shows, as configured for it. Sent with the
21
+ * mapping; every field is optional and an absent field means the viewer's own
22
+ * default.
23
+ */
24
+ interface ViewerSettings {
25
+ readonly ar?: boolean;
26
+ readonly fullscreen?: boolean;
27
+ readonly screenshot?: boolean;
28
+ readonly cameraControls?: boolean;
29
+ /**
30
+ * The resolved per-app annotation mode. Present only when the model has
31
+ * annotations, so a control can never render with nothing to govern;
32
+ * absent means there is nothing to show or toggle.
33
+ */
34
+ readonly annotations?: AnnotationVisibility;
35
+ readonly language?: string;
36
+ /** Where the attribute controls sit: in-frame bottom-left (default) or a docked right panel. */
37
+ readonly configuratorLayout?: 'inframe-bottom-left' | 'sidebar-right' | 'hidden';
38
+ }
39
+ /**
40
+ * Camera movement limits sent to the client via CONFIG.
41
+ * Used to disable camera control buttons when a limit is reached.
42
+ * Units match the camera position: zoom = percentage (1-200), tilt/rotate = degrees.
43
+ */
44
+ interface CameraLimits {
45
+ readonly minZoom?: number;
46
+ readonly maxZoom?: number;
47
+ readonly minTilt?: number;
48
+ readonly maxTilt?: number;
49
+ readonly minRotate?: number;
50
+ readonly maxRotate?: number;
51
+ }
52
+ /** Per selector, the values the buyer can still pick right now. */
53
+ interface SelectableAttribute {
54
+ readonly name: string;
55
+ readonly selectable: string[];
56
+ /**
57
+ * The control should not render at all: a dimension whose component is
58
+ * currently hidden by its show-when conditions.
59
+ * Different from an empty `selectable`, which greys values out but keeps
60
+ * the control visible. Absent means visible.
61
+ */
62
+ readonly hidden?: boolean;
63
+ }
64
+ /**
65
+ * What the configurator does with a matched configuration.
66
+ */
67
+ declare const AVAILABILITY: {
68
+ /** Price and submit button both shown (default). */
69
+ readonly AVAILABLE: "available";
70
+ /** Price shown, submit hidden (sold out / coming soon). */
71
+ readonly VIEW_ONLY: "view_only";
72
+ /** Behaves exactly like an unpriced combination: no price, no button. */
73
+ readonly HIDDEN: "hidden";
74
+ };
75
+ type Availability = (typeof AVAILABILITY)[keyof typeof AVAILABILITY];
76
+ /**
77
+ * One pricing rule: a subset of attribute values mapped to a reference and a
78
+ * price.
79
+ */
80
+ interface PricingRule {
81
+ /**
82
+ * The attribute name→value pairs this rule names. `{}` is a catch-all;
83
+ * omitted names are wildcards. A rule matches when every pair equals the
84
+ * current selection; the rule naming the most attributes wins.
85
+ */
86
+ readonly attributes: Record<string, string>;
87
+ /** The customer's own identifier (SKU, EAN, artikelnummer, name code). */
88
+ readonly reference: string;
89
+ /** Price in minor units (cents), exactly as the source displays it. */
90
+ readonly priceCents: number;
91
+ readonly availability: Availability;
92
+ /** Provenance (manual | imported); audit-only, unused by the resolver. */
93
+ readonly source: 'manual' | 'imported';
94
+ }
95
+ /**
96
+ * A model's pricing document. The viewer's fetcher merges it into the model
97
+ * metadata and the server forwards it to the client via {@link PricingMessage}.
98
+ */
99
+ interface PricingDocument {
100
+ /** Optimistic-concurrency version from the editor; unused by the viewer. */
101
+ readonly version: number;
102
+ /** Customer-authored CTA label; null when the adapter's defaultLabel fills in. */
103
+ readonly buttonLabel: string | null;
104
+ /** ISO 4217 currency code for price formatting. */
105
+ readonly currency: string;
106
+ /** VAT label for bare embeds, e.g. "incl. btw". */
107
+ readonly vatDisplay: string;
108
+ readonly rules: PricingRule[];
109
+ }
110
+
111
+ /**
112
+ * Annotation display: show or hide the model's existing markers.
113
+ */
114
+ declare class Annotations {
115
+ private readonly send;
116
+ /** Whose pins this facade toggles: a pin lives in one model's local space. */
117
+ private readonly instance;
118
+ setEnabled(enabled: boolean): void;
119
+ }
120
+
121
+ type SelectableSnapshot = readonly SelectableAttribute[];
122
+
123
+ /**
124
+ * Camera control API for positioning and zoom
125
+ * Uses chaining pattern for building commands
126
+ */
127
+ declare class Camera {
128
+ private readonly send;
129
+ private commands;
130
+ /**
131
+ * Rotate camera horizontally
132
+ * @param degrees - Absolute rotation in degrees (0 = front view)
133
+ * @throws VirtualdisplayError if value is not a finite number
134
+ */
135
+ rotate(degrees: number): this;
136
+ /**
137
+ * Tilt camera vertically
138
+ * @param degrees - Absolute tilt in degrees (0 = top view, 90 = horizontal)
139
+ * @throws VirtualdisplayError if value is not a finite number
140
+ */
141
+ tilt(degrees: number): this;
142
+ /**
143
+ * Zoom camera
144
+ * @param percentage - Zoom percentage (100 = normal, >100 = zoom in, <100 = zoom out)
145
+ * @throws VirtualdisplayError if value is not a finite number
146
+ */
147
+ zoom(percentage: number): this;
148
+ /**
149
+ * Execute accumulated camera commands
150
+ * @throws VirtualdisplayError if no commands have been accumulated
151
+ */
152
+ set(): void;
153
+ private validateFiniteNumber;
154
+ /**
155
+ * Reset camera to initial position
156
+ * This is not chainable and executes immediately
157
+ */
158
+ reset(): void;
159
+ }
160
+
161
+ /**
162
+ * Camera position state object
163
+ */
164
+ interface CameraPositionState {
165
+ rotation: number;
166
+ tilt: number;
167
+ zoom: number;
168
+ }
169
+ /**
170
+ * Camera position state
171
+ * Tracks current rotation, tilt, zoom, and movement limits from server updates.
172
+ */
173
+ declare class CameraPosition {
174
+ private readonly state;
175
+ private limitsState;
176
+ private readonly changeCallbacks;
177
+ /**
178
+ * Get current rotation in degrees
179
+ */
180
+ get rotation(): number;
181
+ /**
182
+ * Get current tilt in degrees
183
+ */
184
+ get tilt(): number;
185
+ /**
186
+ * Get current zoom percentage
187
+ */
188
+ get zoom(): number;
189
+ /**
190
+ * Subscribe to camera position changes. Also fires when the viewer reports new
191
+ * movement limits, so controls can re-evaluate their disabled state without a
192
+ * second callback.
193
+ */
194
+ onChange(callback: (position: CameraPositionState) => void): void;
195
+ /**
196
+ * Current camera movement limits (set from CONFIG message).
197
+ * Undefined until the server sends limits in its CONFIG payload.
198
+ */
199
+ get limits(): CameraLimits | undefined;
200
+ }
201
+
202
+ /**
203
+ * The buyer's current configuration once it resolves to a price. `availability`
204
+ * is `available` (price + submit) or `view_only` (price, no submit); a matched
205
+ * `hidden` rule and a no-match both surface as `undefined` instead.
206
+ */
207
+ interface ResolvedConfiguration {
208
+ readonly attributes: Record<string, string>;
209
+ readonly reference: string;
210
+ /** Price in minor units (cents), exactly as the source displays it. */
211
+ readonly price: number;
212
+ readonly currency: string;
213
+ readonly availability: 'available' | 'view_only';
214
+ }
215
+ /**
216
+ * What submit hands to the host: the buyer's selection and the reference to act
217
+ * on. Deliberately carries no price — the shop's checkout price is binding and
218
+ * ours is display-only, so handing it into the cart hand-off would only invite a
219
+ * wrong-price error. Price stays on the display side (`current`, `onChange`).
220
+ */
221
+ interface SubmittedConfiguration {
222
+ readonly attributes: Record<string, string>;
223
+ readonly reference: string;
224
+ }
225
+ /** Options for {@link Configuration.onSubmit}. */
226
+ interface SubmitOptions {
227
+ /** Fallback button label when the customer authored none (the adapter brings it). */
228
+ readonly defaultLabel?: string;
229
+ }
230
+ /**
231
+ * Resolves the current selection to a reference and a price, and carries it to
232
+ * the host page. `onChange` fires with the resolved configuration, or
233
+ * `undefined` when nothing matches; `onSubmit` registers the handler the CTA
234
+ * hands that configuration to.
235
+ */
236
+ declare class Configuration {
237
+ private readonly dispatchChange;
238
+ private readonly dispatchSubmit;
239
+ private pricing;
240
+ private selection;
241
+ private resolved;
242
+ private readonly changeCallbacks;
243
+ private readonly renderCallbacks;
244
+ private submitCallback;
245
+ private submitDefaultLabel;
246
+ /** The resolved configuration, or undefined when nothing matches. */
247
+ get current(): ResolvedConfiguration | undefined;
248
+ /** The VAT label for bare embeds (e.g. "incl. btw"), or undefined without pricing. */
249
+ get vatDisplay(): string | undefined;
250
+ /**
251
+ * The CTA label: the customer's `button_label`, or the adapter's `defaultLabel`
252
+ * when that is empty. Undefined when neither is set — a button must know what
253
+ * it says, so the CTA does not render.
254
+ */
255
+ get buttonLabel(): string | undefined;
256
+ /**
257
+ * Whether the current configuration may be submitted: a handler is registered
258
+ * and the configuration is either price-less or an `available` priced one. The
259
+ * CTA's visibility ({@link submitEnabled}) layers a label requirement on top of
260
+ * this; a programmatic `submit()` does not need a label.
261
+ */
262
+ private get submittable();
263
+ /**
264
+ * Whether the CTA should render: the configuration is submittable and a label
265
+ * exists. A button must say something, so an empty label hides the CTA rather
266
+ * than rendering blank.
267
+ */
268
+ get submitEnabled(): boolean;
269
+ /**
270
+ * Subscribe to configuration changes. Fires after every selection change with
271
+ * the resolved configuration, including undefined when nothing matches.
272
+ */
273
+ onChange(callback: (configuration: ResolvedConfiguration | undefined) => void): void;
274
+ /**
275
+ * Register the handler the button hands the configuration to, which switches the button on.
276
+ * `defaultLabel` fills in when no button label was authored. The button reads done when the
277
+ * returned promise resolves and failed when it rejects; reject with a `DOMException` named
278
+ * `AbortError` when the shopper backs out before sending, and it returns to its label.
279
+ */
280
+ onSubmit(callback: (configuration: SubmittedConfiguration) => void | Promise<unknown>, options?: SubmitOptions): void;
281
+ /**
282
+ * Hand the current configuration to the registered handler and fire the
283
+ * bubbling `vd:configuration-submit` event. No-op without a handler or a
284
+ * resolved configuration. Returns the handler's promise so the caller can
285
+ * reflect the result (bezig / gelukt / mislukt).
286
+ */
287
+ submit(): Promise<void>;
288
+ private recompute;
289
+ private notifyRender;
290
+ private resolve;
291
+ }
292
+
293
+ /** The focus state reported to `onChange` and the `vd:focus-change` event. */
294
+ interface FocusState {
295
+ readonly component: string;
296
+ readonly attributes: string[];
297
+ }
298
+ /**
299
+ * Isolate and frame one component, or return to the overview. Alongside
300
+ * `onChange` the container dispatches a bubbling `vd:focus-change` event, so a
301
+ * page can react without registering a callback.
302
+ */
303
+ declare class Focus {
304
+ private readonly send;
305
+ private readonly dispatch;
306
+ /** Which instance this facade addresses; every message it sends carries it. */
307
+ private readonly instance;
308
+ private focused;
309
+ private attributes;
310
+ private readonly changeCallbacks;
311
+ /** The focused component name, or null in overview. */
312
+ get current(): string | null;
313
+ /**
314
+ * Focus a component by name. Sends a focus message to the viewer.
315
+ * @throws VirtualdisplayError if component is not a non-empty string
316
+ */
317
+ set(component: string): void;
318
+ /** Return to the overview — unfocus the current component. */
319
+ clear(): void;
320
+ /**
321
+ * Subscribe to focus changes. The callback fires with the focus state when a
322
+ * component is focused, and with null when returning to overview.
323
+ */
324
+ onChange(callback: (state: FocusState | null) => void): void;
325
+ }
326
+
327
+ /**
328
+ * Error codes for Virtualdisplay client errors
329
+ */
330
+ declare const ERROR_CODES: {
331
+ readonly NO_MAPPING: "NO_MAPPING";
332
+ readonly ATTRIBUTE_NOT_FOUND: "ATTRIBUTE_NOT_FOUND";
333
+ readonly VALUE_NOT_FOUND: "VALUE_NOT_FOUND";
334
+ readonly PARENT_NOT_FOUND: "PARENT_NOT_FOUND";
335
+ readonly INVALID_PARAMETER: "INVALID_PARAMETER";
336
+ readonly SNAPSHOT_FAILED: "SNAPSHOT_FAILED";
337
+ };
338
+ type ErrorCode = typeof ERROR_CODES[keyof typeof ERROR_CODES];
339
+ /**
340
+ * Custom error class for Virtualdisplay client errors
341
+ */
342
+ declare class VirtualdisplayError extends Error {
343
+ readonly code: ErrorCode;
344
+ constructor(message: string, code: ErrorCode);
345
+ static valueNotFound(attributeName: string, valueName: string): VirtualdisplayError;
346
+ static parentNotFound(selector: string): VirtualdisplayError;
347
+ static invalidParameter(reason: string): VirtualdisplayError;
348
+ }
349
+
350
+ interface PhotoData {
351
+ readonly filename: string;
352
+ readonly data: string;
353
+ }
354
+ /**
355
+ * Represents a photo being captured
356
+ * Pure domain object that manages callbacks for when the photo is developed
357
+ */
358
+ declare class Photo {
359
+ private readonly filename;
360
+ private readonly developedCallbacks;
361
+ private readonly errorCallbacks;
362
+ private developed;
363
+ private failed;
364
+ private photoData;
365
+ /**
366
+ * Register a callback for when the photo is developed
367
+ * If the photo is already developed, the callback is called immediately
368
+ *
369
+ * @param callback Function to call with photo data
370
+ * @returns This Photo instance for chaining
371
+ */
372
+ onDeveloped(callback: (photo: PhotoData) => void): this;
373
+ /**
374
+ * Register a callback for when the photo capture fails
375
+ *
376
+ * @param callback Function to call with error
377
+ * @returns This Photo instance for chaining
378
+ */
379
+ onError(callback: (error: VirtualdisplayError) => void): this;
380
+ /**
381
+ * Get the filename for this photo
382
+ */
383
+ getFilename(): string;
384
+ }
385
+
386
+ /**
387
+ * API for taking screenshots of the 3D model
388
+ * Following the camera analogy: take() triggers capture, onDeveloped() gets result
389
+ */
390
+ declare class Snapshot {
391
+ private readonly send;
392
+ private readonly validExtensions;
393
+ private readonly pendingPhotos;
394
+ /**
395
+ * Take a snapshot of the current 3D model view
396
+ *
397
+ * @param filename The filename for the snapshot (must include valid extension)
398
+ * @returns Photo object for registering callbacks
399
+ * @throws VirtualdisplayError if filename is invalid
400
+ */
401
+ take(filename: string): Photo;
402
+ private request;
403
+ /**
404
+ * Fail any pending photos and forget them. Called from client destroy
405
+ * so callers awaiting onError() see a deterministic outcome instead of
406
+ * leaking captures whose results will never arrive.
407
+ */
408
+ clear(): void;
409
+ /**
410
+ * Validate filename has a valid image extension
411
+ */
412
+ private validateFilename;
413
+ }
414
+
415
+ /**
416
+ * Pure domain entity representing a single attribute value
417
+ * No side effects - only state
418
+ */
419
+ declare class AttributeValue {
420
+ readonly value: string;
421
+ readonly attribute: string;
422
+ /**
423
+ * What to show: the model's own label, or the key made readable where it
424
+ * named none (`redWine` reads as "Red wine"). `value` stays the key, so a
425
+ * control renders this and submits that. On a measurement attribute it is
426
+ * the size in whole millimetres.
427
+ */
428
+ readonly label: string;
429
+ private isSelectedValue;
430
+ get isSelected(): boolean;
431
+ }
432
+
433
+ /**
434
+ * Represents a single attribute with its available values
435
+ * Flat API - no source/target translation, works with server values directly
436
+ */
437
+ declare class Attribute {
438
+ readonly name: string;
439
+ readonly defaultValue: string | undefined;
440
+ private readonly values;
441
+ private readonly onSelect;
442
+ private onChangeCallback?;
443
+ /**
444
+ * Select a value for this attribute
445
+ * @throws {VirtualdisplayError} When value not found
446
+ */
447
+ select(value: string): void;
448
+ getValues(): AttributeValue[];
449
+ getValue(value: string): AttributeValue | undefined;
450
+ /** The currently selected value, or undefined before any selection lands. */
451
+ get selected(): string | undefined;
452
+ /**
453
+ * Register callback that fires when selection changes
454
+ * Receives the newly selected AttributeValue
455
+ */
456
+ onChange(callback: (selectedValue: AttributeValue) => void): void;
457
+ private createValues;
458
+ }
459
+
460
+ /**
461
+ * The client's DOM event names, in one registry. The two selection events are
462
+ * what `client.on(...)` subscribes to; the other three bubble out of the
463
+ * container, so the host page can reach them with `addEventListener`.
464
+ */
465
+ declare const VD_EVENTS: {
466
+ /** Attribute selection requested (cancelable, does not bubble). `detail`: `{ attribute, value }`. */
467
+ readonly SELECT: "vd:select";
468
+ /** Attribute selection applied (does not bubble). `detail`: `{ attribute, value }`. */
469
+ readonly SELECTED: "vd:selected";
470
+ /** Focus changed (bubbles). `detail`: `{ component, attributes }`, or `null` for the overview. */
471
+ readonly FOCUS_CHANGE: "vd:focus-change";
472
+ /** Resolved configuration changed (bubbles). `detail`: the resolved configuration, or `null` when nothing matches. */
473
+ readonly CONFIGURATION_CHANGE: "vd:configuration-change";
474
+ /** Configuration submitted (bubbles). `detail`: the resolved configuration handed to the host. */
475
+ readonly CONFIGURATION_SUBMIT: "vd:configuration-submit";
476
+ };
477
+ type VdEvent = typeof VD_EVENTS[keyof typeof VD_EVENTS];
478
+
479
+ interface MutationFailedEvent {
480
+ readonly attribute: string;
481
+ readonly value: string;
482
+ }
483
+ /**
484
+ * Which app the viewer resolved, as handed to an `onAppResolved` callback.
485
+ */
486
+ interface ResolvedAppInfo {
487
+ /** Known values: `AppType`. An unknown value means a newer server; report it, never downgrade to a viewer. */
488
+ readonly appType: string;
489
+ readonly name: string;
490
+ /** The app's public slug (the address a submit POSTs to). Absent from a pre-slug server. */
491
+ readonly slug?: string;
492
+ readonly submit?: AppSubmitSettings;
493
+ /** Features switched on for the app's owner. Absent when there are none. */
494
+ readonly features?: readonly string[];
495
+ }
496
+ interface VirtualdisplaySelectEvent {
497
+ readonly attribute: string;
498
+ readonly value: string;
499
+ preventDefault(): void;
500
+ }
501
+ interface VirtualdisplaySelectedEvent {
502
+ readonly attribute: string;
503
+ readonly value: string;
504
+ }
505
+ type VirtualdisplayUiEventMap = {
506
+ [VD_EVENTS.SELECT]: VirtualdisplaySelectEvent;
507
+ [VD_EVENTS.SELECTED]: VirtualdisplaySelectedEvent;
508
+ };
509
+ type VirtualdisplayUiEventType = keyof VirtualdisplayUiEventMap;
510
+
511
+ /**
512
+ * The shared client composition root: wires the transport, facades and UI, and
513
+ * exposes the integrator-facing API.
514
+ */
515
+ declare class BaseClient {
516
+ private readonly attributes;
517
+ private readonly selectableState;
518
+ private readonly readyStateTracker;
519
+ private readonly messenger;
520
+ private readonly cameraApi;
521
+ private readonly cameraPositionApi;
522
+ private readonly focusApi;
523
+ private readonly configurationApi;
524
+ private readonly snapshotApi;
525
+ private readonly annotationsApi;
526
+ private readonly eventBus;
527
+ private readonly ui;
528
+ private readonly options;
529
+ private readonly serverHost;
530
+ private readonly iframeParams;
531
+ private readonly arActivation;
532
+ private readonly syncTracker;
533
+ private iframe;
534
+ private container;
535
+ private readyCallbacks;
536
+ private readonly mutationFailedCallbacks;
537
+ private viewerSessionId;
538
+ private resolvedApp;
539
+ private readonly appResolvedCallbacks;
540
+ private createStandardInterface;
541
+ private sendControlAnnotationToggle;
542
+ private sendAnnotationToggle;
543
+ private wireIncomingMessages;
544
+ private handleAppResolved;
545
+ private handleSession;
546
+ private notifyMutationFailed;
547
+ private notifyReady;
548
+ private dispatchFocusChange;
549
+ private dispatchConfigurationChange;
550
+ private dispatchConfigurationSubmit;
551
+ private handleConfig;
552
+ private echoAnnotationsDifference;
553
+ private trackFullscreen;
554
+ private initializeLogging;
555
+ private mountIframe;
556
+ select(name: string, value: string): void;
557
+ getValues(name: string): AttributeValue[];
558
+ getValue(name: string, value: string): AttributeValue | undefined;
559
+ onChange(name: string, callback: (selectedValue: AttributeValue) => void): void;
560
+ getAttribute(name: string): Attribute | undefined;
561
+ get isReady(): boolean;
562
+ onReady(callback: (client: this) => void): void;
563
+ onMutationFailed(callback: (event: MutationFailedEvent) => void): void;
564
+ /**
565
+ * Subscribe to which values can be picked right now, per attribute. Fires
566
+ * immediately when a snapshot already arrived. A model with no exclusions
567
+ * never sends one, so this never fires and everything stays selectable.
568
+ */
569
+ onSelectableChange(callback: (snapshot: SelectableSnapshot) => void): void;
570
+ /**
571
+ * Subscribe to which app this viewer resolved (type, name, public submit
572
+ * settings). Reported once by the viewer after its resolve; fires immediately
573
+ * when the report already arrived, so registration order does not matter.
574
+ */
575
+ onAppResolved(callback: (app: ResolvedAppInfo) => void): void;
576
+ /** The selectable values for one attribute right now, or null when unrestricted. */
577
+ getSelectable(name: string): readonly string[] | null;
578
+ /**
579
+ * Start the AR flow directly, as the built-in AR button would. Does nothing
580
+ * when `viewerSettings.ar` is off or the build composes no AR flow.
581
+ */
582
+ activateAr(): void;
583
+ on<T extends VirtualdisplayUiEventType>(type: T, callback: (event: VirtualdisplayUiEventMap[T]) => void): void;
584
+ get annotations(): Annotations;
585
+ get camera(): Camera;
586
+ get focus(): Focus;
587
+ get configuration(): Configuration;
588
+ get cameraPosition(): CameraPosition;
589
+ get snapshot(): Snapshot;
590
+ /** The viewer's tracking session id, for a host page to correlate its own actions. */
591
+ get sessionId(): string | undefined;
592
+ get viewerSettings(): ViewerSettings;
593
+ destroy(): void;
594
+ }
595
+
596
+ /**
597
+ * The integrator-facing viewer settings override. Identical to the wire
598
+ * `ViewerSettings`, except `annotations` also accepts the legacy booleans:
599
+ * they normalise before the merge (`true` → `show`, `false` → `hide`), so
600
+ * existing mounts keep compiling while the package is in alpha.
601
+ */
602
+ type ViewerSettingsOverride = Omit<Partial<ViewerSettings>, 'annotations'> & {
603
+ readonly annotations?: boolean | AnnotationVisibility;
604
+ };
605
+ /**
606
+ * Options shared by both address forms.
607
+ */
608
+ interface ClientOptionsBase {
609
+ readonly parent: string | HTMLElement;
610
+ readonly debug?: boolean | undefined;
611
+ readonly language?: string | undefined;
612
+ /** W3C traceparent string to propagate to the viewer iframe for end-to-end tracing. */
613
+ readonly traceparent?: string | undefined;
614
+ /**
615
+ * A source viewer session id to restore into this mount: the
616
+ * iframe's metadata fetch merges that session's latest configuration into the
617
+ * attribute defaults, so the viewer boots straight into it. Internal option, used
618
+ * by the AR landing, not a customer-facing setting.
619
+ */
620
+ readonly session?: string | undefined;
621
+ /**
622
+ * Override viewer settings from metadata. Omitted fields use the metadata value.
623
+ * A warning is logged when an override differs from the metadata value.
624
+ */
625
+ readonly viewerSettings?: ViewerSettingsOverride;
626
+ }
627
+ /**
628
+ * What the client shows, given either way of naming it: `{ app }`, an app's
629
+ * public link key, or `{ license, model }`, which resolves to that model's
630
+ * default app. Given both, `app` wins and the pair is ignored with a warning.
631
+ */
632
+ type ClientAddress = {
633
+ readonly app: string;
634
+ readonly license?: string | undefined;
635
+ readonly model?: string | undefined;
636
+ } | {
637
+ readonly license: string;
638
+ readonly model: string;
639
+ readonly app?: undefined;
640
+ };
641
+ /**
642
+ * Configuration options for VirtualdisplayClient
643
+ */
644
+ type ClientOptions = ClientOptionsBase & ClientAddress;
645
+
646
+ /**
647
+ * The logger the client exposes: the same four levels as the base logger, but
648
+ * accepting any value as attributes so callers can pass an Error or a bare value.
649
+ */
650
+ interface ClientLogger {
651
+ debug: (msg: string, attrs?: unknown) => void;
652
+ info: (msg: string, attrs?: unknown) => void;
653
+ warn: (msg: string, attrs?: unknown) => void;
654
+ error: (msg: string, attrs?: unknown) => void;
655
+ }
656
+ declare let logger: ClientLogger;
657
+ declare function enableDebugMode(): void;
658
+ declare function isDebugMode(): boolean;
659
+
660
+ /**
661
+ * The Virtualdisplay client: point it at a container and an app or model, and it
662
+ * renders the viewer with the standard interface, the configurator and AR.
663
+ */
664
+ declare class VirtualdisplayClient extends BaseClient {
665
+ private readonly syncStatusTracker;
666
+ constructor(options: ClientOptions);
667
+ /** Subscribe to the live sync channel's connection state. Latest-wins, no buffering. */
668
+ onSyncChange(callback: (connected: boolean) => void): void;
669
+ }
670
+
671
+ export { AVAILABILITY, Annotations, Attribute, AttributeValue, Camera, CameraPosition, Configuration, ERROR_CODES, Focus, Photo, Snapshot, VD_EVENTS, VirtualdisplayClient, VirtualdisplayError, enableDebugMode, isDebugMode, logger };
672
+ export type { AnnotationVisibility, AppSubmitSettings, AppType, Availability, CameraLimits, CameraPositionState, ClientAddress, ClientLogger, ClientOptions, ClientOptionsBase, ErrorCode, FocusState, MutationFailedEvent, PhotoData, PricingDocument, PricingRule, ResolvedAppInfo, ResolvedConfiguration, SelectableAttribute, SelectableSnapshot, SubmitOptions, SubmittedConfiguration, VdEvent, ViewerSettings, ViewerSettingsOverride, VirtualdisplaySelectEvent, VirtualdisplaySelectedEvent, VirtualdisplayUiEventMap, VirtualdisplayUiEventType };
@@ -0,0 +1 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t,t.exports),e=null),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,o)=>(o=n==null?{}:e(i(n)),s(r||!n||!n.__esModule||!a.call(n,`default`)?t(o,`default`,{value:n,enumerable:!0}):o,n));Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return o}});
@@ -0,0 +1,12 @@
1
+ // \0rolldown/runtime.js
2
+ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescriptor, r = Object.getOwnPropertyNames, i = Object.getPrototypeOf, a = Object.prototype.hasOwnProperty, o = (e, t) => () => (t || (e((t = { exports: {} }).exports, t, t.exports), e = null), t.exports), s = (e, i, o, s) => {
3
+ if (i && typeof i == "object" || typeof i == "function") for (var c = r(i), l = 0, u = c.length, d; l < u; l++) d = c[l], !a.call(e, d) && d !== o && t(e, d, {
4
+ get: ((e) => i[e]).bind(null, d),
5
+ enumerable: !(s = n(i, d)) || s.enumerable
6
+ });
7
+ return e;
8
+ }, c = (n, r, o) => (o = n == null ? {} : e(i(n)), s(r || !n || !n.__esModule || !a.call(n, "default") ? t(o, "default", {
9
+ value: n,
10
+ enumerable: !0
11
+ }) : o, n));
12
+ export { c as n, o as t };