@swan-admin/swan-ai-measurements 1.1.46 → 1.1.47

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swan-admin/swan-ai-measurements",
3
- "version": "1.1.46",
3
+ "version": "1.1.47",
4
4
  "description": "provides ai measurement suggestion",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/esm/index.js",
package/src/constants.ts CHANGED
@@ -65,3 +65,4 @@ export const requiredMetaData: RequiredMetaDataKeys[] = ["gender", "focal_length
65
65
  export const REQUIRED_MESSAGE: string = "Please verify required parameters";
66
66
  export const REQUIRED_MESSAGE_FOR_META_DATA: string = "Please verify required parameters in meta data";
67
67
  export const REQUIRED_ERROR_MESSAGE_INVALID_EMAIL = "Invalid Email";
68
+ export const CHUNK_SIZE = 5 * 1024 * 1024;
package/src/fileUpload.ts CHANGED
@@ -1,12 +1,5 @@
1
1
  import axios from "axios";
2
- import {
3
- REQUIRED_MESSAGE,
4
- REQUIRED_MESSAGE_FOR_META_DATA,
5
- FILE_UPLOAD_ENDPOINT,
6
- APP_AUTH_BASE_URL,
7
- REQUIRED_ERROR_MESSAGE_INVALID_EMAIL,
8
- API_ENDPOINTS,
9
- } from "./constants.js";
2
+ import { REQUIRED_MESSAGE, REQUIRED_MESSAGE_FOR_META_DATA, FILE_UPLOAD_ENDPOINT, APP_AUTH_BASE_URL, REQUIRED_ERROR_MESSAGE_INVALID_EMAIL, API_ENDPOINTS, CHUNK_SIZE } from "./constants.js";
10
3
  import { addScanType, checkMetaDataValue, checkParameters, fetchData, getFileChunks, getUrl, isValidEmail } from "./utils.js";
11
4
  import Uppy from "@uppy/core";
12
5
  import AwsS3Multipart from "@uppy/aws-s3-multipart";
@@ -26,7 +19,7 @@ interface SetDeviceInfo {
26
19
  detection?: string;
27
20
  model?: string;
28
21
  gyro: { alpha?: string; gamma?: string; beta?: string; timestamp?: string }[];
29
- scanId:string
22
+ scanId: string;
30
23
  }
31
24
 
32
25
  interface UploadOptions {
@@ -34,6 +27,7 @@ interface UploadOptions {
34
27
  arrayMetaData: Partial<ObjMetaData>[];
35
28
  scanId: string;
36
29
  email: string;
30
+ callBack?: (a: { eventName: string; message: string }) => void;
37
31
  }
38
32
 
39
33
  export default class FileUpload {
@@ -46,7 +40,7 @@ export default class FileUpload {
46
40
  this.#stagingUrl = stagingUrl;
47
41
  }
48
42
 
49
- async uploadFileFrontend({ file, arrayMetaData, scanId, email }: UploadOptions) {
43
+ async uploadFileFrontend({ file, arrayMetaData, scanId, email, callBack }: UploadOptions) {
50
44
  if (!checkParameters(file, arrayMetaData, scanId, email)) {
51
45
  throw new Error(REQUIRED_MESSAGE);
52
46
  }
@@ -66,8 +60,10 @@ export default class FileUpload {
66
60
  limit: 10,
67
61
  retryDelays: [0, 1000, 3000, 5000],
68
62
  companionUrl: getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl }),
69
- getChunkSize: () => 5 * 1024 * 1024,
63
+ getChunkSize: () => CHUNK_SIZE,
70
64
  createMultipartUpload: (file: any) => {
65
+ const totalChunks = Math.ceil(file.size / CHUNK_SIZE);
66
+ callBack?.({eventName:"uploading_start",message:`File ${file.name} will be divided into ${totalChunks} chunks`})
71
67
  const objectKey = `${scanId}.${file.extension}`;
72
68
  return fetchData({
73
69
  path: FILE_UPLOAD_ENDPOINT.UPLOAD_START,
@@ -80,8 +76,9 @@ export default class FileUpload {
80
76
  },
81
77
  });
82
78
  },
83
- completeMultipartUpload: (file: any, { uploadId, key, parts }: { uploadId: string | number; key: string | number; parts: any }) =>
84
- fetchData({
79
+ completeMultipartUpload: (file: any, { uploadId, key, parts }: { uploadId: string | number; key: string | number; parts: any }) => {
80
+ callBack?.({eventName:"uploading_complete_start",message:`${parts.length} chunks of file, uploaded`})
81
+ return fetchData({
85
82
  path: FILE_UPLOAD_ENDPOINT.UPLOAD_COMPLETE,
86
83
  apiKey: this.#accessKey,
87
84
  stagingUrl: this.#stagingUrl,
@@ -91,7 +88,11 @@ export default class FileUpload {
91
88
  parts,
92
89
  originalFileName: file.name,
93
90
  },
94
- }),
91
+ }).then((response) => {
92
+ callBack?.({eventName:"uploading_complete_end",message:`Multipart upload completed successfully`})
93
+ return response;
94
+ });
95
+ },
95
96
 
96
97
  signPart: (file: any, partData: any) =>
97
98
  fetchData({
@@ -114,7 +115,11 @@ export default class FileUpload {
114
115
  });
115
116
 
116
117
  this.#uppyIns.on("upload-error", (file: any, error: any, response: any) => {
117
- reject(error);
118
+ if (error.isNetworkError) {
119
+ this.#uppyIns.retryUpload(file.id);
120
+ }else{
121
+ reject(error);
122
+ }
118
123
  });
119
124
  this.#uppyIns.on("upload-success", () => {
120
125
  resolve({ message: "file uploaded successfully" });
@@ -185,13 +190,17 @@ export default class FileUpload {
185
190
  }
186
191
  });
187
192
  }
188
- async setDeviceInfo(data:SetDeviceInfo) {
189
- const {scanId,...rest} = data;
193
+ async setDeviceInfo(data: SetDeviceInfo) {
194
+ const { scanId, ...rest } = data;
190
195
  if (checkParameters(scanId) === false) {
191
196
  throw new Error(REQUIRED_MESSAGE);
192
- }
193
- return axios.post(`${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.DEVICE_INFO}/${scanId}`,{device_info:{...rest}} , {
194
- headers: { "X-Api-Key": this.#accessKey },
195
- });
197
+ }
198
+ return axios.post(
199
+ `${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.DEVICE_INFO}/${scanId}`,
200
+ { device_info: { ...rest } },
201
+ {
202
+ headers: { "X-Api-Key": this.#accessKey },
203
+ },
204
+ );
196
205
  }
197
206
  }
@@ -3,15 +3,7 @@ import { API_ENDPOINTS, APP_AUTH_BASE_URL, APP_BASE_WEBSOCKET_URL, REQUIRED_MESS
3
3
  import { checkParameters, getUrl } from "./utils.js";
4
4
 
5
5
 
6
- interface TryOnSocketOptions {
7
- shopDomain: string;
8
- scanId: string;
9
- productName: string;
10
- onError?: (error: any) => void;
11
- onSuccess?: (data: any) => void;
12
- onClose?: () => void;
13
- onOpen?: () => void;
14
- }
6
+
15
7
 
16
8
  interface MeasurementRecommendation {
17
9
  shopDomain: string;
@@ -45,7 +37,6 @@ interface HandleTimeOutOptions {
45
37
  }
46
38
 
47
39
  class Measurement {
48
- #tryOnSocketRef: WebSocket | null = null;
49
40
  #measurementSocketRef: WebSocket | null = null;
50
41
  #timerPollingRef: NodeJS.Timeout | null = null;
51
42
  #timerWaitingRef: NodeJS.Timeout | null = null;
@@ -80,61 +71,7 @@ class Measurement {
80
71
  );
81
72
  }
82
73
 
83
- getTryOnMeasurements({ scanId, shopDomain, productName }: TryOnSocketOptions): Promise<AxiosResponse<any>> {
84
- if (!checkParameters(scanId, shopDomain, productName)) {
85
- throw new Error(REQUIRED_MESSAGE);
86
- }
87
- const tryOnUrl = `${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${
88
- API_ENDPOINTS.TRY_ON_SCAN
89
- }/${scanId}/shop/${shopDomain}/product/${productName}`;
90
- return axios.get(tryOnUrl, { headers: { "X-Api-Key": this.#accessKey } });
91
- }
92
-
93
- handleTryOnSocket(options: TryOnSocketOptions): void {
94
- const { shopDomain, scanId, productName, onError, onSuccess, onClose, onOpen } = options;
95
-
96
- if (!checkParameters(shopDomain, scanId, productName)) {
97
- throw new Error(REQUIRED_MESSAGE);
98
- }
99
-
100
- this.#tryOnSocketRef?.close();
101
- const url = `${getUrl({
102
- urlName: APP_BASE_WEBSOCKET_URL,
103
- stagingUrl: this.#stagingUrl,
104
- })}/develop?store_url=${shopDomain}&product_name=${productName}&scan_id=${scanId}`;
105
- this.#tryOnSocketRef = new WebSocket(url);
106
- if (this.#tryOnSocketRef) {
107
- this.#tryOnSocketRef.onopen = () => {
108
- onOpen?.();
109
- };
110
-
111
- this.#tryOnSocketRef.onmessage = (event) => {
112
- let data;
113
- try {
114
- data = JSON.parse(event.data);
115
- } catch (error) {
116
- console.log(data, error, "noy correct format for data");
117
-
118
- return;
119
- }
120
- if (data?.tryOnProcessStatus === "available") {
121
- onSuccess?.(data);
122
- } else {
123
- onError?.({ message: "failed to get image urls" });
124
- }
125
- };
126
74
 
127
- this.#tryOnSocketRef.onclose = () => {
128
- onClose?.();
129
- };
130
-
131
- this.#tryOnSocketRef.onerror = (event) => {
132
- onError?.(event);
133
- };
134
- }
135
-
136
- }
137
-
138
75
  async #getMeasurementsCheck(options: GetMeasurementsCheckOptions): Promise<void> {
139
76
  const { scanId, onSuccess, onError } = options;
140
77