@openreplay/tracker
Advanced tools
Comparing version 13.0.0 to 13.0.1
@@ -0,1 +1,6 @@ | ||
# 13.0.1 | ||
- moved canvas snapshots to webp, additional option to utilize useAnimationFrame method (for webgl) | ||
- simpler, faster canvas recording manager | ||
# 13.0.0 | ||
@@ -2,0 +7,0 @@ |
@@ -7,2 +7,3 @@ import App from '../app/index.js'; | ||
fixedScaling?: boolean; | ||
useAnimationFrame?: boolean; | ||
} | ||
@@ -21,3 +22,3 @@ declare class CanvasRecorder { | ||
sendSnaps(images: { | ||
data: string; | ||
data: Blob; | ||
id: number; | ||
@@ -24,0 +25,0 @@ }[], canvasId: number, createdAt: number): void; |
@@ -61,2 +61,13 @@ "use strict"; | ||
this.app.send(canvasMsg); | ||
const captureFn = (canvas) => { | ||
captureSnapshot(canvas, this.options.quality, this.snapshots[id].dummy, this.options.fixedScaling, (blob) => { | ||
if (!blob) | ||
return; | ||
this.snapshots[id].images.push({ id: this.app.timestamp(), data: blob }); | ||
if (this.snapshots[id].images.length > 9) { | ||
this.sendSnaps(this.snapshots[id].images, id, this.snapshots[id].createdAt); | ||
this.snapshots[id].images = []; | ||
} | ||
}); | ||
}; | ||
const int = setInterval(() => { | ||
@@ -71,8 +82,10 @@ const cid = this.app.nodes.getID(node); | ||
if (!this.snapshots[id].paused) { | ||
const snapshot = captureSnapshot(canvas, this.options.quality, this.snapshots[id].dummy, this.options.fixedScaling); | ||
this.snapshots[id].images.push({ id: this.app.timestamp(), data: snapshot }); | ||
if (this.snapshots[id].images.length > 9) { | ||
this.sendSnaps(this.snapshots[id].images, id, this.snapshots[id].createdAt); | ||
this.snapshots[id].images = []; | ||
if (this.options.useAnimationFrame) { | ||
requestAnimationFrame(() => { | ||
captureFn(canvas); | ||
}); | ||
} | ||
else { | ||
captureFn(canvas); | ||
} | ||
} | ||
@@ -99,8 +112,8 @@ } | ||
images.forEach((snapshot) => { | ||
const blob = dataUrlToBlob(snapshot.data); | ||
const blob = snapshot.data; | ||
if (!blob) | ||
return; | ||
formData.append('snapshot', blob[0], `${createdAt}_${canvasId}_${snapshot.id}.jpeg`); | ||
formData.append('snapshot', blob, `${createdAt}_${canvasId}_${snapshot.id}.webp`); | ||
if (this.options.isDebug) { | ||
saveImageData(snapshot.data, `${createdAt}_${canvasId}_${snapshot.id}.jpeg`); | ||
saveImageData(blob, `${createdAt}_${canvasId}_${snapshot.id}.webp`); | ||
} | ||
@@ -132,4 +145,4 @@ }); | ||
}; | ||
function captureSnapshot(canvas, quality = 'medium', dummy, fixedScaling = false) { | ||
const imageFormat = 'image/jpeg'; // or /png' | ||
function captureSnapshot(canvas, quality = 'medium', dummy, fixedScaling = false, onBlob) { | ||
const imageFormat = 'image/webp'; | ||
if (fixedScaling) { | ||
@@ -144,6 +157,6 @@ const canvasScaleRatio = window.devicePixelRatio || 1; | ||
ctx.drawImage(canvas, 0, 0, dummy.width, dummy.height); | ||
return dummy.toDataURL(imageFormat, qualityInt[quality]); | ||
dummy.toBlob(onBlob, imageFormat, qualityInt[quality]); | ||
} | ||
else { | ||
return canvas.toDataURL(imageFormat, qualityInt[quality]); | ||
canvas.toBlob(onBlob, imageFormat, qualityInt[quality]); | ||
} | ||
@@ -167,3 +180,4 @@ } | ||
} | ||
function saveImageData(imageDataUrl, name) { | ||
function saveImageData(imageDataBlob, name) { | ||
const imageDataUrl = URL.createObjectURL(imageDataBlob); | ||
const link = document.createElement('a'); | ||
@@ -170,0 +184,0 @@ link.href = imageDataUrl; |
@@ -61,2 +61,8 @@ import FeatureFlags from '../modules/featureFlags.js'; | ||
disableCanvas?: boolean; | ||
canvas: { | ||
disableCanvas?: boolean; | ||
fixedCanvasScaling?: boolean; | ||
__save_canvas_locally?: boolean; | ||
useAnimationFrame?: boolean; | ||
}; | ||
/** @deprecated */ | ||
@@ -63,0 +69,0 @@ onStart?: StartCallback; |
@@ -83,3 +83,3 @@ "use strict"; | ||
this.activityState = ActivityState.NotActive; | ||
this.version = '13.0.0'; // TODO: version compatability check inside each plugin. | ||
this.version = '13.0.1'; // TODO: version compatability check inside each plugin. | ||
this.socketMode = false; | ||
@@ -122,2 +122,14 @@ this.compressionThreshold = 24 * 1000; | ||
this.onUxtCb = []; | ||
if (Object.keys(options).findIndex((k) => ['fixedCanvasScaling', 'disableCanvas'].includes(k)) !== | ||
-1) { | ||
console.warn('Openreplay: canvas options are moving to separate key "canvas" in next update. Please update your configuration.'); | ||
options = { | ||
...options, | ||
canvas: { | ||
__save_canvas_locally: options.__save_canvas_locally, | ||
fixedCanvasScaling: options.fixedCanvasScaling, | ||
disableCanvas: options.disableCanvas, | ||
}, | ||
}; | ||
} | ||
this.contextId = Math.random().toString(36).slice(2); | ||
@@ -148,2 +160,8 @@ this.projectKey = projectKey; | ||
assistOnly: false, | ||
canvas: { | ||
disableCanvas: false, | ||
fixedCanvasScaling: false, | ||
__save_canvas_locally: false, | ||
useAnimationFrame: false, | ||
}, | ||
}, options); | ||
@@ -893,3 +911,3 @@ if (!this.options.forceSingleTab && globalThis && 'BroadcastChannel' in globalThis) { | ||
this.activityState = ActivityState.Active; | ||
if (canvasEnabled && !this.options.disableCanvas) { | ||
if (canvasEnabled && !this.options.canvas.disableCanvas) { | ||
this.canvasRecorder = | ||
@@ -900,4 +918,5 @@ this.canvasRecorder ?? | ||
quality: canvasQuality, | ||
isDebug: this.options.__save_canvas_locally, | ||
fixedScaling: this.options.fixedCanvasScaling, | ||
isDebug: this.options.canvas.__save_canvas_locally, | ||
fixedScaling: this.options.canvas.fixedCanvasScaling, | ||
useAnimationFrame: this.options.canvas.useAnimationFrame, | ||
}); | ||
@@ -904,0 +923,0 @@ this.canvasRecorder.startTracking(); |
@@ -100,3 +100,3 @@ "use strict"; | ||
req.send(JSON.stringify({ | ||
trackerVersion: '13.0.0', | ||
trackerVersion: '13.0.1', | ||
projectKey: this.options.projectKey, | ||
@@ -103,0 +103,0 @@ doNotTrack, |
@@ -7,2 +7,3 @@ import App from '../app/index.js'; | ||
fixedScaling?: boolean; | ||
useAnimationFrame?: boolean; | ||
} | ||
@@ -21,3 +22,3 @@ declare class CanvasRecorder { | ||
sendSnaps(images: { | ||
data: string; | ||
data: Blob; | ||
id: number; | ||
@@ -24,0 +25,0 @@ }[], canvasId: number, createdAt: number): void; |
@@ -59,2 +59,13 @@ import { hasTag } from './guards.js'; | ||
this.app.send(canvasMsg); | ||
const captureFn = (canvas) => { | ||
captureSnapshot(canvas, this.options.quality, this.snapshots[id].dummy, this.options.fixedScaling, (blob) => { | ||
if (!blob) | ||
return; | ||
this.snapshots[id].images.push({ id: this.app.timestamp(), data: blob }); | ||
if (this.snapshots[id].images.length > 9) { | ||
this.sendSnaps(this.snapshots[id].images, id, this.snapshots[id].createdAt); | ||
this.snapshots[id].images = []; | ||
} | ||
}); | ||
}; | ||
const int = setInterval(() => { | ||
@@ -69,8 +80,10 @@ const cid = this.app.nodes.getID(node); | ||
if (!this.snapshots[id].paused) { | ||
const snapshot = captureSnapshot(canvas, this.options.quality, this.snapshots[id].dummy, this.options.fixedScaling); | ||
this.snapshots[id].images.push({ id: this.app.timestamp(), data: snapshot }); | ||
if (this.snapshots[id].images.length > 9) { | ||
this.sendSnaps(this.snapshots[id].images, id, this.snapshots[id].createdAt); | ||
this.snapshots[id].images = []; | ||
if (this.options.useAnimationFrame) { | ||
requestAnimationFrame(() => { | ||
captureFn(canvas); | ||
}); | ||
} | ||
else { | ||
captureFn(canvas); | ||
} | ||
} | ||
@@ -97,8 +110,8 @@ } | ||
images.forEach((snapshot) => { | ||
const blob = dataUrlToBlob(snapshot.data); | ||
const blob = snapshot.data; | ||
if (!blob) | ||
return; | ||
formData.append('snapshot', blob[0], `${createdAt}_${canvasId}_${snapshot.id}.jpeg`); | ||
formData.append('snapshot', blob, `${createdAt}_${canvasId}_${snapshot.id}.webp`); | ||
if (this.options.isDebug) { | ||
saveImageData(snapshot.data, `${createdAt}_${canvasId}_${snapshot.id}.jpeg`); | ||
saveImageData(blob, `${createdAt}_${canvasId}_${snapshot.id}.webp`); | ||
} | ||
@@ -130,4 +143,4 @@ }); | ||
}; | ||
function captureSnapshot(canvas, quality = 'medium', dummy, fixedScaling = false) { | ||
const imageFormat = 'image/jpeg'; // or /png' | ||
function captureSnapshot(canvas, quality = 'medium', dummy, fixedScaling = false, onBlob) { | ||
const imageFormat = 'image/webp'; | ||
if (fixedScaling) { | ||
@@ -142,6 +155,6 @@ const canvasScaleRatio = window.devicePixelRatio || 1; | ||
ctx.drawImage(canvas, 0, 0, dummy.width, dummy.height); | ||
return dummy.toDataURL(imageFormat, qualityInt[quality]); | ||
dummy.toBlob(onBlob, imageFormat, qualityInt[quality]); | ||
} | ||
else { | ||
return canvas.toDataURL(imageFormat, qualityInt[quality]); | ||
canvas.toBlob(onBlob, imageFormat, qualityInt[quality]); | ||
} | ||
@@ -165,3 +178,4 @@ } | ||
} | ||
function saveImageData(imageDataUrl, name) { | ||
function saveImageData(imageDataBlob, name) { | ||
const imageDataUrl = URL.createObjectURL(imageDataBlob); | ||
const link = document.createElement('a'); | ||
@@ -168,0 +182,0 @@ link.href = imageDataUrl; |
@@ -61,2 +61,8 @@ import FeatureFlags from '../modules/featureFlags.js'; | ||
disableCanvas?: boolean; | ||
canvas: { | ||
disableCanvas?: boolean; | ||
fixedCanvasScaling?: boolean; | ||
__save_canvas_locally?: boolean; | ||
useAnimationFrame?: boolean; | ||
}; | ||
/** @deprecated */ | ||
@@ -63,0 +69,0 @@ onStart?: StartCallback; |
@@ -54,3 +54,3 @@ import ConditionsManager from '../modules/conditionsManager.js'; | ||
this.activityState = ActivityState.NotActive; | ||
this.version = '13.0.0'; // TODO: version compatability check inside each plugin. | ||
this.version = '13.0.1'; // TODO: version compatability check inside each plugin. | ||
this.socketMode = false; | ||
@@ -93,2 +93,14 @@ this.compressionThreshold = 24 * 1000; | ||
this.onUxtCb = []; | ||
if (Object.keys(options).findIndex((k) => ['fixedCanvasScaling', 'disableCanvas'].includes(k)) !== | ||
-1) { | ||
console.warn('Openreplay: canvas options are moving to separate key "canvas" in next update. Please update your configuration.'); | ||
options = { | ||
...options, | ||
canvas: { | ||
__save_canvas_locally: options.__save_canvas_locally, | ||
fixedCanvasScaling: options.fixedCanvasScaling, | ||
disableCanvas: options.disableCanvas, | ||
}, | ||
}; | ||
} | ||
this.contextId = Math.random().toString(36).slice(2); | ||
@@ -119,2 +131,8 @@ this.projectKey = projectKey; | ||
assistOnly: false, | ||
canvas: { | ||
disableCanvas: false, | ||
fixedCanvasScaling: false, | ||
__save_canvas_locally: false, | ||
useAnimationFrame: false, | ||
}, | ||
}, options); | ||
@@ -864,3 +882,3 @@ if (!this.options.forceSingleTab && globalThis && 'BroadcastChannel' in globalThis) { | ||
this.activityState = ActivityState.Active; | ||
if (canvasEnabled && !this.options.disableCanvas) { | ||
if (canvasEnabled && !this.options.canvas.disableCanvas) { | ||
this.canvasRecorder = | ||
@@ -871,4 +889,5 @@ this.canvasRecorder ?? | ||
quality: canvasQuality, | ||
isDebug: this.options.__save_canvas_locally, | ||
fixedScaling: this.options.fixedCanvasScaling, | ||
isDebug: this.options.canvas.__save_canvas_locally, | ||
fixedScaling: this.options.canvas.fixedCanvasScaling, | ||
useAnimationFrame: this.options.canvas.useAnimationFrame, | ||
}); | ||
@@ -875,0 +894,0 @@ this.canvasRecorder.startTracking(); |
@@ -69,3 +69,3 @@ import App, { DEFAULT_INGEST_POINT } from './app/index.js'; | ||
req.send(JSON.stringify({ | ||
trackerVersion: '13.0.0', | ||
trackerVersion: '13.0.1', | ||
projectKey: this.options.projectKey, | ||
@@ -72,0 +72,0 @@ doNotTrack, |
{ | ||
"name": "@openreplay/tracker", | ||
"description": "The OpenReplay tracker main package", | ||
"version": "13.0.0", | ||
"version": "13.0.1", | ||
"keywords": [ | ||
@@ -6,0 +6,0 @@ "logging", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3996346
23607