@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.
- package/CHANGELOG.md +254 -1
- package/README.md +127 -156
- package/dist/browser-7qZ1KQYo.cjs +8 -0
- package/dist/browser-B8yql1bQ.js +1226 -0
- package/dist/index.d.ts +672 -0
- package/dist/rolldown-runtime-5iZMYShA.cjs +1 -0
- package/dist/rolldown-runtime-CYdcPHCu.js +12 -0
- package/dist/virtualdisplay.client.cjs.js +691 -1
- package/dist/virtualdisplay.client.es.js +3142 -458
- package/dist/virtualdisplay.client.umd.js +698 -1
- package/package.json +3 -3
- package/dist/src/attributes/attribute.d.ts +0 -38
- package/dist/src/attributes/attribute.d.ts.map +0 -1
- package/dist/src/attributes/attributes.d.ts +0 -43
- package/dist/src/attributes/attributes.d.ts.map +0 -1
- package/dist/src/attributes/selections.d.ts +0 -16
- package/dist/src/attributes/selections.d.ts.map +0 -1
- package/dist/src/attributes/value.d.ts +0 -13
- package/dist/src/attributes/value.d.ts.map +0 -1
- package/dist/src/camera/camera.d.ts +0 -40
- package/dist/src/camera/camera.d.ts.map +0 -1
- package/dist/src/camera/index.d.ts +0 -4
- package/dist/src/camera/index.d.ts.map +0 -1
- package/dist/src/camera/position.d.ts +0 -43
- package/dist/src/camera/position.d.ts.map +0 -1
- package/dist/src/client/client.d.ts +0 -83
- package/dist/src/client/client.d.ts.map +0 -1
- package/dist/src/client/error.d.ts +0 -26
- package/dist/src/client/error.d.ts.map +0 -1
- package/dist/src/client/iframe-builder.d.ts +0 -25
- package/dist/src/client/iframe-builder.d.ts.map +0 -1
- package/dist/src/client/options.d.ts +0 -17
- package/dist/src/client/options.d.ts.map +0 -1
- package/dist/src/client/ready-state-tracker.d.ts +0 -26
- package/dist/src/client/ready-state-tracker.d.ts.map +0 -1
- package/dist/src/client/types.d.ts +0 -5
- package/dist/src/client/types.d.ts.map +0 -1
- package/dist/src/index.d.ts +0 -11
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/snapshot/index.d.ts +0 -3
- package/dist/src/snapshot/index.d.ts.map +0 -1
- package/dist/src/snapshot/photo.d.ts +0 -47
- package/dist/src/snapshot/photo.d.ts.map +0 -1
- package/dist/src/snapshot/snapshot.d.ts +0 -30
- package/dist/src/snapshot/snapshot.d.ts.map +0 -1
- package/dist/src/ui/viewer-config.d.ts +0 -63
- package/dist/src/ui/viewer-config.d.ts.map +0 -1
- package/dist/src/utils/logger.d.ts +0 -11
- package/dist/src/utils/logger.d.ts.map +0 -1
package/dist/index.d.ts
ADDED
|
@@ -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 };
|