@swan-admin/swan-ai-measurements 1.1.71 → 1.1.73

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/esm/tryOn.js CHANGED
@@ -18,74 +18,84 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
18
18
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
19
19
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
20
20
  };
21
- var _TryOn_instances, _TryOn_tryOnSocketRef, _TryOn_timerWaitingRef, _TryOn_accessKey, _TryOn_stagingUrl, _TryOn_getSignedUrl, _TryOn_s3Upload, _TryOn_disconnectSocket, _TryOn_handleTimeOut, _TryOn_handleGetTryOnResult;
21
+ var _TryOn_instances, _TryOn_socketMap, _TryOn_timerMap, _TryOn_accessKey, _TryOn_stagingUrl, _TryOn_getSignedUrl, _TryOn_s3Upload, _TryOn_disconnectSocket, _TryOn_handleTimeOut, _TryOn_handleGetTryOnResult;
22
22
  import axios from "axios";
23
23
  import { API_ENDPOINTS, APP_AUTH_BASE_URL, APP_BASE_WEBSOCKET_URL, REQUIRED_ERROR_MESSAGE_INVALID_EMAIL, REQUIRED_MESSAGE } from "./constants.js";
24
24
  import { checkParameters, getUrl, isValidEmail } from "./utils.js";
25
25
  class TryOn {
26
26
  constructor(accessKey, stagingUrl = false) {
27
27
  _TryOn_instances.add(this);
28
- _TryOn_tryOnSocketRef.set(this, null);
29
- _TryOn_timerWaitingRef.set(this, null);
28
+ _TryOn_socketMap.set(this, new Map());
29
+ _TryOn_timerMap.set(this, new Map());
30
30
  _TryOn_accessKey.set(this, void 0);
31
31
  _TryOn_stagingUrl.set(this, void 0);
32
- _TryOn_disconnectSocket.set(this, () => {
33
- var _a;
34
- (_a = __classPrivateFieldGet(this, _TryOn_tryOnSocketRef, "f")) === null || _a === void 0 ? void 0 : _a.close();
35
- if (__classPrivateFieldGet(this, _TryOn_timerWaitingRef, "f")) {
36
- clearTimeout(__classPrivateFieldGet(this, _TryOn_timerWaitingRef, "f"));
32
+ _TryOn_disconnectSocket.set(this, (tryonId) => {
33
+ if (tryonId) {
34
+ const socket = __classPrivateFieldGet(this, _TryOn_socketMap, "f").get(tryonId);
35
+ const timer = __classPrivateFieldGet(this, _TryOn_timerMap, "f").get(tryonId);
36
+ socket === null || socket === void 0 ? void 0 : socket.close();
37
+ if (timer)
38
+ clearTimeout(timer);
39
+ __classPrivateFieldGet(this, _TryOn_socketMap, "f").delete(tryonId);
40
+ __classPrivateFieldGet(this, _TryOn_timerMap, "f").delete(tryonId);
41
+ }
42
+ else {
43
+ // Disconnect all
44
+ __classPrivateFieldGet(this, _TryOn_socketMap, "f").forEach((socket) => socket.close());
45
+ __classPrivateFieldGet(this, _TryOn_timerMap, "f").forEach((timer) => clearTimeout(timer));
46
+ __classPrivateFieldGet(this, _TryOn_socketMap, "f").clear();
47
+ __classPrivateFieldGet(this, _TryOn_timerMap, "f").clear();
37
48
  }
38
49
  });
39
50
  _TryOn_handleTimeOut.set(this, ({ onSuccess, onError, tryonId }) => {
40
- __classPrivateFieldSet(this, _TryOn_timerWaitingRef, setTimeout(() => {
51
+ const timer = setTimeout(() => {
41
52
  __classPrivateFieldGet(this, _TryOn_handleGetTryOnResult, "f").call(this, { onSuccess, onError, tryonId });
42
- __classPrivateFieldGet(this, _TryOn_disconnectSocket, "f").call(this);
43
- }, 150000), "f");
53
+ __classPrivateFieldGet(this, _TryOn_disconnectSocket, "f").call(this, tryonId);
54
+ }, 300000);
55
+ __classPrivateFieldGet(this, _TryOn_timerMap, "f").set(tryonId, timer);
44
56
  });
45
57
  this.handleTryOnWebSocket = ({ tryonId, onError, onSuccess, onClose, onOpen }) => {
46
58
  if (checkParameters(tryonId) === false) {
47
59
  throw new Error(REQUIRED_MESSAGE);
48
60
  }
49
- __classPrivateFieldGet(this, _TryOn_disconnectSocket, "f").call(this);
61
+ __classPrivateFieldGet(this, _TryOn_disconnectSocket, "f").call(this, tryonId);
50
62
  const url = `${getUrl({ urlName: APP_BASE_WEBSOCKET_URL, stagingUrl: __classPrivateFieldGet(this, _TryOn_stagingUrl, "f") })}${API_ENDPOINTS.TRY_ON}?tryonId=${tryonId}`;
51
- __classPrivateFieldSet(this, _TryOn_tryOnSocketRef, new WebSocket(url), "f");
52
- if (__classPrivateFieldGet(this, _TryOn_tryOnSocketRef, "f")) {
53
- __classPrivateFieldGet(this, _TryOn_tryOnSocketRef, "f").onopen = () => __awaiter(this, void 0, void 0, function* () {
54
- onOpen === null || onOpen === void 0 ? void 0 : onOpen();
55
- __classPrivateFieldGet(this, _TryOn_handleTimeOut, "f").call(this, { onSuccess, onError, tryonId });
56
- });
57
- __classPrivateFieldGet(this, _TryOn_tryOnSocketRef, "f").onmessage = (event) => {
58
- let data;
59
- try {
60
- data = JSON.parse(event.data);
61
- }
62
- catch (error) {
63
- console.log(data, error, "not correct format for data");
64
- return;
65
- }
66
- if ((data === null || data === void 0 ? void 0 : data.status) === "success") {
67
- onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(data);
68
- }
69
- else {
70
- onError === null || onError === void 0 ? void 0 : onError(data);
71
- }
72
- if (__classPrivateFieldGet(this, _TryOn_timerWaitingRef, "f")) {
73
- clearTimeout(__classPrivateFieldGet(this, _TryOn_timerWaitingRef, "f"));
74
- }
75
- };
76
- __classPrivateFieldGet(this, _TryOn_tryOnSocketRef, "f").onclose = () => {
77
- onClose === null || onClose === void 0 ? void 0 : onClose();
78
- };
79
- __classPrivateFieldGet(this, _TryOn_tryOnSocketRef, "f").onerror = (event) => {
80
- onError === null || onError === void 0 ? void 0 : onError(event);
81
- if (__classPrivateFieldGet(this, _TryOn_timerWaitingRef, "f")) {
82
- clearTimeout(__classPrivateFieldGet(this, _TryOn_timerWaitingRef, "f"));
83
- }
84
- };
85
- }
86
- else {
87
- console.log("no connection made for websocket");
88
- }
63
+ const socket = new WebSocket(url);
64
+ __classPrivateFieldGet(this, _TryOn_socketMap, "f").set(tryonId, socket);
65
+ socket.onopen = () => {
66
+ onOpen === null || onOpen === void 0 ? void 0 : onOpen();
67
+ __classPrivateFieldGet(this, _TryOn_handleTimeOut, "f").call(this, { onSuccess, onError, tryonId });
68
+ };
69
+ socket.onmessage = (event) => {
70
+ let data;
71
+ try {
72
+ data = JSON.parse(event.data);
73
+ }
74
+ catch (error) {
75
+ console.log("Invalid JSON:", event.data);
76
+ return;
77
+ }
78
+ if ((data === null || data === void 0 ? void 0 : data.status) === "success") {
79
+ onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(data);
80
+ }
81
+ else {
82
+ onError === null || onError === void 0 ? void 0 : onError(data);
83
+ }
84
+ const timer = __classPrivateFieldGet(this, _TryOn_timerMap, "f").get(tryonId);
85
+ if (timer)
86
+ clearTimeout(timer);
87
+ __classPrivateFieldGet(this, _TryOn_timerMap, "f").delete(tryonId);
88
+ };
89
+ socket.onclose = () => {
90
+ onClose === null || onClose === void 0 ? void 0 : onClose();
91
+ // this.#disconnectSocket(tryonId);
92
+ };
93
+ socket.onerror = (event) => {
94
+ onError === null || onError === void 0 ? void 0 : onError(event);
95
+ // const timer = this.#timerMap.get(tryonId);
96
+ // if (timer) clearTimeout(timer);
97
+ // this.#timerMap.delete(tryonId);
98
+ };
89
99
  };
90
100
  _TryOn_handleGetTryOnResult.set(this, (_a) => __awaiter(this, [_a], void 0, function* ({ onSuccess, onError, tryonId }) {
91
101
  try {
@@ -201,7 +211,7 @@ class TryOn {
201
211
  });
202
212
  }
203
213
  }
204
- _TryOn_tryOnSocketRef = new WeakMap(), _TryOn_timerWaitingRef = new WeakMap(), _TryOn_accessKey = new WeakMap(), _TryOn_stagingUrl = new WeakMap(), _TryOn_disconnectSocket = new WeakMap(), _TryOn_handleTimeOut = new WeakMap(), _TryOn_handleGetTryOnResult = new WeakMap(), _TryOn_instances = new WeakSet(), _TryOn_getSignedUrl = function _TryOn_getSignedUrl(payload) {
214
+ _TryOn_socketMap = new WeakMap(), _TryOn_timerMap = new WeakMap(), _TryOn_accessKey = new WeakMap(), _TryOn_stagingUrl = new WeakMap(), _TryOn_disconnectSocket = new WeakMap(), _TryOn_handleTimeOut = new WeakMap(), _TryOn_handleGetTryOnResult = new WeakMap(), _TryOn_instances = new WeakSet(), _TryOn_getSignedUrl = function _TryOn_getSignedUrl(payload) {
205
215
  if (checkParameters(payload) === false) {
206
216
  throw new Error(REQUIRED_MESSAGE);
207
217
  }
package/dist/tryOn.js CHANGED
@@ -7,8 +7,8 @@ const axios_1 = __importDefault(require("axios"));
7
7
  const constants_js_1 = require("./constants.js");
8
8
  const utils_js_1 = require("./utils.js");
9
9
  class TryOn {
10
- #tryOnSocketRef = null;
11
- #timerWaitingRef = null;
10
+ #socketMap = new Map();
11
+ #timerMap = new Map();
12
12
  #accessKey;
13
13
  #stagingUrl;
14
14
  constructor(accessKey, stagingUrl = false) {
@@ -97,62 +97,73 @@ class TryOn {
97
97
  data: payload,
98
98
  });
99
99
  }
100
- #disconnectSocket = () => {
101
- this.#tryOnSocketRef?.close();
102
- if (this.#timerWaitingRef) {
103
- clearTimeout(this.#timerWaitingRef);
100
+ #disconnectSocket = (tryonId) => {
101
+ if (tryonId) {
102
+ const socket = this.#socketMap.get(tryonId);
103
+ const timer = this.#timerMap.get(tryonId);
104
+ socket?.close();
105
+ if (timer)
106
+ clearTimeout(timer);
107
+ this.#socketMap.delete(tryonId);
108
+ this.#timerMap.delete(tryonId);
109
+ }
110
+ else {
111
+ // Disconnect all
112
+ this.#socketMap.forEach((socket) => socket.close());
113
+ this.#timerMap.forEach((timer) => clearTimeout(timer));
114
+ this.#socketMap.clear();
115
+ this.#timerMap.clear();
104
116
  }
105
117
  };
106
118
  #handleTimeOut = ({ onSuccess, onError, tryonId }) => {
107
- this.#timerWaitingRef = setTimeout(() => {
119
+ const timer = setTimeout(() => {
108
120
  this.#handleGetTryOnResult({ onSuccess, onError, tryonId });
109
- this.#disconnectSocket();
110
- }, 150000);
121
+ this.#disconnectSocket(tryonId);
122
+ }, 300000);
123
+ this.#timerMap.set(tryonId, timer);
111
124
  };
112
125
  handleTryOnWebSocket = ({ tryonId, onError, onSuccess, onClose, onOpen }) => {
113
126
  if ((0, utils_js_1.checkParameters)(tryonId) === false) {
114
127
  throw new Error(constants_js_1.REQUIRED_MESSAGE);
115
128
  }
116
- this.#disconnectSocket();
129
+ this.#disconnectSocket(tryonId);
117
130
  const url = `${(0, utils_js_1.getUrl)({ urlName: constants_js_1.APP_BASE_WEBSOCKET_URL, stagingUrl: this.#stagingUrl })}${constants_js_1.API_ENDPOINTS.TRY_ON}?tryonId=${tryonId}`;
118
- this.#tryOnSocketRef = new WebSocket(url);
119
- if (this.#tryOnSocketRef) {
120
- this.#tryOnSocketRef.onopen = async () => {
121
- onOpen?.();
122
- this.#handleTimeOut({ onSuccess, onError, tryonId });
123
- };
124
- this.#tryOnSocketRef.onmessage = (event) => {
125
- let data;
126
- try {
127
- data = JSON.parse(event.data);
128
- }
129
- catch (error) {
130
- console.log(data, error, "not correct format for data");
131
- return;
132
- }
133
- if (data?.status === "success") {
134
- onSuccess?.(data);
135
- }
136
- else {
137
- onError?.(data);
138
- }
139
- if (this.#timerWaitingRef) {
140
- clearTimeout(this.#timerWaitingRef);
141
- }
142
- };
143
- this.#tryOnSocketRef.onclose = () => {
144
- onClose?.();
145
- };
146
- this.#tryOnSocketRef.onerror = (event) => {
147
- onError?.(event);
148
- if (this.#timerWaitingRef) {
149
- clearTimeout(this.#timerWaitingRef);
150
- }
151
- };
152
- }
153
- else {
154
- console.log("no connection made for websocket");
155
- }
131
+ const socket = new WebSocket(url);
132
+ this.#socketMap.set(tryonId, socket);
133
+ socket.onopen = () => {
134
+ onOpen?.();
135
+ this.#handleTimeOut({ onSuccess, onError, tryonId });
136
+ };
137
+ socket.onmessage = (event) => {
138
+ let data;
139
+ try {
140
+ data = JSON.parse(event.data);
141
+ }
142
+ catch (error) {
143
+ console.log("Invalid JSON:", event.data);
144
+ return;
145
+ }
146
+ if (data?.status === "success") {
147
+ onSuccess?.(data);
148
+ }
149
+ else {
150
+ onError?.(data);
151
+ }
152
+ const timer = this.#timerMap.get(tryonId);
153
+ if (timer)
154
+ clearTimeout(timer);
155
+ this.#timerMap.delete(tryonId);
156
+ };
157
+ socket.onclose = () => {
158
+ onClose?.();
159
+ // this.#disconnectSocket(tryonId);
160
+ };
161
+ socket.onerror = (event) => {
162
+ onError?.(event);
163
+ // const timer = this.#timerMap.get(tryonId);
164
+ // if (timer) clearTimeout(timer);
165
+ // this.#timerMap.delete(tryonId);
166
+ };
156
167
  };
157
168
  handleTryOnSubmit({ shopDomain, products, selectedUserImages, requestSource, callbackUrl, openTryonId, selectedProductImageUrl, token }) {
158
169
  if ((0, utils_js_1.checkParameters)(shopDomain, products, token) === false) {
@@ -165,7 +176,7 @@ class TryOn {
165
176
  ...(requestSource !== undefined && requestSource !== null && { requestSource }),
166
177
  ...(callbackUrl !== undefined && callbackUrl !== null && { callbackUrl }),
167
178
  ...(openTryonId !== undefined && openTryonId !== null && { openTryonId }),
168
- ...(selectedProductImageUrl !== undefined && selectedProductImageUrl !== null && { selectedProductImageUrl })
179
+ ...(selectedProductImageUrl !== undefined && selectedProductImageUrl !== null && { selectedProductImageUrl }),
169
180
  };
170
181
  const url = `${(0, utils_js_1.getUrl)({ urlName: constants_js_1.APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${constants_js_1.API_ENDPOINTS.TRY_ON}`;
171
182
  const headers = { "X-Api-Key": this.#accessKey };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swan-admin/swan-ai-measurements",
3
- "version": "1.1.71",
3
+ "version": "1.1.73",
4
4
  "description": "provides ai measurement suggestion",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/esm/index.js",
package/src/tryOn.ts CHANGED
@@ -2,68 +2,70 @@ import axios, { AxiosResponse } from "axios";
2
2
  import { API_ENDPOINTS, APP_AUTH_BASE_URL, APP_BASE_WEBSOCKET_URL, REQUIRED_ERROR_MESSAGE_INVALID_EMAIL, REQUIRED_MESSAGE } from "./constants.js";
3
3
  import { checkParameters, getUrl, isValidEmail } from "./utils.js";
4
4
 
5
-
6
-
7
-
8
5
  interface UploadFileParams {
9
- files: File[];
10
- userEmail: string;
11
- fileNoLimit?:number
6
+ files: File[];
7
+ userEmail: string;
8
+ fileNoLimit?: number;
12
9
  }
13
10
 
14
11
  interface DeleteImageParams {
15
- userEmail: string;
16
- fileName: string;
17
-
12
+ userEmail: string;
13
+ fileName: string;
14
+ }
15
+ interface EligibiltyImageParams {
16
+ storeUrl: string;
17
+ productHandle: string;
18
+ imageURL: string;
19
+ productDescription: string;
18
20
  }
19
- interface EligibiltyImageParams {storeUrl:string,productHandle:string,imageURL:string,productDescription:string}
20
21
  interface HandleTryOnWebSocketParams {
21
- tryonId:string;
22
- onError?: (error: any) => void;
23
- onSuccess?: (data: any) => void;
24
- onClose?: () => void;
25
- onOpen?: () => void;
22
+ tryonId: string;
23
+ onError?: (error: any) => void;
24
+ onSuccess?: (data: any) => void;
25
+ onClose?: () => void;
26
+ onOpen?: () => void;
27
+ }
28
+ interface Products {
29
+ productUrl: string;
30
+ productHandle: string;
31
+ openTryonId?: string;
32
+ selectedProductImageUrl?: string;
26
33
  }
27
- interface Products
28
- {
29
- productUrl:string,
30
- productHandle: string,
31
- openTryonId?: string,
32
- selectedProductImageUrl?:string
33
- }
34
34
 
35
35
  interface HandleForLatestImageParams {
36
36
  shopDomain: string;
37
- products:Products[];
38
- selectedUserImages?:string[];
37
+ products: Products[];
38
+ selectedUserImages?: string[];
39
39
  requestSource?: string;
40
40
  callbackUrl?: string;
41
- openTryonId?:string;
42
- selectedProductImageUrl?:string;
43
- token: string;
41
+ openTryonId?: string;
42
+ selectedProductImageUrl?: string;
43
+ token: string;
44
44
  }
45
45
 
46
46
  interface HandleTimeOutParams {
47
- onSuccess?: (data: any) => void;
48
- onError?: (error: any) => void;
49
- tryonId:string
47
+ onSuccess?: (data: any) => void;
48
+ onError?: (error: any) => void;
49
+ tryonId: string;
50
50
  }
51
51
 
52
52
  interface GetTryOnResultParams {
53
- tryonId :string
53
+ tryonId: string;
54
54
  }
55
55
 
56
56
  class TryOn {
57
- #tryOnSocketRef: WebSocket | null = null;
58
- #timerWaitingRef: ReturnType<typeof setTimeout> | null = null;
59
- #accessKey: string;
60
- #stagingUrl: boolean;
61
- constructor(accessKey: string, stagingUrl = false) {
62
- this.#accessKey = accessKey;
63
- this.#stagingUrl = stagingUrl;
64
- }
57
+ #socketMap: Map<string, WebSocket> = new Map();
58
+ #timerMap: Map<string, ReturnType<typeof setTimeout>> = new Map();
59
+
60
+
61
+ #accessKey: string;
62
+ #stagingUrl: boolean;
63
+ constructor(accessKey: string, stagingUrl = false) {
64
+ this.#accessKey = accessKey;
65
+ this.#stagingUrl = stagingUrl;
66
+ }
65
67
 
66
- async uploadFile({ files, userEmail,fileNoLimit=2 }: UploadFileParams): Promise<string> {
68
+ async uploadFile({ files, userEmail, fileNoLimit = 2 }: UploadFileParams): Promise<string> {
67
69
  if (checkParameters(files, userEmail) === false) {
68
70
  throw new Error(REQUIRED_MESSAGE);
69
71
  }
@@ -71,20 +73,20 @@ class TryOn {
71
73
  if (!isValidEmail(userEmail.trim())) {
72
74
  throw new Error(REQUIRED_ERROR_MESSAGE_INVALID_EMAIL);
73
75
  }
74
- if (fileNoLimit<=0) {
76
+ if (fileNoLimit <= 0) {
75
77
  throw new Error(`Provide valid file number limit ${fileNoLimit}.`);
76
78
  }
77
79
  if (files?.length > fileNoLimit) {
78
80
  throw new Error(`Cannot allow more than ${fileNoLimit} files.`);
79
81
  }
80
82
  try {
81
- const payload :{ userEmail: string; userImages: string[] } = {
83
+ const payload: { userEmail: string; userImages: string[] } = {
82
84
  userEmail,
83
85
  userImages: [],
84
86
  };
85
- files?.forEach((file:File)=>{
86
- payload.userImages.push(file.name)
87
- })
87
+ files?.forEach((file: File) => {
88
+ payload.userImages.push(file.name);
89
+ });
88
90
  const signedUrlRes = await this.#getSignedUrl(payload);
89
91
  for (const file of files) {
90
92
  await this.#s3Upload(signedUrlRes.data.uploadUrls[file.name].url, file);
@@ -95,194 +97,204 @@ class TryOn {
95
97
  }
96
98
  }
97
99
 
98
- #getSignedUrl(payload: { userEmail: string; userImages: string[] }): Promise<AxiosResponse<any>> {
99
- if (checkParameters(payload) === false) {
100
- throw new Error(REQUIRED_MESSAGE);
101
- }
102
- return axios.post(`${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.TRY_ON_IMAGE_UPLOAD}`, payload, {
103
- headers: {
104
- "Content-Type": "application/json",
105
- "X-Api-Key": this.#accessKey,
106
- },
107
- });
108
- }
100
+ #getSignedUrl(payload: { userEmail: string; userImages: string[] }): Promise<AxiosResponse<any>> {
101
+ if (checkParameters(payload) === false) {
102
+ throw new Error(REQUIRED_MESSAGE);
103
+ }
104
+ return axios.post(`${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.TRY_ON_IMAGE_UPLOAD}`, payload, {
105
+ headers: {
106
+ "Content-Type": "application/json",
107
+ "X-Api-Key": this.#accessKey,
108
+ },
109
+ });
110
+ }
109
111
 
110
- #s3Upload(url: string, file: File): Promise<AxiosResponse<any>> {
111
- if (checkParameters(url, file) === false) {
112
- throw new Error(REQUIRED_MESSAGE);
113
- }
114
- return axios.put(url, file, {
115
- headers: {
116
- "Content-Type": file.type,
117
- },
118
- });
119
- }
112
+ #s3Upload(url: string, file: File): Promise<AxiosResponse<any>> {
113
+ if (checkParameters(url, file) === false) {
114
+ throw new Error(REQUIRED_MESSAGE);
115
+ }
116
+ return axios.put(url, file, {
117
+ headers: {
118
+ "Content-Type": file.type,
119
+ },
120
+ });
121
+ }
120
122
 
121
- getUploadedFiles(userEmail: string): Promise<AxiosResponse<any>> {
122
- if (checkParameters(userEmail) === false) {
123
- throw new Error(REQUIRED_MESSAGE);
124
- }
125
- if (!isValidEmail(userEmail.trim())) {
126
- throw new Error(REQUIRED_ERROR_MESSAGE_INVALID_EMAIL);
127
- }
123
+ getUploadedFiles(userEmail: string): Promise<AxiosResponse<any>> {
124
+ if (checkParameters(userEmail) === false) {
125
+ throw new Error(REQUIRED_MESSAGE);
126
+ }
127
+ if (!isValidEmail(userEmail.trim())) {
128
+ throw new Error(REQUIRED_ERROR_MESSAGE_INVALID_EMAIL);
129
+ }
128
130
 
129
- const payload = {
130
- userEmail,
131
- };
131
+ const payload = {
132
+ userEmail,
133
+ };
132
134
 
133
- return axios.post(`${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.TRY_ON_IMAGE_DOWNLOAD}`, payload, {
134
- headers: { "X-Api-Key": this.#accessKey },
135
- });
136
- }
135
+ return axios.post(`${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.TRY_ON_IMAGE_DOWNLOAD}`, payload, {
136
+ headers: { "X-Api-Key": this.#accessKey },
137
+ });
138
+ }
137
139
 
138
- deleteImage({ userEmail, fileName }: DeleteImageParams): Promise<AxiosResponse<any>> {
139
- if (checkParameters(userEmail, fileName) === false) {
140
- throw new Error(REQUIRED_MESSAGE);
141
- }
142
- if (!isValidEmail(userEmail.trim())) {
143
- throw new Error(REQUIRED_ERROR_MESSAGE_INVALID_EMAIL);
144
- }
145
- const payload = {
146
- userEmail,
147
- file: fileName,
148
- };
149
- return axios.delete(`${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.TRY_ON_IMAGE_URLS}`, {
150
- headers: { "X-Api-Key": this.#accessKey },
151
- data: payload,
152
- });
153
- }
140
+ deleteImage({ userEmail, fileName }: DeleteImageParams): Promise<AxiosResponse<any>> {
141
+ if (checkParameters(userEmail, fileName) === false) {
142
+ throw new Error(REQUIRED_MESSAGE);
143
+ }
144
+ if (!isValidEmail(userEmail.trim())) {
145
+ throw new Error(REQUIRED_ERROR_MESSAGE_INVALID_EMAIL);
146
+ }
147
+ const payload = {
148
+ userEmail,
149
+ file: fileName,
150
+ };
151
+ return axios.delete(`${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.TRY_ON_IMAGE_URLS}`, {
152
+ headers: { "X-Api-Key": this.#accessKey },
153
+ data: payload,
154
+ });
155
+ }
154
156
 
155
- #disconnectSocket = (): void => {
156
- this.#tryOnSocketRef?.close();
157
- if (this.#timerWaitingRef) {
158
- clearTimeout(this.#timerWaitingRef);
157
+ #disconnectSocket = (tryonId?: string): void => {
158
+ if (tryonId) {
159
+ const socket = this.#socketMap.get(tryonId);
160
+ const timer = this.#timerMap.get(tryonId);
161
+ socket?.close();
162
+ if (timer) clearTimeout(timer);
163
+ this.#socketMap.delete(tryonId);
164
+ this.#timerMap.delete(tryonId);
165
+ } else {
166
+ // Disconnect all
167
+ this.#socketMap.forEach((socket) => socket.close());
168
+ this.#timerMap.forEach((timer) => clearTimeout(timer));
169
+ this.#socketMap.clear();
170
+ this.#timerMap.clear();
159
171
  }
160
172
  };
173
+
161
174
 
162
- #handleTimeOut = ({ onSuccess, onError,tryonId }: HandleTimeOutParams): void => {
163
- this.#timerWaitingRef = setTimeout(() => {
164
- this.#handleGetTryOnResult({ onSuccess, onError,tryonId });
165
- this.#disconnectSocket();
166
- }, 150000);
175
+ #handleTimeOut = ({ onSuccess, onError, tryonId }: HandleTimeOutParams): void => {
176
+ const timer = setTimeout(() => {
177
+ this.#handleGetTryOnResult({ onSuccess, onError, tryonId });
178
+ this.#disconnectSocket(tryonId);
179
+ }, 300000);
180
+ this.#timerMap.set(tryonId, timer);
167
181
  };
182
+
168
183
 
169
184
  handleTryOnWebSocket = ({ tryonId, onError, onSuccess, onClose, onOpen }: HandleTryOnWebSocketParams): void => {
170
185
  if (checkParameters(tryonId) === false) {
171
186
  throw new Error(REQUIRED_MESSAGE);
172
187
  }
173
- this.#disconnectSocket();
188
+
189
+ this.#disconnectSocket(tryonId);
190
+
174
191
  const url = `${getUrl({ urlName: APP_BASE_WEBSOCKET_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.TRY_ON}?tryonId=${tryonId}`;
175
- this.#tryOnSocketRef = new WebSocket(url);
176
- if(this.#tryOnSocketRef){
177
- this.#tryOnSocketRef.onopen = async () => {
178
- onOpen?.();
179
- this.#handleTimeOut({ onSuccess, onError, tryonId });
180
- };
181
- this.#tryOnSocketRef.onmessage = (event) => {
182
- let data;
183
- try {
184
- data = JSON.parse(event.data);
185
- } catch (error) {
186
- console.log(data, error, "not correct format for data");
187
- return;
188
- }
189
- if (data?.status === "success") {
190
- onSuccess?.(data);
191
- } else {
192
- onError?.(data);
193
- }
194
- if (this.#timerWaitingRef) {
195
- clearTimeout(this.#timerWaitingRef);
196
- }
197
- };
198
- this.#tryOnSocketRef.onclose = () => {
199
- onClose?.();
200
- };
201
- this.#tryOnSocketRef.onerror = (event) => {
202
- onError?.(event);
203
- if (this.#timerWaitingRef) {
204
- clearTimeout(this.#timerWaitingRef);
205
- }
206
- };
207
- }else{
208
- console.log("no connection made for websocket");
209
-
210
- }
211
-
192
+ const socket = new WebSocket(url);
193
+
194
+ this.#socketMap.set(tryonId, socket);
195
+
196
+ socket.onopen = () => {
197
+ onOpen?.();
198
+ this.#handleTimeOut({ onSuccess, onError, tryonId });
199
+ };
200
+
201
+ socket.onmessage = (event) => {
202
+ let data;
203
+ try {
204
+ data = JSON.parse(event.data);
205
+ } catch (error) {
206
+ console.log("Invalid JSON:", event.data);
207
+ return;
208
+ }
209
+
210
+ if (data?.status === "success") {
211
+ onSuccess?.(data);
212
+ } else {
213
+ onError?.(data);
214
+ }
215
+
216
+ const timer = this.#timerMap.get(tryonId);
217
+ if (timer) clearTimeout(timer);
218
+ this.#timerMap.delete(tryonId);
219
+ };
220
+
221
+ socket.onclose = () => {
222
+ onClose?.();
223
+ // this.#disconnectSocket(tryonId);
224
+ };
225
+
226
+ socket.onerror = (event) => {
227
+ onError?.(event);
228
+ // const timer = this.#timerMap.get(tryonId);
229
+ // if (timer) clearTimeout(timer);
230
+ // this.#timerMap.delete(tryonId);
231
+ };
212
232
  };
233
+
213
234
 
214
- handleTryOnSubmit({
215
- shopDomain,
216
- products,
217
- selectedUserImages,
218
- requestSource,
219
- callbackUrl,
220
- openTryonId,
221
- selectedProductImageUrl,
222
- token
223
- }: HandleForLatestImageParams): Promise<AxiosResponse<any>> {
224
- if (checkParameters(shopDomain, products,token) === false) {
235
+ handleTryOnSubmit({ shopDomain, products, selectedUserImages, requestSource, callbackUrl, openTryonId, selectedProductImageUrl, token }: HandleForLatestImageParams): Promise<AxiosResponse<any>> {
236
+ if (checkParameters(shopDomain, products, token) === false) {
225
237
  throw new Error(REQUIRED_MESSAGE);
226
238
  }
227
-
239
+
228
240
  const payload = {
229
241
  products,
230
- customerStoreUrl:shopDomain,
231
- ...(selectedUserImages!==undefined && selectedUserImages!==null &&{selectedUserImages}),
232
- ...(requestSource!==undefined && requestSource!==null &&{requestSource}),
233
- ...(callbackUrl!==undefined && callbackUrl!==null &&{callbackUrl}),
234
- ...(openTryonId!==undefined && openTryonId!==null &&{openTryonId}),
235
- ...(selectedProductImageUrl!==undefined && selectedProductImageUrl!==null &&{selectedProductImageUrl})
242
+ customerStoreUrl: shopDomain,
243
+ ...(selectedUserImages !== undefined && selectedUserImages !== null && { selectedUserImages }),
244
+ ...(requestSource !== undefined && requestSource !== null && { requestSource }),
245
+ ...(callbackUrl !== undefined && callbackUrl !== null && { callbackUrl }),
246
+ ...(openTryonId !== undefined && openTryonId !== null && { openTryonId }),
247
+ ...(selectedProductImageUrl !== undefined && selectedProductImageUrl !== null && { selectedProductImageUrl }),
236
248
  };
237
249
  const url = `${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.TRY_ON}`;
238
- const headers: Record<string, string> = { "X-Api-Key": this.#accessKey };
239
- if (token) {
240
- headers["Authorization"] = `Bearer ${token}`;
241
- }
250
+ const headers: Record<string, string> = { "X-Api-Key": this.#accessKey };
251
+ if (token) {
252
+ headers["Authorization"] = `Bearer ${token}`;
253
+ }
242
254
  return axios.post(url, payload, {
243
- headers,
255
+ headers,
244
256
  });
245
257
  }
246
258
 
247
- #handleGetTryOnResult = async ({ onSuccess, onError, tryonId }: HandleTimeOutParams): Promise<void> => {
248
- try {
249
- const data = await this.getTryOnResult({ tryonId });
250
- onSuccess?.(data.data);
251
- } catch (error) {
252
- onError?.(error);
253
- }
254
- };
259
+ #handleGetTryOnResult = async ({ onSuccess, onError, tryonId }: HandleTimeOutParams): Promise<void> => {
260
+ try {
261
+ const data = await this.getTryOnResult({ tryonId });
262
+ onSuccess?.(data.data);
263
+ } catch (error) {
264
+ onError?.(error);
265
+ }
266
+ };
255
267
 
256
- getShareLink(tryonId: string) {
257
- return axios.post(
258
- `${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.TRY_ON_SHARE}`,
259
- { tryonId },
260
- {
261
- headers: { "X-Api-Key": this.#accessKey },
262
- }
263
- );
264
- }
268
+ getShareLink(tryonId: string) {
269
+ return axios.post(
270
+ `${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.TRY_ON_SHARE}`,
271
+ { tryonId },
272
+ {
273
+ headers: { "X-Api-Key": this.#accessKey },
274
+ },
275
+ );
276
+ }
265
277
 
266
- getTryOnResult = ({tryonId }: GetTryOnResultParams): Promise<AxiosResponse<any>> => {
267
- if (checkParameters(tryonId) === false) {
268
- throw new Error(REQUIRED_MESSAGE);
269
- }
270
- const url = `${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.TRY_ON_RESULT_IMAGE_DOWNLOAD}/${tryonId}`;
271
- return axios.post(url, null,{
272
- headers: { "X-Api-Key": this.#accessKey },
273
- });
274
- };
278
+ getTryOnResult = ({ tryonId }: GetTryOnResultParams): Promise<AxiosResponse<any>> => {
279
+ if (checkParameters(tryonId) === false) {
280
+ throw new Error(REQUIRED_MESSAGE);
281
+ }
282
+ const url = `${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.TRY_ON_RESULT_IMAGE_DOWNLOAD}/${tryonId}`;
283
+ return axios.post(url, null, {
284
+ headers: { "X-Api-Key": this.#accessKey },
285
+ });
286
+ };
275
287
 
276
- getProductImageEligibility({storeUrl,productHandle,imageURL,productDescription}:EligibiltyImageParams){
277
- if (checkParameters(storeUrl, productHandle, imageURL) === false) {
278
- throw new Error(REQUIRED_MESSAGE);
279
- }
280
- const payload = {storeUrl,productHandle,imageURL,productDescription:productDescription??null};
281
- const url = `${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.TRY_ON_PRODUCT_IMAGE_ELIGIBILTY}`;
282
- return axios.post(url, payload, {
283
- headers: { "X-Api-Key": this.#accessKey },
284
- });
285
- }
288
+ getProductImageEligibility({ storeUrl, productHandle, imageURL, productDescription }: EligibiltyImageParams) {
289
+ if (checkParameters(storeUrl, productHandle, imageURL) === false) {
290
+ throw new Error(REQUIRED_MESSAGE);
291
+ }
292
+ const payload = { storeUrl, productHandle, imageURL, productDescription: productDescription ?? null };
293
+ const url = `${getUrl({ urlName: APP_AUTH_BASE_URL, stagingUrl: this.#stagingUrl })}${API_ENDPOINTS.TRY_ON_PRODUCT_IMAGE_ELIGIBILTY}`;
294
+ return axios.post(url, payload, {
295
+ headers: { "X-Api-Key": this.#accessKey },
296
+ });
297
+ }
286
298
  }
287
299
 
288
300
  export default TryOn;