@miso.ai/client-sdk-ui 1.10.0-beta.9 → 1.10.0
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/actor/index.js +0 -7
- package/dist/cjs/actor/tracker.js +47 -102
- package/dist/cjs/actor/utils.js +1 -1
- package/dist/cjs/actor/view.js +12 -1
- package/dist/cjs/actor/views.js +24 -2
- package/dist/cjs/asset/svgs.js +14 -4
- package/dist/cjs/constants.js +3 -2
- package/dist/cjs/layout/affiliation/affiliation.js +150 -58
- package/dist/cjs/layout/input/option-list.js +34 -49
- package/dist/cjs/layout/list/collection.js +22 -43
- package/dist/cjs/layout/templates.js +54 -32
- package/dist/cjs/layout/text/typewriter/index.js +12 -7
- package/dist/cjs/layout/trackable.js +124 -0
- package/dist/cjs/util/bindings.js +58 -110
- package/dist/cjs/util/states.js +31 -24
- package/dist/cjs/util/trackers.js +75 -0
- package/dist/cjs/util/viewables.js +55 -0
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/workflow/ask.js +1 -5
- package/dist/cjs/workflow/base.js +2 -7
- package/dist/cjs/workflow/recommendation.js +2 -0
- package/package.json +2 -2
- package/src/actor/index.js +0 -1
- package/src/actor/tracker.js +37 -94
- package/src/actor/utils.js +1 -1
- package/src/actor/view.js +14 -1
- package/src/actor/views.js +30 -1
- package/src/asset/svgs.js +13 -2
- package/src/constants.js +7 -1
- package/src/layout/affiliation/affiliation.js +142 -55
- package/src/layout/input/option-list.js +35 -43
- package/src/layout/list/collection.js +20 -38
- package/src/layout/templates.js +25 -19
- package/src/layout/text/typewriter/index.js +8 -6
- package/src/layout/trackable.js +106 -0
- package/src/util/bindings.js +47 -103
- package/src/util/states.js +26 -20
- package/src/util/trackers.js +69 -0
- package/src/util/viewables.js +47 -0
- package/src/version.js +1 -1
- package/src/workflow/ask.js +1 -4
- package/src/workflow/base.js +3 -5
- package/src/workflow/recommendation.js +1 -0
- package/dist/cjs/actor/trackers.js +0 -51
- package/dist/cjs/layout/affiliation/viewable.js +0 -65
- package/dist/cjs/layout/text/typewriter/progress.js +0 -45
- package/dist/cjs/util/tracker.js +0 -348
- package/src/actor/trackers.js +0 -45
- package/src/layout/affiliation/viewable.js +0 -61
- package/src/layout/text/typewriter/progress.js +0 -33
- package/src/util/tracker.js +0 -318
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
var _commons = require("@miso.ai/commons");
|
|
8
|
-
class CarouselItemViewableTracker {
|
|
9
|
-
constructor(callback) {
|
|
10
|
-
let {
|
|
11
|
-
area = 0.5,
|
|
12
|
-
duration = 1000
|
|
13
|
-
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
14
|
-
this._callback = callback;
|
|
15
|
-
this._intersection = new IntersectionObserver(this._handleIntersection.bind(this), {
|
|
16
|
-
threshold: area
|
|
17
|
-
});
|
|
18
|
-
this._continuity = new _commons.ContinuityObserver(this._handleContinuity.bind(this), {
|
|
19
|
-
onDuration: duration
|
|
20
|
-
});
|
|
21
|
-
this._displayed = undefined;
|
|
22
|
-
this._intersecting = false;
|
|
23
|
-
this._triggered = new Set();
|
|
24
|
-
}
|
|
25
|
-
observe(element) {
|
|
26
|
-
this._intersection.observe(element);
|
|
27
|
-
}
|
|
28
|
-
unobserve(element) {
|
|
29
|
-
this._intersection.unobserve(element);
|
|
30
|
-
}
|
|
31
|
-
display(index) {
|
|
32
|
-
if (this._triggered.has(index)) {
|
|
33
|
-
index = undefined;
|
|
34
|
-
}
|
|
35
|
-
if (this._displayed === index) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
this._displayed = index;
|
|
39
|
-
this._continuity.value = false; // reset first, the old session is invalid now
|
|
40
|
-
this._syncContinuity();
|
|
41
|
-
}
|
|
42
|
-
disconnect() {
|
|
43
|
-
this._continuity.disconnect();
|
|
44
|
-
this._intersection.disconnect();
|
|
45
|
-
}
|
|
46
|
-
_syncContinuity() {
|
|
47
|
-
this._continuity.value = this._intersecting && this._displayed !== undefined;
|
|
48
|
-
}
|
|
49
|
-
_handleIntersection(entries) {
|
|
50
|
-
this._intersecting = entries[0].isIntersecting;
|
|
51
|
-
this._syncContinuity();
|
|
52
|
-
}
|
|
53
|
-
_handleContinuity(value) {
|
|
54
|
-
const displayed = this._displayed;
|
|
55
|
-
if (value && displayed !== undefined) {
|
|
56
|
-
if (this._triggered.has(displayed)) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
this._triggered.add(displayed);
|
|
60
|
-
this._displayed = undefined;
|
|
61
|
-
this._callback(displayed);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
exports.default = CarouselItemViewableTracker;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
class ProgressController {
|
|
8
|
-
constructor() {
|
|
9
|
-
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
10
|
-
this._cps = normalizeSpeedFunction(options);
|
|
11
|
-
}
|
|
12
|
-
get(prevState, newState) {
|
|
13
|
-
const cps = this._cps(newState);
|
|
14
|
-
const increment = Math.floor((newState.timestamp - prevState.timestamp) * cps / 1000);
|
|
15
|
-
return prevState.cursor + increment;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
exports.default = ProgressController;
|
|
19
|
-
function normalizeSpeedFunction() {
|
|
20
|
-
let {
|
|
21
|
-
speed = 100,
|
|
22
|
-
acceleration = 4
|
|
23
|
-
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
24
|
-
if (typeof speed === 'function') {
|
|
25
|
-
return speed;
|
|
26
|
-
}
|
|
27
|
-
if (typeof speed !== 'number') {
|
|
28
|
-
throw new Error(`Invalid speed: ${speed}`);
|
|
29
|
-
}
|
|
30
|
-
if (typeof acceleration !== 'number') {
|
|
31
|
-
throw new Error(`Invalid acceleration: ${acceleration}`);
|
|
32
|
-
}
|
|
33
|
-
return _ref => {
|
|
34
|
-
let {
|
|
35
|
-
doneAt,
|
|
36
|
-
timestamp
|
|
37
|
-
} = _ref;
|
|
38
|
-
let value = speed * (Math.random() + 0.5);
|
|
39
|
-
if (acceleration > 0 && doneAt !== undefined) {
|
|
40
|
-
// speed up gradually when input is done
|
|
41
|
-
value *= 1 + (timestamp - doneAt) * acceleration / 1000;
|
|
42
|
-
}
|
|
43
|
-
return value;
|
|
44
|
-
};
|
|
45
|
-
}
|
package/dist/cjs/util/tracker.js
DELETED
|
@@ -1,348 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
var _commons = require("@miso.ai/commons");
|
|
8
|
-
var _constants = require("../constants.js");
|
|
9
|
-
var _bindings = require("./bindings.js");
|
|
10
|
-
var _states = _interopRequireDefault(require("./states.js"));
|
|
11
|
-
var _proxy = _interopRequireDefault(require("./proxy.js"));
|
|
12
|
-
const _excluded = ["impression", "viewable", "click"],
|
|
13
|
-
_excluded2 = ["proxyElement", "element", "sessionId", "active", "bindings"];
|
|
14
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
|
-
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
|
|
16
|
-
const {
|
|
17
|
-
IMPRESSION,
|
|
18
|
-
VIEWABLE,
|
|
19
|
-
CLICK
|
|
20
|
-
} = _constants.EVENT_TYPE;
|
|
21
|
-
const {
|
|
22
|
-
UNTRACKED,
|
|
23
|
-
TRACKING,
|
|
24
|
-
TRIGGERED
|
|
25
|
-
} = _constants.TRACKING_STATUS;
|
|
26
|
-
const DEFAULT_TRACKING_OPTIONS = Object.freeze({
|
|
27
|
-
impression: Object.freeze({}),
|
|
28
|
-
viewable: Object.freeze({
|
|
29
|
-
area: 0.5,
|
|
30
|
-
duration: 1000
|
|
31
|
-
}),
|
|
32
|
-
click: Object.freeze({
|
|
33
|
-
lenient: false
|
|
34
|
-
}),
|
|
35
|
-
watch: false
|
|
36
|
-
});
|
|
37
|
-
function mergeOptions(def, opt) {
|
|
38
|
-
// if opt is falsy then return false, merge otherwise
|
|
39
|
-
return !!opt && Object.assign({}, def, opt);
|
|
40
|
-
}
|
|
41
|
-
function normalizeOptions(options) {
|
|
42
|
-
if (options === false) {
|
|
43
|
-
return false; // turn off all tracking
|
|
44
|
-
}
|
|
45
|
-
if (options === true) {
|
|
46
|
-
options = {};
|
|
47
|
-
}
|
|
48
|
-
if (typeof options !== 'object') {
|
|
49
|
-
throw new Error(`Invalid options: ${options}`);
|
|
50
|
-
}
|
|
51
|
-
const {
|
|
52
|
-
impression = {},
|
|
53
|
-
viewable = {},
|
|
54
|
-
click = {}
|
|
55
|
-
} = options,
|
|
56
|
-
rest = _objectWithoutPropertiesLoose(options, _excluded);
|
|
57
|
-
return (0, _commons.trimObj)(Object.assign({}, DEFAULT_TRACKING_OPTIONS, rest, {
|
|
58
|
-
impression: mergeOptions(DEFAULT_TRACKING_OPTIONS.impression, impression),
|
|
59
|
-
viewable: mergeOptions(DEFAULT_TRACKING_OPTIONS.viewable, viewable),
|
|
60
|
-
click: mergeOptions(DEFAULT_TRACKING_OPTIONS.click, click)
|
|
61
|
-
}));
|
|
62
|
-
}
|
|
63
|
-
class Tracker {
|
|
64
|
-
constructor() {
|
|
65
|
-
let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
66
|
-
let {
|
|
67
|
-
proxyElement,
|
|
68
|
-
element,
|
|
69
|
-
sessionId = 'default',
|
|
70
|
-
active = true,
|
|
71
|
-
bindings
|
|
72
|
-
} = _ref,
|
|
73
|
-
options = _objectWithoutPropertiesLoose(_ref, _excluded2);
|
|
74
|
-
this._events = new _commons.EventEmitter({
|
|
75
|
-
target: this
|
|
76
|
-
});
|
|
77
|
-
this._proxyElement = proxyElement || new _proxy.default(element);
|
|
78
|
-
this._getSessionId = typeof sessionId === 'function' ? sessionId : () => sessionId;
|
|
79
|
-
this._isActive = typeof active === 'function' ? active : () => active;
|
|
80
|
-
this._bindings = new _bindings.Bindings(bindings);
|
|
81
|
-
this._viewables = new WeakMap();
|
|
82
|
-
this._options = normalizeOptions(options);
|
|
83
|
-
this._unsubscribes = [this._proxyElement.on('click', event => this._handleClick(event)), this._proxyElement.on('element', () => this.refresh())];
|
|
84
|
-
this.refresh();
|
|
85
|
-
}
|
|
86
|
-
get active() {
|
|
87
|
-
return this._isActive();
|
|
88
|
-
}
|
|
89
|
-
config(options) {
|
|
90
|
-
this._options = normalizeOptions(options);
|
|
91
|
-
}
|
|
92
|
-
refresh() {
|
|
93
|
-
// refresh against root element
|
|
94
|
-
this._syncElement();
|
|
95
|
-
// refresh against view state
|
|
96
|
-
this._syncStates();
|
|
97
|
-
// refresh bindings
|
|
98
|
-
this._refreshBindings();
|
|
99
|
-
}
|
|
100
|
-
_syncStates() {
|
|
101
|
-
const sessionId = this._getSessionId();
|
|
102
|
-
if (!sessionId) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
if (this._states && sessionId !== this._states.sessionId) {
|
|
106
|
-
this._retireStates();
|
|
107
|
-
}
|
|
108
|
-
if (!this._states && sessionId) {
|
|
109
|
-
this._states = new _states.default(sessionId);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
impression(values, options) {
|
|
113
|
-
this._assertActive();
|
|
114
|
-
if (this._options && this._options.impression) {
|
|
115
|
-
this._trigger(IMPRESSION, values, Object.assign({
|
|
116
|
-
manual: true
|
|
117
|
-
}, options));
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
viewable(values, options) {
|
|
121
|
-
this._assertActive();
|
|
122
|
-
if (this._options && this._options.viewable) {
|
|
123
|
-
this._trigger(VIEWABLE, values, Object.assign({
|
|
124
|
-
manual: true
|
|
125
|
-
}, options));
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
click(values, options) {
|
|
129
|
-
this._assertActive();
|
|
130
|
-
if (this._options && this._options.click) {
|
|
131
|
-
this._trigger(CLICK, values, Object.assign({
|
|
132
|
-
manual: true
|
|
133
|
-
}, options));
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
_assertActive() {
|
|
137
|
-
if (!this._isActive()) {
|
|
138
|
-
throw new Error(`Tracker is not active.`);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
getState(value) {
|
|
142
|
-
// TODO: do we have to be so precise?
|
|
143
|
-
return Object.freeze(Object.assign({
|
|
144
|
-
[CLICK]: this._proxyElement.current ? TRACKING : UNTRACKED
|
|
145
|
-
}, this._states.getFullState(value)));
|
|
146
|
-
}
|
|
147
|
-
_syncElement() {
|
|
148
|
-
this._proxyElement.sync({
|
|
149
|
-
silent: true
|
|
150
|
-
});
|
|
151
|
-
const element = this._proxyElement.current;
|
|
152
|
-
if (this._element === element) {
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
// remove observer from old element
|
|
156
|
-
this._retireElement();
|
|
157
|
-
|
|
158
|
-
// add observer on new element
|
|
159
|
-
if (element) {
|
|
160
|
-
if (this._options && this._options.watch) {
|
|
161
|
-
// TODO: move to proxy element
|
|
162
|
-
this._mutationObserver = new MutationObserver(() => this.refresh());
|
|
163
|
-
this._mutationObserver.observe(element, {
|
|
164
|
-
childList: true,
|
|
165
|
-
subtree: true
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
this._element = element;
|
|
170
|
-
}
|
|
171
|
-
_retireElement() {
|
|
172
|
-
if (!this._element) {
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
if (this._mutationObserver) {
|
|
176
|
-
this._mutationObserver.disconnect();
|
|
177
|
-
this._mutationObserver = undefined;
|
|
178
|
-
}
|
|
179
|
-
this._element = undefined;
|
|
180
|
-
}
|
|
181
|
-
_retireStates() {
|
|
182
|
-
const {
|
|
183
|
-
unbounds
|
|
184
|
-
} = this._bindings.unbindAll();
|
|
185
|
-
this._untrackViewables(unbounds);
|
|
186
|
-
this._states = undefined;
|
|
187
|
-
}
|
|
188
|
-
_refreshBindings() {
|
|
189
|
-
if (!this._states) {
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
const element = this._proxyElement.current;
|
|
193
|
-
const {
|
|
194
|
-
bounds,
|
|
195
|
-
unbounds
|
|
196
|
-
} = this._bindings.refresh(element);
|
|
197
|
-
this._untrackViewables(unbounds);
|
|
198
|
-
this._trackImpressions(bounds);
|
|
199
|
-
this._trackViewables(bounds);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// impression //
|
|
203
|
-
_trackImpressions(bindings) {
|
|
204
|
-
const options = this._options && this._options.impression;
|
|
205
|
-
if (!options) {
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
this._trigger(IMPRESSION, bindings.map(b => b.value), {
|
|
209
|
-
bindings
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// viewable //
|
|
214
|
-
_trackViewables(bindings) {
|
|
215
|
-
const options = this._options && this._options.viewable;
|
|
216
|
-
if (!options) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
for (const binding of bindings) {
|
|
220
|
-
this._trackViewableOnElement(binding);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
async _trackViewableOnElement(binding) {
|
|
224
|
-
const {
|
|
225
|
-
value,
|
|
226
|
-
element
|
|
227
|
-
} = binding;
|
|
228
|
-
if (!value || !(0, _commons.isElement)(element) || this._viewables.has(element)) {
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
// TODO: when element is replaced without proper unload...
|
|
232
|
-
const state = this._states.get(value, VIEWABLE);
|
|
233
|
-
if (state !== UNTRACKED) {
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
this._states.set(value, VIEWABLE, TRACKING);
|
|
237
|
-
const {
|
|
238
|
-
area,
|
|
239
|
-
duration
|
|
240
|
-
} = this._options && this._options.viewable;
|
|
241
|
-
// abort signal
|
|
242
|
-
const ac = new AbortController();
|
|
243
|
-
const {
|
|
244
|
-
signal
|
|
245
|
-
} = ac;
|
|
246
|
-
this._viewables.set(element, {
|
|
247
|
-
ac
|
|
248
|
-
});
|
|
249
|
-
await (0, _commons.viewable)(element, {
|
|
250
|
-
area,
|
|
251
|
-
duration,
|
|
252
|
-
signal
|
|
253
|
-
});
|
|
254
|
-
this._viewables.delete(element);
|
|
255
|
-
this._trigger(VIEWABLE, [value], {
|
|
256
|
-
bindings: [binding]
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
_untrackViewableOnElement(_ref2) {
|
|
260
|
-
let {
|
|
261
|
-
value,
|
|
262
|
-
element
|
|
263
|
-
} = _ref2;
|
|
264
|
-
const viewable = this._viewables.get(element);
|
|
265
|
-
if (!viewable) {
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
viewable.ac.abort();
|
|
269
|
-
this._viewables.delete(element);
|
|
270
|
-
const type = VIEWABLE;
|
|
271
|
-
if (this._states.get(value, type) === TRACKING) {
|
|
272
|
-
this._states.set(value, type, UNTRACKED);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
_untrackViewables(bindings) {
|
|
276
|
-
for (const binding of bindings) {
|
|
277
|
-
this._untrackViewableOnElement(binding);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// click //
|
|
282
|
-
_handleClick(event) {
|
|
283
|
-
const options = this._options && this._options.click;
|
|
284
|
-
if (!options || !this._isActive()) {
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
const binding = this._bindings.get(event.target);
|
|
288
|
-
if (!binding) {
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// TODO: refactor
|
|
293
|
-
if (typeof options.validate === 'function') {
|
|
294
|
-
if (!options.validate(event, binding)) {
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
} else if (!options.lenient) {
|
|
298
|
-
// it must be a left click
|
|
299
|
-
if (event.button !== 0) {
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
// event default must not be prevented
|
|
303
|
-
if (event.defaultPrevented) {
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
// must go through a real link
|
|
307
|
-
if (!(0, _commons.findInAncestors)(event.target, element => element.tagName === 'A' && element.href || undefined)) {
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
this._trigger(CLICK, [binding.value], {
|
|
312
|
-
bindings: [binding]
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
_trigger(event, values) {
|
|
316
|
-
let {
|
|
317
|
-
manual = false,
|
|
318
|
-
bindings
|
|
319
|
-
} = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
320
|
-
(0, _constants.validateEventType)(event);
|
|
321
|
-
if (!this._isActive()) {
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// ignore already triggered
|
|
326
|
-
values = this._states.untriggered((0, _commons.asArray)(values), event);
|
|
327
|
-
if (values.length === 0) {
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
this._states.set(values, event, TRIGGERED);
|
|
331
|
-
this._events.emit(event, {
|
|
332
|
-
event,
|
|
333
|
-
values,
|
|
334
|
-
manual,
|
|
335
|
-
bindings
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
destroy() {
|
|
339
|
-
this._retireElement();
|
|
340
|
-
this._retireStates();
|
|
341
|
-
this._bindings._destroy();
|
|
342
|
-
for (const unsubscribe of this._unsubscribes) {
|
|
343
|
-
unsubscribe();
|
|
344
|
-
}
|
|
345
|
-
this._unsubscribes = [];
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
exports.default = Tracker;
|
package/src/actor/trackers.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import Tracker from './tracker.js';
|
|
2
|
-
|
|
3
|
-
export default class Trackers {
|
|
4
|
-
|
|
5
|
-
constructor(hub, { views, options }) {
|
|
6
|
-
this._hub = hub;
|
|
7
|
-
this._views = views;
|
|
8
|
-
this._options = options;
|
|
9
|
-
this._trackers = {};
|
|
10
|
-
options.on('trackers', () => this._syncConfig());
|
|
11
|
-
this._syncConfig();
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
_syncConfig() {
|
|
15
|
-
for (const [role, options] of Object.entries(this._options.resolved.trackers)) {
|
|
16
|
-
this._createOrConfigTracker(role, options);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
_createOrConfigTracker(role, options) {
|
|
21
|
-
if (options === undefined) {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
let tracker = this._trackers[role];
|
|
25
|
-
if (!tracker) {
|
|
26
|
-
tracker = this._trackers[role] = new Tracker(this._hub, this._views.get(role), options);
|
|
27
|
-
Object.defineProperty(this, role, {
|
|
28
|
-
get: () => this._trackers[role],
|
|
29
|
-
});
|
|
30
|
-
} else {
|
|
31
|
-
tracker.config(options);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
_destroy() {
|
|
36
|
-
for (const tracker of Object.values(this._trackers)) {
|
|
37
|
-
try {
|
|
38
|
-
tracker._destroy();
|
|
39
|
-
} catch (e) {
|
|
40
|
-
console.error(e);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { ContinuityObserver } from '@miso.ai/commons';
|
|
2
|
-
|
|
3
|
-
export default class CarouselItemViewableTracker {
|
|
4
|
-
|
|
5
|
-
constructor(callback, { area = 0.5, duration = 1000 } = {}) {
|
|
6
|
-
this._callback = callback;
|
|
7
|
-
this._intersection = new IntersectionObserver(this._handleIntersection.bind(this), { threshold: area });
|
|
8
|
-
this._continuity = new ContinuityObserver(this._handleContinuity.bind(this), { onDuration: duration });
|
|
9
|
-
|
|
10
|
-
this._displayed = undefined;
|
|
11
|
-
this._intersecting = false;
|
|
12
|
-
this._triggered = new Set();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
observe(element) {
|
|
16
|
-
this._intersection.observe(element);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
unobserve(element) {
|
|
20
|
-
this._intersection.unobserve(element);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
display(index) {
|
|
24
|
-
if (this._triggered.has(index)) {
|
|
25
|
-
index = undefined;
|
|
26
|
-
}
|
|
27
|
-
if (this._displayed === index) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
this._displayed = index;
|
|
31
|
-
this._continuity.value = false; // reset first, the old session is invalid now
|
|
32
|
-
this._syncContinuity();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
disconnect() {
|
|
36
|
-
this._continuity.disconnect();
|
|
37
|
-
this._intersection.disconnect();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
_syncContinuity() {
|
|
41
|
-
this._continuity.value = this._intersecting && this._displayed !== undefined;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
_handleIntersection(entries) {
|
|
45
|
-
this._intersecting = entries[0].isIntersecting;
|
|
46
|
-
this._syncContinuity();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
_handleContinuity(value) {
|
|
50
|
-
const displayed = this._displayed;
|
|
51
|
-
if (value && displayed !== undefined) {
|
|
52
|
-
if (this._triggered.has(displayed)) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
this._triggered.add(displayed);
|
|
56
|
-
this._displayed = undefined;
|
|
57
|
-
this._callback(displayed);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
export default class ProgressController {
|
|
2
|
-
|
|
3
|
-
constructor(options = {}) {
|
|
4
|
-
this._cps = normalizeSpeedFunction(options);
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
get(prevState, newState) {
|
|
8
|
-
const cps = this._cps(newState);
|
|
9
|
-
const increment = Math.floor((newState.timestamp - prevState.timestamp) * cps / 1000);
|
|
10
|
-
return prevState.cursor + increment;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function normalizeSpeedFunction({ speed = 100, acceleration = 4 } = {}) {
|
|
16
|
-
if (typeof speed === 'function') {
|
|
17
|
-
return speed;
|
|
18
|
-
}
|
|
19
|
-
if (typeof speed !== 'number') {
|
|
20
|
-
throw new Error(`Invalid speed: ${speed}`);
|
|
21
|
-
}
|
|
22
|
-
if (typeof acceleration !== 'number') {
|
|
23
|
-
throw new Error(`Invalid acceleration: ${acceleration}`);
|
|
24
|
-
}
|
|
25
|
-
return ({ doneAt, timestamp }) => {
|
|
26
|
-
let value = speed * (Math.random() + 0.5);
|
|
27
|
-
if (acceleration > 0 && doneAt !== undefined) {
|
|
28
|
-
// speed up gradually when input is done
|
|
29
|
-
value *= 1 + ((timestamp - doneAt) * acceleration / 1000);
|
|
30
|
-
}
|
|
31
|
-
return value;
|
|
32
|
-
};
|
|
33
|
-
}
|