@virtualdisplay.io/client 4.0.0-alpha.2 → 4.0.0-alpha.6

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 (63) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +36 -161
  3. package/dist/browser-DbgxVbZp.js +1227 -0
  4. package/dist/browser-DiwLZG-y.cjs +8 -0
  5. package/dist/chunk-350yNsax.cjs +1 -0
  6. package/dist/chunk-efA98nb6.js +13 -0
  7. package/dist/src/attributes/attribute.d.ts +38 -0
  8. package/dist/src/attributes/attribute.d.ts.map +1 -0
  9. package/dist/src/attributes/attributes.d.ts +43 -0
  10. package/dist/src/attributes/attributes.d.ts.map +1 -0
  11. package/dist/src/attributes/selections.d.ts +16 -0
  12. package/dist/src/attributes/selections.d.ts.map +1 -0
  13. package/dist/src/attributes/value.d.ts +13 -0
  14. package/dist/src/attributes/value.d.ts.map +1 -0
  15. package/dist/src/camera/camera.d.ts +40 -0
  16. package/dist/src/camera/camera.d.ts.map +1 -0
  17. package/dist/src/camera/index.d.ts +4 -0
  18. package/dist/src/camera/index.d.ts.map +1 -0
  19. package/dist/src/camera/position.d.ts +56 -0
  20. package/dist/src/camera/position.d.ts.map +1 -0
  21. package/dist/src/client/client.d.ts +46 -0
  22. package/dist/src/client/client.d.ts.map +1 -0
  23. package/dist/src/client/error.d.ts +26 -0
  24. package/dist/src/client/error.d.ts.map +1 -0
  25. package/dist/src/client/iframe-builder.d.ts +27 -0
  26. package/dist/src/client/iframe-builder.d.ts.map +1 -0
  27. package/dist/src/client/options.d.ts +11 -0
  28. package/dist/src/client/options.d.ts.map +1 -0
  29. package/dist/src/client/ready-state-tracker.d.ts +13 -0
  30. package/dist/src/client/ready-state-tracker.d.ts.map +1 -0
  31. package/dist/src/client/types.d.ts +19 -0
  32. package/dist/src/client/types.d.ts.map +1 -0
  33. package/dist/src/index.d.ts +11 -0
  34. package/dist/src/index.d.ts.map +1 -0
  35. package/dist/src/snapshot/index.d.ts +3 -0
  36. package/dist/src/snapshot/index.d.ts.map +1 -0
  37. package/dist/src/snapshot/photo.d.ts +47 -0
  38. package/dist/src/snapshot/photo.d.ts.map +1 -0
  39. package/dist/src/snapshot/snapshot.d.ts +30 -0
  40. package/dist/src/snapshot/snapshot.d.ts.map +1 -0
  41. package/dist/src/ui/action-bar.d.ts +17 -0
  42. package/dist/src/ui/action-bar.d.ts.map +1 -0
  43. package/dist/src/ui/camera-controls.d.ts +8 -0
  44. package/dist/src/ui/camera-controls.d.ts.map +1 -0
  45. package/dist/src/ui/controls/attribute-group.d.ts +6 -0
  46. package/dist/src/ui/controls/attribute-group.d.ts.map +1 -0
  47. package/dist/src/ui/event-bus.d.ts +12 -0
  48. package/dist/src/ui/event-bus.d.ts.map +1 -0
  49. package/dist/src/ui/loading.d.ts +43 -0
  50. package/dist/src/ui/loading.d.ts.map +1 -0
  51. package/dist/src/ui/standard-interface.d.ts +35 -0
  52. package/dist/src/ui/standard-interface.d.ts.map +1 -0
  53. package/dist/src/ui/styles.d.ts +3 -0
  54. package/dist/src/ui/styles.d.ts.map +1 -0
  55. package/dist/src/ui/toolbar.d.ts +14 -0
  56. package/dist/src/ui/toolbar.d.ts.map +1 -0
  57. package/dist/src/utils/logger.d.ts +11 -0
  58. package/dist/src/utils/logger.d.ts.map +1 -0
  59. package/dist/virtualdisplay.client.cjs.js +225 -1
  60. package/dist/virtualdisplay.client.es.js +1384 -186
  61. package/dist/virtualdisplay.client.umd.js +232 -1
  62. package/package.json +3 -3
  63. package/dist/index.d.ts +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.0-alpha.6
4
+
5
+ ### Patch Changes
6
+
7
+ Fix camera control buttons accumulating clicks correctly.
8
+
9
+ ## 4.0.0-alpha.5
10
+
11
+ ### Patch Changes
12
+
13
+ Internal code quality improvements.
14
+
15
+ Ship complete TypeScript type definitions for all exports.
16
+
17
+ ## 4.0.0-alpha.4
18
+
19
+ ### Minor Changes
20
+
21
+ Add `language` option to `ClientOptions`. Pass a BCP 47 language tag (e.g. `"nl"`, `"de"`) to override the viewer language at initialisation time. Useful when embedding the same model on multiple pages with different languages.
22
+
23
+ Add built-in standard interface: loading indicator, toolbar (screenshot, AR, fullscreen), camera controls, and attribute controls are now rendered automatically inside the viewer container. UI is driven by `viewerSettings` received from the server and requires no manual setup.
24
+
25
+ ### Patch Changes
26
+
27
+ Fix build target: use ESNext in tsconfig to resolve rolldown bundling issues with ES2022 class fields.
28
+
3
29
  ## 4.0.0-alpha.2
4
30
 
5
31
  ### Patch Changes
package/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  TypeScript library for embedding interactive 3D product models in web
4
4
  applications.
5
5
 
6
+ - Built-in viewer UI with loading indicator, product controls, and action bar
6
7
  - Simple attribute-based API for product configurators
7
8
  - Server-driven configuration, no client-side mapping needed
8
9
  - Fire-and-forget messaging with automatic state synchronisation
@@ -60,43 +61,19 @@ The 3D server hosts the viewer in an iframe, keeping WebGL complexity isolated
60
61
  from your application. The client library handles all communication via
61
62
  postMessage.
62
63
 
63
- ```mermaid
64
- graph LR
65
- A[Your application] -->|API calls| B[VirtualdisplayClient]
66
- B -->|postMessage| C[3D server iframe]
67
- C -->|Events| B
68
- B -->|State updates| A
69
- ```
64
+ ![Architecture overview](docs/arch.png)
70
65
 
71
- On startup, the server tells the client what is available (attributes, values,
72
- defaults). After that, the client sends commands and the server responds with
73
- results.
74
-
75
- ```mermaid
76
- sequenceDiagram
77
- participant UI as Your UI
78
- participant Client as VirtualdisplayClient
79
- participant Server as 3D server
80
-
81
- UI ->> Client: new VirtualdisplayClient(options)
82
- Client ->> Client: Create iframe
83
- Note right of Client: Outgoing messages queued
84
- Server ->> Client: READY
85
- Note right of Client: Queue flushed
86
- opt UI or camera options configured
87
- Client ->> Server: CONFIG
88
- end
89
- Server ->> Client: MAPPING (attributes + values + defaults)
90
- Client ->> Client: Store attribute definitions
91
- Server ->> Client: MUTATION result (defaults, isInitial: true)
92
- Client ->> UI: onReady + onChange callbacks fire
93
- ```
66
+ On startup, the server sends the client its configuration (viewer settings,
67
+ camera limits) and available product attributes. The loading indicator shows
68
+ progress while the model downloads.
69
+
70
+ ![Startup sequence](docs/startup-sequence.png)
94
71
 
95
72
  1. Client creates iframe; outgoing messages are queued until the server is ready.
96
- 2. Server sends `READY` when its message listener is active; client flushes queue.
97
- 3. `CONFIG` is only sent if UI or camera options were provided in the constructor.
98
- 4. Server sends `MAPPING` with attribute definitions, loads the 3D model, applies defaults.
99
- 5. `onReady` fires after the first initial mutation result arrives.
73
+ 2. Server sends `HANDSHAKE` when its message listener is active; client flushes queue.
74
+ 3. Server sends progress updates while the model downloads. The client displays these in the loading indicator.
75
+ 4. Server sends `CONFIG` with viewer settings and camera limits from model metadata.
76
+ 5. Server sends `MAPPING` with attribute definitions, values, and defaults. `onReady` fires.
100
77
 
101
78
  ## Product configuration
102
79
 
@@ -104,23 +81,7 @@ Configure product options by selecting attribute values. The server defines
104
81
  which attributes exist (e.g. "Color", "Size") and which values each has
105
82
  (e.g. "red", "blue"). You select values; the 3D model updates automatically.
106
83
 
107
- ```mermaid
108
- sequenceDiagram
109
- participant UI as Your UI
110
- participant Client as VirtualdisplayClient
111
- participant Server as 3D server
112
-
113
- UI ->> Client: client.select('Color', 'blue')
114
- Client ->> Server: MUTATION
115
- Note right of Client: Fire-and-forget
116
- Server ->> Server: Apply 3D changes
117
- Server ->> Client: MUTATION result
118
- alt All succeeded
119
- Client ->> UI: onChange callbacks fire
120
- else Some failed
121
- Client ->> UI: onMutationFailed callbacks fire
122
- end
123
- ```
84
+ ![Product configuration sequence](docs/mutation.png)
124
85
 
125
86
  - `select()` returns immediately; the result arrives asynchronously.
126
87
  - Each attribute in the result has its own `success` flag and optional `error`.
@@ -134,8 +95,8 @@ client.select('Color', 'blue');
134
95
  client.select('Size', 'large');
135
96
  ```
136
97
 
137
- Can be called before the server is ready. Mutations are buffered and sent when
138
- the mapping arrives.
98
+ Can be called immediately after construction. Selections are buffered until the
99
+ server handshake completes.
139
100
 
140
101
  ### Tracking changes
141
102
 
@@ -192,22 +153,7 @@ client.onMutationFailed(({ attribute, value }) => {
192
153
  Capture the current 3D view as an image. Useful for product shots, social
193
154
  sharing, or saving configurations.
194
155
 
195
- ```mermaid
196
- sequenceDiagram
197
- participant UI as Your UI
198
- participant Client as VirtualdisplayClient
199
- participant Server as 3D server
200
-
201
- UI ->> Client: client.snapshot.take('photo.png')
202
- Client ->> Server: SNAPSHOT request
203
- alt Success
204
- Server ->> Client: SNAPSHOT data (base64)
205
- Client ->> UI: onDeveloped callback fires
206
- else Failure (e.g. no canvas)
207
- Server ->> Client: SNAPSHOT error
208
- Client ->> UI: onError callback fires
209
- end
210
- ```
156
+ ![Snapshot sequence](docs/snapshot.png)
211
157
 
212
158
  - Filename is validated client-side (extension, no path traversal).
213
159
  - Server always responds, either with image data or an error reason.
@@ -236,21 +182,10 @@ Filename must end with `.png`. The server always returns PNG data.
236
182
 
237
183
  ## Camera
238
184
 
239
- Control the 3D viewer's camera position programmatically. Useful for guided
240
- product tours, preset views, or syncing camera state with your UI.
241
-
242
- ```mermaid
243
- sequenceDiagram
244
- participant UI as Your UI
245
- participant Client as VirtualdisplayClient
246
- participant Server as 3D server
185
+ The standard interface includes built-in camera controls when enabled by the
186
+ operator in the portal. The camera can also be controlled programmatically.
247
187
 
248
- UI ->> Client: client.camera.rotate(45).tilt(30).set()
249
- Client ->> Server: CAMERA commands
250
- Server ->> Client: CAMERA position
251
- Client ->> UI: camera.onChange callbacks fire
252
- Note right of Server: Position updates also fire on user<br/>interaction with the 3D viewport
253
- ```
188
+ ![Camera sequence](docs/camera.png)
254
189
 
255
190
  - Commands accumulate via chaining; `.set()` sends them all at once.
256
191
  - `.reset()` sends immediately without chaining.
@@ -263,7 +198,7 @@ sequenceDiagram
263
198
  client.camera.rotate(45).set();
264
199
  client.camera.rotate(90).tilt(45).zoom(150).set();
265
200
 
266
- // Reset to base position (sends immediately)
201
+ // Reset to the default position configured in the portal (sends immediately)
267
202
  client.camera.reset();
268
203
  ```
269
204
 
@@ -283,49 +218,30 @@ console.log(client.cameraPosition.tilt);
283
218
  console.log(client.cameraPosition.zoom);
284
219
  ```
285
220
 
286
- ## UI controls
287
-
288
- Toggle built-in viewer elements like AR, fullscreen, and the loading indicator.
289
- All are visible by default.
290
-
291
- ### Via constructor
292
-
293
- ```typescript
294
- const client = new VirtualdisplayClient({
295
- parent: '#viewer',
296
- license: 'your-license',
297
- model: 'product',
298
- ui: {
299
- arEnabled: false,
300
- loadingIndicatorEnabled: false,
301
- },
302
- });
303
- ```
221
+ ## Standard interface
304
222
 
305
- ### At runtime
223
+ The client renders a complete viewer UI automatically: loading indicator,
224
+ attribute controls, camera controls, and an action bar (AR, fullscreen).
306
225
 
307
- ```typescript
308
- client.viewer.setArEnabled(false);
309
- client.viewer.setFullscreenEnabled(true);
310
- client.viewer.setLoadingIndicatorEnabled(false);
311
-
312
- // Bulk operations
313
- client.viewer.hideAllUI();
314
- client.viewer.showAllUI();
315
- client.viewer.updateUIConfig({ arEnabled: false, fullscreenEnabled: true });
316
- ```
226
+ Which controls are visible is configured by the model operator in the
227
+ Virtualdisplay portal. The operator decides how the viewer looks and
228
+ behaves, not the developer integrating the code. This way the operator
229
+ can match the viewer to their customers' expectations: enabling AR for
230
+ mobile visitors, choosing which product attributes to expose, or setting
231
+ the default camera angle and language.
317
232
 
318
233
  ## Lifecycle
319
234
 
320
235
  ### Ready state
321
236
 
322
- Use `onReady` to know when the 3D model has loaded. For example, to hide
323
- your own loading spinner. It is **not** required before calling `select()` or
324
- `onChange()`.
237
+ Use `onReady` to know when the model and attribute definitions are available.
238
+ Not required before calling `select()` or `onChange()`, those are buffered
239
+ automatically.
325
240
 
326
241
  ```typescript
327
242
  client.onReady(() => {
328
- document.getElementById('loading-spinner').hidden = true;
243
+ const values = client.getValues('Color');
244
+ console.log('Available colours:', values.map(v => v.value));
329
245
  });
330
246
  ```
331
247
 
@@ -343,25 +259,7 @@ interface ClientOptions {
343
259
  license: string; // License key from your Virtualdisplay account
344
260
  model: string; // Which 3D model to load
345
261
  debug?: boolean; // Shows console logs for troubleshooting
346
- language?: string; // UI language: 'nl', 'en', or 'de' (default: 'nl')
347
-
348
- // UI elements (all visible by default)
349
- ui?: {
350
- arEnabled?: boolean;
351
- fullscreenEnabled?: boolean;
352
- loadingIndicatorEnabled?: boolean;
353
- };
354
-
355
- // Camera behaviour
356
- camera?: {
357
- initialRotate?: number; // Starting view angle (-180 to 180, 0 = front)
358
- initialTilt?: number; // Starting elevation (0 = top view, 90 = side view)
359
- initialZoom?: number; // Starting distance (100 = default, may need adjustment)
360
- minZoom?: number; // Minimum zoom level constraint
361
- maxZoom?: number; // Maximum zoom level constraint
362
- minTilt?: number; // Minimum tilt angle constraint
363
- maxTilt?: number; // Maximum tilt angle constraint
364
- };
262
+ language?: string; // Match the viewer language to the page: 'nl', 'en', or 'de'
365
263
  }
366
264
  ```
367
265
 
@@ -370,37 +268,14 @@ interface ClientOptions {
370
268
  The client throws `VirtualdisplayError` for known error conditions:
371
269
 
372
270
  | Code | Meaning |
373
- |-----------------------|--------------------------------------------------|
271
+ | --------------------- | ------------------------------------------------ |
272
+ | `NO_MAPPING` | Attribute data not yet available from the server |
374
273
  | `ATTRIBUTE_NOT_FOUND` | Requested attribute doesn't exist in the mapping |
375
274
  | `VALUE_NOT_FOUND` | Requested value doesn't exist for attribute |
376
275
  | `PARENT_NOT_FOUND` | Parent element for iframe not found |
377
276
  | `INVALID_PARAMETER` | Invalid parameter (e.g. snapshot filename) |
378
277
  | `SNAPSHOT_FAILED` | Server could not capture the snapshot |
379
278
 
380
- ## Real-world example
381
-
382
- ```typescript
383
- const client = new VirtualdisplayClient({
384
- parent: '#product-viewer',
385
- license: 'your-license',
386
- model: 'dining-table',
387
- });
388
-
389
- // Wire up your product option buttons. Selections are buffered until ready.
390
- document.querySelectorAll('.color-option').forEach((button) => {
391
- button.addEventListener('click', () => {
392
- client.select('topMaterial', button.dataset.value);
393
- });
394
- });
395
-
396
- // Keep buttons in sync with 3D state
397
- client.onChange('topMaterial', (selectedValue) => {
398
- document.querySelectorAll('.color-option').forEach((btn) => {
399
- btn.classList.toggle('active', btn.dataset.value === selectedValue.value);
400
- });
401
- });
402
- ```
403
-
404
279
  ## Troubleshooting
405
280
 
406
281
  **Iframe not loading:**