fix(tracker): expose canvas tracking restart method, remove context creation in assist

This commit is contained in:
nick-delirium 2024-01-11 17:03:57 +01:00
parent 1609a6f55a
commit 1796b08a87
6 changed files with 53 additions and 13 deletions

View file

@ -1,3 +1,7 @@
## 7.0.3
- small fix for canvas context tracking
## 7.0.1
- mark live sessions with ux test active

View file

@ -9,7 +9,6 @@ export default class CanvasRecorder {
private readonly onStream: (stream: MediaStream) => void,
private readonly logError: (...args: any[]) => void,
) {
this.canvas.getContext('2d', { alpha: true, })
const stream = this.canvas.captureStream(this.fps)
this.emitStream(stream)
}

View file

@ -4,6 +4,15 @@
- conditional recording with 30s buffer
- websockets tracking hook
# 11.0.5
- add method to restart canvas tracking (in case of context recreation)
- scan dom tree for canvas els on tracker start
# 11.0.4
- some additional security for canvas capture (check if canvas el itself is obscured/ignored)
# 11.0.3
- move all logs under internal debugger

View file

@ -10,6 +10,7 @@ interface CanvasSnapshot {
interface Options {
fps: number
quality: 'low' | 'medium' | 'high'
isDebug?: boolean
}
class CanvasRecorder {
@ -25,10 +26,17 @@ class CanvasRecorder {
}
startTracking() {
setTimeout(() => {
this.app.nodes.scanTree(this.handleCanvasEl)
this.app.nodes.attachNodeCallback((node: Node): void => {
this.handleCanvasEl(node)
})
}, 500)
}
restartTracking = () => {
this.clear()
this.app.nodes.scanTree(this.handleCanvasEl)
this.app.nodes.attachNodeCallback((node: Node): void => {
this.handleCanvasEl(node)
})
}
handleCanvasEl = (node: Node) => {
@ -74,7 +82,9 @@ class CanvasRecorder {
images.forEach((snapshot) => {
const blob = dataUrlToBlob(snapshot.data)[0]
formData.append('snapshot', blob, `${createdAt}_${canvasId}_${snapshot.id}.jpeg`)
// saveImageData(snapshot.data, `${createdAt}_${canvasId}_${snapshot.id}.jpeg`)
if (this.options.isDebug) {
saveImageData(snapshot.data, `${createdAt}_${canvasId}_${snapshot.id}.jpeg`)
}
})
fetch(this.app.options.ingestPoint + '/v1/web/images', {

View file

@ -115,6 +115,7 @@ type AppOptions = {
__is_snippet: boolean
__debug_report_edp: string | null
__debug__?: ILogLevel
__save_canvas_locally?: boolean
localStorage: Storage | null
sessionStorage: Storage | null
forceSingleTab?: boolean
@ -202,6 +203,7 @@ export default class App {
__is_snippet: false,
__debug_report_edp: null,
__debug__: LogLevel.Silent,
__save_canvas_locally: false,
localStorage: null,
sessionStorage: null,
disableStringDict: false,
@ -629,6 +631,7 @@ export default class App {
return needNewSessionID || !sessionToken
}
/**
* start buffering messages without starting the actual session, which gives
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger
@ -1050,6 +1053,17 @@ export default class App {
void this.featureFlags.reloadFlags()
this.activityState = ActivityState.Active
if (canvasEnabled) {
this.canvasRecorder =
this.canvasRecorder ??
new CanvasRecorder(this, {
fps: canvasFPS,
quality: canvasQuality,
isDebug: this.options.__save_canvas_locally,
})
this.canvasRecorder.startTracking()
}
/** --------------- COLD START BUFFER ------------------*/
if (isColdStart) {
const biggestBuffer =
@ -1067,13 +1081,6 @@ export default class App {
this.ticker.start()
}
if (canvasEnabled) {
this.canvasRecorder =
this.canvasRecorder ??
new CanvasRecorder(this, { fps: canvasFPS, quality: canvasQuality })
this.canvasRecorder.startTracking()
}
// get rid of onStart ?
if (typeof this.options.onStart === 'function') {
this.options.onStart(onStartInfo)
@ -1126,6 +1133,10 @@ export default class App {
})
}
restartCanvasTracking = () => {
this.canvasRecorder?.restartTracking()
}
flushBuffer = async (buffer: Message[]) => {
return new Promise((res) => {
let ended = false
@ -1196,7 +1207,7 @@ export default class App {
/**
* Creates a named hook that expects event name, data string and msg direction (up/down),
* it will skip any message bigger than 5 mb or event name bigger than 255 symbols
* @returns {(msgType: string, data: string, dir: 'up' | 'down') => void}
* @returns {(msgType: string, data: string, dir: "up" | "down") => void}
* */
trackWs(channelName: string): (msgType: string, data: string, dir: 'up' | 'down') => void {
const channel = channelName

View file

@ -254,6 +254,13 @@ export default class API {
return this.app?.featureFlags.flags
}
public restartCanvasTracking = () => {
if (this.app === null) {
return
}
this.app.restartCanvasTracking()
}
use<T>(fn: (app: App | null, options?: Options) => T): T {
return fn(this.app, this.options)
}