@miso.ai/client-sdk-core 1.13.0-beta.4 → 1.13.0-beta.6
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/cjs/plugin/analytics.js +75 -1
- package/dist/cjs/version.js +1 -1
- package/package.json +4 -3
- package/src/plugin/analytics.js +78 -2
- package/src/version.js +1 -1
|
@@ -15,6 +15,7 @@ class AnalyticsPlugin extends _commons.Component {
|
|
|
15
15
|
super('analytics');
|
|
16
16
|
this._members = [];
|
|
17
17
|
this._engagement = undefined;
|
|
18
|
+
this._activity = undefined;
|
|
18
19
|
}
|
|
19
20
|
config(options = {}) {
|
|
20
21
|
this._options = options;
|
|
@@ -27,13 +28,19 @@ class AnalyticsPlugin extends _commons.Component {
|
|
|
27
28
|
install(MisoClient, context) {
|
|
28
29
|
context.addSubtree(this);
|
|
29
30
|
this._engagement = new _commons.UserEngagementObserver(this._handleEngagement.bind(this));
|
|
30
|
-
|
|
31
|
+
this._activity = new _commons.UserActivityObserver(this._handleActivity.bind(this));
|
|
32
|
+
// TODO: should we provide a way to stop the observer?
|
|
33
|
+
window.addEventListener('beforeunload', this._handlePageExit.bind(this));
|
|
34
|
+
window.addEventListener('click', this._handleClick.bind(this, MisoClient));
|
|
31
35
|
MisoClient.on('create', this._injectClient.bind(this));
|
|
32
36
|
}
|
|
33
37
|
_injectClient(client) {
|
|
34
38
|
client.on('workflow', this._injectWorkflow.bind(this));
|
|
35
39
|
}
|
|
36
40
|
_injectWorkflow(workflow) {
|
|
41
|
+
if (!shallApplyAnalytics(workflow)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
37
44
|
workflow.analytics = new Analytics(this, workflow);
|
|
38
45
|
}
|
|
39
46
|
_handleEngagement() {
|
|
@@ -41,8 +48,74 @@ class AnalyticsPlugin extends _commons.Component {
|
|
|
41
48
|
member._syncEngagementState();
|
|
42
49
|
}
|
|
43
50
|
}
|
|
51
|
+
_handleActivity(event) {
|
|
52
|
+
for (const member of this._members) {
|
|
53
|
+
member._sendHeartbeat();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
_handlePageExit() {
|
|
57
|
+
for (const member of this._members) {
|
|
58
|
+
member._sendHeartbeat();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
_handleClick(MisoClient, event) {
|
|
62
|
+
// get the first client instance
|
|
63
|
+
const client = MisoClient.instances[0];
|
|
64
|
+
if (!client) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const workflow = getGenericClickWorkflow(this, event);
|
|
68
|
+
if (!workflow || !isDataReady(workflow)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const href = getGenericClickHref(event);
|
|
72
|
+
if (!href) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
workflow.trackers.container.genericClick({
|
|
76
|
+
href
|
|
77
|
+
});
|
|
78
|
+
}
|
|
44
79
|
}
|
|
45
80
|
exports.default = AnalyticsPlugin;
|
|
81
|
+
function shallApplyAnalytics(workflow) {
|
|
82
|
+
return workflow._name === 'ask' && !workflow.previous || workflow._name === 'hybrid-search';
|
|
83
|
+
}
|
|
84
|
+
function getGenericClickWorkflow(plugin, event) {
|
|
85
|
+
// find the closet container
|
|
86
|
+
for (let element = event.target; element; element = element.parentElement) {
|
|
87
|
+
const {
|
|
88
|
+
role,
|
|
89
|
+
workflow
|
|
90
|
+
} = element;
|
|
91
|
+
if (role && !workflow) {
|
|
92
|
+
return undefined; // inside component, not a generic click
|
|
93
|
+
}
|
|
94
|
+
// if inside a container, we should use the container's workflow
|
|
95
|
+
if (workflow) {
|
|
96
|
+
return shallApplyAnalytics(workflow) ? workflow : undefined;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// fallback to default workflow
|
|
101
|
+
for (const member of plugin._members) {
|
|
102
|
+
const workflow = member._workflow;
|
|
103
|
+
if (shallApplyAnalytics(workflow)) {
|
|
104
|
+
return workflow;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
function getGenericClickHref(event) {
|
|
110
|
+
const element = event.target.closest('[href]');
|
|
111
|
+
return element ? element.getAttribute('href') : undefined;
|
|
112
|
+
}
|
|
113
|
+
function isDataReady(workflow) {
|
|
114
|
+
const {
|
|
115
|
+
data = {}
|
|
116
|
+
} = workflow.states;
|
|
117
|
+
return data.status === 'ready';
|
|
118
|
+
}
|
|
46
119
|
function normalizeOptions(_ref = {}) {
|
|
47
120
|
let options = Object.assign({}, (_objectDestructuringEmpty(_ref), _ref));
|
|
48
121
|
return Object.assign({}, options);
|
|
@@ -157,5 +230,6 @@ class Analytics {
|
|
|
157
230
|
} else {
|
|
158
231
|
this._timer.stop();
|
|
159
232
|
}
|
|
233
|
+
this._sendHeartbeat();
|
|
160
234
|
}
|
|
161
235
|
}
|
package/dist/cjs/version.js
CHANGED
package/package.json
CHANGED
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
|
-
"url": "git+https://github.com/MisoAI/miso-client-js-sdk.git"
|
|
21
|
+
"url": "git+https://github.com/MisoAI/miso-client-js-sdk.git",
|
|
22
|
+
"directory": "packages/client-sdk-core"
|
|
22
23
|
},
|
|
23
24
|
"homepage": "https://misoai.github.io/miso-client-js-sdk/",
|
|
24
25
|
"license": "MIT",
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
"url": "https://github.com/MisoAI/miso-client-js-sdk/issues"
|
|
30
31
|
},
|
|
31
32
|
"dependencies": {
|
|
32
|
-
"@miso.ai/commons": "1.13.0-beta.
|
|
33
|
+
"@miso.ai/commons": "1.13.0-beta.6"
|
|
33
34
|
},
|
|
34
|
-
"version": "1.13.0-beta.
|
|
35
|
+
"version": "1.13.0-beta.6"
|
|
35
36
|
}
|
package/src/plugin/analytics.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component, UserEngagementObserver, Stopwatch, trimObj, mergeInteractions } from '@miso.ai/commons';
|
|
1
|
+
import { Component, UserEngagementObserver, UserActivityObserver, Stopwatch, trimObj, mergeInteractions } from '@miso.ai/commons';
|
|
2
2
|
|
|
3
3
|
const PLUGIN_ID = 'std:analytics';
|
|
4
4
|
|
|
@@ -12,6 +12,7 @@ export default class AnalyticsPlugin extends Component {
|
|
|
12
12
|
super('analytics');
|
|
13
13
|
this._members = [];
|
|
14
14
|
this._engagement = undefined;
|
|
15
|
+
this._activity = undefined;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
config(options = {}) {
|
|
@@ -26,7 +27,10 @@ export default class AnalyticsPlugin extends Component {
|
|
|
26
27
|
install(MisoClient, context) {
|
|
27
28
|
context.addSubtree(this);
|
|
28
29
|
this._engagement = new UserEngagementObserver(this._handleEngagement.bind(this));
|
|
29
|
-
|
|
30
|
+
this._activity = new UserActivityObserver(this._handleActivity.bind(this));
|
|
31
|
+
// TODO: should we provide a way to stop the observer?
|
|
32
|
+
window.addEventListener('beforeunload', this._handlePageExit.bind(this));
|
|
33
|
+
window.addEventListener('click', this._handleClick.bind(this, MisoClient));
|
|
30
34
|
MisoClient.on('create', this._injectClient.bind(this));
|
|
31
35
|
}
|
|
32
36
|
|
|
@@ -35,6 +39,9 @@ export default class AnalyticsPlugin extends Component {
|
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
_injectWorkflow(workflow) {
|
|
42
|
+
if (!shallApplyAnalytics(workflow)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
38
45
|
workflow.analytics = new Analytics(this, workflow);
|
|
39
46
|
}
|
|
40
47
|
|
|
@@ -44,6 +51,73 @@ export default class AnalyticsPlugin extends Component {
|
|
|
44
51
|
}
|
|
45
52
|
}
|
|
46
53
|
|
|
54
|
+
_handleActivity(event) {
|
|
55
|
+
for (const member of this._members) {
|
|
56
|
+
member._sendHeartbeat();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
_handlePageExit() {
|
|
61
|
+
for (const member of this._members) {
|
|
62
|
+
member._sendHeartbeat();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
_handleClick(MisoClient, event) {
|
|
67
|
+
// get the first client instance
|
|
68
|
+
const client = MisoClient.instances[0];
|
|
69
|
+
if (!client) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const workflow = getGenericClickWorkflow(this, event);
|
|
73
|
+
if (!workflow || !isDataReady(workflow)) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const href = getGenericClickHref(event);
|
|
77
|
+
if (!href) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
workflow.trackers.container.genericClick({ href });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function shallApplyAnalytics(workflow) {
|
|
86
|
+
return (workflow._name === 'ask' && !workflow.previous) || workflow._name === 'hybrid-search';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function getGenericClickWorkflow(plugin, event) {
|
|
90
|
+
// find the closet container
|
|
91
|
+
for (let element = event.target; element; element = element.parentElement) {
|
|
92
|
+
const { role, workflow } = element;
|
|
93
|
+
if (role && !workflow) {
|
|
94
|
+
return undefined; // inside component, not a generic click
|
|
95
|
+
}
|
|
96
|
+
// if inside a container, we should use the container's workflow
|
|
97
|
+
if (workflow) {
|
|
98
|
+
return shallApplyAnalytics(workflow) ? workflow : undefined;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// fallback to default workflow
|
|
103
|
+
for (const member of plugin._members) {
|
|
104
|
+
const workflow = member._workflow;
|
|
105
|
+
if (shallApplyAnalytics(workflow)) {
|
|
106
|
+
return workflow;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function getGenericClickHref(event) {
|
|
114
|
+
const element = event.target.closest('[href]');
|
|
115
|
+
return element ? element.getAttribute('href') : undefined;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function isDataReady(workflow) {
|
|
119
|
+
const { data = {} } = workflow.states;
|
|
120
|
+
return data.status === 'ready';
|
|
47
121
|
}
|
|
48
122
|
|
|
49
123
|
function normalizeOptions({ ...options } = {}) {
|
|
@@ -180,6 +254,8 @@ class Analytics {
|
|
|
180
254
|
} else {
|
|
181
255
|
this._timer.stop();
|
|
182
256
|
}
|
|
257
|
+
|
|
258
|
+
this._sendHeartbeat();
|
|
183
259
|
}
|
|
184
260
|
|
|
185
261
|
}
|
package/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '1.13.0-beta.
|
|
1
|
+
export default '1.13.0-beta.6';
|