@swan-admin/swan-ai-measurements 1.0.28 → 1.0.30
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/auth.js +93 -60
- package/constants.js +2 -0
- package/custom.js +22 -7
- package/fileUpload.js +88 -81
- package/index.js +24 -77
- package/measurement.js +134 -136
- package/package.json +1 -1
- package/poseDetection.js +46 -44
- package/utils.js +9 -0
package/auth.js
CHANGED
|
@@ -1,60 +1,93 @@
|
|
|
1
|
-
import axios from "axios";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
};
|
|
60
|
-
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import {
|
|
3
|
+
API_ENDPOINTS,
|
|
4
|
+
APP_AUTH_BASE_URL,
|
|
5
|
+
APP_AUTH_WEBSOCKET_URL,
|
|
6
|
+
APP_BASE_URL,
|
|
7
|
+
REQUIRED_MESSAGE,
|
|
8
|
+
} from "./constants.js";
|
|
9
|
+
import { checkParameters } from "./utils.js";
|
|
10
|
+
let socketRef;
|
|
11
|
+
|
|
12
|
+
class Auth {
|
|
13
|
+
static accessKey;
|
|
14
|
+
constructor(key) {
|
|
15
|
+
Auth.accessKey = key;
|
|
16
|
+
}
|
|
17
|
+
registerUser({ email, appVerifyUrl, gender, height, username }) {
|
|
18
|
+
if (checkParameters(email, appVerifyUrl) === false) {
|
|
19
|
+
throw new Error(REQUIRED_MESSAGE);
|
|
20
|
+
}
|
|
21
|
+
let body = {
|
|
22
|
+
username,
|
|
23
|
+
email,
|
|
24
|
+
appVerifyUrl,
|
|
25
|
+
};
|
|
26
|
+
if (gender && height) {
|
|
27
|
+
body = { ...body, attributes: { gender, height } };
|
|
28
|
+
}
|
|
29
|
+
return axios.post(`${APP_AUTH_BASE_URL}${API_ENDPOINTS.REGISTER_USER}`, body);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
verifyToken = (token) => {
|
|
33
|
+
if (!token) {
|
|
34
|
+
throw new Error(REQUIRED_MESSAGE);
|
|
35
|
+
}
|
|
36
|
+
return axios.post(`${APP_AUTH_BASE_URL}${API_ENDPOINTS.VERIFY_USER}`, null, {
|
|
37
|
+
params: { token },
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
addUser = ({ scanId, email, name, height, gender, offsetMarketingConsent }) => {
|
|
42
|
+
if (checkParameters(scanId, email, height, gender) === false) {
|
|
43
|
+
throw new Error(REQUIRED_MESSAGE);
|
|
44
|
+
}
|
|
45
|
+
return axios.post(`${APP_AUTH_BASE_URL}${API_ENDPOINTS.ADD_USER}`, {
|
|
46
|
+
scan_id: scanId,
|
|
47
|
+
email,
|
|
48
|
+
name,
|
|
49
|
+
offsetMarketingConsent,
|
|
50
|
+
attributes: JSON.stringify({ height, gender }),
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
getUserDetail = (email) => {
|
|
55
|
+
if (!email) {
|
|
56
|
+
throw new Error(REQUIRED_MESSAGE);
|
|
57
|
+
}
|
|
58
|
+
return axios.get(`${APP_BASE_URL}${API_ENDPOINTS.GET_USER_DETAIL}/${email}`);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
handleAuthSocket = ({ email, scanId, onError, onSuccess, onClose, onOpen }) => {
|
|
62
|
+
if (checkParameters(email, scanId) === false) {
|
|
63
|
+
throw new Error(REQUIRED_MESSAGE);
|
|
64
|
+
}
|
|
65
|
+
socketRef?.close?.();
|
|
66
|
+
|
|
67
|
+
socketRef = new WebSocket(APP_AUTH_WEBSOCKET_URL);
|
|
68
|
+
const detailObj = {
|
|
69
|
+
email,
|
|
70
|
+
scanId,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
socketRef.onopen = () => {
|
|
74
|
+
socketRef.send(JSON.stringify(detailObj));
|
|
75
|
+
onOpen?.();
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
socketRef.onmessage = (event) => {
|
|
79
|
+
const data = JSON.parse(event.data);
|
|
80
|
+
onSuccess?.(data);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
socketRef.onclose = () => {
|
|
84
|
+
onClose?.();
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
socketRef.onerror = (event) => {
|
|
88
|
+
onError?.(event);
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export default Auth;
|
package/constants.js
CHANGED
package/custom.js
CHANGED
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
import axios from "axios";
|
|
2
|
-
import { API_ENDPOINTS, APP_AUTH_BASE_URL } from "./constants.js";
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { API_ENDPOINTS, APP_AUTH_BASE_URL, REQUIRED_MESSAGE } from "./constants.js";
|
|
3
|
+
|
|
4
|
+
export default class Custom {
|
|
5
|
+
static accessKey;
|
|
6
|
+
constructor(key) {
|
|
7
|
+
Custom.accessKey = key;
|
|
8
|
+
}
|
|
9
|
+
getCustomCustomerConfig = (store_url) => {
|
|
10
|
+
if (!store_url) {
|
|
11
|
+
throw new Error(REQUIRED_MESSAGE);
|
|
12
|
+
}
|
|
13
|
+
return axios.get(`${APP_AUTH_BASE_URL}${API_ENDPOINTS.CUSTOM_CUSTOMER}`, { params: { store_url } });
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
getModelUrl = (id) => {
|
|
17
|
+
if (!id) {
|
|
18
|
+
throw new Error(REQUIRED_MESSAGE);
|
|
19
|
+
}
|
|
20
|
+
return axios.get(`${APP_AUTH_BASE_URL}${API_ENDPOINTS.MODEL}/${id}`);
|
|
21
|
+
};
|
|
22
|
+
}
|
package/fileUpload.js
CHANGED
|
@@ -1,81 +1,88 @@
|
|
|
1
|
-
import AwsS3Multipart from "@uppy/aws-s3-multipart";
|
|
2
|
-
import Uppy from "@uppy/core";
|
|
3
|
-
import { FILE_UPLOAD_KEY, UPPY_FILE_UPLOAD_ENDPOINT } from "./constants.js";
|
|
4
|
-
import { fetchData } from "./utils.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
1
|
+
import AwsS3Multipart from "@uppy/aws-s3-multipart";
|
|
2
|
+
import Uppy from "@uppy/core";
|
|
3
|
+
import { FILE_UPLOAD_KEY, REQUIRED_MESSAGE, UPPY_FILE_UPLOAD_ENDPOINT } from "./constants.js";
|
|
4
|
+
import { checkParameters, fetchData } from "./utils.js";
|
|
5
|
+
|
|
6
|
+
export default class FileUpload {
|
|
7
|
+
static accessKey;
|
|
8
|
+
constructor(key) {
|
|
9
|
+
FileUpload.accessKey = key;
|
|
10
|
+
}
|
|
11
|
+
uploadFile({ file, objMetaData, scanId }) {
|
|
12
|
+
if (checkParameters(file, objMetaData, scanId) === false) {
|
|
13
|
+
throw new Error(REQUIRED_MESSAGE);
|
|
14
|
+
}
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const uppyIns = new Uppy({ autoProceed: true });
|
|
17
|
+
uppyIns.use(AwsS3Multipart, {
|
|
18
|
+
limit: 10,
|
|
19
|
+
retryDelays: [0, 1000, 3000, 5000],
|
|
20
|
+
getChunkSize: () => 5 * 1024 * 1024,
|
|
21
|
+
createMultipartUpload: (file) => {
|
|
22
|
+
const objectKey = `${scanId}.${file.extension}`;
|
|
23
|
+
return fetchData({
|
|
24
|
+
path: UPPY_FILE_UPLOAD_ENDPOINT.UPLOAD_START,
|
|
25
|
+
apiKey: FILE_UPLOAD_KEY,
|
|
26
|
+
body: {
|
|
27
|
+
objectKey,
|
|
28
|
+
contentType: file.type,
|
|
29
|
+
objectMetadata: objMetaData,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
completeMultipartUpload: (file, { uploadId, key, parts }) =>
|
|
34
|
+
fetchData({
|
|
35
|
+
path: UPPY_FILE_UPLOAD_ENDPOINT.UPLOAD_COMPLETE,
|
|
36
|
+
apiKey: FILE_UPLOAD_KEY,
|
|
37
|
+
body: {
|
|
38
|
+
uploadId,
|
|
39
|
+
objectKey: key,
|
|
40
|
+
parts,
|
|
41
|
+
originalFileName: file.name,
|
|
42
|
+
},
|
|
43
|
+
}),
|
|
44
|
+
|
|
45
|
+
signPart: (file, partData) =>
|
|
46
|
+
fetchData({
|
|
47
|
+
path: UPPY_FILE_UPLOAD_ENDPOINT.UPLOAD_SIGN_PART,
|
|
48
|
+
apiKey: FILE_UPLOAD_KEY,
|
|
49
|
+
body: {
|
|
50
|
+
objectKey: partData.key,
|
|
51
|
+
uploadId: partData.uploadId,
|
|
52
|
+
partNumber: partData.partNumber,
|
|
53
|
+
},
|
|
54
|
+
}),
|
|
55
|
+
|
|
56
|
+
abortMultipartUpload: (file, { uploadId, key }) =>
|
|
57
|
+
fetchData({
|
|
58
|
+
path: UPPY_FILE_UPLOAD_ENDPOINT.UPLOAD_ABORT,
|
|
59
|
+
apiKey: FILE_UPLOAD_KEY,
|
|
60
|
+
body: {
|
|
61
|
+
uploadId,
|
|
62
|
+
objectKey: key,
|
|
63
|
+
originalFileName: file.name,
|
|
64
|
+
},
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
uppyIns.addFile({
|
|
69
|
+
source: "manual",
|
|
70
|
+
name: file.name,
|
|
71
|
+
type: file.type,
|
|
72
|
+
data: file,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
uppyIns.on("upload-error", (file, error, response) => {
|
|
76
|
+
reject(error);
|
|
77
|
+
});
|
|
78
|
+
uppyIns.on("upload-success", () => {
|
|
79
|
+
resolve({ message: "file uploaded successfully" });
|
|
80
|
+
});
|
|
81
|
+
uppyIns.on("complete", (result) => {
|
|
82
|
+
if (uppyIns) {
|
|
83
|
+
uppyIns.close();
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
package/index.js
CHANGED
|
@@ -1,77 +1,24 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
addUser({ scanId, email, name, height, gender, offsetMarketingConsent }) {
|
|
28
|
-
return addUser({ scanId, email, name, height, gender, offsetMarketingConsent, accessKey: this.accessKey });
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
getUserDetail(email) {
|
|
32
|
-
return getUserDetail(email, this.accessKey);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
uploadFile({ file, objMetaData, scanId }) {
|
|
36
|
-
return uploadFile({ file, objMetaData, scanId, accessKey: this.accessKey });
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
getModelUrl(id) {
|
|
40
|
-
return getModelUrl(id, this.accessKey);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
getCustomCustomerConfig(storeUrl) {
|
|
44
|
-
return getCustomCustomerConfig(storeUrl, this.accessKey);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
getMeasurementStatus(scanId) {
|
|
48
|
-
return getMeasurementStatus(scanId, this.accessKey);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
getTryOnMeasurements({ scanId, shopDomain, productName }) {
|
|
52
|
-
return getTryOnMeasurements({ scanId, shopDomain, productName, accessKey: this.accessKey });
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
handleTryOnSocket({ shopDomain, scanId, productName, onError, onSuccess, onClose, onOpen }) {
|
|
56
|
-
return handleTryOnSocket({
|
|
57
|
-
shopDomain,
|
|
58
|
-
scanId,
|
|
59
|
-
productName,
|
|
60
|
-
accessKey: this.accessKey,
|
|
61
|
-
onError,
|
|
62
|
-
onSuccess,
|
|
63
|
-
onClose,
|
|
64
|
-
onOpen,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
handleMeasurementSocket({ scanId, onError, onSuccess, onClose, onOpen }) {
|
|
69
|
-
return handleMeasurementSocket({ scanId, accessKey: this.accessKey, onError, onSuccess, onClose, onOpen });
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
handleAuthSocket({ email, scanId, onError, onSuccess, onClose, onOpen }) {
|
|
73
|
-
return handleAuthSocket({ email, scanId, accessKey: this.accessKey, onError, onSuccess, onClose, onOpen });
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
handlePoseDetectionSocket = handlePoseDetectionSocket;
|
|
77
|
-
}
|
|
1
|
+
import Auth from "./auth.js";
|
|
2
|
+
import Custom from "./custom.js";
|
|
3
|
+
import FileUpload from "./fileUpload.js";
|
|
4
|
+
import Measurement from "./measurement.js";
|
|
5
|
+
import PoseDetection from "./poseDetection.js";
|
|
6
|
+
export default class Swan {
|
|
7
|
+
static accessKey;
|
|
8
|
+
constructor(key) {
|
|
9
|
+
if (key !== 9876543210) {
|
|
10
|
+
throw new Error("wrong access key");
|
|
11
|
+
}
|
|
12
|
+
Swan.accessKey = key;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
auth = new Auth(Swan.accessKey);
|
|
16
|
+
|
|
17
|
+
custom = new Custom(Swan.accessKey);
|
|
18
|
+
|
|
19
|
+
fileUpload = new FileUpload(Swan.accessKey);
|
|
20
|
+
|
|
21
|
+
measurement = new Measurement(Swan.accessKey);
|
|
22
|
+
|
|
23
|
+
poseDetection = new PoseDetection(Swan.accessKey);
|
|
24
|
+
}
|
package/measurement.js
CHANGED
|
@@ -1,136 +1,134 @@
|
|
|
1
|
-
import axios from "axios";
|
|
2
|
-
import {
|
|
3
|
-
API_ENDPOINTS,
|
|
4
|
-
APP_AUTH_BASE_URL,
|
|
5
|
-
APP_RECOMMENDATION_WEBSOCKET_URL,
|
|
6
|
-
APP_TRY_ON_WEBSOCKET_URL,
|
|
7
|
-
FILE_UPLOAD_KEY,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
};
|
|
136
|
-
};
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import {
|
|
3
|
+
API_ENDPOINTS,
|
|
4
|
+
APP_AUTH_BASE_URL,
|
|
5
|
+
APP_RECOMMENDATION_WEBSOCKET_URL,
|
|
6
|
+
APP_TRY_ON_WEBSOCKET_URL,
|
|
7
|
+
FILE_UPLOAD_KEY,
|
|
8
|
+
REQUIRED_MESSAGE,
|
|
9
|
+
} from "./constants.js";
|
|
10
|
+
import { checkParameters } from "./utils.js";
|
|
11
|
+
|
|
12
|
+
export default class Measurement {
|
|
13
|
+
static accessKey;
|
|
14
|
+
constructor(key) {
|
|
15
|
+
Measurement.accessKey = key;
|
|
16
|
+
}
|
|
17
|
+
static tryOnSocketRef = null;
|
|
18
|
+
static measurementSocketRef = null;
|
|
19
|
+
static timerPollingRef = null;
|
|
20
|
+
static timerWaitingRef = null;
|
|
21
|
+
|
|
22
|
+
getMeasurementStatus(scanId) {
|
|
23
|
+
if (!scanId) {
|
|
24
|
+
throw new Error(REQUIRED_MESSAGE);
|
|
25
|
+
}
|
|
26
|
+
const url = `${APP_AUTH_BASE_URL}/measurements?scanId=${scanId}`;
|
|
27
|
+
return axios.get(url, {
|
|
28
|
+
headers: { "X-Api-Key": FILE_UPLOAD_KEY },
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getTryOnMeasurements({ scanId, shopDomain, productName }) {
|
|
33
|
+
if (checkParameters(scanId, shopDomain, productName) === false) {
|
|
34
|
+
throw new Error(REQUIRED_MESSAGE);
|
|
35
|
+
}
|
|
36
|
+
const tryOnUrl = `${APP_AUTH_BASE_URL}${API_ENDPOINTS.TRY_ON}/${scanId}/shop/${shopDomain}/product/${productName}`;
|
|
37
|
+
return axios.get(tryOnUrl);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
handleTryOnSocket({ shopDomain, scanId, productName, onError, onSuccess, onClose, onOpen }) {
|
|
41
|
+
if (checkParameters(shopDomain, scanId, productName) === false) {
|
|
42
|
+
throw new Error(REQUIRED_MESSAGE);
|
|
43
|
+
}
|
|
44
|
+
Measurement.tryOnSocketRef?.close();
|
|
45
|
+
|
|
46
|
+
const url = `${APP_TRY_ON_WEBSOCKET_URL}/develop?store_url=${shopDomain}&product_name=${productName}&scan_id=${scanId}`;
|
|
47
|
+
Measurement.tryOnSocketRef = new WebSocket(url);
|
|
48
|
+
|
|
49
|
+
Measurement.tryOnSocketRef.onopen = () => {
|
|
50
|
+
onOpen?.();
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
Measurement.tryOnSocketRef.onmessage = (event) => {
|
|
54
|
+
const data = JSON.parse(event.data);
|
|
55
|
+
if (data?.tryOnProcessStatus === "available") {
|
|
56
|
+
onSuccess?.(data);
|
|
57
|
+
} else {
|
|
58
|
+
onError?.({ message: "failed to get image urls" });
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
Measurement.tryOnSocketRef.onclose = () => {
|
|
63
|
+
onClose?.();
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
Measurement.tryOnSocketRef.onerror = (event) => {
|
|
67
|
+
onError?.(event);
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static getMeasurementsCheck = async (onSuccess, onError, scanId) => {
|
|
72
|
+
try {
|
|
73
|
+
const res = await getMeasurementStatus(scanId);
|
|
74
|
+
if (res?.data && res?.data?.[0]?.isMeasured === true) {
|
|
75
|
+
onSuccess?.(res?.data);
|
|
76
|
+
clearInterval(Measurement.timerPollingRef);
|
|
77
|
+
}
|
|
78
|
+
} catch (e) {
|
|
79
|
+
clearInterval(Measurement.timerPollingRef);
|
|
80
|
+
onError?.(e);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
static handlePolling(onSuccess, onError) {
|
|
85
|
+
clearInterval(Measurement.timerPollingRef);
|
|
86
|
+
Measurement.timerPollingRef = setInterval(() => {
|
|
87
|
+
Measurement.getMeasurementsCheck(onSuccess, onError);
|
|
88
|
+
}, 5000);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static disconnectSocket = () => {
|
|
92
|
+
Measurement.measurementSocketRef?.close();
|
|
93
|
+
clearTimeout(Measurement.timerWaitingRef);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
static handleTimeOut = (onSuccess, onError) => {
|
|
97
|
+
Measurement.timerWaitingRef = setTimeout(() => {
|
|
98
|
+
Measurement.handlePolling(onSuccess, onError);
|
|
99
|
+
disconnectSocket();
|
|
100
|
+
}, 2 * 60000);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
handleMeasurementSocket = ({ scanId, onError, onSuccess, onClose, onOpen }) => {
|
|
104
|
+
if (!scanId) {
|
|
105
|
+
throw new Error(REQUIRED_MESSAGE);
|
|
106
|
+
}
|
|
107
|
+
Measurement.disconnectSocket();
|
|
108
|
+
const url = `${APP_RECOMMENDATION_WEBSOCKET_URL}?scanId=${scanId}`;
|
|
109
|
+
Measurement.measurementSocketRef = new WebSocket(url);
|
|
110
|
+
|
|
111
|
+
Measurement.measurementSocketRef.onopen = () => {
|
|
112
|
+
onOpen?.();
|
|
113
|
+
Measurement.handleTimeOut(onSuccess, onError);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
Measurement.measurementSocketRef.onmessage = (event) => {
|
|
117
|
+
const data = JSON.parse(event.data);
|
|
118
|
+
if (data?.code === 200 && data?.scanStatus === "success") {
|
|
119
|
+
onSuccess?.(data);
|
|
120
|
+
} else {
|
|
121
|
+
onError?.(data);
|
|
122
|
+
}
|
|
123
|
+
clearTimeout(Measurement.timerWaitingRef);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
Measurement.measurementSocketRef.onclose = () => {
|
|
127
|
+
onClose?.();
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
Measurement.measurementSocketRef.onerror = (event) => {
|
|
131
|
+
onError?.(event);
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
}
|
package/package.json
CHANGED
package/poseDetection.js
CHANGED
|
@@ -1,44 +1,46 @@
|
|
|
1
|
-
import { APP_POSE_DETECTION_WEbSOCKET_URL } from "./constants.js";
|
|
2
|
-
import { io } from "socket.io-client";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
1
|
+
import { APP_POSE_DETECTION_WEbSOCKET_URL } from "./constants.js";
|
|
2
|
+
import { io } from "socket.io-client";
|
|
3
|
+
|
|
4
|
+
export default class PoseDetection {
|
|
5
|
+
static socket = null;
|
|
6
|
+
static accessKey;
|
|
7
|
+
constructor(key) {
|
|
8
|
+
PoseDetection.accessKey = key;
|
|
9
|
+
}
|
|
10
|
+
connect() {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
PoseDetection.socket = io.connect(APP_POSE_DETECTION_WEbSOCKET_URL);
|
|
13
|
+
PoseDetection.socket?.on("connect", () => {
|
|
14
|
+
resolve(PoseDetection.socket.id); // "G5p5..."
|
|
15
|
+
});
|
|
16
|
+
PoseDetection.socket?.on("connect_error", (err) => reject(err));
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
videoEmit({ image, scanId }) {
|
|
21
|
+
if (!PoseDetection.socket) {
|
|
22
|
+
throw new Error("socket is not connected");
|
|
23
|
+
}
|
|
24
|
+
PoseDetection.socket.emit("video", {
|
|
25
|
+
image,
|
|
26
|
+
user_unique_key: scanId,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
disconnect() {
|
|
31
|
+
PoseDetection.socket?.disconnect?.();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
poseStatus(callBack) {
|
|
35
|
+
if (!PoseDetection.socket) {
|
|
36
|
+
throw new Error("socket is not connected");
|
|
37
|
+
}
|
|
38
|
+
PoseDetection.socket.on("pose_status", (data) => {
|
|
39
|
+
callBack?.(data);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
connected() {
|
|
44
|
+
return !!PoseDetection.socket?.connected;
|
|
45
|
+
}
|
|
46
|
+
}
|