@openreplay/tracker 3.6.3 → 3.6.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/.eslintignore +8 -0
- package/cjs/app/guards.js +1 -2
- package/cjs/app/index.d.ts +15 -13
- package/cjs/app/index.js +58 -42
- package/cjs/app/logger.js +6 -3
- package/cjs/app/observer/iframe_observer.d.ts +1 -1
- package/cjs/app/observer/iframe_observer.js +1 -1
- package/cjs/app/observer/observer.d.ts +2 -3
- package/cjs/app/observer/observer.js +38 -40
- package/cjs/app/observer/shadow_root_observer.d.ts +1 -1
- package/cjs/app/observer/shadow_root_observer.js +1 -1
- package/cjs/app/observer/top_observer.d.ts +2 -2
- package/cjs/app/observer/top_observer.js +12 -11
- package/cjs/app/sanitizer.d.ts +1 -1
- package/cjs/app/sanitizer.js +5 -5
- package/cjs/app/session.d.ts +14 -2
- package/cjs/app/session.js +19 -6
- package/cjs/app/ticker.d.ts +1 -1
- package/cjs/common/messages.d.ts +1 -1
- package/cjs/common/messages.js +69 -120
- package/cjs/common/webworker.d.ts +3 -3
- package/cjs/index.d.ts +9 -8
- package/cjs/index.js +34 -28
- package/cjs/modules/connection.d.ts +1 -1
- package/cjs/modules/console.d.ts +1 -1
- package/cjs/modules/console.js +5 -5
- package/cjs/modules/cssrules.d.ts +1 -1
- package/cjs/modules/cssrules.js +3 -3
- package/cjs/modules/exception.d.ts +2 -2
- package/cjs/modules/exception.js +7 -6
- package/cjs/modules/img.d.ts +1 -1
- package/cjs/modules/img.js +15 -12
- package/cjs/modules/input.d.ts +1 -1
- package/cjs/modules/input.js +15 -15
- package/cjs/modules/longtasks.d.ts +1 -1
- package/cjs/modules/longtasks.js +13 -5
- package/cjs/modules/mouse.d.ts +1 -1
- package/cjs/modules/mouse.js +10 -12
- package/cjs/modules/performance.d.ts +1 -1
- package/cjs/modules/scroll.d.ts +1 -1
- package/cjs/modules/timing.d.ts +1 -1
- package/cjs/modules/timing.js +12 -24
- package/cjs/modules/viewport.d.ts +1 -1
- package/cjs/utils.js +7 -7
- package/cjs/vendors/finder/finder.js +53 -48
- package/lib/app/guards.js +1 -2
- package/lib/app/index.d.ts +15 -13
- package/lib/app/index.js +67 -51
- package/lib/app/logger.js +6 -3
- package/lib/app/observer/iframe_observer.d.ts +1 -1
- package/lib/app/observer/iframe_observer.js +3 -3
- package/lib/app/observer/observer.d.ts +2 -3
- package/lib/app/observer/observer.js +40 -42
- package/lib/app/observer/shadow_root_observer.d.ts +1 -1
- package/lib/app/observer/shadow_root_observer.js +3 -3
- package/lib/app/observer/top_observer.d.ts +2 -2
- package/lib/app/observer/top_observer.js +17 -16
- package/lib/app/sanitizer.d.ts +1 -1
- package/lib/app/sanitizer.js +7 -7
- package/lib/app/session.d.ts +14 -2
- package/lib/app/session.js +19 -6
- package/lib/app/ticker.d.ts +1 -1
- package/lib/common/messages.d.ts +1 -1
- package/lib/common/messages.js +69 -120
- package/lib/common/tsconfig.tsbuildinfo +1 -1
- package/lib/common/webworker.d.ts +3 -3
- package/lib/index.d.ts +9 -8
- package/lib/index.js +49 -43
- package/lib/modules/connection.d.ts +1 -1
- package/lib/modules/connection.js +1 -1
- package/lib/modules/console.d.ts +1 -1
- package/lib/modules/console.js +8 -8
- package/lib/modules/cssrules.d.ts +1 -1
- package/lib/modules/cssrules.js +5 -5
- package/lib/modules/exception.d.ts +2 -2
- package/lib/modules/exception.js +8 -7
- package/lib/modules/img.d.ts +1 -1
- package/lib/modules/img.js +18 -15
- package/lib/modules/input.d.ts +1 -1
- package/lib/modules/input.js +18 -18
- package/lib/modules/longtasks.d.ts +1 -1
- package/lib/modules/longtasks.js +14 -6
- package/lib/modules/mouse.d.ts +1 -1
- package/lib/modules/mouse.js +14 -16
- package/lib/modules/performance.d.ts +1 -1
- package/lib/modules/performance.js +2 -2
- package/lib/modules/scroll.d.ts +1 -1
- package/lib/modules/scroll.js +2 -2
- package/lib/modules/timing.d.ts +1 -1
- package/lib/modules/timing.js +15 -27
- package/lib/modules/viewport.d.ts +1 -1
- package/lib/modules/viewport.js +1 -1
- package/lib/utils.js +7 -7
- package/lib/vendors/finder/finder.js +53 -48
- package/package.json +28 -10
|
@@ -13,13 +13,9 @@ function isIgnored(node) {
|
|
|
13
13
|
if (tag === 'LINK') {
|
|
14
14
|
const rel = node.getAttribute('rel');
|
|
15
15
|
const as = node.getAttribute('as');
|
|
16
|
-
return !((rel === null || rel === void 0 ? void 0 : rel.includes('stylesheet')) || as ===
|
|
16
|
+
return !((rel === null || rel === void 0 ? void 0 : rel.includes('stylesheet')) || as === 'style' || as === 'font');
|
|
17
17
|
}
|
|
18
|
-
return (tag === 'SCRIPT' ||
|
|
19
|
-
tag === 'NOSCRIPT' ||
|
|
20
|
-
tag === 'META' ||
|
|
21
|
-
tag === 'TITLE' ||
|
|
22
|
-
tag === 'BASE');
|
|
18
|
+
return (tag === 'SCRIPT' || tag === 'NOSCRIPT' || tag === 'META' || tag === 'TITLE' || tag === 'BASE');
|
|
23
19
|
}
|
|
24
20
|
function isObservable(node) {
|
|
25
21
|
if ((0, guards_js_1.isRootNode)(node)) {
|
|
@@ -32,17 +28,11 @@ function isObservable(node) {
|
|
|
32
28
|
- fix unbinding logic + send all removals first (ensure sequence is correct)
|
|
33
29
|
- use document as a 0-node in the upper context (should be updated in player at first)
|
|
34
30
|
*/
|
|
35
|
-
/*
|
|
36
|
-
Nikita:
|
|
37
|
-
- rn we only send unbind event for parent (all child nodes will be cut in the live replay anyways)
|
|
38
|
-
to prevent sending 1k+ unbinds for child nodes and making replay file bigger than it should be
|
|
39
|
-
*/
|
|
40
31
|
var RecentsType;
|
|
41
32
|
(function (RecentsType) {
|
|
42
33
|
RecentsType[RecentsType["New"] = 0] = "New";
|
|
43
34
|
RecentsType[RecentsType["Removed"] = 1] = "Removed";
|
|
44
35
|
RecentsType[RecentsType["Changed"] = 2] = "Changed";
|
|
45
|
-
RecentsType[RecentsType["RemovedChild"] = 3] = "RemovedChild";
|
|
46
36
|
})(RecentsType || (RecentsType = {}));
|
|
47
37
|
class Observer {
|
|
48
38
|
constructor(app, isTopContext = false) {
|
|
@@ -54,7 +44,8 @@ class Observer {
|
|
|
54
44
|
this.attributesMap = new Map();
|
|
55
45
|
this.textSet = new Set();
|
|
56
46
|
this.observer = new MutationObserver(this.app.safe((mutations) => {
|
|
57
|
-
for (const mutation of mutations) {
|
|
47
|
+
for (const mutation of mutations) {
|
|
48
|
+
// mutations order is sequential
|
|
58
49
|
const target = mutation.target;
|
|
59
50
|
const type = mutation.type;
|
|
60
51
|
if (!isObservable(target)) {
|
|
@@ -62,7 +53,10 @@ class Observer {
|
|
|
62
53
|
}
|
|
63
54
|
if (type === 'childList') {
|
|
64
55
|
for (let i = 0; i < mutation.removedNodes.length; i++) {
|
|
65
|
-
|
|
56
|
+
// Should be the same as bindTree(mutation.removedNodes[i]), but logic needs to be be untied
|
|
57
|
+
if (isObservable(mutation.removedNodes[i])) {
|
|
58
|
+
this.bindNode(mutation.removedNodes[i]);
|
|
59
|
+
}
|
|
66
60
|
}
|
|
67
61
|
for (let i = 0; i < mutation.addedNodes.length; i++) {
|
|
68
62
|
this.bindTree(mutation.addedNodes[i]);
|
|
@@ -83,7 +77,7 @@ class Observer {
|
|
|
83
77
|
}
|
|
84
78
|
let attr = this.attributesMap.get(id);
|
|
85
79
|
if (attr === undefined) {
|
|
86
|
-
this.attributesMap.set(id, attr = new Set());
|
|
80
|
+
this.attributesMap.set(id, (attr = new Set()));
|
|
87
81
|
}
|
|
88
82
|
attr.add(name);
|
|
89
83
|
continue;
|
|
@@ -131,7 +125,7 @@ class Observer {
|
|
|
131
125
|
return;
|
|
132
126
|
}
|
|
133
127
|
if (name === 'value' &&
|
|
134
|
-
(0, guards_js_1.hasTag)(node,
|
|
128
|
+
(0, guards_js_1.hasTag)(node, 'INPUT') &&
|
|
135
129
|
node.type !== 'button' &&
|
|
136
130
|
node.type !== 'reset' &&
|
|
137
131
|
node.type !== 'submit') {
|
|
@@ -141,7 +135,7 @@ class Observer {
|
|
|
141
135
|
this.app.send(new messages_js_1.RemoveNodeAttribute(id, name));
|
|
142
136
|
return;
|
|
143
137
|
}
|
|
144
|
-
if (name === 'style' || name === 'href' && (0, guards_js_1.hasTag)(node,
|
|
138
|
+
if (name === 'style' || (name === 'href' && (0, guards_js_1.hasTag)(node, 'LINK'))) {
|
|
145
139
|
this.app.send(new messages_js_1.SetNodeAttributeURLBased(id, name, value, this.app.getBaseHref()));
|
|
146
140
|
return;
|
|
147
141
|
}
|
|
@@ -151,7 +145,7 @@ class Observer {
|
|
|
151
145
|
this.app.send(new messages_js_1.SetNodeAttribute(id, name, value));
|
|
152
146
|
}
|
|
153
147
|
sendNodeData(id, parentElement, data) {
|
|
154
|
-
if ((0, guards_js_1.hasTag)(parentElement,
|
|
148
|
+
if ((0, guards_js_1.hasTag)(parentElement, 'STYLE') || (0, guards_js_1.hasTag)(parentElement, 'style')) {
|
|
155
149
|
this.app.send(new messages_js_1.SetCSSDataURLBased(id, data, this.app.getBaseHref()));
|
|
156
150
|
return;
|
|
157
151
|
}
|
|
@@ -163,40 +157,43 @@ class Observer {
|
|
|
163
157
|
if (isNew) {
|
|
164
158
|
this.recents.set(id, RecentsType.New);
|
|
165
159
|
}
|
|
166
|
-
else if (this.recents.get(id) !== RecentsType.New) {
|
|
160
|
+
else if (this.recents.get(id) !== RecentsType.New) {
|
|
167
161
|
this.recents.set(id, RecentsType.Removed);
|
|
168
162
|
}
|
|
169
163
|
}
|
|
170
|
-
|
|
171
|
-
const [id] = this.app.nodes.registerNode(node);
|
|
172
|
-
this.recents.set(id, RecentsType.RemovedChild);
|
|
173
|
-
}
|
|
174
|
-
bindTree(node, isChildUnbinding = false) {
|
|
164
|
+
bindTree(node) {
|
|
175
165
|
if (!isObservable(node)) {
|
|
176
166
|
return;
|
|
177
167
|
}
|
|
178
168
|
this.bindNode(node);
|
|
179
169
|
const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
|
|
180
|
-
acceptNode: (node) => isIgnored(node)
|
|
181
|
-
|| (this.app.nodes.getID(node) !== undefined && !isChildUnbinding)
|
|
170
|
+
acceptNode: (node) => isIgnored(node) || this.app.nodes.getID(node) !== undefined
|
|
182
171
|
? NodeFilter.FILTER_REJECT
|
|
183
172
|
: NodeFilter.FILTER_ACCEPT,
|
|
184
173
|
},
|
|
185
174
|
// @ts-ignore
|
|
186
175
|
false);
|
|
187
176
|
while (walker.nextNode()) {
|
|
188
|
-
|
|
189
|
-
this.unbindChildNode(walker.currentNode);
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
this.bindNode(walker.currentNode);
|
|
193
|
-
}
|
|
177
|
+
this.bindNode(walker.currentNode);
|
|
194
178
|
}
|
|
195
179
|
}
|
|
196
|
-
|
|
180
|
+
unbindTree(node) {
|
|
197
181
|
const id = this.app.nodes.unregisterNode(node);
|
|
198
182
|
if (id !== undefined && this.recents.get(id) === RecentsType.Removed) {
|
|
199
|
-
|
|
183
|
+
// Sending RemoveNode only for parent to maintain
|
|
184
|
+
this.app.send((0, messages_js_1.RemoveNode)(id));
|
|
185
|
+
// Unregistering all the children in order to clear the memory
|
|
186
|
+
const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
|
|
187
|
+
acceptNode: (node) => isIgnored(node) || this.app.nodes.getID(node) === undefined
|
|
188
|
+
? NodeFilter.FILTER_REJECT
|
|
189
|
+
: NodeFilter.FILTER_ACCEPT,
|
|
190
|
+
},
|
|
191
|
+
// @ts-ignore
|
|
192
|
+
false);
|
|
193
|
+
while (walker.nextNode()) {
|
|
194
|
+
this.app.nodes.unregisterNode(walker.currentNode);
|
|
195
|
+
}
|
|
196
|
+
// MBTODO: count and send RemovedNodesCount (for the page crash detection in heuristics)
|
|
200
197
|
}
|
|
201
198
|
}
|
|
202
199
|
// A top-consumption function on the infinite lists test. (~1% of performance resources)
|
|
@@ -209,20 +206,20 @@ class Observer {
|
|
|
209
206
|
// Disable parent check for the upper context HTMLHtmlElement, because it is root there... (before)
|
|
210
207
|
// TODO: get rid of "special" cases (there is an issue with CreateDocument altered behaviour though)
|
|
211
208
|
// TODO: Clean the logic (though now it workd fine)
|
|
212
|
-
if (!(0, guards_js_1.hasTag)(node,
|
|
209
|
+
if (!(0, guards_js_1.hasTag)(node, 'HTML') || !this.isTopContext) {
|
|
213
210
|
if (parent === null) {
|
|
214
211
|
// Sometimes one observation contains attribute mutations for the removimg node, which gets ignored here.
|
|
215
|
-
// That shouldn't affect the visual rendering ( should it? )
|
|
216
|
-
this.
|
|
212
|
+
// That shouldn't affect the visual rendering ( should it? maybe when transition applied? )
|
|
213
|
+
this.unbindTree(node);
|
|
217
214
|
return false;
|
|
218
215
|
}
|
|
219
216
|
parentID = this.app.nodes.getID(parent);
|
|
220
217
|
if (parentID === undefined) {
|
|
221
|
-
this.
|
|
218
|
+
this.unbindTree(node);
|
|
222
219
|
return false;
|
|
223
220
|
}
|
|
224
221
|
if (!this.commitNode(parentID)) {
|
|
225
|
-
this.
|
|
222
|
+
this.unbindTree(node);
|
|
226
223
|
return false;
|
|
227
224
|
}
|
|
228
225
|
this.app.sanitizer.handleNode(id, parentID, node);
|
|
@@ -317,7 +314,8 @@ class Observer {
|
|
|
317
314
|
});
|
|
318
315
|
this.clear();
|
|
319
316
|
}
|
|
320
|
-
// ISSSUE
|
|
317
|
+
// ISSSUE (nodeToBinde should be the same as node. Look at the comment about 0-node at the beginning of the file.)
|
|
318
|
+
// TODO: use one observer instance for all iframes/shadowRoots (composition instiad of inheritance)
|
|
321
319
|
observeRoot(node, beforeCommit, nodeToBind = node) {
|
|
322
320
|
this.observer.observe(node, {
|
|
323
321
|
childList: true,
|
|
@@ -11,7 +11,7 @@ class ShadowRootObserver extends observer_js_1.default {
|
|
|
11
11
|
} // log
|
|
12
12
|
this.observeRoot(shRoot, (rootID) => {
|
|
13
13
|
if (rootID === undefined) {
|
|
14
|
-
console.log(
|
|
14
|
+
console.log('OpenReplay: Shadow Root was not bound');
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
this.app.send((0, messages_js_1.CreateIFrameDocument)(hostID, rootID));
|
|
@@ -13,18 +13,18 @@ class TopObserver extends observer_js_1.default {
|
|
|
13
13
|
this.iframeObservers = [];
|
|
14
14
|
this.shadowRootObservers = [];
|
|
15
15
|
this.options = Object.assign({
|
|
16
|
-
captureIFrames: true
|
|
16
|
+
captureIFrames: true,
|
|
17
17
|
}, options);
|
|
18
18
|
// IFrames
|
|
19
|
-
this.app.nodes.attachNodeCallback(node => {
|
|
20
|
-
if ((0, guards_js_1.hasTag)(node,
|
|
21
|
-
((this.options.captureIFrames && !(0, utils_js_1.hasOpenreplayAttribute)(node,
|
|
22
|
-
|
|
19
|
+
this.app.nodes.attachNodeCallback((node) => {
|
|
20
|
+
if ((0, guards_js_1.hasTag)(node, 'IFRAME') &&
|
|
21
|
+
((this.options.captureIFrames && !(0, utils_js_1.hasOpenreplayAttribute)(node, 'obscured')) ||
|
|
22
|
+
(0, utils_js_1.hasOpenreplayAttribute)(node, 'capture'))) {
|
|
23
23
|
this.handleIframe(node);
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
26
|
// ShadowDOM
|
|
27
|
-
this.app.nodes.attachNodeCallback(node => {
|
|
27
|
+
this.app.nodes.attachNodeCallback((node) => {
|
|
28
28
|
if ((0, guards_js_1.isElementNode)(node) && node.shadowRoot !== null) {
|
|
29
29
|
this.handleShadowRoot(node.shadowRoot);
|
|
30
30
|
}
|
|
@@ -48,7 +48,7 @@ class TopObserver extends observer_js_1.default {
|
|
|
48
48
|
this.iframeObservers.push(observer);
|
|
49
49
|
observer.observe(iframe);
|
|
50
50
|
});
|
|
51
|
-
iframe.addEventListener(
|
|
51
|
+
iframe.addEventListener('load', handle); // why app.attachEventListener not working?
|
|
52
52
|
handle();
|
|
53
53
|
}
|
|
54
54
|
handleShadowRoot(shRoot) {
|
|
@@ -60,14 +60,15 @@ class TopObserver extends observer_js_1.default {
|
|
|
60
60
|
// Protection from several subsequent calls?
|
|
61
61
|
const observer = this;
|
|
62
62
|
Element.prototype.attachShadow = function () {
|
|
63
|
+
// eslint-disable-next-line
|
|
63
64
|
const shadow = attachShadowNativeFn.apply(this, arguments);
|
|
64
65
|
observer.handleShadowRoot(shadow);
|
|
65
66
|
return shadow;
|
|
66
67
|
};
|
|
67
68
|
// Can observe documentElement (<html>) here, because it is not supposed to be changing.
|
|
68
69
|
// However, it is possible in some exotic cases and may cause an ignorance of the newly created <html>
|
|
69
|
-
// In this case context.document have to be observed, but this will cause
|
|
70
|
-
// the change in the re-player behaviour caused by CreateDocument message:
|
|
70
|
+
// In this case context.document have to be observed, but this will cause
|
|
71
|
+
// the change in the re-player behaviour caused by CreateDocument message:
|
|
71
72
|
// the 0-node ("fRoot") will become #document rather than documentElement as it is now.
|
|
72
73
|
// Alternatively - observe(#document) then bindNode(documentElement)
|
|
73
74
|
this.observeRoot(window.document, () => {
|
|
@@ -76,9 +77,9 @@ class TopObserver extends observer_js_1.default {
|
|
|
76
77
|
}
|
|
77
78
|
disconnect() {
|
|
78
79
|
Element.prototype.attachShadow = attachShadowNativeFn;
|
|
79
|
-
this.iframeObservers.forEach(o => o.disconnect());
|
|
80
|
+
this.iframeObservers.forEach((o) => o.disconnect());
|
|
80
81
|
this.iframeObservers = [];
|
|
81
|
-
this.shadowRootObservers.forEach(o => o.disconnect());
|
|
82
|
+
this.shadowRootObservers.forEach((o) => o.disconnect());
|
|
82
83
|
this.shadowRootObservers = [];
|
|
83
84
|
super.disconnect();
|
|
84
85
|
}
|
package/cjs/app/sanitizer.d.ts
CHANGED
package/cjs/app/sanitizer.js
CHANGED
|
@@ -14,20 +14,20 @@ class Sanitizer {
|
|
|
14
14
|
}
|
|
15
15
|
handleNode(id, parentID, node) {
|
|
16
16
|
if (this.masked.has(parentID) ||
|
|
17
|
-
((0, guards_js_1.isElementNode)(node) &&
|
|
18
|
-
(0, utils_js_1.hasOpenreplayAttribute)(node, 'masked'))) {
|
|
17
|
+
((0, guards_js_1.isElementNode)(node) && (0, utils_js_1.hasOpenreplayAttribute)(node, 'masked'))) {
|
|
19
18
|
this.masked.add(id);
|
|
20
19
|
}
|
|
21
20
|
if (this.maskedContainers.has(parentID) ||
|
|
22
|
-
((0, guards_js_1.isElementNode)(node) &&
|
|
23
|
-
(0, utils_js_1.hasOpenreplayAttribute)(node, 'htmlmasked'))) {
|
|
21
|
+
((0, guards_js_1.isElementNode)(node) && (0, utils_js_1.hasOpenreplayAttribute)(node, 'htmlmasked'))) {
|
|
24
22
|
this.maskedContainers.add(id);
|
|
25
23
|
}
|
|
26
24
|
}
|
|
27
25
|
sanitize(id, data) {
|
|
28
26
|
if (this.masked.has(id)) {
|
|
29
27
|
// TODO: is it the best place to put trim() ? Might trimmed spaces be considered in layout in certain cases?
|
|
30
|
-
return data
|
|
28
|
+
return data
|
|
29
|
+
.trim()
|
|
30
|
+
.replace(/[^\f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/g, '█');
|
|
31
31
|
}
|
|
32
32
|
if (this.options.obscureTextNumbers) {
|
|
33
33
|
data = data.replace(/\d/g, '0');
|
package/cjs/app/session.d.ts
CHANGED
|
@@ -1,14 +1,26 @@
|
|
|
1
|
+
import type App from './index.js';
|
|
1
2
|
interface SessionInfo {
|
|
2
|
-
sessionID: string |
|
|
3
|
+
sessionID: string | undefined;
|
|
3
4
|
metadata: Record<string, string>;
|
|
4
5
|
userID: string | null;
|
|
6
|
+
timestamp: number;
|
|
7
|
+
projectID?: string;
|
|
5
8
|
}
|
|
6
9
|
declare type OnUpdateCallback = (i: Partial<SessionInfo>) => void;
|
|
10
|
+
export declare type Options = {
|
|
11
|
+
session_token_key: string;
|
|
12
|
+
session_pageno_key: string;
|
|
13
|
+
};
|
|
7
14
|
export default class Session {
|
|
15
|
+
private readonly app;
|
|
16
|
+
private readonly options;
|
|
8
17
|
private metadata;
|
|
9
18
|
private userID;
|
|
10
19
|
private sessionID;
|
|
11
|
-
private callbacks;
|
|
20
|
+
private readonly callbacks;
|
|
21
|
+
private timestamp;
|
|
22
|
+
private projectID;
|
|
23
|
+
constructor(app: App, options: Options);
|
|
12
24
|
attachUpdateCallback(cb: OnUpdateCallback): void;
|
|
13
25
|
private handleUpdate;
|
|
14
26
|
update(newInfo: Partial<SessionInfo>): void;
|
package/cjs/app/session.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
class Session {
|
|
4
|
-
constructor() {
|
|
4
|
+
constructor(app, options) {
|
|
5
|
+
this.app = app;
|
|
6
|
+
this.options = options;
|
|
5
7
|
this.metadata = {};
|
|
6
8
|
this.userID = null;
|
|
7
|
-
this.sessionID = null;
|
|
8
9
|
this.callbacks = [];
|
|
10
|
+
this.timestamp = 0;
|
|
9
11
|
}
|
|
10
12
|
attachUpdateCallback(cb) {
|
|
11
13
|
this.callbacks.push(cb);
|
|
@@ -17,18 +19,25 @@ class Session {
|
|
|
17
19
|
if (newInfo.sessionID == null) {
|
|
18
20
|
delete newInfo.sessionID;
|
|
19
21
|
}
|
|
20
|
-
this.callbacks.forEach(cb => cb(newInfo));
|
|
22
|
+
this.callbacks.forEach((cb) => cb(newInfo));
|
|
21
23
|
}
|
|
22
24
|
update(newInfo) {
|
|
23
|
-
if (newInfo.userID !== undefined) {
|
|
25
|
+
if (newInfo.userID !== undefined) {
|
|
26
|
+
// TODO clear nullable/undefinable types
|
|
24
27
|
this.userID = newInfo.userID;
|
|
25
28
|
}
|
|
26
29
|
if (newInfo.metadata !== undefined) {
|
|
27
|
-
Object.entries(newInfo.metadata).forEach(([k, v]) => this.metadata[k] = v);
|
|
30
|
+
Object.entries(newInfo.metadata).forEach(([k, v]) => (this.metadata[k] = v));
|
|
28
31
|
}
|
|
29
32
|
if (newInfo.sessionID !== undefined) {
|
|
30
33
|
this.sessionID = newInfo.sessionID;
|
|
31
34
|
}
|
|
35
|
+
if (newInfo.timestamp !== undefined) {
|
|
36
|
+
this.timestamp = newInfo.timestamp;
|
|
37
|
+
}
|
|
38
|
+
if (newInfo.projectID !== undefined) {
|
|
39
|
+
this.projectID = newInfo.projectID;
|
|
40
|
+
}
|
|
32
41
|
this.handleUpdate(newInfo);
|
|
33
42
|
}
|
|
34
43
|
setMetadata(key, value) {
|
|
@@ -44,12 +53,16 @@ class Session {
|
|
|
44
53
|
sessionID: this.sessionID,
|
|
45
54
|
metadata: this.metadata,
|
|
46
55
|
userID: this.userID,
|
|
56
|
+
timestamp: this.timestamp,
|
|
57
|
+
projectID: this.projectID,
|
|
47
58
|
};
|
|
48
59
|
}
|
|
49
60
|
reset() {
|
|
61
|
+
this.app.sessionStorage.removeItem(this.options.session_token_key);
|
|
50
62
|
this.metadata = {};
|
|
51
63
|
this.userID = null;
|
|
52
|
-
this.sessionID =
|
|
64
|
+
this.sessionID = undefined;
|
|
65
|
+
this.timestamp = 0;
|
|
53
66
|
}
|
|
54
67
|
}
|
|
55
68
|
exports.default = Session;
|
package/cjs/app/ticker.d.ts
CHANGED
package/cjs/common/messages.d.ts
CHANGED