iidrak-analytics-react 1.2.4
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/README.md +170 -0
- package/index.d.ts +1 -0
- package/index.js +4 -0
- package/metastreamio/metastreamio.account.js +65 -0
- package/metastreamio/metastreamio.cart.js +192 -0
- package/metastreamio/metastreamio.constants.js +256 -0
- package/metastreamio/metastreamio.date.js +41 -0
- package/metastreamio/metastreamio.environment.js +406 -0
- package/metastreamio/metastreamio.interface.js +591 -0
- package/metastreamio/metastreamio.logger.js +150 -0
- package/metastreamio/metastreamio.network.js +313 -0
- package/metastreamio/metastreamio.provider.js +50 -0
- package/metastreamio/metastreamio.queue.js +68 -0
- package/metastreamio/metastreamio.recorder.js +157 -0
- package/metastreamio/metastreamio.session.js +150 -0
- package/metastreamio/metastreamio.user.js +79 -0
- package/metastreamio/metastreamio.userproperties.js +76 -0
- package/metastreamio/metastreamio.utility.js +206 -0
- package/metastreamio/models/constructor.app.js +24 -0
- package/metastreamio/models/constructor.config.js +33 -0
- package/metastreamio/models/constructor.user.js +30 -0
- package/metastreamio/models/event.account.balance.js +12 -0
- package/metastreamio/models/event.account.js +22 -0
- package/metastreamio/models/event.appinfo.js +28 -0
- package/metastreamio/models/event.appperformance.js +25 -0
- package/metastreamio/models/event.cart.js +19 -0
- package/metastreamio/models/event.cartitem.js +34 -0
- package/metastreamio/models/event.device.js +55 -0
- package/metastreamio/models/event.event.js +88 -0
- package/metastreamio/models/event.network.js +27 -0
- package/metastreamio/models/event.parameter.js +12 -0
- package/metastreamio/models/event.parameters.js +38 -0
- package/metastreamio/models/event.session.js +24 -0
- package/metastreamio/models/event.session.utm.js +37 -0
- package/metastreamio/models/event.userproperty.js +14 -0
- package/metastreamio/string.format.js +7 -0
- package/package.json +21 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { strf } from "./string.format.js";
|
|
4
|
+
import ViewShot, { captureRef } from "react-native-view-shot";
|
|
5
|
+
import { Platform, Dimensions } from "react-native";
|
|
6
|
+
|
|
7
|
+
strf();
|
|
8
|
+
|
|
9
|
+
class MetaStreamIORecorder {
|
|
10
|
+
constructor({ constants, logger, network, config } = {}) {
|
|
11
|
+
this.constant = constants;
|
|
12
|
+
this.logger = logger;
|
|
13
|
+
this.network = network;
|
|
14
|
+
this.config = config;
|
|
15
|
+
|
|
16
|
+
this.isRecording = false;
|
|
17
|
+
this.sessionId = null;
|
|
18
|
+
this.endpoint = null;
|
|
19
|
+
this.intervalId = null;
|
|
20
|
+
|
|
21
|
+
// Default to first endpoint if specific one not provided
|
|
22
|
+
this.endpoint = config.recordingEndpoint || (this.network.endpoints.length > 0 ? this.network.endpoints[0].replace(/:[0-9]+/, "") + ":8000" : null);
|
|
23
|
+
|
|
24
|
+
// Use lower quality by default to save bandwidth
|
|
25
|
+
this.quality = config.quality || 0.5;
|
|
26
|
+
this.fps = config.fps || 2; // Frames per second (0.5s interval)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
setSessionId(id) {
|
|
30
|
+
this.sessionId = id;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async startRecording(viewRef) {
|
|
34
|
+
if (this.isRecording || !this.sessionId || !this.endpoint) {
|
|
35
|
+
if (!this.endpoint) this.logger.warn("recorder", "No recording endpoint configured");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
this.logger.log("recorder", `Starting session recording for ${this.sessionId} to ${this.endpoint}`);
|
|
41
|
+
|
|
42
|
+
// 1. Initialize Session on Python Server
|
|
43
|
+
// Note: We use a separate fetch here because the payload format is different from standard analytics
|
|
44
|
+
await fetch(`${this.endpoint}/sessions`, {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers: { 'Content-Type': 'application/json' },
|
|
47
|
+
body: JSON.stringify({
|
|
48
|
+
device_info: {
|
|
49
|
+
width: Dimensions.get('window').width,
|
|
50
|
+
height: Dimensions.get('window').height,
|
|
51
|
+
platform: Platform.OS,
|
|
52
|
+
sessionId: this.sessionId // Pass our analytics session ID
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
}).then(async res => {
|
|
56
|
+
if (res.ok) {
|
|
57
|
+
const data = await res.json();
|
|
58
|
+
// Server might return its own ID, but we want to map them.
|
|
59
|
+
// For simplicity, we assume server respects ours or we track the mapping.
|
|
60
|
+
// In this demo, the server generates a timestamp ID. That's fine.
|
|
61
|
+
this.recorderSessionId = data.session_id;
|
|
62
|
+
this.isRecording = true;
|
|
63
|
+
this.startLoop(viewRef);
|
|
64
|
+
} else {
|
|
65
|
+
this.logger.error("recorder", "Failed to start session on recording server");
|
|
66
|
+
}
|
|
67
|
+
}).catch(err => {
|
|
68
|
+
this.logger.error("recorder", "Connection error to recording server: " + err);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
} catch (err) {
|
|
72
|
+
this.logger.error("recorder", "Start recording error: " + err);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
stopRecording() {
|
|
77
|
+
if (this.intervalId) {
|
|
78
|
+
clearInterval(this.intervalId);
|
|
79
|
+
this.intervalId = null;
|
|
80
|
+
}
|
|
81
|
+
this.isRecording = false;
|
|
82
|
+
this.logger.log("recorder", "Stopped recording");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
startLoop(viewRef) {
|
|
86
|
+
const intervalMs = 1000 / this.fps;
|
|
87
|
+
|
|
88
|
+
this.intervalId = setInterval(async () => {
|
|
89
|
+
if (!viewRef.current) return;
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const uri = await captureRef(viewRef, {
|
|
93
|
+
format: "jpg",
|
|
94
|
+
quality: this.quality,
|
|
95
|
+
result: "tmpfile"
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
this.uploadFrame(uri);
|
|
99
|
+
} catch (e) {
|
|
100
|
+
// Silent fail on capture error to avoid log spam
|
|
101
|
+
}
|
|
102
|
+
}, intervalMs);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async uploadFrame(uri) {
|
|
106
|
+
if (!this.recorderSessionId) return;
|
|
107
|
+
|
|
108
|
+
const formData = new FormData();
|
|
109
|
+
const duration = 1.0 / this.fps;
|
|
110
|
+
const timestamp = Date.now() / 1000;
|
|
111
|
+
|
|
112
|
+
formData.append('timestamp', String(timestamp));
|
|
113
|
+
formData.append('duration', String(duration));
|
|
114
|
+
formData.append('file', {
|
|
115
|
+
uri: uri,
|
|
116
|
+
type: 'image/jpeg',
|
|
117
|
+
name: 'screenshot.jpg',
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
await fetch(`${this.endpoint}/sessions/${this.recorderSessionId}/screenshot`, {
|
|
122
|
+
method: 'POST',
|
|
123
|
+
body: formData,
|
|
124
|
+
headers: {
|
|
125
|
+
'Content-Type': 'multipart/form-data',
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
} catch (e) {
|
|
129
|
+
// Network error, drop frame
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Record interactions (Touch events)
|
|
134
|
+
async recordInteraction(type, nativeEvent) {
|
|
135
|
+
if (!this.isRecording || !this.recorderSessionId) return;
|
|
136
|
+
|
|
137
|
+
const { pageX, pageY } = nativeEvent;
|
|
138
|
+
const { width, height } = Dimensions.get('window');
|
|
139
|
+
|
|
140
|
+
const event = {
|
|
141
|
+
type,
|
|
142
|
+
x: pageX / width,
|
|
143
|
+
y: pageY / height,
|
|
144
|
+
timestamp: Date.now() / 1000
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
fetch(`${this.endpoint}/sessions/${this.recorderSessionId}/events`, {
|
|
149
|
+
method: 'POST',
|
|
150
|
+
headers: { 'Content-Type': 'application/json' },
|
|
151
|
+
body: JSON.stringify([event])
|
|
152
|
+
}).catch(() => { });
|
|
153
|
+
} catch (e) { }
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export { MetaStreamIORecorder };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { strf } from "./string.format.js";
|
|
4
|
+
|
|
5
|
+
strf();
|
|
6
|
+
|
|
7
|
+
import { SessionModel } from "./models/event.session.js";
|
|
8
|
+
import { UtmModel } from "./models/event.session.utm.js";
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
*
|
|
12
|
+
* Session management
|
|
13
|
+
*
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
class MetaStreamIOSession {
|
|
17
|
+
constructor({
|
|
18
|
+
constants,
|
|
19
|
+
date,
|
|
20
|
+
environment,
|
|
21
|
+
logger,
|
|
22
|
+
network,
|
|
23
|
+
sessionLength,
|
|
24
|
+
utility,
|
|
25
|
+
} = {}) {
|
|
26
|
+
this.constant = constants;
|
|
27
|
+
this.date = date;
|
|
28
|
+
this.environment = environment;
|
|
29
|
+
this.logger = logger;
|
|
30
|
+
this.network = network;
|
|
31
|
+
this.session_length = sessionLength
|
|
32
|
+
? sessionLength
|
|
33
|
+
: this.constant.MetaStreamIO_SessionLengthSeconds;
|
|
34
|
+
this.session = new SessionModel();
|
|
35
|
+
this.utility = utility;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
reset() {
|
|
39
|
+
this.session = new SessionModel();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
generateNewSessionId(session_id) {
|
|
43
|
+
if (session_id) {
|
|
44
|
+
return session_id;
|
|
45
|
+
} else {
|
|
46
|
+
return this.utility.generateRandomId();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
setSource(source = null) {
|
|
51
|
+
this.session.source = source ? source : null;
|
|
52
|
+
return this.session.source;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
setUTM({
|
|
56
|
+
utm_source = null,
|
|
57
|
+
utm_medium = null,
|
|
58
|
+
utm_campaign = null,
|
|
59
|
+
utm_term = null,
|
|
60
|
+
utm_content = null,
|
|
61
|
+
} = {}) {
|
|
62
|
+
this.session.utm = new UtmModel({
|
|
63
|
+
utm_source: utm_source ? utm_source : null,
|
|
64
|
+
utm_medium: utm_medium ? utm_medium : null,
|
|
65
|
+
utm_campaign: utm_campaign ? utm_campaign : null,
|
|
66
|
+
utm_term: utm_term ? utm_term : null,
|
|
67
|
+
utm_content: utm_content ? utm_content : null,
|
|
68
|
+
}).list();
|
|
69
|
+
return this.session.utm;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
createNewSession({
|
|
73
|
+
session_id = null,
|
|
74
|
+
session_source = null,
|
|
75
|
+
session_utm = null,
|
|
76
|
+
} = {}) {
|
|
77
|
+
let _id, _source, _start_time, _utm;
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
_id = this.generateNewSessionId(session_id);
|
|
81
|
+
} catch (err) {
|
|
82
|
+
this.logger.warn(
|
|
83
|
+
"session",
|
|
84
|
+
"<createNewSession> could not generate / set new id: " + err
|
|
85
|
+
);
|
|
86
|
+
_id = null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
_source = session_source ? session_source : null;
|
|
91
|
+
} catch {
|
|
92
|
+
source = null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
_start_time = this.date.getEventTimestamp();
|
|
97
|
+
} catch {
|
|
98
|
+
_start_time = null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
_utm = this.setUTM(session_utm);
|
|
103
|
+
} catch (err) {
|
|
104
|
+
this.logger.warn("session", "could not set session UTM: " + err);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
this.session = new SessionModel({
|
|
108
|
+
id: _id,
|
|
109
|
+
source: _source,
|
|
110
|
+
start_time: _start_time,
|
|
111
|
+
utm: _utm,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
logSession({ last_event_time = null } = {}) {
|
|
116
|
+
if (last_event_time) {
|
|
117
|
+
if (!this.checkSessionIsValid(last_event_time)) {
|
|
118
|
+
this.logger.warn("session", "session expired - starting new session");
|
|
119
|
+
this.createNewSession();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return this.utility.copyObject(this.session);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
checkSessionIsValid(last_event_time) {
|
|
126
|
+
try {
|
|
127
|
+
let current_time = this.date.getEventTimestamp();
|
|
128
|
+
let session_length_seconds = (current_time - last_event_time) / 1e6;
|
|
129
|
+
this.logger.log(
|
|
130
|
+
"session",
|
|
131
|
+
"<checkSessionIsValid> current session length: ",
|
|
132
|
+
session_length_seconds
|
|
133
|
+
);
|
|
134
|
+
if (!last_event_time || session_length_seconds > this.session.length) {
|
|
135
|
+
return false;
|
|
136
|
+
} else {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
} catch (err) {
|
|
140
|
+
this.logger.log(
|
|
141
|
+
"session",
|
|
142
|
+
"<checkSessionIsValid> problem checking session length: ",
|
|
143
|
+
err
|
|
144
|
+
);
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export { MetaStreamIOSession };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { strf } from "./string.format.js";
|
|
4
|
+
|
|
5
|
+
strf();
|
|
6
|
+
|
|
7
|
+
class MetaStreamIOUser {
|
|
8
|
+
constructor({
|
|
9
|
+
constants = null,
|
|
10
|
+
logger = null,
|
|
11
|
+
id = null,
|
|
12
|
+
ciam_id = null,
|
|
13
|
+
email_id = null,
|
|
14
|
+
country = null,
|
|
15
|
+
} = {}) {
|
|
16
|
+
this.constant = constants;
|
|
17
|
+
this.logger = logger;
|
|
18
|
+
this.set(id);
|
|
19
|
+
this.setCountry(country);
|
|
20
|
+
this.setCiam(ciam_id);
|
|
21
|
+
this.setEmail(email_id);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
reset() {
|
|
25
|
+
this.set();
|
|
26
|
+
this.setCiam();
|
|
27
|
+
this.setDeviceToken();
|
|
28
|
+
this.setEmail();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
set(id = null) {
|
|
32
|
+
if (id !== null) {
|
|
33
|
+
this.id = id;
|
|
34
|
+
} else {
|
|
35
|
+
this.id = this.constant.MetaStreamIO_User_Guest;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
this.logger.log(
|
|
39
|
+
"user",
|
|
40
|
+
this.constant.MetaStreamIO_Log_UserIdSet.format(this.id)
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
setCiam(id = null) {
|
|
45
|
+
this.ciam_id = id;
|
|
46
|
+
this.logger.log(
|
|
47
|
+
"user",
|
|
48
|
+
this.constant.MetaStreamIO_Log_CIAMIdSet.format(this.ciam_id)
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
setCountry(country = null) {
|
|
53
|
+
this.country = country;
|
|
54
|
+
this.logger.log(
|
|
55
|
+
"user",
|
|
56
|
+
this.constant.MetaStreamIO_Log_UserCountrySet.format(this.country)
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
setDeviceToken(device_token = null) {
|
|
61
|
+
this.device_token = device_token;
|
|
62
|
+
this.logger.log(
|
|
63
|
+
"user",
|
|
64
|
+
this.constant.MetaStreamIO_Log_PushDeviceTokenSet.format(
|
|
65
|
+
this.device_token
|
|
66
|
+
)
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
setEmail(email = null) {
|
|
71
|
+
this.email_id = email;
|
|
72
|
+
this.logger.log(
|
|
73
|
+
"user",
|
|
74
|
+
this.constant.MetaStreamIO_Log_EmailIdSet.format(this.email_id)
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export { MetaStreamIOUser };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { strf } from "./string.format.js";
|
|
4
|
+
|
|
5
|
+
strf();
|
|
6
|
+
|
|
7
|
+
import { UserPropertyModel } from "./models/event.userproperty.js";
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
*
|
|
11
|
+
* Environment class
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
class MetaStreamIOUserProperties {
|
|
16
|
+
constructor({ constants, logger, stored_user_properties, utility } = {}) {
|
|
17
|
+
this.constant = constants;
|
|
18
|
+
this.logger = logger;
|
|
19
|
+
this.properties = stored_user_properties ? stored_user_properties : {};
|
|
20
|
+
this.utility = utility;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
reset() {
|
|
24
|
+
this.properties = {};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
delete({ key } = {}) {
|
|
28
|
+
if (key in this.properties) {
|
|
29
|
+
delete this.properties[key];
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get({ key } = {}) {
|
|
35
|
+
if (key in this.properties) {
|
|
36
|
+
return this.properties[key];
|
|
37
|
+
} else {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
set({ key, value } = {}) {
|
|
43
|
+
let value_type = this.utility.type_to_name(value);
|
|
44
|
+
|
|
45
|
+
this.properties[key] = new UserPropertyModel({
|
|
46
|
+
key: key,
|
|
47
|
+
value_type: value_type,
|
|
48
|
+
value: value,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
this.logger.log(
|
|
52
|
+
"userproperties",
|
|
53
|
+
this.constant.MetaStreamIO_Log_UserPropertySet.format(
|
|
54
|
+
key,
|
|
55
|
+
JSON.stringify(value),
|
|
56
|
+
value_type
|
|
57
|
+
)
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
return this.get({ key: key });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
list() {
|
|
64
|
+
let properties = Object.keys(this.properties);
|
|
65
|
+
let list = [];
|
|
66
|
+
for (let property of properties) {
|
|
67
|
+
list.push({
|
|
68
|
+
key: this.properties[property].key,
|
|
69
|
+
value: this.properties[property].value_type_value,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return list;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { MetaStreamIOUserProperties };
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { strf } from "./string.format.js";
|
|
4
|
+
|
|
5
|
+
strf();
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
*
|
|
9
|
+
* Utilities class
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
class MetaStreamIOUtils {
|
|
14
|
+
constructor({ constants, date, logger } = {}) {
|
|
15
|
+
this.date = date;
|
|
16
|
+
this.logger = logger;
|
|
17
|
+
this.constant = constants;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
generateRandomId() {
|
|
21
|
+
return (
|
|
22
|
+
String(this.date.getEventTimestamp() * Math.random()) +
|
|
23
|
+
":" +
|
|
24
|
+
String(Math.floor(1000 + (9999 - 1000) * Math.random()))
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Check if input is an integer
|
|
29
|
+
isInteger(n) {
|
|
30
|
+
if (n != null) {
|
|
31
|
+
return Math.ceil(parseFloat(n)) === n;
|
|
32
|
+
} else {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Return the type of a given input
|
|
38
|
+
type_to_name(value) {
|
|
39
|
+
var type = typeof value;
|
|
40
|
+
if (type == "number") {
|
|
41
|
+
if (this.isInteger(value) === true) {
|
|
42
|
+
type = "integer";
|
|
43
|
+
} else {
|
|
44
|
+
type = "float";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return type;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Make a distinct copy of an object
|
|
51
|
+
copyObject(input) {
|
|
52
|
+
try {
|
|
53
|
+
return JSON.parse(JSON.stringify(input));
|
|
54
|
+
// return clone;
|
|
55
|
+
} catch {
|
|
56
|
+
return {};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Flatten an object
|
|
61
|
+
flattenArray(source, delimiter = ".", filter) {
|
|
62
|
+
var result = {};
|
|
63
|
+
(function flat(obj, stack) {
|
|
64
|
+
try {
|
|
65
|
+
Object.keys(obj).forEach(function (k) {
|
|
66
|
+
var s = stack.concat([k]);
|
|
67
|
+
var v = obj[k];
|
|
68
|
+
if (filter && filter(k, v)) return;
|
|
69
|
+
if (typeof v === "object") flat(v, s);
|
|
70
|
+
else result[s.join(delimiter)] = v;
|
|
71
|
+
});
|
|
72
|
+
} catch (err) {
|
|
73
|
+
return {};
|
|
74
|
+
}
|
|
75
|
+
})(source, []);
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Compare two objects
|
|
80
|
+
compareArrays({ newArray, oldArray } = {}) {
|
|
81
|
+
var nK = this.flattenArray(newArray);
|
|
82
|
+
var oK = this.flattenArray(oldArray);
|
|
83
|
+
if (Object.keys(nK).length !== Object.keys(oK).length) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
if (nK != null || nK != {}) {
|
|
87
|
+
if (oK != null || oK != {}) {
|
|
88
|
+
for (let x in nK) {
|
|
89
|
+
if (nK[x] !== oK[x]) {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Convert event object to a list of objects
|
|
101
|
+
eventObjToList(input = {}) {
|
|
102
|
+
var output = [];
|
|
103
|
+
var iK = Object.keys(input);
|
|
104
|
+
if (iK.length > 0) {
|
|
105
|
+
for (let x of iK) {
|
|
106
|
+
let val = {};
|
|
107
|
+
val["key"] = x;
|
|
108
|
+
val["value"] = input[x];
|
|
109
|
+
output.push(val);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return output;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Convert cart object to a list of objects with the bundle id as the key for each
|
|
116
|
+
cartObjToList(input = {}) {
|
|
117
|
+
var output = [];
|
|
118
|
+
var iK = Object.keys(input);
|
|
119
|
+
if (iK.length > 0) {
|
|
120
|
+
for (let x of iK) {
|
|
121
|
+
let bundle = {};
|
|
122
|
+
bundle["bundle_id"] = x;
|
|
123
|
+
let target = Object.assign({}, bundle, input[x]);
|
|
124
|
+
output.push(target);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return output;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Data hygiene: return only input or null
|
|
131
|
+
validateData(input) {
|
|
132
|
+
if (input !== "undefined" && input !== null) {
|
|
133
|
+
return input;
|
|
134
|
+
} else {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
setAppId(id) {
|
|
140
|
+
if (typeof id !== "undefined" && id.length > 0) {
|
|
141
|
+
this.logger.log(
|
|
142
|
+
"project",
|
|
143
|
+
this.constant.MetaStreamIO_IO_ProjectIdSet.format(id)
|
|
144
|
+
);
|
|
145
|
+
return id;
|
|
146
|
+
} else {
|
|
147
|
+
this.logger.warn(
|
|
148
|
+
"project",
|
|
149
|
+
this.constant.MetaStreamIO_IO_ProjectIdNotSet
|
|
150
|
+
);
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
sleep(ms) {
|
|
156
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
castEventParameterTypes(eventParameters) {
|
|
160
|
+
try {
|
|
161
|
+
let castEventParameters = [];
|
|
162
|
+
eventParameters.forEach((parameter) => {
|
|
163
|
+
let value_type = this.type_to_name(parameter.value);
|
|
164
|
+
let temp_param = {};
|
|
165
|
+
temp_param["key"] = parameter.key;
|
|
166
|
+
temp_param["value"] = { ["" + value_type]: parameter.value };
|
|
167
|
+
castEventParameters.push(temp_param);
|
|
168
|
+
});
|
|
169
|
+
return castEventParameters;
|
|
170
|
+
} catch (err) {
|
|
171
|
+
return [];
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async checkBlockingProcess(checkVariable) {
|
|
176
|
+
return new Promise(async (resolve, reject) => {
|
|
177
|
+
var max_retries = 5;
|
|
178
|
+
var retry = 0;
|
|
179
|
+
while (checkVariable === false && retry < max_retries) {
|
|
180
|
+
await this.sleep(500);
|
|
181
|
+
retry++;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
if (checkVariable === true) {
|
|
185
|
+
resolve(checkVariable);
|
|
186
|
+
} else {
|
|
187
|
+
reject(Object.keys(checkVariable));
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async makeBlockingProcess(checkVariable, fn, args) {
|
|
193
|
+
checkVariable = true;
|
|
194
|
+
let function_call = await fn(args)
|
|
195
|
+
.then((result) => {
|
|
196
|
+
return Promise.resolve(result);
|
|
197
|
+
})
|
|
198
|
+
.catch((result) => {
|
|
199
|
+
return Promise.reject(result);
|
|
200
|
+
});
|
|
201
|
+
checkVariable = false;
|
|
202
|
+
return function_call;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export { MetaStreamIOUtils };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export class AppConstructorModel {
|
|
2
|
+
constructor({
|
|
3
|
+
id = null,
|
|
4
|
+
channel = null,
|
|
5
|
+
environment = null,
|
|
6
|
+
endpoints = null,
|
|
7
|
+
headers = null,
|
|
8
|
+
} = {}) {
|
|
9
|
+
this.id = id;
|
|
10
|
+
this.channel = channel;
|
|
11
|
+
this.environment = environment;
|
|
12
|
+
this.endpoints = endpoints;
|
|
13
|
+
this.headers = headers;
|
|
14
|
+
}
|
|
15
|
+
json() {
|
|
16
|
+
return {
|
|
17
|
+
id: this.id,
|
|
18
|
+
channel: this.channel,
|
|
19
|
+
environment: this.environment,
|
|
20
|
+
endpoints: this.endpoints,
|
|
21
|
+
headers: this.headers,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
}
|