@openreplay/tracker 12.0.0 → 12.0.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ # 12.0.2
2
+
3
+ - fix for canvas snapshot check
4
+
5
+ # 12.0.1
6
+
7
+ - pause canvas snapshotting when its offscreen
8
+
1
9
  # 12.0.0
2
10
 
3
11
  - offline session recording and manual sending
@@ -13,7 +13,8 @@ declare class CanvasRecorder {
13
13
  constructor(app: App, options: Options);
14
14
  startTracking(): void;
15
15
  restartTracking: () => void;
16
- handleCanvasEl: (node: Node) => void;
16
+ captureCanvas: (node: Node) => void;
17
+ recordCanvas: (node: Node, id: number) => void;
17
18
  sendSnaps(images: {
18
19
  data: string;
19
20
  id: number;
package/cjs/app/canvas.js CHANGED
@@ -10,9 +10,9 @@ class CanvasRecorder {
10
10
  this.intervals = [];
11
11
  this.restartTracking = () => {
12
12
  this.clear();
13
- this.app.nodes.scanTree(this.handleCanvasEl);
13
+ this.app.nodes.scanTree(this.captureCanvas);
14
14
  };
15
- this.handleCanvasEl = (node) => {
15
+ this.captureCanvas = (node) => {
16
16
  const id = this.app.nodes.getID(node);
17
17
  if (!id || !(0, guards_js_1.hasTag)(node, 'canvas')) {
18
18
  return;
@@ -21,10 +21,39 @@ class CanvasRecorder {
21
21
  if (isIgnored || !(0, guards_js_1.hasTag)(node, 'canvas') || this.snapshots[id]) {
22
22
  return;
23
23
  }
24
+ const observer = new IntersectionObserver((entries) => {
25
+ entries.forEach((entry) => {
26
+ if (entry.isIntersecting) {
27
+ if (entry.target) {
28
+ if (this.snapshots[id] && this.snapshots[id].createdAt) {
29
+ this.snapshots[id].paused = false;
30
+ }
31
+ else {
32
+ this.recordCanvas(entry.target, id);
33
+ }
34
+ /**
35
+ * We can switch this to start observing when element is in the view
36
+ * but otherwise right now we're just pausing when it's not
37
+ * just to save some bandwidth and space on backend
38
+ * */
39
+ // observer.unobserve(entry.target)
40
+ }
41
+ else {
42
+ if (this.snapshots[id]) {
43
+ this.snapshots[id].paused = true;
44
+ }
45
+ }
46
+ }
47
+ });
48
+ });
49
+ observer.observe(node);
50
+ };
51
+ this.recordCanvas = (node, id) => {
24
52
  const ts = this.app.timestamp();
25
53
  this.snapshots[id] = {
26
54
  images: [],
27
55
  createdAt: ts,
56
+ paused: false,
28
57
  };
29
58
  const canvasMsg = (0, messages_gen_js_1.CanvasNode)(id.toString(), ts);
30
59
  this.app.send(canvasMsg);
@@ -36,11 +65,13 @@ class CanvasRecorder {
36
65
  clearInterval(int);
37
66
  }
38
67
  else {
39
- const snapshot = captureSnapshot(canvas, this.options.quality);
40
- this.snapshots[id].images.push({ id: this.app.timestamp(), data: snapshot });
41
- if (this.snapshots[id].images.length > 9) {
42
- this.sendSnaps(this.snapshots[id].images, id, this.snapshots[id].createdAt);
43
- this.snapshots[id].images = [];
68
+ if (!this.snapshots[id].paused) {
69
+ const snapshot = captureSnapshot(canvas, this.options.quality);
70
+ this.snapshots[id].images.push({ id: this.app.timestamp(), data: snapshot });
71
+ if (this.snapshots[id].images.length > 9) {
72
+ this.sendSnaps(this.snapshots[id].images, id, this.snapshots[id].createdAt);
73
+ this.snapshots[id].images = [];
74
+ }
44
75
  }
45
76
  }
46
77
  }, this.interval);
@@ -50,9 +81,9 @@ class CanvasRecorder {
50
81
  }
51
82
  startTracking() {
52
83
  setTimeout(() => {
53
- this.app.nodes.scanTree(this.handleCanvasEl);
84
+ this.app.nodes.scanTree(this.captureCanvas);
54
85
  this.app.nodes.attachNodeCallback((node) => {
55
- this.handleCanvasEl(node);
86
+ this.captureCanvas(node);
56
87
  });
57
88
  }, 500);
58
89
  }
@@ -101,6 +132,8 @@ function captureSnapshot(canvas, quality = 'medium') {
101
132
  }
102
133
  function dataUrlToBlob(dataUrl) {
103
134
  const [header, base64] = dataUrl.split(',');
135
+ if (!header || !base64)
136
+ return null;
104
137
  const encParts = header.match(/:(.*?);/);
105
138
  if (!encParts)
106
139
  return null;
package/cjs/app/index.js CHANGED
@@ -81,7 +81,7 @@ class App {
81
81
  this.stopCallbacks = [];
82
82
  this.commitCallbacks = [];
83
83
  this.activityState = ActivityState.NotActive;
84
- this.version = '12.0.0'; // TODO: version compatability check inside each plugin.
84
+ this.version = '12.0.2'; // TODO: version compatability check inside each plugin.
85
85
  this.compressionThreshold = 24 * 1000;
86
86
  this.restartAttempts = 0;
87
87
  this.bc = null;
package/cjs/index.js CHANGED
@@ -98,7 +98,7 @@ class API {
98
98
  const orig = this.options.ingestPoint || index_js_1.DEFAULT_INGEST_POINT;
99
99
  req.open('POST', orig + '/v1/web/not-started');
100
100
  req.send(JSON.stringify({
101
- trackerVersion: '12.0.0',
101
+ trackerVersion: '12.0.2',
102
102
  projectKey: this.options.projectKey,
103
103
  doNotTrack,
104
104
  reason,
@@ -13,7 +13,8 @@ declare class CanvasRecorder {
13
13
  constructor(app: App, options: Options);
14
14
  startTracking(): void;
15
15
  restartTracking: () => void;
16
- handleCanvasEl: (node: Node) => void;
16
+ captureCanvas: (node: Node) => void;
17
+ recordCanvas: (node: Node, id: number) => void;
17
18
  sendSnaps(images: {
18
19
  data: string;
19
20
  id: number;
package/lib/app/canvas.js CHANGED
@@ -8,9 +8,9 @@ class CanvasRecorder {
8
8
  this.intervals = [];
9
9
  this.restartTracking = () => {
10
10
  this.clear();
11
- this.app.nodes.scanTree(this.handleCanvasEl);
11
+ this.app.nodes.scanTree(this.captureCanvas);
12
12
  };
13
- this.handleCanvasEl = (node) => {
13
+ this.captureCanvas = (node) => {
14
14
  const id = this.app.nodes.getID(node);
15
15
  if (!id || !hasTag(node, 'canvas')) {
16
16
  return;
@@ -19,10 +19,39 @@ class CanvasRecorder {
19
19
  if (isIgnored || !hasTag(node, 'canvas') || this.snapshots[id]) {
20
20
  return;
21
21
  }
22
+ const observer = new IntersectionObserver((entries) => {
23
+ entries.forEach((entry) => {
24
+ if (entry.isIntersecting) {
25
+ if (entry.target) {
26
+ if (this.snapshots[id] && this.snapshots[id].createdAt) {
27
+ this.snapshots[id].paused = false;
28
+ }
29
+ else {
30
+ this.recordCanvas(entry.target, id);
31
+ }
32
+ /**
33
+ * We can switch this to start observing when element is in the view
34
+ * but otherwise right now we're just pausing when it's not
35
+ * just to save some bandwidth and space on backend
36
+ * */
37
+ // observer.unobserve(entry.target)
38
+ }
39
+ else {
40
+ if (this.snapshots[id]) {
41
+ this.snapshots[id].paused = true;
42
+ }
43
+ }
44
+ }
45
+ });
46
+ });
47
+ observer.observe(node);
48
+ };
49
+ this.recordCanvas = (node, id) => {
22
50
  const ts = this.app.timestamp();
23
51
  this.snapshots[id] = {
24
52
  images: [],
25
53
  createdAt: ts,
54
+ paused: false,
26
55
  };
27
56
  const canvasMsg = CanvasNode(id.toString(), ts);
28
57
  this.app.send(canvasMsg);
@@ -34,11 +63,13 @@ class CanvasRecorder {
34
63
  clearInterval(int);
35
64
  }
36
65
  else {
37
- const snapshot = captureSnapshot(canvas, this.options.quality);
38
- this.snapshots[id].images.push({ id: this.app.timestamp(), data: snapshot });
39
- if (this.snapshots[id].images.length > 9) {
40
- this.sendSnaps(this.snapshots[id].images, id, this.snapshots[id].createdAt);
41
- this.snapshots[id].images = [];
66
+ if (!this.snapshots[id].paused) {
67
+ const snapshot = captureSnapshot(canvas, this.options.quality);
68
+ this.snapshots[id].images.push({ id: this.app.timestamp(), data: snapshot });
69
+ if (this.snapshots[id].images.length > 9) {
70
+ this.sendSnaps(this.snapshots[id].images, id, this.snapshots[id].createdAt);
71
+ this.snapshots[id].images = [];
72
+ }
42
73
  }
43
74
  }
44
75
  }, this.interval);
@@ -48,9 +79,9 @@ class CanvasRecorder {
48
79
  }
49
80
  startTracking() {
50
81
  setTimeout(() => {
51
- this.app.nodes.scanTree(this.handleCanvasEl);
82
+ this.app.nodes.scanTree(this.captureCanvas);
52
83
  this.app.nodes.attachNodeCallback((node) => {
53
- this.handleCanvasEl(node);
84
+ this.captureCanvas(node);
54
85
  });
55
86
  }, 500);
56
87
  }
@@ -99,6 +130,8 @@ function captureSnapshot(canvas, quality = 'medium') {
99
130
  }
100
131
  function dataUrlToBlob(dataUrl) {
101
132
  const [header, base64] = dataUrl.split(',');
133
+ if (!header || !base64)
134
+ return null;
102
135
  const encParts = header.match(/:(.*?);/);
103
136
  if (!encParts)
104
137
  return null;
package/lib/app/index.js CHANGED
@@ -52,7 +52,7 @@ export default class App {
52
52
  this.stopCallbacks = [];
53
53
  this.commitCallbacks = [];
54
54
  this.activityState = ActivityState.NotActive;
55
- this.version = '12.0.0'; // TODO: version compatability check inside each plugin.
55
+ this.version = '12.0.2'; // TODO: version compatability check inside each plugin.
56
56
  this.compressionThreshold = 24 * 1000;
57
57
  this.restartAttempts = 0;
58
58
  this.bc = null;
package/lib/index.js CHANGED
@@ -67,7 +67,7 @@ export default class API {
67
67
  const orig = this.options.ingestPoint || DEFAULT_INGEST_POINT;
68
68
  req.open('POST', orig + '/v1/web/not-started');
69
69
  req.send(JSON.stringify({
70
- trackerVersion: '12.0.0',
70
+ trackerVersion: '12.0.2',
71
71
  projectKey: this.options.projectKey,
72
72
  doNotTrack,
73
73
  reason,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@openreplay/tracker",
3
3
  "description": "The OpenReplay tracker main package",
4
- "version": "12.0.0",
4
+ "version": "12.0.2",
5
5
  "keywords": [
6
6
  "logging",
7
7
  "replay"