tracker 14.0.10, fixes memory leaks, iframe tracking stability, etc
This commit is contained in:
parent
b5e681ff00
commit
f041859a06
33 changed files with 923 additions and 121 deletions
Binary file not shown.
|
|
@ -1,3 +1,8 @@
|
|||
## 10.0.0
|
||||
|
||||
- memory handling improvements to prevent possible leaks on sessions with multiple canvas nodes
|
||||
- use new tracker.waitStatus api to wait for restarts
|
||||
|
||||
## 9.0.0
|
||||
|
||||
- support for message compression inside plugin (requires v1.18 frontend)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@openreplay/tracker-assist",
|
||||
"description": "Tracker plugin for screen assistance through the WebRTC",
|
||||
"version": "9.0.2-beta.11",
|
||||
"version": "10.0.0",
|
||||
"keywords": [
|
||||
"WebRTC",
|
||||
"assistance",
|
||||
|
|
@ -16,11 +16,11 @@
|
|||
"tsrun": "tsc",
|
||||
"lint": "eslint src --ext .ts,.js --fix --quiet",
|
||||
"build": "bun run replace-pkg-version && bun run build-es && bun run build-cjs",
|
||||
"build-es": "rm -Rf lib && tsc && bun run replace-req-version",
|
||||
"build-cjs": "rm -Rf cjs && tsc --project tsconfig-cjs.json && echo '{ \"type\": \"commonjs\" }' > cjs/package.json && bun run replace-paths && bun run replace-req-version",
|
||||
"build-es": "rm -Rf lib && tsc --project tsconfig.json && bun run replace-req-version",
|
||||
"build-cjs": "rm -Rf cjs && tsc --project tsconfig-cjs.json && echo '{ \"type\": \"commonjs\" }' > cjs/package.json && bun run replace-req-version",
|
||||
"replace-paths": "replace-in-files cjs/* --string='@openreplay/tracker' --replacement='@openreplay/tracker/cjs' && replace-in-files cjs/* --string='/lib/' --replacement='/'",
|
||||
"replace-pkg-version": "sh pkgver.sh",
|
||||
"replace-req-version": "replace-in-files lib/* cjs/* --string='REQUIRED_TRACKER_VERSION' --replacement='13.0.0'",
|
||||
"replace-req-version": "replace-in-files lib/* cjs/* --string='REQUIRED_TRACKER_VERSION' --replacement='14.0.10'",
|
||||
"prepublishOnly": "bun run test && bun run build",
|
||||
"lint-front": "lint-staged",
|
||||
"test": "jest --coverage=false",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import Mouse from './Mouse.js'
|
||||
import ConfirmWindow from './ConfirmWindow/ConfirmWindow.js'
|
||||
import { controlConfirmDefault, } from './ConfirmWindow/defaults.js'
|
||||
import type { Options as AssistOptions, } from './Assist'
|
||||
import type { Options as AssistOptions, } from './Assist.js'
|
||||
|
||||
export enum RCStatus {
|
||||
Disabled,
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
export const pkgVersion = "9.0.2-beta.11";
|
||||
export const pkgVersion = "10.0.0";
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"strictNullChecks": true,
|
||||
"alwaysStrict": true,
|
||||
"target": "es2017",
|
||||
"module": "es6",
|
||||
"moduleResolution": "node",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"declaration": true,
|
||||
"outDir": "./lib",
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,250 +1,286 @@
|
|||
# 14.0.10
|
||||
## 14.0.10
|
||||
|
||||
- adjust timestamps for messages from tracker instances inside child iframes (if they were loaded later)
|
||||
- restart child trackers if parent tracker is restarted
|
||||
- fixes for general stability of crossdomain iframe tracking
|
||||
- refactored usage of memory for everything regarding dom nodes to prevent possible memory leaks (i.e switched Map/Set to WeakMap/WeakSet where possible)
|
||||
- introduced configurable Maintainer to drop nodes that are not in the dom anymore from memory;
|
||||
|
||||
# 14.0.9
|
||||
```
|
||||
interface MaintainerOptions {
|
||||
/**
|
||||
* Run cleanup each X ms
|
||||
*
|
||||
* @default 30 * 1000
|
||||
* */
|
||||
interval: number
|
||||
/**
|
||||
* Maintainer checks nodes in small batches over 50ms timeouts
|
||||
*
|
||||
* @default 2500
|
||||
* */
|
||||
batchSize: number
|
||||
/**
|
||||
* @default true
|
||||
* */
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
new Tracker({
|
||||
...yourOptions,
|
||||
nodes: {
|
||||
maintainer: {
|
||||
interval: 60 * 1000,
|
||||
batchSize: 2500,
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
- added `startCallback` option callback to tracker.start options (returns `{ success: false, reason: string } | { success: true, sessionToken, userUUID, sessionID }`)
|
||||
|
||||
## 14.0.9
|
||||
|
||||
- more stable crossdomain iframe tracking (refactored child/parent process discovery)
|
||||
- checks for bad start error
|
||||
|
||||
# 14.0.8
|
||||
## 14.0.8
|
||||
|
||||
- use separate library to handle network requests ([@openreplay/network-proxy](https://www.npmjs.com/package/@openreplay/network-proxy))
|
||||
- fixes for window.message listeners
|
||||
|
||||
# 14.0.7
|
||||
## 14.0.7
|
||||
|
||||
- check for stopping status during restarts
|
||||
- restart if token expired during canvas fetch
|
||||
|
||||
# 14.0.6
|
||||
## 14.0.6
|
||||
|
||||
- support feature off toggle for feature flags and usability testing
|
||||
- additional checks for canvas snapshots
|
||||
|
||||
# 14.0.5
|
||||
## 14.0.5
|
||||
|
||||
- remove canvas snapshot interval if canvas is gone
|
||||
|
||||
# 14.0.4
|
||||
## 14.0.4
|
||||
|
||||
- remove reject from start
|
||||
|
||||
# 14.0.3
|
||||
## 14.0.3
|
||||
|
||||
- send integer instead of float for normalizedX/Y coords (basically moving from 0-100 to 0-10000 range)
|
||||
|
||||
# 14.0.2
|
||||
## 14.0.2
|
||||
|
||||
- fix logger check
|
||||
|
||||
# 14.0.0 & .1
|
||||
## 14.0.0 & .1
|
||||
|
||||
- titles for tabs
|
||||
- new `MouseClick` message to introduce heatmaps instead of clickmaps
|
||||
- crossdomain iframe tracking functionality
|
||||
- updated graphql plugin and messages
|
||||
|
||||
# 13.0.2
|
||||
## 13.0.2
|
||||
|
||||
- more file extensions for canvas
|
||||
|
||||
# 13.0.1
|
||||
## 13.0.1
|
||||
|
||||
- moved canvas snapshots to webp, additional option to utilize useAnimationFrame method (for webgl)
|
||||
- simpler, faster canvas recording manager
|
||||
|
||||
# 13.0.0
|
||||
## 13.0.0
|
||||
|
||||
- `assistOnly` flag for tracker options (EE only feature)
|
||||
|
||||
# 12.0.12
|
||||
## 12.0.12
|
||||
|
||||
- fix for potential redux plugin issues after .11 ...
|
||||
|
||||
# 12.0.11
|
||||
## 12.0.11
|
||||
|
||||
- better restart on unauth (new token assign for long sessions)
|
||||
- more safeguards around arraybuffer and dataview types for network proxy
|
||||
|
||||
# 12.0.10
|
||||
## 12.0.10
|
||||
|
||||
- improved logs for node binding errors, full nodelist clear before start, getSessionInfo method
|
||||
|
||||
# 12.0.9
|
||||
## 12.0.9
|
||||
|
||||
- moved logging to query
|
||||
|
||||
# 12.0.8
|
||||
## 12.0.8
|
||||
|
||||
- better logging for network batches
|
||||
|
||||
# 12.0.7
|
||||
## 12.0.7
|
||||
|
||||
- fixes for window.open reinit method
|
||||
|
||||
# 12.0.6
|
||||
## 12.0.6
|
||||
|
||||
- allow network sanitizer to return null (will ignore network req)
|
||||
|
||||
# 12.0.5
|
||||
## 12.0.5
|
||||
|
||||
- patch for img.ts srcset detector
|
||||
|
||||
# 12.0.4
|
||||
## 12.0.4
|
||||
|
||||
- patch for email sanitizer (supports + now)
|
||||
- update fflate version for better compression
|
||||
- `disableCanvas` option to disable canvas capture
|
||||
- better check for adopted stylesheets in doc (old browser support)
|
||||
|
||||
# 12.0.3
|
||||
## 12.0.3
|
||||
|
||||
- fixed scaling option for canvas (to ignore window.devicePixelRatio and always render the canvas as 1)
|
||||
|
||||
# 12.0.2
|
||||
## 12.0.2
|
||||
|
||||
- fix for canvas snapshot check
|
||||
|
||||
# 12.0.1
|
||||
## 12.0.1
|
||||
|
||||
- pause canvas snapshotting when its offscreen
|
||||
|
||||
# 12.0.0
|
||||
## 12.0.0
|
||||
|
||||
- offline session recording and manual sending
|
||||
- conditional recording with 30s buffer
|
||||
- websockets tracking hook
|
||||
|
||||
# 11.0.5
|
||||
## 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
|
||||
## 11.0.4
|
||||
|
||||
- some additional security for canvas capture (check if canvas el itself is obscured/ignored)
|
||||
|
||||
# 11.0.3
|
||||
## 11.0.3
|
||||
|
||||
- move all logs under internal debugger
|
||||
- fix for XHR proxy ORSC 'abort' state
|
||||
|
||||
# 11.0.1 & 11.0.2
|
||||
## 11.0.1 & 11.0.2
|
||||
|
||||
- minor fixes and refactoring
|
||||
|
||||
# 11.0.0
|
||||
## 11.0.0
|
||||
|
||||
- canvas support
|
||||
- some safety guards for iframe components
|
||||
- user testing module
|
||||
|
||||
# 10.0.2
|
||||
## 10.0.2
|
||||
|
||||
- fix default ignore headers
|
||||
|
||||
# 10.0.1
|
||||
## 10.0.1
|
||||
|
||||
- network proxy api is now default turned on
|
||||
|
||||
# 10.0.0
|
||||
## 10.0.0
|
||||
|
||||
- networkRequest message changed to include `TransferredBodySize`
|
||||
- tracker now attempts to create proxy for beacon api as well (if its in scope of the current env)
|
||||
- safe wrapper for angular apps
|
||||
- better browser lag handling (and some performance improvements as a bonus)
|
||||
|
||||
# 9.0.11
|
||||
## 9.0.11
|
||||
|
||||
- new `resetTabOnWindowOpen` option to fix window.open issue with sessionStorage being inherited (replicating tabId bug), users still should use 'noopener=true' in window.open to prevent it in general...
|
||||
- do not create BC channel in iframe context, add regeneration of tabid incase of duplication
|
||||
|
||||
# 9.0.10
|
||||
## 9.0.10
|
||||
|
||||
- added `excludedResourceUrls` to timings options to better sanitize network data
|
||||
|
||||
# 9.0.9
|
||||
## 9.0.9
|
||||
|
||||
- Fix for `{disableStringDict: true}` behavior
|
||||
|
||||
# 9.0.8
|
||||
## 9.0.8
|
||||
|
||||
- added slight delay to iframe handler (rapid updates of stacked frames used to break player)
|
||||
|
||||
# 9.0.7
|
||||
## 9.0.7
|
||||
|
||||
- fix for `getSessionURL` method
|
||||
|
||||
# 9.0.6
|
||||
## 9.0.6
|
||||
|
||||
- added `tokenUrlMatcher` option to network settings, allowing to ingest session token header to custom allowed urls
|
||||
|
||||
# 9.0.5
|
||||
## 9.0.5
|
||||
|
||||
- same fixes but for fetch proxy
|
||||
|
||||
# 9.0.2 & 9.0.3 & 9.0.4
|
||||
## 9.0.2 & 9.0.3 & 9.0.4
|
||||
|
||||
- fixes for "setSessionTokenHeader" method
|
||||
|
||||
# 9.0.1
|
||||
## 9.0.1
|
||||
|
||||
- Warning about SSR mode
|
||||
- Prevent crashes due to network proxy in SSR
|
||||
|
||||
# 9.0.0
|
||||
## 9.0.0
|
||||
|
||||
- Option to disable string dictionary `{disableStringDict: true}` in Tracker constructor
|
||||
- Introduced Feature flags api
|
||||
- Fixed input durations recorded on programmable autofill
|
||||
- change InputMode from enum to const Object
|
||||
|
||||
# 8.1.2
|
||||
## 8.1.2
|
||||
|
||||
- option to disable string dictionary `{disableStringDict: true}` in Tracker constructor
|
||||
|
||||
# 8.1.1
|
||||
## 8.1.1
|
||||
|
||||
[collective patch]
|
||||
|
||||
- Console and network are now using proxy objects to capture calls (opt in for network), use ` { network: { useProxy: true } }` to enable it
|
||||
- Force disable Multitab feature for old browsers (2016 and older + safari 14)
|
||||
|
||||
# 8.0.0
|
||||
## 8.0.0
|
||||
|
||||
- **[breaking]** support for multi-tab sessions
|
||||
|
||||
# 7.0.4
|
||||
## 7.0.4
|
||||
|
||||
- option to disable string dictionary `{disableStringDict: true}` in Tracker constructor
|
||||
|
||||
# 7.0.3
|
||||
## 7.0.3
|
||||
|
||||
- Prevent auto restart after manual stop
|
||||
|
||||
# 7.0.2
|
||||
## 7.0.2
|
||||
|
||||
- fixed header sanitization for axios causing empty string in some cases
|
||||
|
||||
# 7.0.1
|
||||
## 7.0.1
|
||||
|
||||
- fix time inputs capturing
|
||||
- add option `{ network: { captureInIframes: boolean } }` to disable network tracking inside iframes (default true)
|
||||
- added option `{ network: { axiosInstances: AxiosInstance[] } }` to include custom axios instances for better tracking
|
||||
|
||||
# 7.0.0
|
||||
## 7.0.0
|
||||
|
||||
- **[breaking]** added gzip compression to large messages
|
||||
- fix email regexp to significantly improve performance
|
||||
|
||||
# 6.0.2
|
||||
## 6.0.2
|
||||
|
||||
- fix network tracking for same domain iframes created by js code
|
||||
|
||||
# 6.0.1
|
||||
## 6.0.1
|
||||
|
||||
- fix webworker writer re-init request
|
||||
- remove useless logs
|
||||
|
|
@ -252,7 +288,7 @@
|
|||
- fix iframe handling
|
||||
- optimise node counting for dom drop
|
||||
|
||||
# 6.0.0
|
||||
## 6.0.0
|
||||
|
||||
**(Compatible with OpenReplay v1.11.0+ only)**
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@openreplay/tracker",
|
||||
"description": "The OpenReplay tracker main package",
|
||||
"version": "14.0.11-30",
|
||||
"version": "14.0.10",
|
||||
"keywords": [
|
||||
"logging",
|
||||
"replay"
|
||||
|
|
@ -13,14 +13,29 @@
|
|||
],
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"main": "./lib/index.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"require": "./dist/cjs/index.js",
|
||||
"import": "./dist/lib/index.js",
|
||||
"types": "./dist/lib/main/index.d.ts"
|
||||
},
|
||||
"./cjs": {
|
||||
"require": "./dist/cjs/index.js",
|
||||
"types": "./dist/cjs/main/index.d.ts"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist/lib/**/*",
|
||||
"dist/cjs/**/*"
|
||||
],
|
||||
"main": "./dist/cjs/index.js",
|
||||
"module": "./dist/lib/index.js",
|
||||
"types": "./dist/lib/main/index.d.ts",
|
||||
"scripts": {
|
||||
"lint": "eslint src --ext .ts,.js --fix --quiet",
|
||||
"clean": "rm -Rf build && rm -Rf lib && rm -Rf cjs",
|
||||
"tscRun": "tsc -b src/main && tsc -b src/webworker && tsc --project src/main/tsconfig-cjs.json",
|
||||
"rollup": "rollup --config rollup.config.js",
|
||||
"compile": "node --experimental-modules --experimental-json-modules scripts/compile.cjs",
|
||||
"build": "bun run clean && bun run tscRun && bun run rollup && bun run compile",
|
||||
"build:common": "tsc -b src/common",
|
||||
"build": "yarn run clean && yarn build:common && rollup --config rollup.config.js",
|
||||
"lint-front": "lint-staged",
|
||||
"test": "jest --coverage=false",
|
||||
"test:ci": "jest --coverage=true",
|
||||
|
|
@ -32,7 +47,9 @@
|
|||
"@jest/globals": "^29.3.1",
|
||||
"@rollup/plugin-babel": "^6.0.4",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@rollup/plugin-replace": "^6.0.1",
|
||||
"@rollup/plugin-terser": "0.4.4",
|
||||
"@rollup/plugin-typescript": "^12.1.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.30.0",
|
||||
"@typescript-eslint/parser": "^5.30.0",
|
||||
"eslint": "^8.57.1",
|
||||
|
|
@ -52,6 +69,7 @@
|
|||
"@medv/finder": "^3.2.0",
|
||||
"@openreplay/network-proxy": "^1.0.3",
|
||||
"error-stack-parser": "^2.0.6",
|
||||
"error-stack-parser-es": "^0.1.5",
|
||||
"fflate": "^0.8.2"
|
||||
},
|
||||
"engines": {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,79 @@
|
|||
import resolve from '@rollup/plugin-node-resolve'
|
||||
import { babel } from '@rollup/plugin-babel'
|
||||
import terser from '@rollup/plugin-terser';
|
||||
import typescript from '@rollup/plugin-typescript'
|
||||
import terser from '@rollup/plugin-terser'
|
||||
import replace from '@rollup/plugin-replace'
|
||||
import { rollup } from 'rollup'
|
||||
import { createRequire } from 'module'
|
||||
const require = createRequire(import.meta.url)
|
||||
const packageConfig = require('./package.json')
|
||||
|
||||
export default {
|
||||
input: 'build/webworker/index.js',
|
||||
output: {
|
||||
file: 'build/webworker.js',
|
||||
format: 'cjs',
|
||||
},
|
||||
plugins: [resolve(), babel({ babelHelpers: 'bundled' }), terser({ mangle: { reserved: ['$'] } })],
|
||||
export default async () => {
|
||||
const webworkerContent = await buildWebWorker()
|
||||
|
||||
const commonPlugins = [
|
||||
resolve(),
|
||||
// terser(),
|
||||
replace({
|
||||
preventAssignment: true,
|
||||
values: {
|
||||
TRACKER_VERSION: packageConfig.version,
|
||||
WEBWORKER_BODY: JSON.stringify(webworkerContent),
|
||||
},
|
||||
}),
|
||||
]
|
||||
return [
|
||||
{
|
||||
input: 'src/main/index.ts',
|
||||
output: {
|
||||
dir: 'dist/lib',
|
||||
format: 'es',
|
||||
sourcemap: true,
|
||||
entryFileNames: '[name].js',
|
||||
},
|
||||
plugins: [
|
||||
...commonPlugins,
|
||||
typescript({
|
||||
tsconfig: 'src/main/tsconfig.json',
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
input: 'src/main/index.ts',
|
||||
output: {
|
||||
dir: 'dist/cjs',
|
||||
format: 'cjs',
|
||||
sourcemap: true,
|
||||
entryFileNames: '[name].js',
|
||||
},
|
||||
plugins: [
|
||||
...commonPlugins,
|
||||
typescript({
|
||||
tsconfig: 'src/main/tsconfig-cjs.json',
|
||||
}),
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
async function buildWebWorker() {
|
||||
console.log('building wworker')
|
||||
const bundle = await rollup({
|
||||
input: 'src/webworker/index.ts',
|
||||
plugins: [
|
||||
resolve(),
|
||||
typescript({
|
||||
tsconfig: 'src/webworker/tsconfig.json',
|
||||
}),
|
||||
terser(),
|
||||
],
|
||||
})
|
||||
|
||||
const { output } = await bundle.generate({
|
||||
format: 'iife',
|
||||
name: 'WebWorker',
|
||||
inlineDynamicImports: true,
|
||||
})
|
||||
const webWorkerCode = output[0].code
|
||||
console.log('webworker done!')
|
||||
return webWorkerCode.replace(/"/g, '\\"').replace(/\n/g, '')
|
||||
}
|
||||
|
|
|
|||
37
tracker/tracker/src/common/interaction.d.ts
vendored
Normal file
37
tracker/tracker/src/common/interaction.d.ts
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import Message from './messages.gen.js';
|
||||
export interface Options {
|
||||
connAttemptCount?: number;
|
||||
connAttemptGap?: number;
|
||||
}
|
||||
type Start = {
|
||||
type: 'start';
|
||||
ingestPoint: string;
|
||||
pageNo: number;
|
||||
timestamp: number;
|
||||
url: string;
|
||||
tabId: string;
|
||||
} & Options;
|
||||
type Auth = {
|
||||
type: 'auth';
|
||||
token: string;
|
||||
beaconSizeLimit?: number;
|
||||
};
|
||||
export type ToWorkerData = null | 'stop' | Start | Auth | Array<Message> | {
|
||||
type: 'compressed';
|
||||
batch: Uint8Array;
|
||||
} | {
|
||||
type: 'uncompressed';
|
||||
batch: Uint8Array;
|
||||
} | 'forceFlushBatch' | 'check_queue';
|
||||
type Failure = {
|
||||
type: 'failure';
|
||||
reason: string;
|
||||
};
|
||||
type QEmpty = {
|
||||
type: 'queue_empty';
|
||||
};
|
||||
export type FromWorkerData = 'a_stop' | 'a_start' | Failure | 'not_init' | {
|
||||
type: 'compress';
|
||||
batch: Uint8Array;
|
||||
} | QEmpty;
|
||||
export {};
|
||||
1
tracker/tracker/src/common/interaction.js
Normal file
1
tracker/tracker/src/common/interaction.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
export {};
|
||||
1
tracker/tracker/src/common/interaction.js.map
Normal file
1
tracker/tracker/src/common/interaction.js.map
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"interaction.js","sourceRoot":"","sources":["interaction.ts"],"names":[],"mappings":""}
|
||||
548
tracker/tracker/src/common/messages.gen.d.ts
vendored
Normal file
548
tracker/tracker/src/common/messages.gen.d.ts
vendored
Normal file
|
|
@ -0,0 +1,548 @@
|
|||
export declare const enum Type {
|
||||
Timestamp = 0,
|
||||
SetPageLocationDeprecated = 4,
|
||||
SetViewportSize = 5,
|
||||
SetViewportScroll = 6,
|
||||
CreateDocument = 7,
|
||||
CreateElementNode = 8,
|
||||
CreateTextNode = 9,
|
||||
MoveNode = 10,
|
||||
RemoveNode = 11,
|
||||
SetNodeAttribute = 12,
|
||||
RemoveNodeAttribute = 13,
|
||||
SetNodeData = 14,
|
||||
SetNodeScroll = 16,
|
||||
SetInputTarget = 17,
|
||||
SetInputValue = 18,
|
||||
SetInputChecked = 19,
|
||||
MouseMove = 20,
|
||||
NetworkRequestDeprecated = 21,
|
||||
ConsoleLog = 22,
|
||||
PageLoadTiming = 23,
|
||||
PageRenderTiming = 24,
|
||||
CustomEvent = 27,
|
||||
UserID = 28,
|
||||
UserAnonymousID = 29,
|
||||
Metadata = 30,
|
||||
CSSInsertRule = 37,
|
||||
CSSDeleteRule = 38,
|
||||
Fetch = 39,
|
||||
Profiler = 40,
|
||||
OTable = 41,
|
||||
StateAction = 42,
|
||||
ReduxDeprecated = 44,
|
||||
Vuex = 45,
|
||||
MobX = 46,
|
||||
NgRx = 47,
|
||||
GraphQLDeprecated = 48,
|
||||
PerformanceTrack = 49,
|
||||
StringDict = 50,
|
||||
SetNodeAttributeDict = 51,
|
||||
ResourceTimingDeprecated = 53,
|
||||
ConnectionInformation = 54,
|
||||
SetPageVisibility = 55,
|
||||
LoadFontFace = 57,
|
||||
SetNodeFocus = 58,
|
||||
LongTask = 59,
|
||||
SetNodeAttributeURLBased = 60,
|
||||
SetCSSDataURLBased = 61,
|
||||
TechnicalInfo = 63,
|
||||
CustomIssue = 64,
|
||||
CSSInsertRuleURLBased = 67,
|
||||
MouseClick = 68,
|
||||
MouseClickDeprecated = 69,
|
||||
CreateIFrameDocument = 70,
|
||||
AdoptedSSReplaceURLBased = 71,
|
||||
AdoptedSSInsertRuleURLBased = 73,
|
||||
AdoptedSSDeleteRule = 75,
|
||||
AdoptedSSAddOwner = 76,
|
||||
AdoptedSSRemoveOwner = 77,
|
||||
JSException = 78,
|
||||
Zustand = 79,
|
||||
BatchMetadata = 81,
|
||||
PartitionedMessage = 82,
|
||||
NetworkRequest = 83,
|
||||
WSChannel = 84,
|
||||
InputChange = 112,
|
||||
SelectionChange = 113,
|
||||
MouseThrashing = 114,
|
||||
UnbindNodes = 115,
|
||||
ResourceTiming = 116,
|
||||
TabChange = 117,
|
||||
TabData = 118,
|
||||
CanvasNode = 119,
|
||||
TagTrigger = 120,
|
||||
Redux = 121,
|
||||
SetPageLocation = 122,
|
||||
GraphQL = 123
|
||||
}
|
||||
export type Timestamp = [
|
||||
Type.Timestamp,
|
||||
number
|
||||
];
|
||||
export type SetPageLocationDeprecated = [
|
||||
Type.SetPageLocationDeprecated,
|
||||
string,
|
||||
string,
|
||||
number
|
||||
];
|
||||
export type SetViewportSize = [
|
||||
Type.SetViewportSize,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type SetViewportScroll = [
|
||||
Type.SetViewportScroll,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type CreateDocument = [
|
||||
Type.CreateDocument
|
||||
];
|
||||
export type CreateElementNode = [
|
||||
Type.CreateElementNode,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
string,
|
||||
boolean
|
||||
];
|
||||
export type CreateTextNode = [
|
||||
Type.CreateTextNode,
|
||||
number,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type MoveNode = [
|
||||
Type.MoveNode,
|
||||
number,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type RemoveNode = [
|
||||
Type.RemoveNode,
|
||||
number
|
||||
];
|
||||
export type SetNodeAttribute = [
|
||||
Type.SetNodeAttribute,
|
||||
number,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type RemoveNodeAttribute = [
|
||||
Type.RemoveNodeAttribute,
|
||||
number,
|
||||
string
|
||||
];
|
||||
export type SetNodeData = [
|
||||
Type.SetNodeData,
|
||||
number,
|
||||
string
|
||||
];
|
||||
export type SetNodeScroll = [
|
||||
Type.SetNodeScroll,
|
||||
number,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type SetInputTarget = [
|
||||
Type.SetInputTarget,
|
||||
number,
|
||||
string
|
||||
];
|
||||
export type SetInputValue = [
|
||||
Type.SetInputValue,
|
||||
number,
|
||||
string,
|
||||
number
|
||||
];
|
||||
export type SetInputChecked = [
|
||||
Type.SetInputChecked,
|
||||
number,
|
||||
boolean
|
||||
];
|
||||
export type MouseMove = [
|
||||
Type.MouseMove,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type NetworkRequestDeprecated = [
|
||||
Type.NetworkRequestDeprecated,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
number,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type ConsoleLog = [
|
||||
Type.ConsoleLog,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type PageLoadTiming = [
|
||||
Type.PageLoadTiming,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type PageRenderTiming = [
|
||||
Type.PageRenderTiming,
|
||||
number,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type CustomEvent = [
|
||||
Type.CustomEvent,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type UserID = [
|
||||
Type.UserID,
|
||||
string
|
||||
];
|
||||
export type UserAnonymousID = [
|
||||
Type.UserAnonymousID,
|
||||
string
|
||||
];
|
||||
export type Metadata = [
|
||||
Type.Metadata,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type CSSInsertRule = [
|
||||
Type.CSSInsertRule,
|
||||
number,
|
||||
string,
|
||||
number
|
||||
];
|
||||
export type CSSDeleteRule = [
|
||||
Type.CSSDeleteRule,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type Fetch = [
|
||||
Type.Fetch,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
number,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type Profiler = [
|
||||
Type.Profiler,
|
||||
string,
|
||||
number,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type OTable = [
|
||||
Type.OTable,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type StateAction = [
|
||||
Type.StateAction,
|
||||
string
|
||||
];
|
||||
export type ReduxDeprecated = [
|
||||
Type.ReduxDeprecated,
|
||||
string,
|
||||
string,
|
||||
number
|
||||
];
|
||||
export type Vuex = [
|
||||
Type.Vuex,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type MobX = [
|
||||
Type.MobX,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type NgRx = [
|
||||
Type.NgRx,
|
||||
string,
|
||||
string,
|
||||
number
|
||||
];
|
||||
export type GraphQLDeprecated = [
|
||||
Type.GraphQLDeprecated,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
number
|
||||
];
|
||||
export type PerformanceTrack = [
|
||||
Type.PerformanceTrack,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type StringDict = [
|
||||
Type.StringDict,
|
||||
number,
|
||||
string
|
||||
];
|
||||
export type SetNodeAttributeDict = [
|
||||
Type.SetNodeAttributeDict,
|
||||
number,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type ResourceTimingDeprecated = [
|
||||
Type.ResourceTimingDeprecated,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type ConnectionInformation = [
|
||||
Type.ConnectionInformation,
|
||||
number,
|
||||
string
|
||||
];
|
||||
export type SetPageVisibility = [
|
||||
Type.SetPageVisibility,
|
||||
boolean
|
||||
];
|
||||
export type LoadFontFace = [
|
||||
Type.LoadFontFace,
|
||||
number,
|
||||
string,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type SetNodeFocus = [
|
||||
Type.SetNodeFocus,
|
||||
number
|
||||
];
|
||||
export type LongTask = [
|
||||
Type.LongTask,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
string,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type SetNodeAttributeURLBased = [
|
||||
Type.SetNodeAttributeURLBased,
|
||||
number,
|
||||
string,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type SetCSSDataURLBased = [
|
||||
Type.SetCSSDataURLBased,
|
||||
number,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type TechnicalInfo = [
|
||||
Type.TechnicalInfo,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type CustomIssue = [
|
||||
Type.CustomIssue,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type CSSInsertRuleURLBased = [
|
||||
Type.CSSInsertRuleURLBased,
|
||||
number,
|
||||
string,
|
||||
number,
|
||||
string
|
||||
];
|
||||
export type MouseClick = [
|
||||
Type.MouseClick,
|
||||
number,
|
||||
number,
|
||||
string,
|
||||
string,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type MouseClickDeprecated = [
|
||||
Type.MouseClickDeprecated,
|
||||
number,
|
||||
number,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type CreateIFrameDocument = [
|
||||
Type.CreateIFrameDocument,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type AdoptedSSReplaceURLBased = [
|
||||
Type.AdoptedSSReplaceURLBased,
|
||||
number,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type AdoptedSSInsertRuleURLBased = [
|
||||
Type.AdoptedSSInsertRuleURLBased,
|
||||
number,
|
||||
string,
|
||||
number,
|
||||
string
|
||||
];
|
||||
export type AdoptedSSDeleteRule = [
|
||||
Type.AdoptedSSDeleteRule,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type AdoptedSSAddOwner = [
|
||||
Type.AdoptedSSAddOwner,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type AdoptedSSRemoveOwner = [
|
||||
Type.AdoptedSSRemoveOwner,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type JSException = [
|
||||
Type.JSException,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type Zustand = [
|
||||
Type.Zustand,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type BatchMetadata = [
|
||||
Type.BatchMetadata,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
string
|
||||
];
|
||||
export type PartitionedMessage = [
|
||||
Type.PartitionedMessage,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type NetworkRequest = [
|
||||
Type.NetworkRequest,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type WSChannel = [
|
||||
Type.WSChannel,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
number,
|
||||
string,
|
||||
string
|
||||
];
|
||||
export type InputChange = [
|
||||
Type.InputChange,
|
||||
number,
|
||||
string,
|
||||
boolean,
|
||||
string,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type SelectionChange = [
|
||||
Type.SelectionChange,
|
||||
number,
|
||||
number,
|
||||
string
|
||||
];
|
||||
export type MouseThrashing = [
|
||||
Type.MouseThrashing,
|
||||
number
|
||||
];
|
||||
export type UnbindNodes = [
|
||||
Type.UnbindNodes,
|
||||
number
|
||||
];
|
||||
export type ResourceTiming = [
|
||||
Type.ResourceTiming,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
string,
|
||||
string,
|
||||
number,
|
||||
boolean
|
||||
];
|
||||
export type TabChange = [
|
||||
Type.TabChange,
|
||||
string
|
||||
];
|
||||
export type TabData = [
|
||||
Type.TabData,
|
||||
string
|
||||
];
|
||||
export type CanvasNode = [
|
||||
Type.CanvasNode,
|
||||
string,
|
||||
number
|
||||
];
|
||||
export type TagTrigger = [
|
||||
Type.TagTrigger,
|
||||
number
|
||||
];
|
||||
export type Redux = [
|
||||
Type.Redux,
|
||||
string,
|
||||
string,
|
||||
number,
|
||||
number
|
||||
];
|
||||
export type SetPageLocation = [
|
||||
Type.SetPageLocation,
|
||||
string,
|
||||
string,
|
||||
number,
|
||||
string
|
||||
];
|
||||
export type GraphQL = [
|
||||
Type.GraphQL,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
number
|
||||
];
|
||||
type Message = Timestamp | SetPageLocationDeprecated | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | ReduxDeprecated | Vuex | MobX | NgRx | GraphQLDeprecated | PerformanceTrack | StringDict | SetNodeAttributeDict | ResourceTimingDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | MouseClickDeprecated | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | NetworkRequest | WSChannel | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTiming | TabChange | TabData | CanvasNode | TagTrigger | Redux | SetPageLocation | GraphQL;
|
||||
export default Message;
|
||||
3
tracker/tracker/src/common/messages.gen.js
Normal file
3
tracker/tracker/src/common/messages.gen.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
// Auto-generated, do not edit
|
||||
/* eslint-disable */
|
||||
export {};
|
||||
1
tracker/tracker/src/common/messages.gen.js.map
Normal file
1
tracker/tracker/src/common/messages.gen.js.map
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"messages.gen.js","sourceRoot":"","sources":["messages.gen.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,oBAAoB"}
|
||||
1
tracker/tracker/src/common/tsconfig.tsbuildinfo
Normal file
1
tracker/tracker/src/common/tsconfig.tsbuildinfo
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -40,6 +40,7 @@ import Sanitizer from './sanitizer.js'
|
|||
import type { Options as SessOptions } from './session.js'
|
||||
import Session from './session.js'
|
||||
import Ticker from './ticker.js'
|
||||
import { MaintainerOptions } from './nodes/maintainer.js'
|
||||
|
||||
interface TypedWorker extends Omit<Worker, 'postMessage'> {
|
||||
postMessage(data: ToWorkerData): void
|
||||
|
|
@ -174,6 +175,16 @@ type AppOptions = {
|
|||
* and event listeners
|
||||
* */
|
||||
forceNgOff?: boolean
|
||||
/**
|
||||
* This option is used to change how tracker handles potentially detached nodes
|
||||
*
|
||||
* defaults here are tested and proven to be lightweight and easy on cpu
|
||||
*
|
||||
* consult the docs before changing it
|
||||
* */
|
||||
nodes?: {
|
||||
maintainer: Partial<MaintainerOptions>
|
||||
}
|
||||
} & WebworkerOptions &
|
||||
SessOptions
|
||||
|
||||
|
|
@ -340,6 +351,7 @@ export default class App {
|
|||
this.nodes = new Nodes({
|
||||
node_id: this.options.node_id,
|
||||
forceNgOff: Boolean(options.forceNgOff),
|
||||
maintainer: this.options.nodes?.maintainer,
|
||||
})
|
||||
this.observer = new Observer({ app: this, options })
|
||||
this.ticker = new Ticker(this)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
import { createEventListener, deleteEventListener } from '../../utils.js'
|
||||
import Maintainer from './maintainer.js'
|
||||
import Maintainer, { MaintainerOptions } from './maintainer.js'
|
||||
|
||||
type NodeCallback = (node: Node, isStart: boolean) => void
|
||||
type ElementListener = [string, EventListener, boolean]
|
||||
|
||||
export interface NodesOptions {
|
||||
node_id: string
|
||||
forceNgOff: boolean
|
||||
maintainer?: Partial<MaintainerOptions>
|
||||
}
|
||||
|
||||
export default class Nodes {
|
||||
private readonly nodes: Map<number, Node | void> = new Map()
|
||||
private totalNodeAmount = 0
|
||||
|
|
@ -14,10 +20,10 @@ export default class Nodes {
|
|||
private readonly forceNgOff: boolean
|
||||
private readonly maintainer: Maintainer
|
||||
|
||||
constructor(params: { node_id: string; forceNgOff: boolean }) {
|
||||
constructor(params: NodesOptions) {
|
||||
this.node_id = params.node_id
|
||||
this.forceNgOff = params.forceNgOff
|
||||
this.maintainer = new Maintainer(this.nodes, this.unregisterNode)
|
||||
this.maintainer = new Maintainer(this.nodes, this.unregisterNode, params.maintainer)
|
||||
this.maintainer.start()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,25 +57,62 @@ function isNodeStillActive(node: Node): boolean {
|
|||
}
|
||||
}
|
||||
|
||||
export interface MaintainerOptions {
|
||||
/**
|
||||
* Run cleanup each X ms
|
||||
*
|
||||
* @default 30 * 1000
|
||||
* */
|
||||
interval: number
|
||||
/**
|
||||
* Maintainer checks nodes in small batches over 50ms timeouts
|
||||
*
|
||||
* @default 2500
|
||||
* */
|
||||
batchSize: number
|
||||
/**
|
||||
* @default true
|
||||
* */
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
const defaults = {
|
||||
interval: SECOND * 30,
|
||||
batchSize: 2500,
|
||||
enabled: true,
|
||||
}
|
||||
|
||||
class Maintainer {
|
||||
private interval: ReturnType<typeof setInterval>
|
||||
private readonly options: MaintainerOptions
|
||||
constructor(
|
||||
private readonly nodes: Map<number, Node | void>,
|
||||
private readonly unregisterNode: (node: Node) => void,
|
||||
) {}
|
||||
options?: Partial<MaintainerOptions>,
|
||||
) {
|
||||
this.options = { ...defaults, ...options }
|
||||
}
|
||||
|
||||
public start = () => {
|
||||
if (!this.options.enabled) {
|
||||
return
|
||||
}
|
||||
|
||||
this.stop()
|
||||
|
||||
this.interval = setInterval(() => {
|
||||
processMapInBatches(this.nodes, SECOND * 2.5, (node) => {
|
||||
processMapInBatches(this.nodes, this.options.batchSize, (node) => {
|
||||
if (!isNodeStillActive(node)) {
|
||||
this.unregisterNode(node)
|
||||
}
|
||||
})
|
||||
}, SECOND * 30)
|
||||
}, this.options.interval)
|
||||
}
|
||||
|
||||
public stop = () => {
|
||||
clearInterval(this.interval)
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,10 @@ export default class API {
|
|||
if (!IN_BROWSER || !processOptions(options)) {
|
||||
return
|
||||
}
|
||||
if ((window as any).__OPENREPLAY__) {
|
||||
if (
|
||||
(window as any).__OPENREPLAY__ ||
|
||||
(!this.crossdomainMode && inIframe() && (window.top as any)?.__OPENREPLAY__)
|
||||
) {
|
||||
console.error('OpenReplay: one tracker instance has been initialised already')
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type App from '../app/index.js'
|
||||
import type Message from '../app/messages.gen.js'
|
||||
import { JSException } from '../app/messages.gen.js'
|
||||
import ErrorStackParser from 'error-stack-parser'
|
||||
import { parse } from 'error-stack-parser-es'
|
||||
|
||||
export interface Options {
|
||||
captureExceptions: boolean
|
||||
|
|
@ -34,7 +34,7 @@ export function getExceptionMessage(
|
|||
): Message {
|
||||
let stack = fallbackStack
|
||||
try {
|
||||
stack = ErrorStackParser.parse(error)
|
||||
stack = parse(error)
|
||||
} catch (e) {}
|
||||
return JSException(error.name, error.message, JSON.stringify(stack), JSON.stringify(metadata))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,9 @@ class TagWatcher {
|
|||
this.sessionStorage = params.sessionStorage
|
||||
this.errLog = params.errLog
|
||||
this.onTag = params.onTag
|
||||
// @ts-ignore
|
||||
const tags: { id: number; selector: string }[] = JSON.parse(
|
||||
sessionStorage.getItem(WATCHED_TAGS_KEY) ?? '[]',
|
||||
params.sessionStorage.getItem(WATCHED_TAGS_KEY) ?? '[]',
|
||||
)
|
||||
this.setTags(tags)
|
||||
this.observer = new IntersectionObserver((entries) => {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "CommonJS",
|
||||
"outDir": "../../build/cjs"
|
||||
"moduleResolution": "Node",
|
||||
"declarationDir": "../../dist/cjs"
|
||||
},
|
||||
"references": [{ "path": "../common" }]
|
||||
}
|
||||
|
|
@ -3,7 +3,8 @@
|
|||
"compilerOptions": {
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"lib": ["es2020", "dom"],
|
||||
"declaration": true
|
||||
"declaration": true,
|
||||
"declarationDir": "../../dist/lib",
|
||||
},
|
||||
"references": [{ "path": "../common" }]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,10 @@ describe('AttributeSender', () => {
|
|||
appMock = {
|
||||
send: (...args: any[]) => args,
|
||||
}
|
||||
attributeSender = new AttributeSender(appMock, false)
|
||||
attributeSender = new AttributeSender({
|
||||
app: appMock,
|
||||
isDictDisabled: false,
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import FeatureFlags, { FetchPersistFlagsData, IFeatureFlag } from '../main/modules/FeatureFlags'
|
||||
import FeatureFlags, { FetchPersistFlagsData, IFeatureFlag } from '../main/modules/featureFlags'
|
||||
import { describe, expect, jest, afterEach, beforeEach, test } from '@jest/globals'
|
||||
|
||||
jest.mock('../main/app/index.js')
|
||||
|
|
|
|||
|
|
@ -7,7 +7,10 @@ describe('Nodes', () => {
|
|||
const mockCallback = jest.fn()
|
||||
|
||||
beforeEach(() => {
|
||||
nodes = new Nodes(nodeId, false)
|
||||
nodes = new Nodes({
|
||||
node_id: nodeId,
|
||||
forceNgOff: false,
|
||||
})
|
||||
mockCallback.mockClear()
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,11 @@ describe('Sanitizer', () => {
|
|||
getID: (el: { mockId: number }) => el.mockId,
|
||||
},
|
||||
}
|
||||
// @ts-expect-error
|
||||
sanitizer = new Sanitizer(app, options)
|
||||
sanitizer = new Sanitizer({
|
||||
// @ts-expect-error
|
||||
app,
|
||||
options,
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
|
|
@ -78,7 +81,7 @@ describe('Sanitizer', () => {
|
|||
}
|
||||
|
||||
// @ts-expect-error
|
||||
sanitizer = new Sanitizer(app, options)
|
||||
sanitizer = new Sanitizer({ app, options })
|
||||
|
||||
const spanNode = document.createElement('span')
|
||||
const divNode = document.createElement('div')
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { jest, test, describe, beforeEach, afterEach, expect } from '@jest/globals'
|
||||
import Session from '../main/app/Session'
|
||||
import Session from '../main/app/session'
|
||||
import App from '../main/app/index.js'
|
||||
import { generateRandomId } from '../main/utils.js'
|
||||
|
||||
|
|
@ -34,7 +34,10 @@ describe('Session', () => {
|
|||
// @ts-ignore
|
||||
generateRandomId.mockReturnValue('random_id')
|
||||
|
||||
session = new Session(mockApp as unknown as App, mockOptions)
|
||||
session = new Session({
|
||||
app: mockApp as App,
|
||||
options: mockOptions,
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
import TagWatcher, { WATCHED_TAGS_KEY } from '../main/modules/TagWatcher'
|
||||
import TagWatcher, { WATCHED_TAGS_KEY } from '../main/modules/tagWatcher'
|
||||
import { describe, expect, jest, afterEach, beforeEach, test } from '@jest/globals'
|
||||
|
||||
const getMockSaved = () => '[{"id":1,"selector":"div"},{"id":2,"selector":"span"}]'
|
||||
describe('TagWatcher', () => {
|
||||
let sessionStorageMock: Storage
|
||||
const sessionStorageMock = {
|
||||
getItem: getMockSaved,
|
||||
setItem: jest.fn(),
|
||||
} as unknown as Storage
|
||||
let errLogMock: (args: any[]) => void
|
||||
const onTag = jest.fn()
|
||||
let mockObserve: Function
|
||||
|
|
@ -10,11 +14,6 @@ describe('TagWatcher', () => {
|
|||
let mockDisconnect: Function
|
||||
|
||||
beforeEach(() => {
|
||||
sessionStorageMock = {
|
||||
// @ts-ignore
|
||||
getItem: jest.fn(),
|
||||
setItem: jest.fn(),
|
||||
}
|
||||
errLogMock = jest.fn()
|
||||
mockObserve = jest.fn()
|
||||
mockUnobserve = jest.fn()
|
||||
|
|
@ -46,11 +45,9 @@ describe('TagWatcher', () => {
|
|||
}
|
||||
|
||||
test('constructor initializes with tags from sessionStorage', () => {
|
||||
// @ts-ignore
|
||||
sessionStorageMock.getItem.mockReturnValue(
|
||||
'[{"id":1,"selector":"div"},{"id":2,"selector":"span"}]',
|
||||
)
|
||||
const watcher = new TagWatcher(sessionStorageMock, errLogMock, onTag)
|
||||
const watcher = new TagWatcher({
|
||||
sessionStorage: sessionStorageMock, errLog: errLogMock, onTag
|
||||
})
|
||||
expect(watcher.tags).toEqual([
|
||||
{ id: 1, selector: 'div' },
|
||||
{ id: 2, selector: 'span' },
|
||||
|
|
@ -73,7 +70,9 @@ describe('TagWatcher', () => {
|
|||
}),
|
||||
}),
|
||||
)
|
||||
const watcher = new TagWatcher(sessionStorageMock, errLogMock, onTag)
|
||||
const watcher = new TagWatcher({
|
||||
sessionStorage: sessionStorageMock, errLog: errLogMock, onTag
|
||||
})
|
||||
await watcher.fetchTags('https://localhost.com', '123')
|
||||
expect(watcher.tags).toEqual([
|
||||
{ id: 1, selector: 'div' },
|
||||
|
|
@ -87,7 +86,9 @@ describe('TagWatcher', () => {
|
|||
})
|
||||
|
||||
test('setTags sets intervals for each tag', () => {
|
||||
const watcher = new TagWatcher(sessionStorageMock, errLogMock, onTag)
|
||||
const watcher = new TagWatcher({
|
||||
sessionStorage: sessionStorageMock, errLog: errLogMock, onTag
|
||||
})
|
||||
watcher.setTags([
|
||||
{ id: 1, selector: 'div' },
|
||||
{ id: 2, selector: 'p' },
|
||||
|
|
@ -98,7 +99,9 @@ describe('TagWatcher', () => {
|
|||
})
|
||||
|
||||
test('onTagRendered sends messages', () => {
|
||||
const watcher = new TagWatcher(sessionStorageMock, errLogMock, onTag)
|
||||
const watcher = new TagWatcher({
|
||||
sessionStorage: sessionStorageMock, errLog: errLogMock, onTag
|
||||
})
|
||||
watcher.setTags([{ id: 1, selector: 'div' }])
|
||||
// @ts-ignore
|
||||
document.querySelectorAll.mockReturnValue([{ __or_watcher_tagname: 'div' }]) // Mock a found element
|
||||
|
|
@ -109,7 +112,9 @@ describe('TagWatcher', () => {
|
|||
})
|
||||
|
||||
test('clear method clears all intervals and resets tags', () => {
|
||||
const watcher = new TagWatcher(sessionStorageMock, errLogMock, onTag)
|
||||
const watcher = new TagWatcher({
|
||||
sessionStorage: sessionStorageMock, errLog: errLogMock, onTag
|
||||
})
|
||||
watcher.setTags([
|
||||
{ id: 1, selector: 'div' },
|
||||
{ id: 2, selector: 'p' },
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
{
|
||||
"extends": "../../tsconfig-base.json",
|
||||
"compilerOptions": {
|
||||
"lib": ["es6"]
|
||||
"lib": ["es6", "webworker"],
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
"target": "es2016",
|
||||
"preserveConstEnums": false,
|
||||
"declaration": false
|
||||
},
|
||||
"references": [{ "path": "../common" }]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"rootDir": "src",
|
||||
"outDir": "build",
|
||||
"declaration": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"alwaysStrict": true,
|
||||
"target": "es2020",
|
||||
"module": "es6",
|
||||
"moduleResolution": "node",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"resolveJsonModule": true,
|
||||
},
|
||||
"exclude": ["**/*.test.ts"]
|
||||
"exclude": ["**/*.test.ts"],
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue