@virtualdisplay.io/client 4.0.0-alpha.23 → 4.0.0-alpha.25

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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.0-alpha.25
4
+
5
+ ### Minor Changes
6
+
7
+ Add `onSelectableChange(callback)` and `getSelectable(name)` to follow which
8
+ attribute values the buyer can still pick under the current selection. The
9
+ standard sidebar greys out values the selection rules out. Models without
10
+ exclusions behave exactly as before.
11
+
12
+ ## 4.0.0-alpha.24
13
+
14
+ ### Patch Changes
15
+
16
+ Accept `undefined` for the optional `ClientOptions` fields `language`, `debug` and `traceparent`. Projects that enable `exactOptionalPropertyTypes` can now pass a possibly-undefined value straight through without a type error.
17
+
3
18
  ## 4.0.0-alpha.23
4
19
 
5
20
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -21,6 +21,7 @@ declare const MESSAGE_TYPES: {
21
21
  readonly PRICING: "pricing";
22
22
  readonly QR_SHOWN: "qr_shown";
23
23
  readonly SYNC: "sync";
24
+ readonly SELECTABLE: "selectable";
24
25
  };
25
26
  interface MutationDto {
26
27
  readonly name: string;
@@ -144,6 +145,23 @@ interface MappingMessage {
144
145
  readonly type: typeof MESSAGE_TYPES.MAPPING;
145
146
  readonly attributes: AttributeDefinition[];
146
147
  }
148
+ /** Per selector, the values the buyer can still pick right now. */
149
+ interface SelectableAttribute {
150
+ readonly name: string;
151
+ readonly selectable: string[];
152
+ }
153
+ /**
154
+ * Selectability snapshot (server → client): sent after the mapping and after
155
+ * every choice that changes the picture. Always the complete state, never a
156
+ * diff; a value not in its list is not pickable (the client greys it out).
157
+ * The client only renders, it never knows the exclusion rules. Named
158
+ * `selectable`, not availability: that word is taken by pricing
159
+ * (AVAILABILITY, available/view_only).
160
+ */
161
+ interface SelectableMessage {
162
+ readonly type: typeof MESSAGE_TYPES.SELECTABLE;
163
+ readonly attributes: SelectableAttribute[];
164
+ }
147
165
  /**
148
166
  * Loading indicator (server → client): progress percentage, phase label, or error.
149
167
  * Sent during model download and parse so the client loading indicator can update.
@@ -299,7 +317,7 @@ interface PricingMessage {
299
317
  readonly type: typeof MESSAGE_TYPES.PRICING;
300
318
  readonly pricing: PricingDocument$1;
301
319
  }
302
- type Message = HandshakeMessage | SessionMessage | MutationMessage | MutationResultMessage | CameraCommandMessage | CameraPositionMessage | SnapshotRequestMessage | SnapshotResultMessage | MappingMessage | LoadingIndicatorMessage | ArActivateMessage | FullscreenMessage | ConfigMessage | AnnotationToggleMessage | FocusMessage | FocusStateMessage | PricingMessage | QrShownMessage | SyncMessage;
320
+ type Message = HandshakeMessage | SessionMessage | MutationMessage | MutationResultMessage | CameraCommandMessage | CameraPositionMessage | SnapshotRequestMessage | SnapshotResultMessage | MappingMessage | LoadingIndicatorMessage | ArActivateMessage | FullscreenMessage | ConfigMessage | AnnotationToggleMessage | FocusMessage | FocusStateMessage | PricingMessage | QrShownMessage | SyncMessage | SelectableMessage;
303
321
  type MessageCallback = (message: Message) => void | Promise<void>;
304
322
 
305
323
  /**
@@ -311,18 +329,6 @@ interface MessengerOptions {
311
329
  * When false (default), incoming messages are processed immediately.
312
330
  */
313
331
  bufferIncoming?: boolean;
314
- /**
315
- * When buffering, messages where this returns false bypass the buffer
316
- * and are routed to handlers immediately. Used for urgent messages
317
- * like CONFIG that must be handled before the model loads.
318
- */
319
- shouldBuffer?: (message: Message) => boolean;
320
- /**
321
- * Restrict postMessage to a specific origin (e.g. 'https://example.com').
322
- * Defaults to '*' when not set. Set this when the target origin is known
323
- * to prevent messages from being intercepted by unintended recipients.
324
- */
325
- targetOrigin?: string;
326
332
  /**
327
333
  * Which protocol to validate incoming messages against — not whether to validate.
328
334
  * Both sides always reject browser-extension noise and unknown message types. The
@@ -357,11 +363,11 @@ interface MessengerOptions {
357
363
  * messenger.send({ type: 'mutation', mutations, isInitial: true });
358
364
  * ```
359
365
  *
360
- * @example Server (inside iframe — both queues, CONFIG bypasses consumer)
366
+ * @example Server (inside iframe — both queues)
361
367
  * ```ts
362
368
  * const messenger = new IframeMessenger(
363
369
  * () => window.parent !== window ? window.parent : null,
364
- * { bufferIncoming: true, shouldBuffer: (msg) => msg.type !== 'config' },
370
+ * { bufferIncoming: true },
365
371
  * );
366
372
  * messenger.on('mutation', processMutation);
367
373
  * messenger.on('config', applyConfig);
@@ -376,7 +382,6 @@ declare class IframeMessenger {
376
382
  private readonly handlers;
377
383
  private readonly publisher;
378
384
  private readonly consumer;
379
- private readonly shouldBuffer;
380
385
  private listener;
381
386
  private readonly sourceId;
382
387
  private targetOrigin;
@@ -386,10 +391,6 @@ declare class IframeMessenger {
386
391
  * Register a handler for a specific message type
387
392
  */
388
393
  on(type: string, handler: MessageCallback): void;
389
- /**
390
- * Remove a handler for a specific message type
391
- */
392
- off(type: string): void;
393
394
  /**
394
395
  * Update the target origin for outgoing postMessage calls.
395
396
  * Use when the target origin is discovered at runtime (e.g. from the first incoming message).
@@ -403,8 +404,8 @@ declare class IframeMessenger {
403
404
  /**
404
405
  * Feed a message through the same routing path as one that just arrived via
405
406
  * postMessage, without an actual postMessage round-trip: still validated
406
- * against `isValid`, and still respects the consumer queue's buffering and
407
- * the `shouldBuffer` bypass. For a transport that delivers messages some
407
+ * against `isValid`, and still respects the consumer queue's buffering. For
408
+ * a transport that delivers messages some
408
409
  * other way than the iframe channel this messenger already listens on (the
409
410
  * viewer engine's SSE-sourced live sync channel, ar-session-handoff) and
410
411
  * needs them to land exactly where a postMessage would.
@@ -456,6 +457,8 @@ declare class Annotations {
456
457
  setEnabled(enabled: boolean): void;
457
458
  }
458
459
 
460
+ type SelectableSnapshot = readonly SelectableAttribute[];
461
+
459
462
  /**
460
463
  * Camera control API for positioning and zoom
461
464
  * Uses chaining pattern for building commands
@@ -866,17 +869,17 @@ interface ClientOptions {
866
869
  readonly parent: string | HTMLElement;
867
870
  readonly model: string;
868
871
  readonly license: string;
869
- readonly debug?: boolean;
870
- readonly language?: string;
872
+ readonly debug?: boolean | undefined;
873
+ readonly language?: string | undefined;
871
874
  /** W3C traceparent string to propagate to the viewer iframe for end-to-end tracing. */
872
- readonly traceparent?: string;
875
+ readonly traceparent?: string | undefined;
873
876
  /**
874
877
  * A source viewer session id to restore into this mount (ar-session-handoff): the
875
878
  * iframe's metadata fetch merges that session's latest configuration into the
876
879
  * attribute defaults, so the viewer boots straight into it. Internal option, used
877
880
  * by the AR landing, not a customer-facing setting.
878
881
  */
879
- readonly session?: string;
882
+ readonly session?: string | undefined;
880
883
  /**
881
884
  * Override viewer settings from metadata. Omitted fields use the metadata value.
882
885
  * A warning is logged when an override differs from the metadata value.
@@ -966,6 +969,12 @@ interface BaseClientExtensions {
966
969
  * so the host cannot be a single build-time env shared by both.
967
970
  */
968
971
  readonly serverHost?: string;
972
+ /**
973
+ * Extra query parameters for the viewer iframe URL. An extension seam like
974
+ * `serverHost`: a client type's fixed capability flags (the studio client's
975
+ * metadata-override boot mode), never a per-instance public option.
976
+ */
977
+ readonly iframeParams?: Readonly<Record<string, string>>;
969
978
  /**
970
979
  * The AR flow behind the standard interface's AR button. The public client
971
980
  * composes its `ArActivation` here; the studio composes nothing (the editor
@@ -987,6 +996,7 @@ interface BaseClientExtensions {
987
996
  */
988
997
  declare class BaseClient {
989
998
  private readonly attributes;
999
+ private readonly selectableState;
990
1000
  private readonly readyStateTracker;
991
1001
  private readonly messenger;
992
1002
  private readonly cameraApi;
@@ -999,6 +1009,7 @@ declare class BaseClient {
999
1009
  private readonly ui;
1000
1010
  private readonly options;
1001
1011
  private readonly serverHost;
1012
+ private readonly iframeParams;
1002
1013
  /** The composed AR flow, or undefined in builds without one (the studio). */
1003
1014
  private readonly arActivation;
1004
1015
  /** The composed sync tracker, or undefined in builds without one (the studio). */
@@ -1043,6 +1054,16 @@ declare class BaseClient {
1043
1054
  get isReady(): boolean;
1044
1055
  onReady(callback: (client: this) => void): void;
1045
1056
  onMutationFailed(callback: (event: MutationFailedEvent) => void): void;
1057
+ /**
1058
+ * Subscribe to the viewer's selectability snapshots (kiesbaarheid live):
1059
+ * per attribute, which values the buyer can pick right now. Fires with the
1060
+ * current snapshot immediately when one already arrived. A model without
1061
+ * exclusions never sends one: everything stays selectable and this never
1062
+ * fires.
1063
+ */
1064
+ onSelectableChange(callback: (snapshot: SelectableSnapshot) => void): void;
1065
+ /** The selectable values for one attribute right now, or null when unrestricted. */
1066
+ getSelectable(name: string): readonly string[] | null;
1046
1067
  /**
1047
1068
  * Trigger the composed AR flow directly (ar-session-handoff task 035): a host
1048
1069
  * page that hides the built-in corner button (`viewerSettings.ar = false`,