@akinon/pz-virtual-try-on 2.0.34-beta.0 → 2.0.34

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.
@@ -8,12 +8,17 @@ import type {
8
8
  VirtualTryOnJobStatus
9
9
  } from '../types';
10
10
  import {
11
+ useVirtualTryOnSingleMutation,
11
12
  useVirtualTryOnAsyncMutation,
12
13
  useLazyGetVirtualTryOnJobStatusQuery,
13
14
  useSubmitVirtualTryOnFeedbackMutation
14
15
  } from '../data/endpoints';
15
16
  import { VirtualTryOnPoller } from '../utils/polling';
16
- import { hasLegalConsentAccepted, setLegalConsentAccepted } from '../utils';
17
+ import {
18
+ hasLegalConsentAccepted,
19
+ setLegalConsentAccepted,
20
+ parseVirtualTryOnError
21
+ } from '../utils';
17
22
  import { useImageCropper } from './use-image-cropper';
18
23
 
19
24
  const extractCategoryIds = (
@@ -66,6 +71,13 @@ const extractCategoryIds = (
66
71
  return categoryIds;
67
72
  };
68
73
 
74
+ const resolveStartErrorMessage = (err: any, fallback: string): string => {
75
+ if (err?.status === 429 || err?.data?.code === 'TRY_ON_LIMIT_EXCEEDED') {
76
+ return parseVirtualTryOnError(err?.data?.error || err?.data?.message || '');
77
+ }
78
+ return err?.data?.message || err?.message || fallback;
79
+ };
80
+
69
81
  export function useVirtualTryOnAsync(
70
82
  products: BasketProduct | BasketProduct[],
71
83
  categoryMapping: Record<string, number[]> = {}
@@ -85,11 +97,16 @@ export function useVirtualTryOnAsync(
85
97
  const [feedbackStates, setFeedbackStates] = useState<
86
98
  Record<number, 'positive' | 'negative' | null>
87
99
  >({});
100
+ const [limitInfo, setLimitInfo] = useState<{
101
+ tryon_limit?: number;
102
+ used_count?: number;
103
+ } | null>(null);
88
104
  const [isCropLoading, setIsCropLoading] = useState(false);
89
105
  const [abortController, setAbortController] =
90
106
  useState<AbortController | null>(null);
91
107
 
92
108
  const pollerRef = useRef<VirtualTryOnPoller | null>(null);
109
+ const maxAttemptsRef = useRef(productsArray.length > 1 ? 150 : 60);
93
110
 
94
111
  const cropperHook = useImageCropper(
95
112
  setIsCropLoading,
@@ -99,8 +116,11 @@ export function useVirtualTryOnAsync(
99
116
  () => setFileError('')
100
117
  );
101
118
 
102
- const [startAsyncTryOn, { isLoading: isStarting }] =
119
+ const [startSingleTryOn, { isLoading: isStartingSingle }] =
120
+ useVirtualTryOnSingleMutation();
121
+ const [startAsyncTryOn, { isLoading: isStartingMultiple }] =
103
122
  useVirtualTryOnAsyncMutation();
123
+ const isStarting = isStartingSingle || isStartingMultiple;
104
124
  const [getJobStatus] = useLazyGetVirtualTryOnJobStatusQuery();
105
125
  const [submitFeedback] = useSubmitVirtualTryOnFeedbackMutation();
106
126
 
@@ -198,6 +218,7 @@ export function useVirtualTryOnAsync(
198
218
  setResults([]);
199
219
  setPollingAttempts(0);
200
220
  setFeedbackStates({});
221
+ setLimitInfo(null);
201
222
 
202
223
  try {
203
224
  const productsData = productsArray.map((product) => {
@@ -220,14 +241,18 @@ export function useVirtualTryOnAsync(
220
241
  };
221
242
  });
222
243
 
223
- const requestData = {
224
- products: productsData,
225
- reference_image: uploadedImage
226
- };
227
-
228
244
  let response;
229
245
  try {
230
- response = await startAsyncTryOn(requestData).unwrap();
246
+ response =
247
+ productsData.length === 1
248
+ ? await startSingleTryOn({
249
+ ...productsData[0],
250
+ reference_image: uploadedImage
251
+ }).unwrap()
252
+ : await startAsyncTryOn({
253
+ products: productsData,
254
+ reference_image: uploadedImage
255
+ }).unwrap();
231
256
  } catch (apiError: any) {
232
257
  console.error('[useVirtualTryOnAsync] API Error:', apiError);
233
258
  throw apiError;
@@ -239,16 +264,19 @@ export function useVirtualTryOnAsync(
239
264
  return;
240
265
  }
241
266
 
242
- if (!response || !response.reference_url) {
267
+ if (!response || !response.process_id) {
243
268
  throw new Error('Invalid response from server');
244
269
  }
245
270
 
246
- setReferenceUrl(response.reference_url);
271
+ setReferenceUrl(response.process_id);
247
272
  setJobStatus('pending');
248
273
 
274
+ const maxAttempts = productsData.length > 1 ? 150 : 60;
275
+ maxAttemptsRef.current = maxAttempts;
276
+
249
277
  pollerRef.current = new VirtualTryOnPoller({
250
- referenceUrl: response.reference_url,
251
- maxAttempts: 60,
278
+ referenceUrl: response.process_id,
279
+ maxAttempts,
252
280
  interval: 2000,
253
281
  abortSignal: controller.signal,
254
282
  onStatusChange: (status, attempts) => {
@@ -262,8 +290,16 @@ export function useVirtualTryOnAsync(
262
290
 
263
291
  setJobStatus('completed');
264
292
 
293
+ if (result.tryon_limit !== undefined) {
294
+ setLimitInfo({
295
+ tryon_limit: result.tryon_limit,
296
+ used_count: result.used_count
297
+ });
298
+ }
299
+
265
300
  if (
266
- result.result?.job_type === 'multiple' &&
301
+ (result.result?.job_type === 'multiple_try_on' ||
302
+ result.result?.job_type === 'multiple') &&
267
303
  result.result?.multiple?.products
268
304
  ) {
269
305
  const apiProducts = result.result.multiple.products;
@@ -276,6 +312,7 @@ export function useVirtualTryOnAsync(
276
312
  reference: apiResult.reference,
277
313
  generated: apiResult.generated,
278
314
  selected: apiResult.selected,
315
+ used_count: apiResult.used_count,
279
316
  error: apiResult.error || null
280
317
  };
281
318
  }
@@ -326,7 +363,11 @@ export function useVirtualTryOnAsync(
326
363
  },
327
364
  onTimeout: () => {
328
365
  setJobStatus('failed');
329
- setError('Processing timeout after 60 attempts (60 seconds)');
366
+ setError(
367
+ `Processing timeout after ${maxAttempts} attempts (${
368
+ (maxAttempts * 2) / 60
369
+ } minutes)`
370
+ );
330
371
  }
331
372
  });
332
373
 
@@ -346,7 +387,7 @@ export function useVirtualTryOnAsync(
346
387
  }
347
388
 
348
389
  setJobStatus('failed');
349
- setError(err.data?.message || err.message || 'Failed to start try-on');
390
+ setError(resolveStartErrorMessage(err, 'Failed to start try-on'));
350
391
  } finally {
351
392
  setAbortController(null);
352
393
  }
@@ -354,6 +395,7 @@ export function useVirtualTryOnAsync(
354
395
  uploadedImage,
355
396
  productsArray,
356
397
  categoryMapping,
398
+ startSingleTryOn,
357
399
  startAsyncTryOn,
358
400
  getJobStatus,
359
401
  abortController
@@ -407,6 +449,7 @@ export function useVirtualTryOnAsync(
407
449
  setError(null);
408
450
  setFileError('');
409
451
  setFeedbackStates({});
452
+ setLimitInfo(null);
410
453
  setAbortController(null);
411
454
  cropperHook.resetCrop();
412
455
  }, [cropperHook, abortController]);
@@ -480,14 +523,18 @@ export function useVirtualTryOnAsync(
480
523
  };
481
524
  });
482
525
 
483
- const requestData = {
484
- products: productsData,
485
- reference_image: uploadedImage
486
- };
487
-
488
526
  let response;
489
527
  try {
490
- response = await startAsyncTryOn(requestData).unwrap();
528
+ response =
529
+ productsData.length === 1
530
+ ? await startSingleTryOn({
531
+ ...productsData[0],
532
+ reference_image: uploadedImage
533
+ }).unwrap()
534
+ : await startAsyncTryOn({
535
+ products: productsData,
536
+ reference_image: uploadedImage
537
+ }).unwrap();
491
538
  } catch (apiError: any) {
492
539
  console.error('[useVirtualTryOnAsync] Retry API Error:', apiError);
493
540
  throw apiError;
@@ -498,16 +545,19 @@ export function useVirtualTryOnAsync(
498
545
  return;
499
546
  }
500
547
 
501
- if (!response || !response.reference_url) {
548
+ if (!response || !response.process_id) {
502
549
  throw new Error('Invalid response from server');
503
550
  }
504
551
 
505
- setReferenceUrl(response.reference_url);
552
+ setReferenceUrl(response.process_id);
506
553
  setJobStatus('pending');
507
554
 
555
+ const maxAttempts = productsData.length > 1 ? 150 : 60;
556
+ maxAttemptsRef.current = maxAttempts;
557
+
508
558
  pollerRef.current = new VirtualTryOnPoller({
509
- referenceUrl: response.reference_url,
510
- maxAttempts: 60,
559
+ referenceUrl: response.process_id,
560
+ maxAttempts,
511
561
  interval: 2000,
512
562
  abortSignal: controller.signal,
513
563
  onStatusChange: (status, attempts) => {
@@ -521,10 +571,18 @@ export function useVirtualTryOnAsync(
521
571
 
522
572
  setJobStatus('completed');
523
573
 
574
+ if (result.tryon_limit !== undefined) {
575
+ setLimitInfo({
576
+ tryon_limit: result.tryon_limit,
577
+ used_count: result.used_count
578
+ });
579
+ }
580
+
524
581
  let newResults: VirtualTryOnMultipleResult[] = [];
525
582
 
526
583
  if (
527
- result.result?.job_type === 'multiple' &&
584
+ (result.result?.job_type === 'multiple_try_on' ||
585
+ result.result?.job_type === 'multiple') &&
528
586
  result.result?.multiple?.products
529
587
  ) {
530
588
  newResults = result.result.multiple.products.map((item) => ({
@@ -532,6 +590,7 @@ export function useVirtualTryOnAsync(
532
590
  reference: item.reference,
533
591
  generated: item.generated,
534
592
  selected: item.selected,
593
+ used_count: item.used_count,
535
594
  error: item.error || null
536
595
  }));
537
596
  } else {
@@ -589,7 +648,11 @@ export function useVirtualTryOnAsync(
589
648
  },
590
649
  onTimeout: () => {
591
650
  setJobStatus('failed');
592
- setError('Retry processing timeout after 60 attempts (60 seconds)');
651
+ setError(
652
+ `Retry processing timeout after ${maxAttempts} attempts (${
653
+ (maxAttempts * 2) / 60
654
+ } minutes)`
655
+ );
593
656
  }
594
657
  });
595
658
 
@@ -608,7 +671,7 @@ export function useVirtualTryOnAsync(
608
671
  }
609
672
 
610
673
  setJobStatus('failed');
611
- setError(err.data?.message || err.message || 'Failed to retry try-on');
674
+ setError(resolveStartErrorMessage(err, 'Failed to retry try-on'));
612
675
  } finally {
613
676
  setAbortController(null);
614
677
  }
@@ -617,6 +680,7 @@ export function useVirtualTryOnAsync(
617
680
  productsArray,
618
681
  categoryMapping,
619
682
  results,
683
+ startSingleTryOn,
620
684
  startAsyncTryOn,
621
685
  getJobStatus,
622
686
  abortController,
@@ -660,22 +724,18 @@ export function useVirtualTryOnAsync(
660
724
  .join('')
661
725
  );
662
726
 
663
- const productData = {
727
+ const requestData = {
664
728
  sku: product.sku,
665
729
  images: allImages,
666
730
  category_ids: categoryIds,
667
731
  category_paths: categoryPaths,
668
- product_description: product.name
669
- };
670
-
671
- const requestData = {
672
- products: [productData],
732
+ product_description: product.name,
673
733
  reference_image: uploadedImage
674
734
  };
675
735
 
676
736
  let response;
677
737
  try {
678
- response = await startAsyncTryOn(requestData).unwrap();
738
+ response = await startSingleTryOn(requestData).unwrap();
679
739
  } catch (apiError: any) {
680
740
  throw apiError;
681
741
  }
@@ -684,15 +744,17 @@ export function useVirtualTryOnAsync(
684
744
  return;
685
745
  }
686
746
 
687
- if (!response || !response.reference_url) {
747
+ if (!response || !response.process_id) {
688
748
  throw new Error('Invalid response from server');
689
749
  }
690
750
 
691
- setReferenceUrl(response.reference_url);
751
+ setReferenceUrl(response.process_id);
692
752
  setJobStatus('pending');
693
753
 
754
+ maxAttemptsRef.current = 60;
755
+
694
756
  pollerRef.current = new VirtualTryOnPoller({
695
- referenceUrl: response.reference_url,
757
+ referenceUrl: response.process_id,
696
758
  maxAttempts: 60,
697
759
  interval: 2000,
698
760
  abortSignal: controller.signal,
@@ -707,10 +769,18 @@ export function useVirtualTryOnAsync(
707
769
 
708
770
  setJobStatus('completed');
709
771
 
772
+ if (result.tryon_limit !== undefined) {
773
+ setLimitInfo({
774
+ tryon_limit: result.tryon_limit,
775
+ used_count: result.used_count
776
+ });
777
+ }
778
+
710
779
  let newResult: VirtualTryOnMultipleResult | null = null;
711
780
 
712
781
  if (
713
- result.result?.job_type === 'multiple' &&
782
+ (result.result?.job_type === 'multiple_try_on' ||
783
+ result.result?.job_type === 'multiple') &&
714
784
  result.result?.multiple?.products?.[0]
715
785
  ) {
716
786
  const item = result.result.multiple.products[0];
@@ -719,6 +789,7 @@ export function useVirtualTryOnAsync(
719
789
  reference: item.reference,
720
790
  generated: item.generated,
721
791
  selected: item.selected,
792
+ used_count: item.used_count,
722
793
  error: item.error || null
723
794
  };
724
795
  } else {
@@ -760,7 +831,7 @@ export function useVirtualTryOnAsync(
760
831
  },
761
832
  onTimeout: () => {
762
833
  setJobStatus('failed');
763
- setError('Retry processing timeout after 60 attempts (60 seconds)');
834
+ setError('Retry processing timeout after 60 attempts (2 minutes)');
764
835
  }
765
836
  });
766
837
 
@@ -778,7 +849,7 @@ export function useVirtualTryOnAsync(
778
849
  }
779
850
 
780
851
  setJobStatus('failed');
781
- setError(err.data?.message || err.message || 'Failed to retry try-on');
852
+ setError(resolveStartErrorMessage(err, 'Failed to retry try-on'));
782
853
  } finally {
783
854
  setAbortController(null);
784
855
  }
@@ -787,7 +858,7 @@ export function useVirtualTryOnAsync(
787
858
  uploadedImage,
788
859
  productsArray,
789
860
  categoryMapping,
790
- startAsyncTryOn,
861
+ startSingleTryOn,
791
862
  getJobStatus,
792
863
  abortController,
793
864
  submitFeedbackForResult
@@ -813,6 +884,7 @@ export function useVirtualTryOnAsync(
813
884
  fileError,
814
885
  showLegalConsent,
815
886
  feedbackStates,
887
+ limitInfo,
816
888
  currentStep: 'upload' as const,
817
889
  tryOnResult: null,
818
890
  isEnabled: true,
@@ -844,6 +916,6 @@ export function useVirtualTryOnAsync(
844
916
  hasResults: results.length > 0,
845
917
  hasFailedResults,
846
918
  failedResultsCount,
847
- maxAttemptsReached: pollingAttempts >= 60
919
+ maxAttemptsReached: pollingAttempts >= maxAttemptsRef.current
848
920
  };
849
921
  }
@@ -1,7 +1,7 @@
1
1
  import { useState, useCallback, useMemo, useEffect } from 'react';
2
2
  import { Product } from '@akinon/next/types';
3
3
  import {
4
- useVirtualTryOnAsyncMutation,
4
+ useVirtualTryOnSingleMutation,
5
5
  useGetVirtualTryOnLimitedCategoriesQuery,
6
6
  useSubmitVirtualTryOnFeedbackMutation,
7
7
  useLazyGetVirtualTryOnJobStatusQuery
@@ -16,7 +16,8 @@ import {
16
16
  VirtualTryOnCache,
17
17
  compressImageToUnder1MB,
18
18
  convertWebPToJPEG,
19
- validateImageAspectRatio
19
+ validateImageAspectRatio,
20
+ parseVirtualTryOnError
20
21
  } from '../utils';
21
22
  import { useImageCropper } from './use-image-cropper';
22
23
  import type { VirtualTryOnResponse } from '../types';
@@ -94,6 +95,10 @@ export function useVirtualTryOn(product: Product) {
94
95
  >(null);
95
96
  const [abortController, setAbortController] =
96
97
  useState<AbortController | null>(null);
98
+ const [limitInfo, setLimitInfo] = useState<{
99
+ tryon_limit?: number;
100
+ used_count?: number;
101
+ } | null>(null);
97
102
 
98
103
  const localStorageEnabled = getVirtualTryOnEnabled();
99
104
  const [cachedLimitedCategories, setCachedLimitedCategories] = useState<{
@@ -101,7 +106,7 @@ export function useVirtualTryOn(product: Product) {
101
106
  } | null>(() => VirtualTryOnCache.retrieveLimitedCategories());
102
107
 
103
108
  const [processVirtualTryOn, { isLoading: isProcessing }] =
104
- useVirtualTryOnAsyncMutation();
109
+ useVirtualTryOnSingleMutation();
105
110
  const [submitFeedback] = useSubmitVirtualTryOnFeedbackMutation();
106
111
  const { data: limitedCategoriesData, isLoading: isLimitedCategoriesLoading } =
107
112
  useGetVirtualTryOnLimitedCategoriesQuery(undefined, {
@@ -217,6 +222,7 @@ export function useVirtualTryOn(product: Product) {
217
222
  setCurrentStep('processing');
218
223
  setFileError('');
219
224
  setError('');
225
+ setLimitInfo(null);
220
226
 
221
227
  try {
222
228
  const sku = product.sku || product.pk.toString();
@@ -252,16 +258,12 @@ export function useVirtualTryOn(product: Product) {
252
258
  }
253
259
  }
254
260
 
255
- const productData = {
261
+ const requestData = {
256
262
  sku,
257
263
  images: productImages,
258
264
  category_ids: categoryIds,
259
265
  category_paths: categoryPaths,
260
- product_description: product.name || ''
261
- };
262
-
263
- const requestData = {
264
- products: [productData],
266
+ product_description: product.name || '',
265
267
  reference_image: uploadedImage
266
268
  };
267
269
 
@@ -273,11 +275,11 @@ export function useVirtualTryOn(product: Product) {
273
275
  throw apiError;
274
276
  }
275
277
 
276
- if (!asyncResponse || !asyncResponse.reference_url) {
278
+ if (!asyncResponse || !asyncResponse.process_id) {
277
279
  throw new Error('Invalid response from server');
278
280
  }
279
281
 
280
- const pollForResult = async (referenceUrl: string, maxAttempts = 60) => {
282
+ const pollForResult = async (processId: string, maxAttempts = 60) => {
281
283
  let rateLimitRetries = 0;
282
284
  const maxRateLimitRetries = 3;
283
285
 
@@ -300,8 +302,8 @@ export function useVirtualTryOn(product: Product) {
300
302
 
301
303
  try {
302
304
  const response = await fetch(
303
- `/api/virtual-try-on?endpoint=job-status&reference_url=${encodeURIComponent(
304
- referenceUrl
305
+ `/api/virtual-try-on?endpoint=job-status&process_id=${encodeURIComponent(
306
+ processId
305
307
  )}`,
306
308
  {
307
309
  method: 'GET',
@@ -332,25 +334,35 @@ export function useVirtualTryOn(product: Product) {
332
334
  const data = await response.json();
333
335
 
334
336
  if (data.status === 'completed') {
335
- let generated, selected;
337
+ let generated, selected, reference;
336
338
 
337
339
  if (
338
- data.result?.job_type === 'multiple' &&
340
+ (data.result?.job_type === 'multiple_try_on' ||
341
+ data.result?.job_type === 'multiple') &&
339
342
  data.result?.multiple?.products?.[0]
340
343
  ) {
341
344
  generated = data.result.multiple.products[0].generated;
342
345
  selected = data.result.multiple.products[0].selected || [];
346
+ reference = data.result.multiple.products[0].reference;
343
347
  } else if (data.result?.single) {
344
348
  generated = data.result.single.generated;
345
349
  selected = data.result.single.selected || [];
350
+ reference = data.result.single.reference;
346
351
  } else {
347
352
  generated = data.generated;
348
353
  selected = data.selected || [];
349
354
  }
350
355
 
356
+ if (data.tryon_limit !== undefined) {
357
+ setLimitInfo({
358
+ tryon_limit: data.tryon_limit,
359
+ used_count: data.used_count
360
+ });
361
+ }
362
+
351
363
  if (generated) {
352
364
  setTryOnResult({
353
- reference: referenceUrl,
365
+ reference: reference || processId,
354
366
  generated: generated,
355
367
  selected: selected,
356
368
  status: 'success'
@@ -361,8 +373,13 @@ export function useVirtualTryOn(product: Product) {
361
373
  throw new Error('No generated image in completed response');
362
374
  }
363
375
  } else if (data.status === 'failed') {
376
+ const rawError = data.error || data.result?.error;
364
377
  const errorMsg =
365
- data.error || data.result?.error || 'Processing failed';
378
+ typeof rawError === 'string'
379
+ ? parseVirtualTryOnError(rawError)
380
+ : rawError?.detail || rawError?.message
381
+ ? parseVirtualTryOnError(rawError.detail || rawError.message)
382
+ : 'Processing failed';
366
383
  setError(errorMsg);
367
384
  setCurrentStep('processing');
368
385
  cropperHook.closeCrop();
@@ -373,10 +390,10 @@ export function useVirtualTryOn(product: Product) {
373
390
  throw pollError;
374
391
  }
375
392
  }
376
- throw new Error('Processing timeout after 60 attempts');
393
+ throw new Error('Processing timeout after 60 attempts (2 minutes)');
377
394
  };
378
395
 
379
- await pollForResult(asyncResponse.reference_url);
396
+ await pollForResult(asyncResponse.process_id);
380
397
  } catch (error: any) {
381
398
  if (
382
399
  error?.name === 'AbortError' ||
@@ -387,16 +404,18 @@ export function useVirtualTryOn(product: Product) {
387
404
  return;
388
405
  }
389
406
 
390
- setFileError(
391
- error?.data?.message ||
392
- error?.message ||
393
- 'Virtual try-on processing failed'
394
- );
395
- setError(
396
- error?.data?.message ||
407
+ const isLimitExceeded =
408
+ error?.status === 429 || error?.data?.code === 'TRY_ON_LIMIT_EXCEEDED';
409
+ const errorMessage = isLimitExceeded
410
+ ? parseVirtualTryOnError(
411
+ error?.data?.error || error?.data?.message || ''
412
+ )
413
+ : error?.data?.message ||
397
414
  error?.message ||
398
- 'Virtual try-on processing failed'
399
- );
415
+ 'Virtual try-on processing failed';
416
+
417
+ setFileError(errorMessage);
418
+ setError(errorMessage);
400
419
  setCurrentStep('processing');
401
420
  cropperHook.closeCrop();
402
421
  } finally {
@@ -439,6 +458,7 @@ export function useVirtualTryOn(product: Product) {
439
458
  setError('');
440
459
  setCurrentStep('upload');
441
460
  setSelectedFeedback(null);
461
+ setLimitInfo(null);
442
462
  cropperHook.resetCrop();
443
463
  }, [cropperHook]);
444
464
 
@@ -490,6 +510,7 @@ export function useVirtualTryOn(product: Product) {
490
510
  isEnabled,
491
511
  isLimitedCategoriesLoading,
492
512
  selectedFeedback,
513
+ limitInfo,
493
514
  handleFileUpload,
494
515
  processTryOn,
495
516
  acceptLegalConsent,
package/src/index.ts CHANGED
@@ -23,9 +23,12 @@ export { useBarcodeSearch } from './hooks/use-barcode-search';
23
23
  export { useVirtualTryOnAsync } from './hooks/use-virtual-try-on-async';
24
24
 
25
25
  export {
26
+ useVirtualTryOnSingleMutation,
26
27
  useVirtualTryOnAsyncMutation,
27
28
  useGetVirtualTryOnJobStatusQuery,
28
29
  useLazyGetVirtualTryOnJobStatusQuery,
30
+ useGetTryOnUsageMutation,
31
+ useSubmitTryOnEventMutation,
29
32
  useGetVirtualTryOnLimitedCategoriesQuery,
30
33
  useSubmitVirtualTryOnFeedbackMutation
31
34
  } from './data/endpoints';
@@ -48,6 +51,8 @@ export type {
48
51
  VirtualTryOnJobStatusResponse,
49
52
  VirtualTryOnMultipleResult,
50
53
  VirtualTryOnCompatibilityError,
54
+ TryOnUsageResponse,
55
+ TryOnEventResponse,
51
56
  BasketProduct,
52
57
  VirtualTryOnMultipleModalProps,
53
58
  BarcodeFormat,