From d22fcb3a2d70f8de3368b1500aae9e61f51a1040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=91=D0=B0=D0=B1?= =?UTF-8?q?=D1=83=D1=88=D0=BA=D0=B8=D0=BD?= Date: Thu, 17 Apr 2025 14:55:18 +0200 Subject: [PATCH] add node deletion to maintainer --- tracker/tracker/src/main/app/index.ts | 5 ++++- tracker/tracker/src/main/app/nodes/index.ts | 5 ++++- .../tracker/src/main/app/nodes/maintainer.ts | 18 ++++++++++++++---- .../tracker/src/main/app/observer/observer.ts | 4 ---- .../src/main/app/observer/top_observer.ts | 10 ++++++---- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/tracker/tracker/src/main/app/index.ts b/tracker/tracker/src/main/app/index.ts index 90e073ea3..843051981 100644 --- a/tracker/tracker/src/main/app/index.ts +++ b/tracker/tracker/src/main/app/index.ts @@ -279,6 +279,7 @@ export default class App { this.nodes.unregisterNodeById(id) this.send(RemoveNode(id)) }) + private readonly iframes: Map = new Map(); constructor( projectKey: string, @@ -367,8 +368,10 @@ export default class App { node_id: this.options.node_id, forceNgOff: Boolean(options.forceNgOff), maintainer: this.options.nodes?.maintainer, + vTree: this.vTree, + iframes: this.iframes, }) - this.observer = new Observer({ app: this, options, vTree: this.vTree }) + this.observer = new Observer({ app: this, options }, this.vTree, this.iframes) this.ticker = new Ticker(this) this.ticker.attach(() => this.commit()) this.debug = new Logger(this.options.__debug__) diff --git a/tracker/tracker/src/main/app/nodes/index.ts b/tracker/tracker/src/main/app/nodes/index.ts index feed5e841..22e8d4144 100644 --- a/tracker/tracker/src/main/app/nodes/index.ts +++ b/tracker/tracker/src/main/app/nodes/index.ts @@ -1,4 +1,5 @@ import { createEventListener, deleteEventListener } from '../../utils.js' +import VirtualNodeTree from '../observer/vTree.js' import Maintainer, { MaintainerOptions } from './maintainer.js' type NodeCallback = (node: Node, isStart: boolean) => void @@ -8,6 +9,8 @@ export interface NodesOptions { node_id: string forceNgOff: boolean maintainer?: Partial + vTree: VirtualNodeTree + iframes: Map } export default class Nodes { @@ -23,7 +26,7 @@ export default class Nodes { constructor(params: NodesOptions) { this.node_id = params.node_id this.forceNgOff = params.forceNgOff - this.maintainer = new Maintainer(this.nodes, this.unregisterNode, params.maintainer) + this.maintainer = new Maintainer(this.nodes, this.unregisterNode, params.vTree, params.iframes, params.maintainer) this.maintainer.start() } diff --git a/tracker/tracker/src/main/app/nodes/maintainer.ts b/tracker/tracker/src/main/app/nodes/maintainer.ts index cbc33de0d..060a7c836 100644 --- a/tracker/tracker/src/main/app/nodes/maintainer.ts +++ b/tracker/tracker/src/main/app/nodes/maintainer.ts @@ -1,9 +1,11 @@ +import VirtualNodeTree from "../observer/vTree" + const SECOND = 1000 function processMapInBatches( map: Map, batchSize: number, - processBatchCallback: (node: Node) => void, + processBatchCallback: (node: Node, nodeId: number) => void, ) { const iterator = map.entries() @@ -17,9 +19,9 @@ function processMapInBatches( } if (batch.length > 0) { - batch.forEach(([_, node]) => { + batch.forEach(([nodeId, node]) => { if (node) { - processBatchCallback(node) + processBatchCallback(node, nodeId) } }) @@ -87,12 +89,18 @@ const defaults = { class Maintainer { private interval: ReturnType private readonly options: MaintainerOptions + private readonly vTree: VirtualNodeTree + private readonly iframes: Map constructor( private readonly nodes: Map, private readonly unregisterNode: (node: Node) => void, + vTree: VirtualNodeTree, + iframes: Map, options?: Partial, ) { this.options = { ...defaults, ...options } + this.vTree = vTree + this.iframes = iframes } public start = () => { @@ -103,10 +111,12 @@ class Maintainer { this.stop() this.interval = setInterval(() => { - processMapInBatches(this.nodes, this.options.batchSize, (node) => { + processMapInBatches(this.nodes, this.options.batchSize, (node, nodeId) => { const isActive = isNodeStillActive(node)[0] if (!isActive) { this.unregisterNode(node) + this.vTree?.removeNode(nodeId) + this.iframes.delete(nodeId) } }) }, this.options.interval) diff --git a/tracker/tracker/src/main/app/observer/observer.ts b/tracker/tracker/src/main/app/observer/observer.ts index 27ec6dbcc..4e156fa01 100644 --- a/tracker/tracker/src/main/app/observer/observer.ts +++ b/tracker/tracker/src/main/app/observer/observer.ts @@ -184,10 +184,6 @@ enum RecentsType { export default abstract class Observer { /** object tree where key is node id, value is null if it has no children, or object with same structure */ - // private readonly vTree = new vElTree((id: number) => { - // this.app.nodes.unregisterNodeById(id) - // this.app.send(RemoveNode(id)) - // }) private readonly observer: MutationObserver private readonly commited: Array = [] private readonly recents: Map = new Map() diff --git a/tracker/tracker/src/main/app/observer/top_observer.ts b/tracker/tracker/src/main/app/observer/top_observer.ts index 54aba1726..0c02fca43 100644 --- a/tracker/tracker/src/main/app/observer/top_observer.ts +++ b/tracker/tracker/src/main/app/observer/top_observer.ts @@ -8,6 +8,7 @@ import IFrameOffsets, { Offset } from './iframe_offsets.js' import { CreateDocument } from '../messages.gen.js' import App from '../index.js' import { IN_BROWSER, hasOpenreplayAttribute, canAccessIframe } from '../../utils.js' +import VirtualNodeTree from './vTree.js' export interface Options { captureIFrames: boolean @@ -22,10 +23,10 @@ const attachShadowNativeFn = IN_BROWSER ? Element.prototype.attachShadow : () => export default class TopObserver extends Observer { private readonly options: Options private readonly iframeOffsets: IFrameOffsets = new IFrameOffsets() + private readonly iframes: Map readonly app: App - public iframes: Map = new Map() - constructor(params: { app: App; options: Partial; vTree: any }) { + constructor(params: { app: App; options: Partial }, vTree: VirtualNodeTree, iframes: Map) { const opts = Object.assign( { captureIFrames: true, @@ -33,10 +34,11 @@ export default class TopObserver extends Observer { }, params.options, ) - super(params.app, true, opts, params.vTree) + super(params.app, true, opts, vTree) this.app = params.app this.options = opts - this.vTree = params.vTree + this.vTree = vTree + this.iframes = iframes // IFrames this.app.nodes.attachNodeCallback((node) => { const nodeId = this.app.nodes.getID(node);