@neurodyn/react-model-viewer 0.1.1 → 0.2.0

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/dist/index.d.ts CHANGED
@@ -3,15 +3,50 @@ import { JSX } from 'react/jsx-runtime';
3
3
  import type { default as React_2 } from 'react';
4
4
  import * as React_3 from 'react';
5
5
 
6
+ /**
7
+ * How long a tap may wait on a host's own AR before the native launch goes
8
+ * ahead instead.
9
+ *
10
+ * Chrome lets a page navigate on behalf of a tap for about five seconds, and
11
+ * the Scene Viewer intent is such a navigation: sent any later, the browser
12
+ * drops it as one nobody asked for. A host that loads its AR on the tap races
13
+ * the load against this, so a slow connection gets Scene Viewer for this tap
14
+ * and the host's AR for the next, the download having gone on meanwhile.
15
+ */
16
+ export declare const AR_TAP_WINDOW_MS = 3000;
17
+
6
18
  /** What the host needs to open its own AR experience for the shown model. */
7
19
  export declare interface ArLaunchTarget {
20
+ /**
21
+ * The API the viewer's widget session was issued by, when the host set one.
22
+ * A host continuing that session has to refresh it there.
23
+ */
24
+ apiBaseUrl?: string;
25
+ /**
26
+ * The public key the viewer runs on — including one a QR handoff code
27
+ * resolved, which the host page never saw.
28
+ */
29
+ apiKey?: string;
8
30
  /** Material collection currently shown, which may differ from the entry url. */
9
31
  hid?: string;
32
+ /** The viewer's UI language, so the host's AR speaks the same one. */
33
+ lang?: 'en' | 'ru';
34
+ /** The object's display name, for the host AR's accessible label. */
35
+ name?: string;
10
36
  tinuuid: string;
37
+ /**
38
+ * A live token of the viewer's widget session, so the host's AR continues
39
+ * that session instead of activating a second one.
40
+ */
41
+ widgetSessionToken?: string;
11
42
  }
12
43
 
13
44
  declare type DialogProps = React_3.ComponentProps<typeof DialogPrimitive.Root>
14
45
 
46
+ export declare function isIOSDevice(): boolean;
47
+
48
+ export declare function isMobileArDevice(): boolean;
49
+
15
50
  /**
16
51
  * Lets the host open its own AR experience instead of the native one.
17
52
  *
@@ -27,9 +62,9 @@ export declare type ModelViewerArExperience = 'advanced' | 'standard';
27
62
 
28
63
  declare type ModelViewerBackground = 'default' | 'transparent';
29
64
 
30
- export declare function ModelViewerDialog({ tinuuid, apiKey, apiBaseUrl, appClipBundleId, initialWidgetSessionToken, handoffUrl, hid, lang, mode, sizeType, dimensionAxes, cameraOrbit, minCameraOrbit, maxCameraOrbit, ...props }: ModelViewerDialogProps): JSX.Element;
65
+ export declare function ModelViewerDialog({ tinuuid, apiKey, apiBaseUrl, appClipBundleId, initialWidgetSessionToken, handoffUrl, hid, lang, launchAr, mode, sizeType, dimensionAxes, cameraOrbit, minCameraOrbit, maxCameraOrbit, ...props }: ModelViewerDialogProps): JSX.Element;
31
66
 
32
- export declare interface ModelViewerDialogProps extends Pick<ModelViewerRootProps, 'apiBaseUrl' | 'apiKey' | 'appClipBundleId' | 'cameraOrbit' | 'dimensionAxes' | 'handoffUrl' | 'hid' | 'initialWidgetSessionToken' | 'lang' | 'maxCameraOrbit' | 'minCameraOrbit' | 'mode' | 'sizeType' | 'tinuuid'>, Omit<DialogProps, 'children' | 'open' | 'defaultOpen' | 'onOpenChange' | 'modal'> {
67
+ export declare interface ModelViewerDialogProps extends Pick<ModelViewerRootProps, 'apiBaseUrl' | 'apiKey' | 'appClipBundleId' | 'cameraOrbit' | 'dimensionAxes' | 'handoffUrl' | 'hid' | 'initialWidgetSessionToken' | 'lang' | 'launchAr' | 'maxCameraOrbit' | 'minCameraOrbit' | 'mode' | 'sizeType' | 'tinuuid'>, Omit<DialogProps, 'children' | 'open' | 'defaultOpen' | 'onOpenChange' | 'modal'> {
33
68
  /** The controlled open state of the dialog. Use with `onOpenChange`. */
34
69
  open?: DialogProps['open'];
35
70
  /** The initial open state when the dialog is uncontrolled. */
@@ -99,4 +134,7 @@ export declare type SizeAxis = 'x' | 'y' | 'z';
99
134
 
100
135
  export declare type SizeType = 'cm' | 'inch';
101
136
 
137
+ /** The value, or `null` once the tap's window has passed; a rejection still rejects. */
138
+ export declare function withinTapWindow<T>(promise: Promise<T>, windowMs?: number): Promise<T | null>;
139
+
102
140
  export { }
package/dist/index.js CHANGED
@@ -6369,12 +6369,18 @@ function shouldRetryViewerQuery(failureCount, error) {
6369
6369
  return failureCount < 2;
6370
6370
  }
6371
6371
  const WIDGET_SESSION_TOKEN_HEADER = 'x-widget-session-token';
6372
+ const APP_TYPE_HEADER = 'x-app-type';
6372
6373
  const DEFAULT_REFRESH_THRESHOLD_MS = 30000;
6373
6374
  const ALLOWED_PRODUCT_TYPES = new Set([
6374
6375
  'core-ar',
6375
6376
  'core-ar-shopify'
6376
6377
  ]);
6377
6378
  const ASSUMED_HANDOFF_SESSION_TTL_SECONDS = 900;
6379
+ function getAppTypeHeaders(appType) {
6380
+ return appType ? {
6381
+ [APP_TYPE_HEADER]: appType
6382
+ } : {};
6383
+ }
6378
6384
  async function activateCoreArWidgetSession(mode, requestConfig) {
6379
6385
  const activation = await publicApiControllerActivateCoreAR({
6380
6386
  mode
@@ -6385,6 +6391,7 @@ async function activateCoreArWidgetSession(mode, requestConfig) {
6385
6391
  class ModelViewerWidgetSession {
6386
6392
  apiBaseUrl;
6387
6393
  apiKey;
6394
+ appTypeHeaders;
6388
6395
  issueWidgetToken;
6389
6396
  mode;
6390
6397
  now;
@@ -6394,6 +6401,7 @@ class ModelViewerWidgetSession {
6394
6401
  constructor(activationData, options){
6395
6402
  this.apiBaseUrl = options.apiBaseUrl;
6396
6403
  this.apiKey = options.apiKey;
6404
+ this.appTypeHeaders = getAppTypeHeaders(options.appType);
6397
6405
  this.issueWidgetToken = options.issueWidgetToken ?? publicApiControllerIssueWidgetToken;
6398
6406
  this.mode = options.mode;
6399
6407
  this.now = options.now ?? Date.now;
@@ -6419,6 +6427,7 @@ class ModelViewerWidgetSession {
6419
6427
  return {
6420
6428
  baseURL: this.apiBaseUrl,
6421
6429
  headers: {
6430
+ ...this.appTypeHeaders,
6422
6431
  [WIDGET_SESSION_TOKEN_HEADER]: await this.getTokenForRequest()
6423
6432
  },
6424
6433
  signal
@@ -6431,6 +6440,7 @@ class ModelViewerWidgetSession {
6431
6440
  this.session = this.toSnapshot(await activateCoreArWidgetSession(this.mode, {
6432
6441
  baseURL: this.apiBaseUrl,
6433
6442
  headers: {
6443
+ ...this.appTypeHeaders,
6434
6444
  'x-api-key': this.apiKey
6435
6445
  },
6436
6446
  signal
@@ -6445,6 +6455,7 @@ class ModelViewerWidgetSession {
6445
6455
  }, {
6446
6456
  baseURL: this.apiBaseUrl,
6447
6457
  headers: {
6458
+ ...this.appTypeHeaders,
6448
6459
  'x-api-key': this.apiKey
6449
6460
  }
6450
6461
  }).then((data)=>this.toSnapshot(parseWidgetSession(data))).then((session)=>{
@@ -6462,7 +6473,7 @@ class ModelViewerWidgetSession {
6462
6473
  };
6463
6474
  }
6464
6475
  }
6465
- async function createModelViewerWidgetSession({ apiBaseUrl, apiKey, initialWidgetSessionToken, mode, signal }) {
6476
+ async function createModelViewerWidgetSession({ apiBaseUrl, apiKey, appType, initialWidgetSessionToken, mode, signal }) {
6466
6477
  if (initialWidgetSessionToken) return new ModelViewerWidgetSession({
6467
6478
  expiresIn: ASSUMED_HANDOFF_SESSION_TTL_SECONDS,
6468
6479
  sid: initialWidgetSessionToken,
@@ -6470,11 +6481,13 @@ async function createModelViewerWidgetSession({ apiBaseUrl, apiKey, initialWidge
6470
6481
  }, {
6471
6482
  apiBaseUrl,
6472
6483
  apiKey,
6484
+ appType,
6473
6485
  mode
6474
6486
  });
6475
6487
  const activationData = await activateCoreArWidgetSession(mode, {
6476
6488
  baseURL: apiBaseUrl,
6477
6489
  headers: {
6490
+ ...getAppTypeHeaders(appType),
6478
6491
  'x-api-key': apiKey
6479
6492
  },
6480
6493
  signal
@@ -6482,6 +6495,7 @@ async function createModelViewerWidgetSession({ apiBaseUrl, apiKey, initialWidge
6482
6495
  return new ModelViewerWidgetSession(activationData, {
6483
6496
  apiBaseUrl,
6484
6497
  apiKey,
6498
+ appType,
6485
6499
  mode
6486
6500
  });
6487
6501
  }
@@ -6537,12 +6551,13 @@ async function issueWidgetHandoffCode(session, params) {
6537
6551
  expiresIn: data.expiresIn
6538
6552
  };
6539
6553
  }
6540
- async function resolveWidgetHandoffCode(apiBaseUrl, code) {
6554
+ async function resolveWidgetHandoffCode(apiBaseUrl, code, appType) {
6541
6555
  try {
6542
6556
  const data = await widgetHandoffControllerResolveHandoff({
6543
6557
  code
6544
6558
  }, {
6545
- baseURL: apiBaseUrl
6559
+ baseURL: apiBaseUrl,
6560
+ headers: getAppTypeHeaders(appType)
6546
6561
  });
6547
6562
  if (!data?.apiKey || !data.token) return null;
6548
6563
  return {
@@ -6597,6 +6612,7 @@ function useObjectData(tinuuid, initialHid, options) {
6597
6612
  {
6598
6613
  apiBaseUrl: options.apiBaseUrl ?? null,
6599
6614
  apiKey: options.apiKey,
6615
+ appType: options.appType ?? null,
6600
6616
  handoffCode: options.handoffCode ?? null,
6601
6617
  initialHid: initialHid ?? null,
6602
6618
  initialWidgetSessionToken: options.initialWidgetSessionToken ?? null,
@@ -6609,12 +6625,13 @@ function useObjectData(tinuuid, initialHid, options) {
6609
6625
  refetchOnMount: 'always',
6610
6626
  queryFn: async ({ signal })=>{
6611
6627
  if (options.handoffCode) {
6612
- const resolved = readHandoffResolution(options.handoffCode) ?? await resolveWidgetHandoffCode(options.apiBaseUrl ?? window.location.origin, options.handoffCode);
6628
+ const resolved = readHandoffResolution(options.handoffCode) ?? await resolveWidgetHandoffCode(options.apiBaseUrl ?? window.location.origin, options.handoffCode, options.appType);
6613
6629
  if (!resolved) throw new WidgetHandoffExpiredError();
6614
6630
  rememberHandoffResolution(options.handoffCode, resolved);
6615
6631
  const widgetSession = await createModelViewerWidgetSession({
6616
6632
  apiBaseUrl: options.apiBaseUrl,
6617
6633
  apiKey: resolved.apiKey,
6634
+ appType: options.appType,
6618
6635
  initialWidgetSessionToken: resolved.token,
6619
6636
  mode: options.mode,
6620
6637
  signal
@@ -6630,6 +6647,7 @@ function useObjectData(tinuuid, initialHid, options) {
6630
6647
  tinuuid
6631
6648
  }, {
6632
6649
  baseURL: options.apiBaseUrl,
6650
+ headers: getAppTypeHeaders(options.appType),
6633
6651
  signal
6634
6652
  });
6635
6653
  return {
@@ -6640,6 +6658,7 @@ function useObjectData(tinuuid, initialHid, options) {
6640
6658
  const widgetSession = await createModelViewerWidgetSession({
6641
6659
  apiBaseUrl: options.apiBaseUrl,
6642
6660
  apiKey: options.apiKey,
6661
+ appType: options.appType,
6643
6662
  initialWidgetSessionToken: options.initialWidgetSessionToken,
6644
6663
  mode: options.mode,
6645
6664
  signal
@@ -6716,6 +6735,7 @@ function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExp
6716
6735
  const { object, material, error, isLoading, setMaterialHid: setObjectMaterialHid, widgetSession } = useObjectData(tinuuid, hid, {
6717
6736
  apiBaseUrl,
6718
6737
  apiKey,
6738
+ appType: 'ru' === lang ? 'arizo' : 'vizbl',
6719
6739
  handoffCode,
6720
6740
  initialWidgetSessionToken,
6721
6741
  mode
@@ -6834,6 +6854,7 @@ function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExp
6834
6854
  widgetSession
6835
6855
  ]);
6836
6856
  const contextValue = external_react_useMemo(()=>({
6857
+ apiBaseUrl,
6837
6858
  apiKey,
6838
6859
  appClipBundleId,
6839
6860
  arExperience,
@@ -6865,6 +6886,7 @@ function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExp
6865
6886
  setModelViewerEl,
6866
6887
  trackEvent
6867
6888
  }), [
6889
+ apiBaseUrl,
6868
6890
  apiKey,
6869
6891
  appClipBundleId,
6870
6892
  arExperience,
@@ -6978,7 +7000,20 @@ async function launchArOverride(launchAr, target) {
6978
7000
  return false;
6979
7001
  }
6980
7002
  }
6981
- function buildModelViewerHandoffUrl({ apiKey, arExperience, baseUrl, hid, mode, tinuuid, widgetSessionToken }) {
7003
+ const AR_TAP_WINDOW_MS = 3000;
7004
+ function withinTapWindow(promise, windowMs = AR_TAP_WINDOW_MS) {
7005
+ return new Promise((resolve, reject)=>{
7006
+ const timer = setTimeout(()=>resolve(null), windowMs);
7007
+ promise.then((value)=>{
7008
+ clearTimeout(timer);
7009
+ resolve(value);
7010
+ }, (error)=>{
7011
+ clearTimeout(timer);
7012
+ reject(error);
7013
+ });
7014
+ });
7015
+ }
7016
+ function buildModelViewerHandoffUrl({ apiKey, arExperience, baseUrl, hid, lang, mode, tinuuid, widgetSessionToken }) {
6982
7017
  if (!baseUrl || !tinuuid) return null;
6983
7018
  let url;
6984
7019
  try {
@@ -6992,6 +7027,7 @@ function buildModelViewerHandoffUrl({ apiKey, arExperience, baseUrl, hid, mode,
6992
7027
  else url.searchParams.delete('ar-experience');
6993
7028
  if (hid) url.searchParams.set('hid', hid);
6994
7029
  else url.searchParams.delete('hid');
7030
+ setLang(url, lang);
6995
7031
  const fragment = new URLSearchParams(url.hash.slice(1));
6996
7032
  if (apiKey) fragment.set('api-key', apiKey);
6997
7033
  else fragment.delete('api-key');
@@ -7000,7 +7036,7 @@ function buildModelViewerHandoffUrl({ apiKey, arExperience, baseUrl, hid, mode,
7000
7036
  url.hash = fragment.toString();
7001
7037
  return url.toString();
7002
7038
  }
7003
- function buildModelViewerHandoffCodeUrl({ arExperience, baseUrl, code, hid, mode, tinuuid }) {
7039
+ function buildModelViewerHandoffCodeUrl({ arExperience, baseUrl, code, hid, lang, mode, tinuuid }) {
7004
7040
  if (!baseUrl || !tinuuid) return null;
7005
7041
  let url;
7006
7042
  try {
@@ -7014,6 +7050,7 @@ function buildModelViewerHandoffCodeUrl({ arExperience, baseUrl, code, hid, mode
7014
7050
  else url.searchParams.delete('ar-experience');
7015
7051
  if (hid) url.searchParams.set('hid', hid);
7016
7052
  else url.searchParams.delete('hid');
7053
+ setLang(url, lang);
7017
7054
  const fragment = new URLSearchParams(url.hash.slice(1));
7018
7055
  if (code) fragment.set('code', code);
7019
7056
  else fragment.delete('code');
@@ -7023,9 +7060,14 @@ function buildModelViewerHandoffCodeUrl({ arExperience, baseUrl, code, hid, mode
7023
7060
  function handoffCodeReissueDelayMs(expiresInSeconds) {
7024
7061
  return Math.round(1000 * expiresInSeconds * 2 / 3);
7025
7062
  }
7063
+ function setLang(url, lang) {
7064
+ if (lang) url.searchParams.set('lang', lang);
7065
+ else url.searchParams.delete('lang');
7066
+ }
7026
7067
  const EVENT_FLUSH_TIMEOUT_MS = 300;
7068
+ const LAUNCH_TOKEN_TIMEOUT_MS = 800;
7027
7069
  const HANDOFF_CODE_RETRY_MS = 15000;
7028
- async function issueHandoffQrCode(widgetSession, { arExperience, baseUrl, hid, mode, tinuuid }) {
7070
+ async function issueHandoffQrCode(widgetSession, { arExperience, baseUrl, hid, lang, mode, tinuuid }) {
7029
7071
  const { code, expiresIn } = await issueWidgetHandoffCode(widgetSession, {
7030
7072
  arExperience,
7031
7073
  hid,
@@ -7036,6 +7078,7 @@ async function issueHandoffQrCode(widgetSession, { arExperience, baseUrl, hid, m
7036
7078
  baseUrl,
7037
7079
  code,
7038
7080
  hid,
7081
+ lang,
7039
7082
  mode,
7040
7083
  tinuuid
7041
7084
  });
@@ -7054,7 +7097,7 @@ async function flushWidgetEvent(eventRequest) {
7054
7097
  });
7055
7098
  }
7056
7099
  function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
7057
- const { apiKey, appClipBundleId, arExperience, containerEl, handoffUrl, isLoading, isModelLoading, lang, launchAr, material, mode, modelViewerEl, object, tinuuid, trackEvent, widgetSession } = useModelViewer();
7100
+ const { apiBaseUrl, apiKey, appClipBundleId, arExperience, containerEl, handoffUrl, isLoading, isModelLoading, lang, launchAr, material, mode, modelViewerEl, object, tinuuid, trackEvent, widgetSession } = useModelViewer();
7058
7101
  const [open, setOpen] = useState(false);
7059
7102
  const [qrState, setQrState] = useState({
7060
7103
  status: 'loading'
@@ -7063,12 +7106,33 @@ function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
7063
7106
  const widgetSessionSid = widgetSession?.sid;
7064
7107
  const isDisabled = isLoading || isModelLoading || null === material;
7065
7108
  const arTarget = external_react_useMemo(()=>({
7109
+ apiBaseUrl,
7110
+ apiKey: widgetSession?.apiKey || apiKey || void 0,
7066
7111
  hid: material?.hid,
7112
+ lang,
7113
+ name: object?.name ?? void 0,
7067
7114
  tinuuid: object?.tinuuid ?? tinuuid
7068
7115
  }), [
7116
+ apiBaseUrl,
7117
+ apiKey,
7118
+ lang,
7069
7119
  material?.hid,
7120
+ object?.name,
7070
7121
  object?.tinuuid,
7071
- tinuuid
7122
+ tinuuid,
7123
+ widgetSession
7124
+ ]);
7125
+ const launchHostAr = useCallback(async ()=>{
7126
+ if (!launchAr) return false;
7127
+ const widgetSessionToken = widgetSession ? await withinTapWindow(widgetSession.getTokenForRequest(), LAUNCH_TOKEN_TIMEOUT_MS).catch(()=>null) ?? widgetSession.token : void 0;
7128
+ return launchArOverride(launchAr, {
7129
+ ...arTarget,
7130
+ widgetSessionToken
7131
+ });
7132
+ }, [
7133
+ arTarget,
7134
+ launchAr,
7135
+ widgetSession
7072
7136
  ]);
7073
7137
  const directArExperience = resolveDirectArExperience(mode, arExperience);
7074
7138
  const directArLaunchOptions = external_react_useMemo(()=>{
@@ -7116,7 +7180,7 @@ function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
7116
7180
  const timer = window.setTimeout(()=>{
7117
7181
  (async ()=>{
7118
7182
  if (autoLaunchKeyRef.current !== launchKey) return;
7119
- if (await launchArOverride(launchAr, arTarget)) return;
7183
+ if (await launchHostAr()) return;
7120
7184
  await flushWidgetEvent(trackEvent('ar_launched'));
7121
7185
  if (autoLaunchKeyRef.current === launchKey) launchDirectAr(directArLaunchOptions);
7122
7186
  })();
@@ -7126,10 +7190,9 @@ function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
7126
7190
  if (autoLaunchKeyRef.current === launchKey) autoLaunchKeyRef.current = null;
7127
7191
  };
7128
7192
  }, [
7129
- arTarget,
7130
7193
  directArLaunchOptions,
7131
7194
  isLoading,
7132
- launchAr,
7195
+ launchHostAr,
7133
7196
  material?.hid,
7134
7197
  mode,
7135
7198
  trackEvent,
@@ -7149,6 +7212,7 @@ function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
7149
7212
  arExperience,
7150
7213
  baseUrl,
7151
7214
  hid: material?.hid,
7215
+ lang,
7152
7216
  mode,
7153
7217
  tinuuid: resolvedTinuuid
7154
7218
  });
@@ -7165,6 +7229,7 @@ function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
7165
7229
  arExperience,
7166
7230
  baseUrl,
7167
7231
  hid: material?.hid,
7232
+ lang,
7168
7233
  mode,
7169
7234
  tinuuid: resolvedTinuuid
7170
7235
  });
@@ -7179,6 +7244,7 @@ function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
7179
7244
  arExperience,
7180
7245
  baseUrl,
7181
7246
  hid: material?.hid,
7247
+ lang,
7182
7248
  mode,
7183
7249
  tinuuid: resolvedTinuuid,
7184
7250
  widgetSessionToken: sessionToken
@@ -7202,6 +7268,7 @@ function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
7202
7268
  arExperience,
7203
7269
  baseUrl: handoffUrl || MODEL_VIEWER_URL,
7204
7270
  hid: material?.hid,
7271
+ lang,
7205
7272
  mode,
7206
7273
  tinuuid: object?.tinuuid ?? tinuuid
7207
7274
  });
@@ -7223,6 +7290,7 @@ function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
7223
7290
  }, [
7224
7291
  arExperience,
7225
7292
  handoffUrl,
7293
+ lang,
7226
7294
  material?.hid,
7227
7295
  mode,
7228
7296
  object?.tinuuid,
@@ -7233,7 +7301,7 @@ function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
7233
7301
  ]);
7234
7302
  const handleClick = async ()=>{
7235
7303
  if (!modelViewerEl || isDisabled) return;
7236
- if (await launchArOverride(launchAr, arTarget)) return void onBeforeActivateAr?.();
7304
+ if (await launchHostAr()) return void onBeforeActivateAr?.();
7237
7305
  if (directArLaunchOptions && isMobileArDevice()) {
7238
7306
  onBeforeActivateAr?.();
7239
7307
  await flushWidgetEvent(trackEvent('ar_launched'));
@@ -8070,7 +8138,7 @@ function ModelViewerRoot({ tinuuid, apiKey, appClipBundleId = 'com.us.vizbl.Clip
8070
8138
  })
8071
8139
  });
8072
8140
  }
8073
- function ModelViewerDialog({ tinuuid, apiKey, apiBaseUrl, appClipBundleId, initialWidgetSessionToken, handoffUrl, hid, lang = 'en', mode = 'ar-viewer', sizeType, dimensionAxes, cameraOrbit, minCameraOrbit, maxCameraOrbit, ...props }) {
8141
+ function ModelViewerDialog({ tinuuid, apiKey, apiBaseUrl, appClipBundleId, initialWidgetSessionToken, handoffUrl, hid, lang = 'en', launchAr, mode = 'ar-viewer', sizeType, dimensionAxes, cameraOrbit, minCameraOrbit, maxCameraOrbit, ...props }) {
8074
8142
  const [container, setContainer] = useState(null);
8075
8143
  return /*#__PURE__*/ jsxs(Fragment, {
8076
8144
  children: [
@@ -8111,6 +8179,7 @@ function ModelViewerDialog({ tinuuid, apiKey, apiBaseUrl, appClipBundleId, initi
8111
8179
  lang: lang,
8112
8180
  handoffUrl: handoffUrl,
8113
8181
  hid: hid,
8182
+ launchAr: launchAr,
8114
8183
  sizeType: sizeType,
8115
8184
  dimensionAxes: dimensionAxes,
8116
8185
  cameraOrbit: cameraOrbit,
@@ -8202,4 +8271,5 @@ function ModelViewer({ tinuuid, apiKey, appClipBundleId, arExperience, hid, apiB
8202
8271
  ]
8203
8272
  });
8204
8273
  }
8205
- export { ModelViewer, ModelViewerDialog };
8274
+ var __webpack_exports__AR_TAP_WINDOW_MS = 3000;
8275
+ export { ModelViewer, ModelViewerDialog, isIOSDevice, isMobileArDevice, withinTapWindow, __webpack_exports__AR_TAP_WINDOW_MS as AR_TAP_WINDOW_MS };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@neurodyn/react-model-viewer",
3
3
  "type": "module",
4
- "version": "0.1.1",
4
+ "version": "0.2.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },