From 13f348e79851fed19baf04fda653adc78061a4de Mon Sep 17 00:00:00 2001 From: Benoit Zugmeyer Date: Thu, 30 Oct 2025 19:00:09 +0100 Subject: [PATCH 01/58] =?UTF-8?q?=F0=9F=91=B7=20build=20modules=20using=20?= =?UTF-8?q?a=20script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/package.json | 5 +- packages/core/tsconfig.cjs.json | 12 ---- packages/core/tsconfig.esm.json | 11 --- packages/flagging/package.json | 6 +- packages/flagging/tsconfig.cjs.json | 12 ---- packages/flagging/tsconfig.esm.json | 12 ---- packages/logs/package.json | 6 +- packages/logs/tsconfig.cjs.json | 12 ---- packages/logs/tsconfig.esm.json | 12 ---- packages/rum-core/package.json | 5 +- packages/rum-core/tsconfig.cjs.json | 12 ---- packages/rum-core/tsconfig.esm.json | 11 --- packages/rum-react/package.json | 4 +- packages/rum-react/tsconfig.cjs.json | 12 ---- packages/rum-react/tsconfig.esm.json | 11 --- packages/rum-slim/package.json | 5 +- packages/rum-slim/tsconfig.cjs.json | 12 ---- packages/rum-slim/tsconfig.esm.json | 11 --- packages/rum/package.json | 6 +- packages/rum/tsconfig.cjs.json | 13 ---- packages/rum/tsconfig.esm.json | 12 ---- scripts/build/build-package.ts | 102 +++++++++++++++++++++++++++ scripts/build/replace-build-env.ts | 27 ------- 23 files changed, 113 insertions(+), 218 deletions(-) delete mode 100644 packages/core/tsconfig.cjs.json delete mode 100644 packages/core/tsconfig.esm.json delete mode 100644 packages/flagging/tsconfig.cjs.json delete mode 100644 packages/flagging/tsconfig.esm.json delete mode 100644 packages/logs/tsconfig.cjs.json delete mode 100644 packages/logs/tsconfig.esm.json delete mode 100644 packages/rum-core/tsconfig.cjs.json delete mode 100644 packages/rum-core/tsconfig.esm.json delete mode 100644 packages/rum-react/tsconfig.cjs.json delete mode 100644 packages/rum-react/tsconfig.esm.json delete mode 100644 packages/rum-slim/tsconfig.cjs.json delete mode 100644 packages/rum-slim/tsconfig.esm.json delete mode 100644 packages/rum/tsconfig.cjs.json delete mode 100644 packages/rum/tsconfig.esm.json create mode 100644 scripts/build/build-package.ts delete mode 100644 scripts/build/replace-build-env.ts diff --git a/packages/core/package.json b/packages/core/package.json index cefb22ed8e..a75630310a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -8,10 +8,7 @@ "sideEffects": false, "scripts": { "pack": "yarn pack", - "build": "run-p build:cjs build:esm", - "build:cjs": "rm -rf cjs && tsc -p tsconfig.cjs.json && yarn replace-build-env cjs", - "build:esm": "rm -rf esm && tsc -p tsconfig.esm.json && yarn replace-build-env esm", - "replace-build-env": "node ../../scripts/build/replace-build-env.ts" + "build": "node ../../scripts/build/build-package.ts --modules" }, "repository": { "type": "git", diff --git a/packages/core/tsconfig.cjs.json b/packages/core/tsconfig.cjs.json deleted file mode 100644 index d78ac200b2..0000000000 --- a/packages/core/tsconfig.cjs.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "baseUrl": ".", - "declaration": true, - "module": "commonjs", - "rootDir": "./src/", - "outDir": "./cjs/" - }, - "include": ["./src/**/*.ts"], - "exclude": ["./src/**/*.spec.ts", "./src/**/*.specHelper.ts"] -} diff --git a/packages/core/tsconfig.esm.json b/packages/core/tsconfig.esm.json deleted file mode 100644 index 9d1d447af3..0000000000 --- a/packages/core/tsconfig.esm.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "baseUrl": ".", - "declaration": true, - "rootDir": "./src/", - "outDir": "./esm/" - }, - "include": ["./src/**/*.ts"], - "exclude": ["./src/**/*.spec.ts", "./src/**/*.specHelper.ts"] -} diff --git a/packages/flagging/package.json b/packages/flagging/package.json index bc188a9716..6bfc372cb4 100644 --- a/packages/flagging/package.json +++ b/packages/flagging/package.json @@ -7,11 +7,9 @@ "types": "cjs/entries/main.d.ts", "scripts": { "pack": "yarn pack", - "build": "run-p build:cjs build:esm build:bundle", + "build": "run-p build:modules build:bundle", "build:bundle": "rm -rf bundle && SDK_SETUP=cdn webpack --disable-interpret --mode=production", - "build:cjs": "rm -rf cjs && tsc -p tsconfig.cjs.json && yarn replace-build-env cjs", - "build:esm": "rm -rf esm && tsc -p tsconfig.esm.json && yarn replace-build-env esm", - "replace-build-env": "node ../../scripts/build/replace-build-env.ts" + "build:modules": "node ../../scripts/build/build-package.ts --modules" }, "dependencies": { "@datadog/browser-core": "6.22.0" diff --git a/packages/flagging/tsconfig.cjs.json b/packages/flagging/tsconfig.cjs.json deleted file mode 100644 index d78ac200b2..0000000000 --- a/packages/flagging/tsconfig.cjs.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "baseUrl": ".", - "declaration": true, - "module": "commonjs", - "rootDir": "./src/", - "outDir": "./cjs/" - }, - "include": ["./src/**/*.ts"], - "exclude": ["./src/**/*.spec.ts", "./src/**/*.specHelper.ts"] -} diff --git a/packages/flagging/tsconfig.esm.json b/packages/flagging/tsconfig.esm.json deleted file mode 100644 index fee4f61227..0000000000 --- a/packages/flagging/tsconfig.esm.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "baseUrl": ".", - "declaration": true, - "module": "es6", - "rootDir": "./src/", - "outDir": "./esm/" - }, - "include": ["./src/**/*.ts"], - "exclude": ["./src/**/*.spec.ts", "./src/**/*.specHelper.ts"] -} diff --git a/packages/logs/package.json b/packages/logs/package.json index a3a96902d2..1331a19ad0 100644 --- a/packages/logs/package.json +++ b/packages/logs/package.json @@ -7,11 +7,9 @@ "types": "cjs/entries/main.d.ts", "scripts": { "pack": "yarn pack", - "build": "run-p build:cjs build:esm build:bundle", + "build": "run-p build:modules build:bundle", "build:bundle": "rm -rf bundle && SDK_SETUP=cdn webpack --disable-interpret --mode=production", - "build:cjs": "rm -rf cjs && tsc -p tsconfig.cjs.json && yarn replace-build-env cjs", - "build:esm": "rm -rf esm && tsc -p tsconfig.esm.json && yarn replace-build-env esm", - "replace-build-env": "node ../../scripts/build/replace-build-env.ts" + "build:modules": "node ../../scripts/build/build-package.ts --modules" }, "dependencies": { "@datadog/browser-core": "6.23.0" diff --git a/packages/logs/tsconfig.cjs.json b/packages/logs/tsconfig.cjs.json deleted file mode 100644 index d78ac200b2..0000000000 --- a/packages/logs/tsconfig.cjs.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "baseUrl": ".", - "declaration": true, - "module": "commonjs", - "rootDir": "./src/", - "outDir": "./cjs/" - }, - "include": ["./src/**/*.ts"], - "exclude": ["./src/**/*.spec.ts", "./src/**/*.specHelper.ts"] -} diff --git a/packages/logs/tsconfig.esm.json b/packages/logs/tsconfig.esm.json deleted file mode 100644 index fee4f61227..0000000000 --- a/packages/logs/tsconfig.esm.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "baseUrl": ".", - "declaration": true, - "module": "es6", - "rootDir": "./src/", - "outDir": "./esm/" - }, - "include": ["./src/**/*.ts"], - "exclude": ["./src/**/*.spec.ts", "./src/**/*.specHelper.ts"] -} diff --git a/packages/rum-core/package.json b/packages/rum-core/package.json index f0dd7783da..f541f747c1 100644 --- a/packages/rum-core/package.json +++ b/packages/rum-core/package.json @@ -7,10 +7,7 @@ "types": "cjs/index.d.ts", "scripts": { "pack": "yarn pack", - "build": "run-p build:cjs build:esm", - "build:cjs": "rm -rf cjs && tsc -p tsconfig.cjs.json && yarn replace-build-env cjs", - "build:esm": "rm -rf esm && tsc -p tsconfig.esm.json && yarn replace-build-env esm", - "replace-build-env": "node ../../scripts/build/replace-build-env.ts" + "build": "node ../../scripts/build/build-package.ts --modules" }, "dependencies": { "@datadog/browser-core": "6.23.0" diff --git a/packages/rum-core/tsconfig.cjs.json b/packages/rum-core/tsconfig.cjs.json deleted file mode 100644 index d78ac200b2..0000000000 --- a/packages/rum-core/tsconfig.cjs.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "baseUrl": ".", - "declaration": true, - "module": "commonjs", - "rootDir": "./src/", - "outDir": "./cjs/" - }, - "include": ["./src/**/*.ts"], - "exclude": ["./src/**/*.spec.ts", "./src/**/*.specHelper.ts"] -} diff --git a/packages/rum-core/tsconfig.esm.json b/packages/rum-core/tsconfig.esm.json deleted file mode 100644 index 9d1d447af3..0000000000 --- a/packages/rum-core/tsconfig.esm.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "baseUrl": ".", - "declaration": true, - "rootDir": "./src/", - "outDir": "./esm/" - }, - "include": ["./src/**/*.ts"], - "exclude": ["./src/**/*.spec.ts", "./src/**/*.specHelper.ts"] -} diff --git a/packages/rum-react/package.json b/packages/rum-react/package.json index ac24842189..0171cdd876 100644 --- a/packages/rum-react/package.json +++ b/packages/rum-react/package.json @@ -7,9 +7,7 @@ "types": "cjs/entries/main.d.ts", "scripts": { "pack": "yarn pack", - "build": "run-p build:cjs build:esm", - "build:cjs": "rm -rf cjs && tsc -p tsconfig.cjs.json --noCheck", - "build:esm": "rm -rf esm && tsc -p tsconfig.esm.json --noCheck", + "build": "node ../../scripts/build/build-package.ts --modules", "prepack": "npm run build" }, "dependencies": { diff --git a/packages/rum-react/tsconfig.cjs.json b/packages/rum-react/tsconfig.cjs.json deleted file mode 100644 index d78ac200b2..0000000000 --- a/packages/rum-react/tsconfig.cjs.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "baseUrl": ".", - "declaration": true, - "module": "commonjs", - "rootDir": "./src/", - "outDir": "./cjs/" - }, - "include": ["./src/**/*.ts"], - "exclude": ["./src/**/*.spec.ts", "./src/**/*.specHelper.ts"] -} diff --git a/packages/rum-react/tsconfig.esm.json b/packages/rum-react/tsconfig.esm.json deleted file mode 100644 index 9d1d447af3..0000000000 --- a/packages/rum-react/tsconfig.esm.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "baseUrl": ".", - "declaration": true, - "rootDir": "./src/", - "outDir": "./esm/" - }, - "include": ["./src/**/*.ts"], - "exclude": ["./src/**/*.spec.ts", "./src/**/*.specHelper.ts"] -} diff --git a/packages/rum-slim/package.json b/packages/rum-slim/package.json index 8f67cb2401..b77066946b 100644 --- a/packages/rum-slim/package.json +++ b/packages/rum-slim/package.json @@ -7,10 +7,9 @@ "types": "cjs/entries/main.d.ts", "scripts": { "pack": "yarn pack", - "build": "run-p build:cjs build:esm build:bundle", + "build": "run-p build:modules build:bundle", "build:bundle": "rm -rf bundle && SDK_SETUP=cdn webpack --disable-interpret --mode=production", - "build:cjs": "rm -rf cjs && tsc -p tsconfig.cjs.json", - "build:esm": "rm -rf esm && tsc -p tsconfig.esm.json" + "build:modules": "node ../../scripts/build/build-package.ts --modules" }, "dependencies": { "@datadog/browser-core": "6.23.0", diff --git a/packages/rum-slim/tsconfig.cjs.json b/packages/rum-slim/tsconfig.cjs.json deleted file mode 100644 index d78ac200b2..0000000000 --- a/packages/rum-slim/tsconfig.cjs.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "baseUrl": ".", - "declaration": true, - "module": "commonjs", - "rootDir": "./src/", - "outDir": "./cjs/" - }, - "include": ["./src/**/*.ts"], - "exclude": ["./src/**/*.spec.ts", "./src/**/*.specHelper.ts"] -} diff --git a/packages/rum-slim/tsconfig.esm.json b/packages/rum-slim/tsconfig.esm.json deleted file mode 100644 index 9d1d447af3..0000000000 --- a/packages/rum-slim/tsconfig.esm.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "baseUrl": ".", - "declaration": true, - "rootDir": "./src/", - "outDir": "./esm/" - }, - "include": ["./src/**/*.ts"], - "exclude": ["./src/**/*.spec.ts", "./src/**/*.specHelper.ts"] -} diff --git a/packages/rum/package.json b/packages/rum/package.json index 8c3ad07013..60c86b8c5d 100644 --- a/packages/rum/package.json +++ b/packages/rum/package.json @@ -7,11 +7,9 @@ "types": "cjs/entries/main.d.ts", "scripts": { "pack": "yarn pack", - "build": "run-p build:cjs build:esm build:bundle", + "build": "run-p build:modules build:bundle", "build:bundle": "rm -rf bundle && SDK_SETUP=cdn webpack --disable-interpret --mode=production", - "build:cjs": "rm -rf cjs && tsc -p tsconfig.cjs.json && yarn replace-build-env cjs", - "build:esm": "rm -rf esm && tsc -p tsconfig.esm.json && yarn replace-build-env esm", - "replace-build-env": "node ../../scripts/build/replace-build-env.ts" + "build:modules": "node ../../scripts/build/build-package.ts --modules" }, "dependencies": { "@datadog/browser-core": "6.23.0", diff --git a/packages/rum/tsconfig.cjs.json b/packages/rum/tsconfig.cjs.json deleted file mode 100644 index 1106af4343..0000000000 --- a/packages/rum/tsconfig.cjs.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "baseUrl": ".", - "declaration": true, - "allowJs": true, - "module": "commonjs", - "rootDir": "./src/", - "outDir": "./cjs/" - }, - "include": ["./src"], - "exclude": ["./src/**/*.spec.ts", "./src/**/*.specHelper.ts"] -} diff --git a/packages/rum/tsconfig.esm.json b/packages/rum/tsconfig.esm.json deleted file mode 100644 index 815687627a..0000000000 --- a/packages/rum/tsconfig.esm.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "baseUrl": ".", - "declaration": true, - "allowJs": true, - "rootDir": "./src/", - "outDir": "./esm/" - }, - "include": ["./src"], - "exclude": ["./src/**/*.spec.ts", "./src/**/*.specHelper.ts"] -} diff --git a/scripts/build/build-package.ts b/scripts/build/build-package.ts new file mode 100644 index 0000000000..a4274cc30c --- /dev/null +++ b/scripts/build/build-package.ts @@ -0,0 +1,102 @@ +import fs from 'node:fs/promises' +import { parseArgs } from 'node:util' +import ts from 'typescript' +import { globSync } from 'glob' + +import { printLog, runMain } from '../lib/executionUtils.ts' +import { modifyFile } from '../lib/filesUtils.ts' +import { buildEnvKeys, getBuildEnvValue } from '../lib/buildEnv.ts' + +runMain(async () => { + const { values } = parseArgs({ + options: { + modules: { + type: 'boolean', + }, + verbose: { + type: 'boolean', + default: false, + }, + }, + }) + + if (values.modules) { + printLog('Building modules...') + await buildModules({ + outDir: './cjs', + module: 'commonjs', + verbose: values.verbose, + }) + await buildModules({ + outDir: './esm', + module: 'es2020', + verbose: values.verbose, + }) + } +}) + +async function buildModules({ outDir, module, verbose }: { outDir: string; module: string; verbose: boolean }) { + await fs.rm(outDir, { recursive: true, force: true }) + + // TODO: in the future, consider building packages with something else than typescript (ex: + // rspack, tsdown...) + + const parsed = ts.parseJsonConfigFileContent( + { + extends: '../../tsconfig.base.json', + compilerOptions: { + baseUrl: '.', + declaration: true, + allowJs: true, + module, + rootDir: './src/', + outDir, + }, + include: ['./src'], + exclude: ['./src/**/*.spec.*', './src/**/*.specHelper.*'], + }, + ts.sys, + process.cwd(), + undefined, + 'tsconfig.json' // just used in messages + ) + + const host = ts.createCompilerHost(parsed.options) + const program = ts.createProgram({ + rootNames: parsed.fileNames, + options: parsed.options, + host, + }) + + const emitResult = program.emit() + const diagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics) + + if (diagnostics.length) { + const formatHost: ts.FormatDiagnosticsHost = { + getCanonicalFileName: (f) => f, + // eslint-disable-next-line @typescript-eslint/unbound-method + getCurrentDirectory: ts.sys.getCurrentDirectory, + getNewLine: () => ts.sys.newLine, + } + console.error(ts.formatDiagnosticsWithColorAndContext(diagnostics, formatHost)) + } + + if (emitResult.emitSkipped) { + throw new Error('Failed to build package') + } + + for (const path of globSync('**/*.js', { cwd: outDir, absolute: true })) { + if (await modifyFile(path, (content: string) => replaceBuildEnv(content))) { + if (verbose) { + printLog(`Replaced BuildEnv in ${path}`) + } + } + } + + function replaceBuildEnv(content: string): string { + return buildEnvKeys.reduce( + (content, key) => content.replaceAll(`__BUILD_ENV__${key}__`, () => JSON.stringify(getBuildEnvValue(key))), + content + ) + } +} diff --git a/scripts/build/replace-build-env.ts b/scripts/build/replace-build-env.ts deleted file mode 100644 index 23554f6003..0000000000 --- a/scripts/build/replace-build-env.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { globSync } from 'glob' -import { printLog, runMain } from '../lib/executionUtils.ts' -import { modifyFile } from '../lib/filesUtils.ts' -import { buildEnvKeys, getBuildEnvValue } from '../lib/buildEnv.ts' - -/** - * Replace BuildEnv in build files - * Usage: - * BUILD_MODE=zzz node replace-build-env.ts /path/to/build/directory - */ - -runMain(async () => { - const buildDirectory = process.argv[2] - - for (const path of globSync('**/*.js', { cwd: buildDirectory, absolute: true })) { - if (await modifyFile(path, (content: string) => replaceBuildEnv(content))) { - printLog(`Replaced BuildEnv in ${path}`) - } - } -}) - -function replaceBuildEnv(content: string): string { - return buildEnvKeys.reduce( - (content, key) => content.replaceAll(`__BUILD_ENV__${key}__`, () => JSON.stringify(getBuildEnvValue(key))), - content - ) -} From daf11300e14678df860018f8c02289a20a484a5c Mon Sep 17 00:00:00 2001 From: Benoit Zugmeyer Date: Fri, 31 Oct 2025 10:27:51 +0100 Subject: [PATCH 02/58] =?UTF-8?q?=F0=9F=91=B7=20build=20bundles=20using=20?= =?UTF-8?q?a=20script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/flagging/package.json | 5 ++-- packages/flagging/webpack.config.mts | 10 -------- packages/logs/package.json | 5 ++-- packages/logs/webpack.config.mts | 10 -------- packages/rum-slim/package.json | 5 ++-- packages/rum-slim/webpack.config.mts | 10 -------- packages/rum/package.json | 5 ++-- packages/rum/webpack.config.mts | 10 -------- packages/worker/package.json | 3 ++- packages/worker/webpack.config.mts | 10 -------- scripts/build/build-package.ts | 37 ++++++++++++++++++++++++++++ 11 files changed, 47 insertions(+), 63 deletions(-) delete mode 100644 packages/flagging/webpack.config.mts delete mode 100644 packages/logs/webpack.config.mts delete mode 100644 packages/rum-slim/webpack.config.mts delete mode 100644 packages/rum/webpack.config.mts delete mode 100644 packages/worker/webpack.config.mts diff --git a/packages/flagging/package.json b/packages/flagging/package.json index 6bfc372cb4..901d299606 100644 --- a/packages/flagging/package.json +++ b/packages/flagging/package.json @@ -7,9 +7,8 @@ "types": "cjs/entries/main.d.ts", "scripts": { "pack": "yarn pack", - "build": "run-p build:modules build:bundle", - "build:bundle": "rm -rf bundle && SDK_SETUP=cdn webpack --disable-interpret --mode=production", - "build:modules": "node ../../scripts/build/build-package.ts --modules" + "build": "node ../../scripts/build/build-package.ts --modules --bundle datadog-flagging.js", + "build:bundle": "node ../../scripts/build/build-package.ts --bundle datadog-flagging.js" }, "dependencies": { "@datadog/browser-core": "6.22.0" diff --git a/packages/flagging/webpack.config.mts b/packages/flagging/webpack.config.mts deleted file mode 100644 index f12387f8d3..0000000000 --- a/packages/flagging/webpack.config.mts +++ /dev/null @@ -1,10 +0,0 @@ -import path from 'path' -import type webpack from 'webpack' -import webpackBase from '../../webpack.base.ts' - -export default (_env: unknown, argv: { mode?: webpack.Configuration['mode'] }) => - webpackBase({ - mode: argv.mode, - entry: path.resolve(import.meta.dirname, 'src/entries/main.ts'), - filename: 'datadog-flagging.js', - }) diff --git a/packages/logs/package.json b/packages/logs/package.json index 1331a19ad0..3d00c9cd30 100644 --- a/packages/logs/package.json +++ b/packages/logs/package.json @@ -7,9 +7,8 @@ "types": "cjs/entries/main.d.ts", "scripts": { "pack": "yarn pack", - "build": "run-p build:modules build:bundle", - "build:bundle": "rm -rf bundle && SDK_SETUP=cdn webpack --disable-interpret --mode=production", - "build:modules": "node ../../scripts/build/build-package.ts --modules" + "build": "node ../../scripts/build/build-package.ts --modules --bundle datadog-logs.js", + "build:bundle": "node ../../scripts/build/build-package.ts --bundle datadog-logs.js" }, "dependencies": { "@datadog/browser-core": "6.23.0" diff --git a/packages/logs/webpack.config.mts b/packages/logs/webpack.config.mts deleted file mode 100644 index 0ab813e642..0000000000 --- a/packages/logs/webpack.config.mts +++ /dev/null @@ -1,10 +0,0 @@ -import path from 'path' -import type webpack from 'webpack' -import webpackBase from '../../webpack.base.ts' - -export default (_env: unknown, argv: { mode?: webpack.Configuration['mode'] }) => - webpackBase({ - mode: argv.mode, - entry: path.resolve(import.meta.dirname, 'src/entries/main.ts'), - filename: 'datadog-logs.js', - }) diff --git a/packages/rum-slim/package.json b/packages/rum-slim/package.json index b77066946b..a974852aba 100644 --- a/packages/rum-slim/package.json +++ b/packages/rum-slim/package.json @@ -7,9 +7,8 @@ "types": "cjs/entries/main.d.ts", "scripts": { "pack": "yarn pack", - "build": "run-p build:modules build:bundle", - "build:bundle": "rm -rf bundle && SDK_SETUP=cdn webpack --disable-interpret --mode=production", - "build:modules": "node ../../scripts/build/build-package.ts --modules" + "build": "node ../../scripts/build/build-package.ts --modules --bundle datadog-rum-slim.js", + "build:bundle": "node ../../scripts/build/build-package.ts --bundle datadog-rum-slim.js" }, "dependencies": { "@datadog/browser-core": "6.23.0", diff --git a/packages/rum-slim/webpack.config.mts b/packages/rum-slim/webpack.config.mts deleted file mode 100644 index 26cb6f3743..0000000000 --- a/packages/rum-slim/webpack.config.mts +++ /dev/null @@ -1,10 +0,0 @@ -import path from 'path' -import type webpack from 'webpack' -import webpackBase from '../../webpack.base.ts' - -export default (_env: unknown, argv: { mode?: webpack.Configuration['mode'] }) => - webpackBase({ - mode: argv.mode, - entry: path.resolve(import.meta.dirname, 'src/entries/main.ts'), - filename: 'datadog-rum-slim.js', - }) diff --git a/packages/rum/package.json b/packages/rum/package.json index 60c86b8c5d..46e16fdd53 100644 --- a/packages/rum/package.json +++ b/packages/rum/package.json @@ -7,9 +7,8 @@ "types": "cjs/entries/main.d.ts", "scripts": { "pack": "yarn pack", - "build": "run-p build:modules build:bundle", - "build:bundle": "rm -rf bundle && SDK_SETUP=cdn webpack --disable-interpret --mode=production", - "build:modules": "node ../../scripts/build/build-package.ts --modules" + "build": "node ../../scripts/build/build-package.ts --modules --bundle datadog-rum.js", + "build:bundle": "node ../../scripts/build/build-package.ts --bundle datadog-rum.js" }, "dependencies": { "@datadog/browser-core": "6.23.0", diff --git a/packages/rum/webpack.config.mts b/packages/rum/webpack.config.mts deleted file mode 100644 index 74361fe83d..0000000000 --- a/packages/rum/webpack.config.mts +++ /dev/null @@ -1,10 +0,0 @@ -import path from 'path' -import type webpack from 'webpack' -import webpackBase from '../../webpack.base.ts' - -export default (_env: unknown, argv: { mode?: webpack.Configuration['mode'] }) => - webpackBase({ - mode: argv.mode, - entry: path.resolve(import.meta.dirname, 'src/entries/main.ts'), - filename: 'datadog-rum.js', - }) diff --git a/packages/worker/package.json b/packages/worker/package.json index b6e1cdb9c2..eb2e6ad622 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -5,7 +5,8 @@ "main": "bundle/worker.js", "scripts": { "pack": "yarn pack", - "build": "rm -rf bundle && webpack --disable-interpret --mode=production" + "build": "node ../../scripts/build/build-package.ts --bundle worker.js", + "build:bundle": "yarn build" }, "dependencies": { "@datadog/browser-core": "6.23.0" diff --git a/packages/worker/webpack.config.mts b/packages/worker/webpack.config.mts deleted file mode 100644 index 7f75d48873..0000000000 --- a/packages/worker/webpack.config.mts +++ /dev/null @@ -1,10 +0,0 @@ -import path from 'path' -import type webpack from 'webpack' -import webpackBase from '../../webpack.base.ts' - -export default (_env: unknown, argv: { mode?: webpack.Configuration['mode'] }) => - webpackBase({ - mode: argv.mode, - entry: path.resolve(import.meta.dirname, 'src/entries/main.ts'), - filename: 'worker.js', - }) diff --git a/scripts/build/build-package.ts b/scripts/build/build-package.ts index a4274cc30c..ecb4710645 100644 --- a/scripts/build/build-package.ts +++ b/scripts/build/build-package.ts @@ -2,6 +2,8 @@ import fs from 'node:fs/promises' import { parseArgs } from 'node:util' import ts from 'typescript' import { globSync } from 'glob' +import webpack from 'webpack' +import webpackBase from '../../webpack.base.ts' import { printLog, runMain } from '../lib/executionUtils.ts' import { modifyFile } from '../lib/filesUtils.ts' @@ -13,6 +15,9 @@ runMain(async () => { modules: { type: 'boolean', }, + bundle: { + type: 'string', + }, verbose: { type: 'boolean', default: false, @@ -33,8 +38,40 @@ runMain(async () => { verbose: values.verbose, }) } + + if (values.bundle) { + printLog('Building bundle...') + await buildBundle({ + filename: values.bundle, + verbose: values.verbose, + }) + } }) +async function buildBundle({ filename, verbose }: { filename: string; verbose: boolean }) { + await fs.rm('./bundle', { recursive: true, force: true }) + return new Promise((resolve, reject) => { + webpack( + webpackBase({ + mode: 'production', + entry: './src/entries/main.ts', + filename, + }), + (error, stats) => { + if (error) { + reject(error) + return + } + + if (verbose) { + console.log(stats!.toString({ colors: true })) + } + resolve() + } + ) + }) +} + async function buildModules({ outDir, module, verbose }: { outDir: string; module: string; verbose: boolean }) { await fs.rm(outDir, { recursive: true, force: true }) From a2998402f6ca1e953cca2fe228ac9683bb8e3040 Mon Sep 17 00:00:00 2001 From: Benoit Zugmeyer Date: Fri, 31 Oct 2025 10:59:04 +0100 Subject: [PATCH 03/58] =?UTF-8?q?=F0=9F=91=B7=20adjust=20sandbox=20build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/dev-server.ts | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/scripts/dev-server.ts b/scripts/dev-server.ts index f08be09627..64e8706fb9 100644 --- a/scripts/dev-server.ts +++ b/scripts/dev-server.ts @@ -4,16 +4,13 @@ import HtmlWebpackPlugin from 'html-webpack-plugin' import webpack from 'webpack' import cors from 'cors' import webpackBase from '../webpack.base.ts' -import logsConfig from '../packages/logs/webpack.config.mts' -import rumSlimConfig from '../packages/rum-slim/webpack.config.mts' -import rumConfig from '../packages/rum/webpack.config.mts' -import flaggingConfig from '../packages/flagging/webpack.config.mts' -import workerConfig from '../packages/worker/webpack.config.mts' import { printLog, runMain } from './lib/executionUtils.ts' const sandboxPath = './sandbox' const port = 8080 +const PACKAGES_WITH_BUNDLE = ['rum', 'rum-slim', 'logs', 'flagging', 'worker'] + runMain(() => { const app = express() app.use(createStaticSandboxApp()) @@ -25,8 +22,19 @@ function createStaticSandboxApp(): express.Application { const app = express() app.use(cors()) app.use(express.static(sandboxPath)) - for (const config of [rumConfig, rumSlimConfig, logsConfig, flaggingConfig, workerConfig]) { - app.use(middleware(webpack(config(null, { mode: 'development' }))!)) + for (const packageName of PACKAGES_WITH_BUNDLE) { + const packagePath = `./packages/${packageName}` + app.use( + middleware( + webpack( + webpackBase({ + mode: 'development', + entry: `${packagePath}/src/entries/main.ts`, + filename: packageName === 'worker' ? 'worker.js' : `datadog-${packageName}.js`, + }) + )! + ) + ) } // Redirect suffixed files From de520ca578da073cff1ad71c3a88a9d8b1b432b2 Mon Sep 17 00:00:00 2001 From: Benoit Zugmeyer Date: Fri, 31 Oct 2025 10:59:04 +0100 Subject: [PATCH 04/58] =?UTF-8?q?=F0=9F=91=B7=20fix=20check-packages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/check-packages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check-packages.ts b/scripts/check-packages.ts index 499acc29e2..c4114d59e1 100644 --- a/scripts/check-packages.ts +++ b/scripts/check-packages.ts @@ -48,7 +48,7 @@ function getPackageFiles(packagePath: string): string[] { // // [1]: Quoting Lerna doc: "Lerna always uses npm to publish packages." // https://lerna.js.org/docs/features/version-and-publish#from-package - const output = command`npm pack --dry-run --json`.withCurrentWorkingDirectory(packagePath).run() + const output = command`npm pack --ignore-scripts --dry-run --json`.withCurrentWorkingDirectory(packagePath).run() const parsed: NpmPackOutput[] = JSON.parse(output) return parsed[0].files.map((file) => file.path) } From 2be9686a4bd033a2487cca166e60276f197d5e97 Mon Sep 17 00:00:00 2001 From: Benoit Zugmeyer Date: Tue, 4 Nov 2025 18:12:56 +0100 Subject: [PATCH 05/58] =?UTF-8?q?=F0=9F=94=A5=20remove=20now=20unused=20np?= =?UTF-8?q?m-run-all=20dependency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE-3rdparty.csv | 1 - package.json | 1 - packages/flagging/package.json | 1 - yarn.lock | 152 +-------------------------------- 4 files changed, 3 insertions(+), 152 deletions(-) diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index b1b3cda52f..45c99de481 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -57,7 +57,6 @@ dev,karma-webpack,MIT,Copyright JS Foundation and other contributors dev,lerna,MIT,Copyright 2015-present Lerna Contributors dev,minimatch,ISC,Copyright (c) Isaac Z. Schlueter and Contributors dev,node-forge,BSD,Copyright (c) 2010, Digital Bazaar, Inc. -dev,npm-run-all,MIT,Copyright 2015 Toru Nagashima dev,pako,MIT,(C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin dev,prettier,MIT,Copyright James Long and contributors dev,puppeteer,Apache-2.0,Copyright 2017 Google Inc. diff --git a/package.json b/package.json index 210e3c6f09..01e21174f6 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,6 @@ "karma-webpack": "5.0.0", "lerna": "9.0.0", "minimatch": "10.0.3", - "npm-run-all": "4.1.5", "prettier": "3.6.2", "puppeteer": "24.26.0", "swc-loader": "0.2.6", diff --git a/packages/flagging/package.json b/packages/flagging/package.json index 901d299606..523f64e9fe 100644 --- a/packages/flagging/package.json +++ b/packages/flagging/package.json @@ -33,7 +33,6 @@ "access": "public" }, "devDependencies": { - "npm-run-all": "4.1.5", "webpack": "5.102.1" } } diff --git a/yarn.lock b/yarn.lock index d4f6d86bb0..323a87f7ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -236,7 +236,6 @@ __metadata: resolution: "@datadog/browser-flagging@workspace:packages/flagging" dependencies: "@datadog/browser-core": "npm:6.22.0" - npm-run-all: "npm:4.1.5" webpack: "npm:5.102.1" peerDependencies: "@datadog/browser-rum": 6.22.0 @@ -3295,15 +3294,6 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^3.2.1": - version: 3.2.1 - resolution: "ansi-styles@npm:3.2.1" - dependencies: - color-convert: "npm:^1.9.0" - checksum: 10c0/ece5a8ef069fcc5298f67e3f4771a663129abd174ea2dfa87923a2be2abf6cd367ef72ac87942da00ce85bd1d651d4cd8595aebdb1b385889b89b205860e977b - languageName: node - linkType: hard - "ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": version: 4.3.0 resolution: "ansi-styles@npm:4.3.0" @@ -3868,7 +3858,6 @@ __metadata: karma-webpack: "npm:5.0.0" lerna: "npm:9.0.0" minimatch: "npm:10.0.3" - npm-run-all: "npm:4.1.5" prettier: "npm:3.6.2" puppeteer: "npm:24.26.0" swc-loader: "npm:0.2.6" @@ -4122,17 +4111,6 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^2.4.1": - version: 2.4.2 - resolution: "chalk@npm:2.4.2" - dependencies: - ansi-styles: "npm:^3.2.1" - escape-string-regexp: "npm:^1.0.5" - supports-color: "npm:^5.3.0" - checksum: 10c0/e6543f02ec877732e3a2d1c3c3323ddb4d39fbab687c23f526e25bd4c6a9bf3b83a696e8c769d078e04e5754921648f7821b2a2acfd16c550435fd630026e073 - languageName: node - linkType: hard - "chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" @@ -4362,15 +4340,6 @@ __metadata: languageName: node linkType: hard -"color-convert@npm:^1.9.0": - version: 1.9.3 - resolution: "color-convert@npm:1.9.3" - dependencies: - color-name: "npm:1.1.3" - checksum: 10c0/5ad3c534949a8c68fca8fbc6f09068f435f0ad290ab8b2f76841b9e6af7e0bb57b98cb05b0e19fe33f5d91e5a8611ad457e5f69e0a484caad1f7487fd0e8253c - languageName: node - linkType: hard - "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -4380,13 +4349,6 @@ __metadata: languageName: node linkType: hard -"color-name@npm:1.1.3": - version: 1.1.3 - resolution: "color-name@npm:1.1.3" - checksum: 10c0/566a3d42cca25b9b3cd5528cd7754b8e89c0eb646b7f214e8e2eaddb69994ac5f0557d9c175eb5d8f0ad73531140d9c47525085ee752a91a2ab15ab459caf6d6 - languageName: node - linkType: hard - "color-name@npm:~1.1.4": version: 1.1.4 resolution: "color-name@npm:1.1.4" @@ -4805,19 +4767,6 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^6.0.5": - version: 6.0.6 - resolution: "cross-spawn@npm:6.0.6" - dependencies: - nice-try: "npm:^1.0.4" - path-key: "npm:^2.0.1" - semver: "npm:^5.5.0" - shebang-command: "npm:^1.2.0" - which: "npm:^1.2.9" - checksum: 10c0/bf61fb890e8635102ea9bce050515cf915ff6a50ccaa0b37a17dc82fded0fb3ed7af5478b9367b86baee19127ad86af4be51d209f64fd6638c0862dca185fe1d - languageName: node - linkType: hard - "cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" @@ -7048,13 +6997,6 @@ __metadata: languageName: node linkType: hard -"has-flag@npm:^3.0.0": - version: 3.0.0 - resolution: "has-flag@npm:3.0.0" - checksum: 10c0/1c6c83b14b8b1b3c25b0727b8ba3e3b647f99e9e6e13eb7322107261de07a4c1be56fc0d45678fc376e09772a3a1642ccdaf8fc69bdf123b6c086598397ce473 - languageName: node - linkType: hard - "has-flag@npm:^4.0.0": version: 4.0.0 resolution: "has-flag@npm:4.0.0" @@ -9082,13 +9024,6 @@ __metadata: languageName: node linkType: hard -"memorystream@npm:^0.3.1": - version: 0.3.1 - resolution: "memorystream@npm:0.3.1" - checksum: 10c0/4bd164657711d9747ff5edb0508b2944414da3464b7fe21ac5c67cf35bba975c4b446a0124bd0f9a8be54cfc18faf92e92bd77563a20328b1ccf2ff04e9f39b9 - languageName: node - linkType: hard - "meow@npm:^8.1.2": version: 8.1.2 resolution: "meow@npm:8.1.2" @@ -9572,13 +9507,6 @@ __metadata: languageName: node linkType: hard -"nice-try@npm:^1.0.4": - version: 1.0.5 - resolution: "nice-try@npm:1.0.5" - checksum: 10c0/95568c1b73e1d0d4069a3e3061a2102d854513d37bcfda73300015b7ba4868d3b27c198d1dbbd8ebdef4112fc2ed9e895d4a0f2e1cce0bd334f2a1346dc9205f - languageName: node - linkType: hard - "no-case@npm:^3.0.4": version: 3.0.4 resolution: "no-case@npm:3.0.4" @@ -9824,27 +9752,6 @@ __metadata: languageName: node linkType: hard -"npm-run-all@npm:4.1.5": - version: 4.1.5 - resolution: "npm-run-all@npm:4.1.5" - dependencies: - ansi-styles: "npm:^3.2.1" - chalk: "npm:^2.4.1" - cross-spawn: "npm:^6.0.5" - memorystream: "npm:^0.3.1" - minimatch: "npm:^3.0.4" - pidtree: "npm:^0.3.0" - read-pkg: "npm:^3.0.0" - shell-quote: "npm:^1.6.1" - string.prototype.padend: "npm:^3.0.0" - bin: - npm-run-all: bin/npm-run-all/index.js - run-p: bin/run-p/index.js - run-s: bin/run-s/index.js - checksum: 10c0/736ee39bd35454d3efaa4a2e53eba6c523e2e17fba21a18edcce6b221f5cab62000bef16bb6ae8aff9e615831e6b0eb25ab51d52d60e6fa6f4ea880e4c6d31f4 - languageName: node - linkType: hard - "npm-run-path@npm:^4.0.1": version: 4.0.1 resolution: "npm-run-path@npm:4.0.1" @@ -10517,13 +10424,6 @@ __metadata: languageName: node linkType: hard -"path-key@npm:^2.0.1": - version: 2.0.1 - resolution: "path-key@npm:2.0.1" - checksum: 10c0/dd2044f029a8e58ac31d2bf34c34b93c3095c1481942960e84dd2faa95bbb71b9b762a106aead0646695330936414b31ca0bd862bf488a937ad17c8c5d73b32b - languageName: node - linkType: hard - "path-key@npm:^3.0.0, path-key@npm:^3.1.0": version: 3.1.1 resolution: "path-key@npm:3.1.1" @@ -10630,15 +10530,6 @@ __metadata: languageName: node linkType: hard -"pidtree@npm:^0.3.0": - version: 0.3.1 - resolution: "pidtree@npm:0.3.1" - bin: - pidtree: bin/pidtree.js - checksum: 10c0/cd69b0182f749f45ab48584e3442c48c5dc4512502c18d5b0147a33b042c41a4db4269b9ce2f7c48f11833ee5e79d81f5ebc6f7bf8372d4ea55726f60dc505a1 - languageName: node - linkType: hard - "pify@npm:5.0.0": version: 5.0.0 resolution: "pify@npm:5.0.0" @@ -11798,7 +11689,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.5.0, semver@npm:^5.6.0": +"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.6.0": version: 5.7.2 resolution: "semver@npm:5.7.2" bin: @@ -11996,15 +11887,6 @@ __metadata: languageName: node linkType: hard -"shebang-command@npm:^1.2.0": - version: 1.2.0 - resolution: "shebang-command@npm:1.2.0" - dependencies: - shebang-regex: "npm:^1.0.0" - checksum: 10c0/7b20dbf04112c456b7fc258622dafd566553184ac9b6938dd30b943b065b21dabd3776460df534cc02480db5e1b6aec44700d985153a3da46e7db7f9bd21326d - languageName: node - linkType: hard - "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -12014,13 +11896,6 @@ __metadata: languageName: node linkType: hard -"shebang-regex@npm:^1.0.0": - version: 1.0.0 - resolution: "shebang-regex@npm:1.0.0" - checksum: 10c0/9abc45dee35f554ae9453098a13fdc2f1730e525a5eb33c51f096cc31f6f10a4b38074c1ebf354ae7bffa7229506083844008dfc3bb7818228568c0b2dc1fff2 - languageName: node - linkType: hard - "shebang-regex@npm:^3.0.0": version: 3.0.0 resolution: "shebang-regex@npm:3.0.0" @@ -12028,7 +11903,7 @@ __metadata: languageName: node linkType: hard -"shell-quote@npm:^1.6.1, shell-quote@npm:^1.8.3": +"shell-quote@npm:^1.8.3": version: 1.8.3 resolution: "shell-quote@npm:1.8.3" checksum: 10c0/bee87c34e1e986cfb4c30846b8e6327d18874f10b535699866f368ade11ea4ee45433d97bf5eada22c4320c27df79c3a6a7eb1bf3ecfc47f2c997d9e5e2672fd @@ -12458,18 +12333,6 @@ __metadata: languageName: node linkType: hard -"string.prototype.padend@npm:^3.0.0": - version: 3.1.6 - resolution: "string.prototype.padend@npm:3.1.6" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-object-atoms: "npm:^1.0.0" - checksum: 10c0/8f2c8c1f3db1efcdc210668c80c87f2cea1253d6029ff296a172b5e13edc9adebeed4942d023de8d31f9b13b69f3f5d73de7141959b1f09817fba5f527e83be1 - languageName: node - linkType: hard - "string.prototype.trim@npm:^1.2.10": version: 1.2.10 resolution: "string.prototype.trim@npm:1.2.10" @@ -12597,15 +12460,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^5.3.0": - version: 5.5.0 - resolution: "supports-color@npm:5.5.0" - dependencies: - has-flag: "npm:^3.0.0" - checksum: 10c0/6ae5ff319bfbb021f8a86da8ea1f8db52fac8bd4d499492e30ec17095b58af11f0c55f8577390a749b1c4dde691b6a0315dab78f5f54c9b3d83f8fb5905c1c05 - languageName: node - linkType: hard - "supports-color@npm:^7.1.0": version: 7.2.0 resolution: "supports-color@npm:7.2.0" @@ -13828,7 +13682,7 @@ __metadata: languageName: node linkType: hard -"which@npm:^1.2.1, which@npm:^1.2.9": +"which@npm:^1.2.1": version: 1.3.1 resolution: "which@npm:1.3.1" dependencies: From 3b108a1bff4ea20ea6c6cfffbf31d50c612a93b2 Mon Sep 17 00:00:00 2001 From: Benoit Zugmeyer Date: Thu, 6 Nov 2025 17:10:16 +0100 Subject: [PATCH 06/58] =?UTF-8?q?=F0=9F=91=8C=20revamp=20build-package=20s?= =?UTF-8?q?cript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/build/build-package.ts | 91 ++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 38 deletions(-) diff --git a/scripts/build/build-package.ts b/scripts/build/build-package.ts index ecb4710645..a45707eb7b 100644 --- a/scripts/build/build-package.ts +++ b/scripts/build/build-package.ts @@ -46,6 +46,8 @@ runMain(async () => { verbose: values.verbose, }) } + + printLog('Done.') }) async function buildBundle({ filename, verbose }: { filename: string; verbose: boolean }) { @@ -78,51 +80,30 @@ async function buildModules({ outDir, module, verbose }: { outDir: string; modul // TODO: in the future, consider building packages with something else than typescript (ex: // rspack, tsdown...) - const parsed = ts.parseJsonConfigFileContent( - { - extends: '../../tsconfig.base.json', - compilerOptions: { - baseUrl: '.', - declaration: true, - allowJs: true, - module, - rootDir: './src/', - outDir, - }, - include: ['./src'], - exclude: ['./src/**/*.spec.*', './src/**/*.specHelper.*'], + const diagnostics = buildWithTypeScript({ + extends: '../../tsconfig.base.json', + compilerOptions: { + baseUrl: '.', + declaration: true, + allowJs: true, + module, + rootDir: './src/', + outDir, }, - ts.sys, - process.cwd(), - undefined, - 'tsconfig.json' // just used in messages - ) - - const host = ts.createCompilerHost(parsed.options) - const program = ts.createProgram({ - rootNames: parsed.fileNames, - options: parsed.options, - host, + include: ['./src'], + exclude: ['./src/**/*.spec.*', './src/**/*.specHelper.*'], }) - const emitResult = program.emit() - const diagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics) - if (diagnostics.length) { - const formatHost: ts.FormatDiagnosticsHost = { - getCanonicalFileName: (f) => f, - // eslint-disable-next-line @typescript-eslint/unbound-method - getCurrentDirectory: ts.sys.getCurrentDirectory, - getNewLine: () => ts.sys.newLine, - } - console.error(ts.formatDiagnosticsWithColorAndContext(diagnostics, formatHost)) + printTypeScriptDiagnostics(diagnostics) + throw new Error('Failed to build package due to TypeScript errors') } - if (emitResult.emitSkipped) { - throw new Error('Failed to build package') - } + await replaceBuildEnvInDirectory(outDir, { verbose }) +} - for (const path of globSync('**/*.js', { cwd: outDir, absolute: true })) { +async function replaceBuildEnvInDirectory(dir: string, { verbose }: { verbose: boolean }) { + for (const path of globSync('**/*.js', { cwd: dir, absolute: true })) { if (await modifyFile(path, (content: string) => replaceBuildEnv(content))) { if (verbose) { printLog(`Replaced BuildEnv in ${path}`) @@ -137,3 +118,37 @@ async function buildModules({ outDir, module, verbose }: { outDir: string; modul ) } } + +function buildWithTypeScript(configuration: { [key: string]: unknown }) { + const parsedConfiguration = ts.parseJsonConfigFileContent( + configuration, + ts.sys, + process.cwd(), + undefined, + 'tsconfig.json' // just used in messages + ) + + const host = ts.createCompilerHost(parsedConfiguration.options) + const program = ts.createProgram({ + rootNames: parsedConfiguration.fileNames, + options: parsedConfiguration.options, + host, + }) + + const emitResult = program.emit() + if (emitResult.emitSkipped) { + throw new Error('No files were emitted') + } + + return [...ts.getPreEmitDiagnostics(program), ...emitResult.diagnostics] +} + +function printTypeScriptDiagnostics(diagnostics: ts.Diagnostic[]) { + const formatHost: ts.FormatDiagnosticsHost = { + getCanonicalFileName: (f) => f, + // eslint-disable-next-line @typescript-eslint/unbound-method + getCurrentDirectory: ts.sys.getCurrentDirectory, + getNewLine: () => ts.sys.newLine, + } + console.error(ts.formatDiagnosticsWithColorAndContext(diagnostics, formatHost)) +} From 872295479fca1b0bc31b0cde75807817c3a40ac6 Mon Sep 17 00:00:00 2001 From: Benoit Zugmeyer Date: Thu, 6 Nov 2025 18:07:04 +0100 Subject: [PATCH 07/58] adjust build-package script to use the native globSync --- scripts/build/build-package.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/build/build-package.ts b/scripts/build/build-package.ts index a45707eb7b..35de4985c5 100644 --- a/scripts/build/build-package.ts +++ b/scripts/build/build-package.ts @@ -1,7 +1,8 @@ import fs from 'node:fs/promises' import { parseArgs } from 'node:util' +import path from 'node:path' +import { globSync } from 'node:fs' import ts from 'typescript' -import { globSync } from 'glob' import webpack from 'webpack' import webpackBase from '../../webpack.base.ts' @@ -103,10 +104,11 @@ async function buildModules({ outDir, module, verbose }: { outDir: string; modul } async function replaceBuildEnvInDirectory(dir: string, { verbose }: { verbose: boolean }) { - for (const path of globSync('**/*.js', { cwd: dir, absolute: true })) { - if (await modifyFile(path, (content: string) => replaceBuildEnv(content))) { + for (const relativePath of globSync('**/*.js', { cwd: dir })) { + const absolutePath = path.resolve(dir, relativePath) + if (await modifyFile(absolutePath, (content: string) => replaceBuildEnv(content))) { if (verbose) { - printLog(`Replaced BuildEnv in ${path}`) + printLog(`Replaced BuildEnv in ${absolutePath}`) } } } From 02b3e38dda793b3377bf3146df0b70be30d64ce7 Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Tue, 11 Nov 2025 10:32:34 +0100 Subject: [PATCH 08/58] =?UTF-8?q?=F0=9F=91=B7=20handle=20dev-extension=20t?= =?UTF-8?q?o=20run=20in=20electron?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- developer-extension/src/panel/hooks/useEvents/useEvents.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer-extension/src/panel/hooks/useEvents/useEvents.ts b/developer-extension/src/panel/hooks/useEvents/useEvents.ts index b54d048414..89ccbec762 100644 --- a/developer-extension/src/panel/hooks/useEvents/useEvents.ts +++ b/developer-extension/src/panel/hooks/useEvents/useEvents.ts @@ -31,7 +31,7 @@ export function useEvents({ }, [eventCollectionStrategy]) useEffect(() => { - if (!preserveEvents) { + if (!preserveEvents && 'webNavigation' in chrome) { const clearCurrentEvents = (details: chrome.webNavigation.WebNavigationTransitionCallbackDetails) => { if (details.transitionType === 'reload' && details.tabId === chrome.devtools.inspectedWindow.tabId) { clearEvents() From bbcfe4e8db09fd78781dbe6cbb501007465b9bb1 Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Tue, 11 Nov 2025 17:02:43 +0100 Subject: [PATCH 09/58] =?UTF-8?q?=F0=9F=99=88=20[wip]=20Add=20Electron=20p?= =?UTF-8?q?ackage=20with=20initial=20setup=20and=20integration=20for=20Dat?= =?UTF-8?q?adog=20tracing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + packages/core/src/browser/cookie.ts | 3 +- packages/core/src/tools/utils/byteUtils.ts | 6 +- packages/electron/.npmignore | 9 + packages/electron/.yarnrc | 2 + packages/electron/bridge/package.json | 6 + packages/electron/package.json | 45 + packages/electron/src/entries/bridge.ts | 21 + packages/electron/src/entries/main.ts | 206 +++++ packages/electron/src/tracer.ts | 40 + packages/electron/typedoc.json | 4 + yarn.lock | 924 ++++++++++++++++++++- 12 files changed, 1249 insertions(+), 18 deletions(-) create mode 100644 packages/electron/.npmignore create mode 100644 packages/electron/.yarnrc create mode 100644 packages/electron/bridge/package.json create mode 100644 packages/electron/package.json create mode 100644 packages/electron/src/entries/bridge.ts create mode 100644 packages/electron/src/entries/main.ts create mode 100644 packages/electron/src/tracer.ts create mode 100644 packages/electron/typedoc.json diff --git a/package.json b/package.json index 3f7befb1d4..91041dc7ad 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "scripts": { "postinstall": "scripts/cli init_submodule", "build": "lerna run build --stream", + "build:electron": "lerna run build:modules --scope=@datadog/electron", "build:bundle": "lerna run build:bundle --stream", "build:apps": "node scripts/build/build-test-apps.ts", "build:docs:json": "typedoc --logLevel Verbose --json ./docs.json", diff --git a/packages/core/src/browser/cookie.ts b/packages/core/src/browser/cookie.ts index bab3f49e93..3e47802fbf 100644 --- a/packages/core/src/browser/cookie.ts +++ b/packages/core/src/browser/cookie.ts @@ -7,6 +7,7 @@ import { generateUUID, } from '../tools/utils/stringUtils' import { buildUrl } from '../tools/utils/urlPolyfill' +import { getGlobalObject } from '../tools/globalObject' export interface CookieOptions { secure?: boolean @@ -65,7 +66,7 @@ export function deleteCookie(name: string, options?: CookieOptions) { } export function areCookiesAuthorized(options: CookieOptions): boolean { - if (document.cookie === undefined || document.cookie === null) { + if (getGlobalObject().document?.cookie === undefined || getGlobalObject().document?.cookie === null) { return false } try { diff --git a/packages/core/src/tools/utils/byteUtils.ts b/packages/core/src/tools/utils/byteUtils.ts index ed8071f858..57935566be 100644 --- a/packages/core/src/tools/utils/byteUtils.ts +++ b/packages/core/src/tools/utils/byteUtils.ts @@ -1,3 +1,5 @@ +import { globalObject } from '../globalObject' + export const ONE_KIBI_BYTE = 1024 export const ONE_MEBI_BYTE = 1024 * ONE_KIBI_BYTE @@ -16,8 +18,8 @@ export function computeBytesCount(candidate: string): number { return candidate.length } - if (window.TextEncoder !== undefined) { - return new TextEncoder().encode(candidate).length + if ('TextEncoder' in globalObject) { + return new (globalObject as { TextEncoder: typeof TextEncoder }).TextEncoder().encode(candidate).length } return new Blob([candidate]).size diff --git a/packages/electron/.npmignore b/packages/electron/.npmignore new file mode 100644 index 0000000000..254b105e43 --- /dev/null +++ b/packages/electron/.npmignore @@ -0,0 +1,9 @@ +* +!/bundle/**/*.js +!/cjs/**/* +!/esm/**/* +!/src/**/* +/src/**/*.spec.ts +/src/**/*.specHelper.ts +!/internal/* +!/internal-synthetics/* diff --git a/packages/electron/.yarnrc b/packages/electron/.yarnrc new file mode 100644 index 0000000000..db15371515 --- /dev/null +++ b/packages/electron/.yarnrc @@ -0,0 +1,2 @@ +save-exact true + diff --git a/packages/electron/bridge/package.json b/packages/electron/bridge/package.json new file mode 100644 index 0000000000..494c5afc44 --- /dev/null +++ b/packages/electron/bridge/package.json @@ -0,0 +1,6 @@ +{ + "private": true, + "main": "../cjs/entries/bridge.js", + "module": "../esm/entries/bridge.js", + "types": "../cjs/entries/bridge.d.ts" +} diff --git a/packages/electron/package.json b/packages/electron/package.json new file mode 100644 index 0000000000..55ffbd284c --- /dev/null +++ b/packages/electron/package.json @@ -0,0 +1,45 @@ +{ + "name": "@datadog/electron", + "version": "6.23.0", + "license": "Apache-2.0", + "main": "cjs/entries/main.js", + "module": "esm/entries/main.js", + "types": "cjs/entries/main.d.ts", + "scripts": { + "pack": "yarn pack", + "build": "node ../../scripts/build/build-package.ts --modules --bundle datadog-electron.js", + "build:modules": "node ../../scripts/build/build-package.ts --modules", + "build:bundle": "node ../../scripts/build/build-package.ts --bundle datadog-electron.js" + }, + "dependencies": { + "@datadog/browser-core": "6.23.0", + "@datadog/browser-rum-core": "6.23.0", + "@msgpack/msgpack": "3.1.2", + "dd-trace": "^5.76.0" + }, + "peerDependencies": { + "@datadog/browser-logs": "6.23.0", + "electron": "39" + }, + "peerDependenciesMeta": { + "@datadog/browser-logs": { + "optional": true + } + }, + "repository": { + "type": "git", + "url": "https://github.com/DataDog/browser-sdk.git", + "directory": "packages/electron" + }, + "devDependencies": { + "@types/pako": "2.0.4", + "electron": "39", + "pako": "2.1.0" + }, + "volta": { + "extends": "../../package.json" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/electron/src/entries/bridge.ts b/packages/electron/src/entries/bridge.ts new file mode 100644 index 0000000000..3090a02203 --- /dev/null +++ b/packages/electron/src/entries/bridge.ts @@ -0,0 +1,21 @@ +import { contextBridge, ipcRenderer } from 'electron' +import type { DatadogEventBridge } from '@datadog/browser-core/src/transport' + +export function setupElectronBridge() { + console.log('setupElectronBridge') + + contextBridge.exposeInMainWorld('DatadogEventBridge', { + getCapabilities() { + return JSON.stringify(['electron']) + }, + getPrivacyLevel() { + return 'mask' + }, + getAllowedWebViewHosts() { + return JSON.stringify([location.hostname]) + }, + send(msg: string) { + void ipcRenderer.invoke('datadog:send', msg) + }, + } satisfies DatadogEventBridge) +} diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts new file mode 100644 index 0000000000..a4dd52619e --- /dev/null +++ b/packages/electron/src/entries/main.ts @@ -0,0 +1,206 @@ +/* eslint-disable local-rules/enforce-prod-deps-imports */ +/* eslint-disable local-rules/disallow-side-effects */ +/** + * TODO: + * - [ ] Basic session management + * - [x] Transport layer (for the bridge from webview, from dd-trace) + * - [x] handle rum events + * - [ ] handle routing for other type of events + * - [ ] handle dd-trace events (forwards APM spans to trace intake) + * - [x] setup bridge client with ipc from webviews (renderer processes) + * - [x] use `exposeInMainWorld` to setup the bridge function that will setup the ipc to the main process + */ +import crypto from 'node:crypto' +import { createServer } from 'node:http' +import { ipcMain } from 'electron' +import type { RawError, PageMayExitEvent, Encoder, Context, InitConfiguration } from '@datadog/browser-core' +import { + Observable, + DeflateEncoderStreamId, + createBatch, + createHttpRequest, + createFlushController, + createIdentityEncoder, +} from '@datadog/browser-core' +import type { AllowedRawRumEvent, RumConfiguration, RumEvent, RumInitConfiguration } from '@datadog/browser-rum-core' +import { RumEventType } from '@datadog/browser-rum-core' +import { validateAndBuildRumConfiguration } from '@datadog/browser-rum-core/cjs/domain/configuration' +import type { Batch } from '@datadog/browser-core/cjs/transport/batch' +import { decode } from '@msgpack/msgpack' +import type { TrackType } from '@datadog/browser-core/cjs/domain/configuration' +import { createEndpointBuilder } from '@datadog/browser-core/cjs/domain/configuration' +import tracer from '../tracer' + +const sessionId = crypto.randomUUID() +console.log('sessionId', sessionId) + +function makeDatadogElectron() { + return { + init(initConfiguration: RumInitConfiguration) { + console.log('init from SDK Electron') + + const configuration = validateAndBuildRumConfiguration(initConfiguration) + + if (!configuration) { + return + } + + const pageMayExitObservable = new Observable() + const sessionExpireObservable = new Observable() + const createEncoder = () => createIdentityEncoder() + + const rumBatch = startElectronRumBatch( + configuration, + () => { + console.error('Error reporting to Datadog') + }, + pageMayExitObservable, + sessionExpireObservable, + createEncoder + ) + const spanBatch = startElectronSpanBatch( + initConfiguration, + configuration, + () => { + console.error('Error reporting to Datadog') + }, + pageMayExitObservable, + sessionExpireObservable, + createEncoder + ) + setupIpcHandlers(rumBatch, configuration) + createDdTraceAgent(spanBatch) + + setInterval(() => { + pageMayExitObservable.notify({ reason: 'page_hide' }) + }, 1000) + }, + } +} + +export const ddElectron = makeDatadogElectron() + +export function startElectronRumBatch( + configuration: RumConfiguration, + reportError: (error: RawError) => void, + pageMayExitObservable: Observable, + sessionExpireObservable: Observable, + createEncoder: (streamId: DeflateEncoderStreamId) => Encoder +) { + const batch = createBatch({ + encoder: createEncoder(DeflateEncoderStreamId.RUM), + request: createHttpRequest([configuration.rumEndpointBuilder], configuration.batchBytesLimit, reportError), + flushController: createFlushController({ + messagesLimit: configuration.batchMessagesLimit, + bytesLimit: configuration.batchBytesLimit, + durationLimit: configuration.flushTimeout, + pageMayExitObservable, + sessionExpireObservable, + }), + messageBytesLimit: configuration.messageBytesLimit, + }) + + return batch +} + +export function startElectronSpanBatch( + initConfiguration: InitConfiguration, + configuration: RumConfiguration, + reportError: (error: RawError) => void, + pageMayExitObservable: Observable, + sessionExpireObservable: Observable, + createEncoder: (streamId: DeflateEncoderStreamId) => Encoder +) { + const endpoints = [createEndpointBuilder(initConfiguration, 'spans' as TrackType)] + const batch = createBatch({ + encoder: createEncoder(DeflateEncoderStreamId.RUM), + request: createHttpRequest(endpoints, configuration.batchBytesLimit, reportError), + flushController: createFlushController({ + messagesLimit: configuration.batchMessagesLimit, + bytesLimit: configuration.batchBytesLimit, + durationLimit: configuration.flushTimeout, + pageMayExitObservable, + sessionExpireObservable, + }), + messageBytesLimit: configuration.messageBytesLimit, + }) + + return batch +} + +function setupIpcHandlers(batch: Batch, configuration: RumConfiguration) { + ipcMain.handle('datadog:send', (_event, msg: string) => { + const serverRumEvent = JSON.parse(msg) as BridgeEvent + + if (serverRumEvent.eventType !== 'rum') { + console.log('not a rum event', serverRumEvent) + + return + } + + serverRumEvent.event.session.id = sessionId + serverRumEvent.event.application.id = configuration.applicationId + + if (serverRumEvent.event.type === RumEventType.VIEW) { + batch.upsert(serverRumEvent.event as unknown as Context, serverRumEvent.event.view.id) + } else { + batch.add(serverRumEvent.event as unknown as Context) + } + }) +} + +interface BridgeEvent { + eventType: 'rum' + event: RumEvent & { session: { id: string } } & { application: { id: string } } +} + +function createDdTraceAgent(batch: Batch) { + const server = createServer() + + server.on('request', (req, res) => { + // Collect binary data chunks + const chunks: Buffer[] = [] + req.on('data', (chunk: Buffer) => { + chunks.push(chunk) + }) + req.on('end', () => { + const buffer = Buffer.concat(chunks) + + const decoded = decode(buffer) as unknown[] + + for (const trace of decoded) { + console.log('trace', trace) + batch.add(trace as Context) + } + }) + + // Respond with the agent API format that dd-trace expects + res.writeHead(200, { 'Content-Type': 'application/json' }) + res.end( + JSON.stringify({ + rate_by_service: { + 'service:dd-trace,env:prod': 1, + }, + }) + ) + }) + + server.listen(0, () => { + const addressInfo = server.address() + if (!addressInfo) { + throw new Error('Failed to get server address') + } + + if (typeof addressInfo === 'string') { + throw new Error(`Address is a string: ${addressInfo}`) + } + + const { port } = addressInfo + const url = `http://127.0.0.1:${port}` + + console.log('agents url', url) + tracer.setUrl(url) + }) +} + +export { tracer } diff --git a/packages/electron/src/tracer.ts b/packages/electron/src/tracer.ts new file mode 100644 index 0000000000..3846d6f37c --- /dev/null +++ b/packages/electron/src/tracer.ts @@ -0,0 +1,40 @@ +import tracer from 'dd-trace' +import { app } from 'electron' + +/* +// configuring metrics can help troubleshoot the setup +// but will generate spans for each request to the metrics intake +import metrics from 'datadog-metrics' +metrics.init({ prefix: 'electron-main-ps.' }); + +function collectMemoryStats() { + const memUsage = process.memoryUsage(); + metrics.gauge('memory.rss', memUsage.rss); + metrics.gauge('memory.heapTotal', memUsage.heapTotal); + metrics.gauge('memory.heapUsed', memUsage.heapUsed); +} + +setInterval(collectMemoryStats, 5000); +*/ +tracer.init({ + tags: { + electron: { + appName: app.getName(), + appVersion: app.getVersion(), + version: process.versions.electron, + }, + node: { + version: process.versions.node, + }, + os: { + platform: process.platform, + release: process.release, + }, + chrome: { + version: process.versions.chrome, + }, + env: 'prod', + }, +}) +// initialized in a different file to avoid hoisting. +export default tracer diff --git a/packages/electron/typedoc.json b/packages/electron/typedoc.json new file mode 100644 index 0000000000..002b26a53c --- /dev/null +++ b/packages/electron/typedoc.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "entryPoints": ["src/entries/main.ts"] +} diff --git a/yarn.lock b/yarn.lock index 8b1db08db0..a2509ac1aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -369,6 +369,120 @@ __metadata: languageName: unknown linkType: soft +"@datadog/electron@workspace:packages/electron": + version: 0.0.0-use.local + resolution: "@datadog/electron@workspace:packages/electron" + dependencies: + "@datadog/browser-core": "npm:6.23.0" + "@datadog/browser-rum-core": "npm:6.23.0" + "@msgpack/msgpack": "npm:3.1.2" + "@types/pako": "npm:2.0.4" + dd-trace: "npm:^5.76.0" + electron: "npm:39" + pako: "npm:2.1.0" + peerDependencies: + "@datadog/browser-logs": 6.23.0 + electron: 39 + peerDependenciesMeta: + "@datadog/browser-logs": + optional: true + languageName: unknown + linkType: soft + +"@datadog/flagging-core@npm:0.1.0-preview.13": + version: 0.1.0-preview.13 + resolution: "@datadog/flagging-core@npm:0.1.0-preview.13" + dependencies: + spark-md5: "npm:^3.0.2" + peerDependencies: + "@openfeature/core": ^1.8.1 + checksum: 10c0/0d34958d25ec6656ba987e311dae659bdada2e6fb3bdb07e0283ec0661459e08b6a36543717725a28e597781c58df210c0c1cbe582e1ae8a9470ca1e776dd846 + languageName: node + linkType: hard + +"@datadog/libdatadog@npm:0.7.0": + version: 0.7.0 + resolution: "@datadog/libdatadog@npm:0.7.0" + checksum: 10c0/04ca10b1f3a393e3a6356c80ca257c79c9ebca98923b88fd55d11e732f3721b4fd6fba134737b19d56da1b579c8633824364c724303f33106db461ad7f61c669 + languageName: node + linkType: hard + +"@datadog/native-appsec@npm:10.3.0": + version: 10.3.0 + resolution: "@datadog/native-appsec@npm:10.3.0" + dependencies: + node-gyp: "npm:latest" + node-gyp-build: "npm:^3.9.0" + checksum: 10c0/a1c5eac27d566148c58559e1e3d481efb0bf336b14a2e2a4bcdef6d7137b3fd6401781deac0271b5aa71634796af3f6ffcc1608609268355d4632c6f99dc338f + languageName: node + linkType: hard + +"@datadog/native-iast-taint-tracking@npm:4.0.0": + version: 4.0.0 + resolution: "@datadog/native-iast-taint-tracking@npm:4.0.0" + dependencies: + node-gyp: "npm:latest" + node-gyp-build: "npm:^3.9.0" + checksum: 10c0/72a18959a9eccfeff4b791ff9929a384df84385596232685a65ca9a0225306f376e85bd44540e98467d8058e54bc776b3fd52ed029c04eebb9ef7d3ae73c5df7 + languageName: node + linkType: hard + +"@datadog/native-metrics@npm:3.1.1": + version: 3.1.1 + resolution: "@datadog/native-metrics@npm:3.1.1" + dependencies: + node-addon-api: "npm:^6.1.0" + node-gyp: "npm:latest" + node-gyp-build: "npm:^3.9.0" + checksum: 10c0/05757cd34fca5f129130dba95be32012a9693ac59e7517145560d71275dd9b7592aad60e8f0d1d805b99d74ea834d8ae1e5db00b0de75bc6faba84419cb35393 + languageName: node + linkType: hard + +"@datadog/openfeature-node-server@npm:0.1.0-preview.13": + version: 0.1.0-preview.13 + resolution: "@datadog/openfeature-node-server@npm:0.1.0-preview.13" + dependencies: + "@datadog/flagging-core": "npm:0.1.0-preview.13" + "@openfeature/server-sdk": "npm:~1.18.0" + peerDependencies: + "@openfeature/server-sdk": ~1.18.0 + checksum: 10c0/bb8533ee3dd2e178fa1ef856a7b3233a45a03833de57637daedab034f2c8273993e581254bd77a92a583225bd12857e982349f5c53cfbde44a3d47571d723da6 + languageName: node + linkType: hard + +"@datadog/pprof@npm:5.12.0": + version: 5.12.0 + resolution: "@datadog/pprof@npm:5.12.0" + dependencies: + delay: "npm:^5.0.0" + node-gyp: "npm:latest" + node-gyp-build: "npm:<4.0" + p-limit: "npm:^3.1.0" + pprof-format: "npm:^2.2.1" + source-map: "npm:^0.7.4" + checksum: 10c0/e18e9e941fbd7ba6de52f3e8d92d7b4612ab054b302d2b2581932be41d1f4bb03d27b753ab9242364b897ba2773c105b1badb2d760db4b1fe633e1b8c23c1013 + languageName: node + linkType: hard + +"@datadog/sketches-js@npm:2.1.1": + version: 2.1.1 + resolution: "@datadog/sketches-js@npm:2.1.1" + checksum: 10c0/4b930240202e4e94ac49fc95298a7111202492566f76672e0ec43425a1710a0e3650a20f858a6358509ab08363d39fce5db210c88d94b4225f96b3bfe645cc5c + languageName: node + linkType: hard + +"@datadog/wasm-js-rewriter@npm:4.0.1": + version: 4.0.1 + resolution: "@datadog/wasm-js-rewriter@npm:4.0.1" + dependencies: + js-yaml: "npm:^4.1.0" + lru-cache: "npm:^7.14.0" + module-details-from-path: "npm:^1.0.3" + node-gyp-build: "npm:^4.5.0" + checksum: 10c0/3a9770de5e5e32701c2ed3a5c9da7844c64e1003db855e4c2feead89e50292c04b281e55aa1e98170a2ecdbf2289cdc91c26e9489dabf1e03d8fcb0ebb840fa4 + languageName: node + linkType: hard + "@discoveryjs/json-ext@npm:^0.6.1": version: 0.6.3 resolution: "@discoveryjs/json-ext@npm:0.6.3" @@ -376,6 +490,25 @@ __metadata: languageName: node linkType: hard +"@electron/get@npm:^2.0.0": + version: 2.0.3 + resolution: "@electron/get@npm:2.0.3" + dependencies: + debug: "npm:^4.1.1" + env-paths: "npm:^2.2.0" + fs-extra: "npm:^8.1.0" + global-agent: "npm:^3.0.0" + got: "npm:^11.8.5" + progress: "npm:^2.0.3" + semver: "npm:^6.2.0" + sumchecker: "npm:^3.0.1" + dependenciesMeta: + global-agent: + optional: true + checksum: 10c0/148957d531bac50c29541515f2483c3e5c9c6ba9f0269a5d536540d2b8d849188a89588f18901f3a84c2b4fd376d1e0c5ea2159eb2d17bda68558f57df19015e + languageName: node + linkType: hard + "@emnapi/core@npm:^1.1.0": version: 1.7.0 resolution: "@emnapi/core@npm:1.7.0" @@ -929,6 +1062,13 @@ __metadata: languageName: node linkType: hard +"@isaacs/ttlcache@npm:^1.4.1": + version: 1.4.1 + resolution: "@isaacs/ttlcache@npm:1.4.1" + checksum: 10c0/6921de516917b02673a58e543c2b06fd04237cbf6d089ca22d6e98defa4b1e9a48258cb071d6b581284bb497bea687320788830541511297eecbe6e93a665bbf + languageName: node + linkType: hard + "@istanbuljs/schema@npm:^0.1.2": version: 0.1.3 resolution: "@istanbuljs/schema@npm:0.1.3" @@ -1043,6 +1183,24 @@ __metadata: languageName: node linkType: hard +"@jsep-plugin/assignment@npm:^1.3.0": + version: 1.3.0 + resolution: "@jsep-plugin/assignment@npm:1.3.0" + peerDependencies: + jsep: ^0.4.0||^1.0.0 + checksum: 10c0/d749554dc691798116eb068eebe2d9bcb0b0d89ef6c7cc7c2a9f37d03da15fdbf8053407e97008090cd1bd6f256ea6c26abbada7399cf79f0b6b502e164b084b + languageName: node + linkType: hard + +"@jsep-plugin/regex@npm:^1.0.4": + version: 1.0.4 + resolution: "@jsep-plugin/regex@npm:1.0.4" + peerDependencies: + jsep: ^0.4.0||^1.0.0 + checksum: 10c0/bec7eb7ea6ab453a2672edc808644c5be3dc06b2a9d77182e18cd595b37deba6dcdb3760849d8684afc5779a86b7d2604dd525cb612a548f9ed9f31a8032ec24 + languageName: node + linkType: hard + "@jsonjoy.com/base64@npm:^1.1.2": version: 1.1.2 resolution: "@jsonjoy.com/base64@npm:1.1.2" @@ -1221,6 +1379,13 @@ __metadata: languageName: node linkType: hard +"@msgpack/msgpack@npm:3.1.2": + version: 3.1.2 + resolution: "@msgpack/msgpack@npm:3.1.2" + checksum: 10c0/4fee6dbea70a485d3a787ac76dd43687f489d662f22919237db1f2abbc3c88070c1d3ad78417ce6e764bcd041051680284654021f52068e0aff82d570cb942d5 + languageName: node + linkType: hard + "@napi-rs/wasm-runtime@npm:0.2.4": version: 0.2.4 resolution: "@napi-rs/wasm-runtime@npm:0.2.4" @@ -1768,6 +1933,79 @@ __metadata: languageName: node linkType: hard +"@openfeature/server-sdk@npm:~1.18.0": + version: 1.18.0 + resolution: "@openfeature/server-sdk@npm:1.18.0" + peerDependencies: + "@openfeature/core": ^1.7.0 + checksum: 10c0/5c3aa8fee5ec4ad9ec40ee74094fe0377b28cadfcc6f71414fa1762035cb994891184cc491a59dbaade71afe0139cd39c193e3897b05df8fa21f0e7b84b67c53 + languageName: node + linkType: hard + +"@opentelemetry/api-logs@npm:<1.0.0": + version: 0.208.0 + resolution: "@opentelemetry/api-logs@npm:0.208.0" + dependencies: + "@opentelemetry/api": "npm:^1.3.0" + checksum: 10c0/dc1fbee6219df4166509f43b74ea936bb18b6d594565b0bcf56b654a1c958b50d6046b8739dc36c98149fe890c02150ff3814e963f5ea439a07ff3c562555b99 + languageName: node + linkType: hard + +"@opentelemetry/api@npm:>=1.0.0 <1.10.0, @opentelemetry/api@npm:^1.3.0": + version: 1.9.0 + resolution: "@opentelemetry/api@npm:1.9.0" + checksum: 10c0/9aae2fe6e8a3a3eeb6c1fdef78e1939cf05a0f37f8a4fae4d6bf2e09eb1e06f966ece85805626e01ba5fab48072b94f19b835449e58b6d26720ee19a58298add + languageName: node + linkType: hard + +"@opentelemetry/core@npm:1.9.1": + version: 1.9.1 + resolution: "@opentelemetry/core@npm:1.9.1" + dependencies: + "@opentelemetry/semantic-conventions": "npm:1.9.1" + peerDependencies: + "@opentelemetry/api": ">=1.0.0 <1.5.0" + checksum: 10c0/c890878d6bda33b8998a2622104d39a098febbf792f7c123eca3d5c14e98a963af37cea63adaecabeeeeab72659c4e01f708934ffe040c1a167dd04a0105cb6f + languageName: node + linkType: hard + +"@opentelemetry/core@npm:>=1.14.0 <1.31.0": + version: 1.30.1 + resolution: "@opentelemetry/core@npm:1.30.1" + dependencies: + "@opentelemetry/semantic-conventions": "npm:1.28.0" + peerDependencies: + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: 10c0/4c25ba50a6137c2ba9ca563fb269378f3c9ca6fd1b3f15dbb6eff78eebf5656f281997cbb7be8e51c01649fd6ad091083fcd8a42dd9b5dfac907dc06d7cfa092 + languageName: node + linkType: hard + +"@opentelemetry/resources@npm:>=1.0.0 <1.10.0": + version: 1.9.1 + resolution: "@opentelemetry/resources@npm:1.9.1" + dependencies: + "@opentelemetry/core": "npm:1.9.1" + "@opentelemetry/semantic-conventions": "npm:1.9.1" + peerDependencies: + "@opentelemetry/api": ">=1.0.0 <1.5.0" + checksum: 10c0/d307e7377e9dd7e2955939e3386c6187324186bc6c5ee66f6315af43cee9a4ec733d5bf08bbb43527c3814df0ed63ec6c30364bd44be182b749c765901142a19 + languageName: node + linkType: hard + +"@opentelemetry/semantic-conventions@npm:1.28.0": + version: 1.28.0 + resolution: "@opentelemetry/semantic-conventions@npm:1.28.0" + checksum: 10c0/deb8a0f744198071e70fea27143cf7c9f7ecb7e4d7b619488c917834ea09b31543c1c2bcea4ec5f3cf68797f0ef3549609c14e859013d9376400ac1499c2b9cb + languageName: node + linkType: hard + +"@opentelemetry/semantic-conventions@npm:1.9.1": + version: 1.9.1 + resolution: "@opentelemetry/semantic-conventions@npm:1.9.1" + checksum: 10c0/6acca1e2ad6eff361e779de4a5260f9c0542c6557b0105e5785deaa5aa1bbf74625f8267df4be33580f190efeb70da949ecbfe0cf74e89488abf1e0ba479daf1 + languageName: node + linkType: hard + "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -1822,6 +2060,79 @@ __metadata: languageName: node linkType: hard +"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/aspromise@npm:1.1.2" + checksum: 10c0/a83343a468ff5b5ec6bff36fd788a64c839e48a07ff9f4f813564f58caf44d011cd6504ed2147bf34835bd7a7dd2107052af755961c6b098fd8902b4f6500d0f + languageName: node + linkType: hard + +"@protobufjs/base64@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/base64@npm:1.1.2" + checksum: 10c0/eec925e681081af190b8ee231f9bad3101e189abbc182ff279da6b531e7dbd2a56f1f306f37a80b1be9e00aa2d271690d08dcc5f326f71c9eed8546675c8caf6 + languageName: node + linkType: hard + +"@protobufjs/codegen@npm:^2.0.4": + version: 2.0.4 + resolution: "@protobufjs/codegen@npm:2.0.4" + checksum: 10c0/26ae337c5659e41f091606d16465bbcc1df1f37cc1ed462438b1f67be0c1e28dfb2ca9f294f39100c52161aef82edf758c95d6d75650a1ddf31f7ddee1440b43 + languageName: node + linkType: hard + +"@protobufjs/eventemitter@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/eventemitter@npm:1.1.0" + checksum: 10c0/1eb0a75180e5206d1033e4138212a8c7089a3d418c6dfa5a6ce42e593a4ae2e5892c4ef7421f38092badba4040ea6a45f0928869989411001d8c1018ea9a6e70 + languageName: node + linkType: hard + +"@protobufjs/fetch@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/fetch@npm:1.1.0" + dependencies: + "@protobufjs/aspromise": "npm:^1.1.1" + "@protobufjs/inquire": "npm:^1.1.0" + checksum: 10c0/cda6a3dc2d50a182c5865b160f72077aac197046600091dbb005dd0a66db9cce3c5eaed6d470ac8ed49d7bcbeef6ee5f0bc288db5ff9a70cbd003e5909065233 + languageName: node + linkType: hard + +"@protobufjs/float@npm:^1.0.2": + version: 1.0.2 + resolution: "@protobufjs/float@npm:1.0.2" + checksum: 10c0/18f2bdede76ffcf0170708af15c9c9db6259b771e6b84c51b06df34a9c339dbbeec267d14ce0bddd20acc142b1d980d983d31434398df7f98eb0c94a0eb79069 + languageName: node + linkType: hard + +"@protobufjs/inquire@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/inquire@npm:1.1.0" + checksum: 10c0/64372482efcba1fb4d166a2664a6395fa978b557803857c9c03500e0ac1013eb4b1aacc9ed851dd5fc22f81583670b4f4431bae186f3373fedcfde863ef5921a + languageName: node + linkType: hard + +"@protobufjs/path@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/path@npm:1.1.2" + checksum: 10c0/cece0a938e7f5dfd2fa03f8c14f2f1cf8b0d6e13ac7326ff4c96ea311effd5fb7ae0bba754fbf505312af2e38500250c90e68506b97c02360a43793d88a0d8b4 + languageName: node + linkType: hard + +"@protobufjs/pool@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/pool@npm:1.1.0" + checksum: 10c0/eda2718b7f222ac6e6ad36f758a92ef90d26526026a19f4f17f668f45e0306a5bd734def3f48f51f8134ae0978b6262a5c517c08b115a551756d1a3aadfcf038 + languageName: node + linkType: hard + +"@protobufjs/utf8@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/utf8@npm:1.1.0" + checksum: 10c0/a3fe31fe3fa29aa3349e2e04ee13dc170cc6af7c23d92ad49e3eeaf79b9766264544d3da824dba93b7855bd6a2982fb40032ef40693da98a136d835752beb487 + languageName: node + linkType: hard + "@puppeteer/browsers@npm:2.10.12": version: 2.10.12 resolution: "@puppeteer/browsers@npm:2.10.12" @@ -2028,6 +2339,13 @@ __metadata: languageName: node linkType: hard +"@sindresorhus/is@npm:^4.0.0": + version: 4.6.0 + resolution: "@sindresorhus/is@npm:4.6.0" + checksum: 10c0/33b6fb1d0834ec8dd7689ddc0e2781c2bfd8b9c4e4bacbcb14111e0ae00621f2c264b8a7d36541799d74888b5dccdf422a891a5cb5a709ace26325eedc81e22e + languageName: node + linkType: hard + "@socket.io/component-emitter@npm:~3.1.0": version: 3.1.2 resolution: "@socket.io/component-emitter@npm:3.1.2" @@ -2167,6 +2485,15 @@ __metadata: languageName: node linkType: hard +"@szmarczak/http-timer@npm:^4.0.5": + version: 4.0.6 + resolution: "@szmarczak/http-timer@npm:4.0.6" + dependencies: + defer-to-connect: "npm:^2.0.0" + checksum: 10c0/73946918c025339db68b09abd91fa3001e87fc749c619d2e9c2003a663039d4c3cb89836c98a96598b3d47dec2481284ba85355392644911f5ecd2336536697f + languageName: node + linkType: hard + "@tabler/icons-react@npm:3.35.0": version: 3.35.0 resolution: "@tabler/icons-react@npm:3.35.0" @@ -2284,6 +2611,18 @@ __metadata: languageName: node linkType: hard +"@types/cacheable-request@npm:^6.0.1": + version: 6.0.3 + resolution: "@types/cacheable-request@npm:6.0.3" + dependencies: + "@types/http-cache-semantics": "npm:*" + "@types/keyv": "npm:^3.1.4" + "@types/node": "npm:*" + "@types/responselike": "npm:^1.0.0" + checksum: 10c0/10816a88e4e5b144d43c1d15a81003f86d649776c7f410c9b5e6579d0ad9d4ca71c541962fb403077388b446e41af7ae38d313e46692144985f006ac5e11fa03 + languageName: node + linkType: hard + "@types/chrome@npm:0.1.24": version: 0.1.24 resolution: "@types/chrome@npm:0.1.24" @@ -2484,6 +2823,13 @@ __metadata: languageName: node linkType: hard +"@types/http-cache-semantics@npm:*": + version: 4.0.4 + resolution: "@types/http-cache-semantics@npm:4.0.4" + checksum: 10c0/51b72568b4b2863e0fe8d6ce8aad72a784b7510d72dc866215642da51d84945a9459fa89f49ec48f1e9a1752e6a78e85a4cda0ded06b1c73e727610c925f9ce6 + languageName: node + linkType: hard + "@types/http-errors@npm:*": version: 2.0.5 resolution: "@types/http-errors@npm:2.0.5" @@ -2521,6 +2867,15 @@ __metadata: languageName: node linkType: hard +"@types/keyv@npm:^3.1.4": + version: 3.1.4 + resolution: "@types/keyv@npm:3.1.4" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/ff8f54fc49621210291f815fe5b15d809fd7d032941b3180743440bd507ecdf08b9e844625fa346af568c84bf34114eb378dcdc3e921a08ba1e2a08d7e3c809c + languageName: node + linkType: hard + "@types/lodash@npm:^4.14.182": version: 4.17.20 resolution: "@types/lodash@npm:4.17.20" @@ -2565,7 +2920,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:>=10.0.0": +"@types/node@npm:*, @types/node@npm:>=10.0.0, @types/node@npm:>=13.7.0": version: 24.10.0 resolution: "@types/node@npm:24.10.0" dependencies: @@ -2583,6 +2938,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^22.7.7": + version: 22.19.0 + resolution: "@types/node@npm:22.19.0" + dependencies: + undici-types: "npm:~6.21.0" + checksum: 10c0/66b98fcd38efb4ae58c628d61fed2b8f17c830eb665d8bceabc4174cae1dd81b8e4caac4c70d7dc929f9f76a3dc46cb21f480e904d0b898297bd12c0a2d1571a + languageName: node + linkType: hard + "@types/normalize-package-data@npm:^2.4.0": version: 2.4.4 resolution: "@types/normalize-package-data@npm:2.4.4" @@ -2636,6 +3000,15 @@ __metadata: languageName: node linkType: hard +"@types/responselike@npm:^1.0.0": + version: 1.0.3 + resolution: "@types/responselike@npm:1.0.3" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/a58ba341cb9e7d74f71810a88862da7b2a6fa42e2a1fc0ce40498f6ea1d44382f0640117057da779f74c47039f7166bf48fad02dc876f94e005c7afa50f5e129 + languageName: node + linkType: hard + "@types/retry@npm:0.12.2": version: 0.12.2 resolution: "@types/retry@npm:0.12.2" @@ -3155,6 +3528,15 @@ __metadata: languageName: node linkType: hard +"acorn-import-attributes@npm:^1.9.5": + version: 1.9.5 + resolution: "acorn-import-attributes@npm:1.9.5" + peerDependencies: + acorn: ^8 + checksum: 10c0/5926eaaead2326d5a86f322ff1b617b0f698aa61dc719a5baa0e9d955c9885cc71febac3fb5bacff71bbf2c4f9c12db2056883c68c53eb962c048b952e1e013d + languageName: node + linkType: hard + "acorn-import-phases@npm:^1.0.3": version: 1.0.4 resolution: "acorn-import-phases@npm:1.0.4" @@ -3182,7 +3564,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.4.1": +"acorn@npm:^8.11.0, acorn@npm:^8.14.0, acorn@npm:^8.15.0, acorn@npm:^8.4.1": version: 8.15.0 resolution: "acorn@npm:8.15.0" bin: @@ -3820,6 +4202,13 @@ __metadata: languageName: node linkType: hard +"boolean@npm:^3.0.1": + version: 3.2.0 + resolution: "boolean@npm:3.2.0" + checksum: 10c0/6a0dc9668f6f3dda42a53c181fcbdad223169c8d87b6c4011b87a8b14a21770efb2934a778f063d7ece17280f8c06d313c87f7b834bb1dd526a867ffcd00febf + languageName: node + linkType: hard + "brace-expansion@npm:^1.1.7": version: 1.1.12 resolution: "brace-expansion@npm:1.1.12" @@ -4053,6 +4442,28 @@ __metadata: languageName: node linkType: hard +"cacheable-lookup@npm:^5.0.3": + version: 5.0.4 + resolution: "cacheable-lookup@npm:5.0.4" + checksum: 10c0/a6547fb4954b318aa831cbdd2f7b376824bc784fb1fa67610e4147099e3074726072d9af89f12efb69121415a0e1f2918a8ddd4aafcbcf4e91fbeef4a59cd42c + languageName: node + linkType: hard + +"cacheable-request@npm:^7.0.2": + version: 7.0.4 + resolution: "cacheable-request@npm:7.0.4" + dependencies: + clone-response: "npm:^1.0.2" + get-stream: "npm:^5.1.0" + http-cache-semantics: "npm:^4.0.0" + keyv: "npm:^4.0.0" + lowercase-keys: "npm:^2.0.0" + normalize-url: "npm:^6.0.1" + responselike: "npm:^2.0.0" + checksum: 10c0/0834a7d17ae71a177bc34eab06de112a43f9b5ad05ebe929bec983d890a7d9f2bc5f1aa8bb67ea2b65e07a3bc74bea35fa62dd36dbac52876afe36fdcf83da41 + languageName: node + linkType: hard + "call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": version: 1.0.2 resolution: "call-bind-apply-helpers@npm:1.0.2" @@ -4244,6 +4655,13 @@ __metadata: languageName: node linkType: hard +"cjs-module-lexer@npm:^1.2.2": + version: 1.4.3 + resolution: "cjs-module-lexer@npm:1.4.3" + checksum: 10c0/076b3af85adc4d65dbdab1b5b240fe5b45d44fcf0ef9d429044dd94d19be5589376805c44fb2d4b3e684e5fe6a9b7cf3e426476a6507c45283c5fc6ff95240be + languageName: node + linkType: hard + "clean-css@npm:^5.2.2": version: 5.3.3 resolution: "clean-css@npm:5.3.3" @@ -4345,6 +4763,15 @@ __metadata: languageName: node linkType: hard +"clone-response@npm:^1.0.2": + version: 1.0.3 + resolution: "clone-response@npm:1.0.3" + dependencies: + mimic-response: "npm:^1.0.0" + checksum: 10c0/06a2b611824efb128810708baee3bd169ec9a1bf5976a5258cd7eb3f7db25f00166c6eee5961f075c7e38e194f373d4fdf86b8166ad5b9c7e82bbd2e333a6087 + languageName: node + linkType: hard + "clone@npm:^1.0.2": version: 1.0.4 resolution: "clone@npm:1.0.4" @@ -4811,6 +5238,13 @@ __metadata: languageName: node linkType: hard +"crypto-randomuuid@npm:^1.0.0": + version: 1.0.0 + resolution: "crypto-randomuuid@npm:1.0.0" + checksum: 10c0/6c8f7513f3b0c38b876b5011d91e21c284f7a695d27b6ef25a2a1ca89c362af23e321bf47953069b9fe56bc384de7880a13c390a4663ac5dcf525a1b4f937a1f + languageName: node + linkType: hard + "css-loader@npm:7.1.2": version: 7.1.2 resolution: "css-loader@npm:7.1.2" @@ -4949,6 +5383,58 @@ __metadata: languageName: node linkType: hard +"dc-polyfill@npm:^0.1.10": + version: 0.1.10 + resolution: "dc-polyfill@npm:0.1.10" + checksum: 10c0/b4a847b5883fb3bc1173d48b98d2aa554af12b427b13d3f5fbd31a4d4cbfc733d8134e261e442ac890df3606f97e5440b603ff72d0c9cd62ac2e5f3cbc52aa6d + languageName: node + linkType: hard + +"dd-trace@npm:^5.76.0": + version: 5.76.0 + resolution: "dd-trace@npm:5.76.0" + dependencies: + "@datadog/libdatadog": "npm:0.7.0" + "@datadog/native-appsec": "npm:10.3.0" + "@datadog/native-iast-taint-tracking": "npm:4.0.0" + "@datadog/native-metrics": "npm:3.1.1" + "@datadog/openfeature-node-server": "npm:0.1.0-preview.13" + "@datadog/pprof": "npm:5.12.0" + "@datadog/sketches-js": "npm:2.1.1" + "@datadog/wasm-js-rewriter": "npm:4.0.1" + "@isaacs/ttlcache": "npm:^1.4.1" + "@opentelemetry/api": "npm:>=1.0.0 <1.10.0" + "@opentelemetry/api-logs": "npm:<1.0.0" + "@opentelemetry/core": "npm:>=1.14.0 <1.31.0" + "@opentelemetry/resources": "npm:>=1.0.0 <1.10.0" + crypto-randomuuid: "npm:^1.0.0" + dc-polyfill: "npm:^0.1.10" + escape-string-regexp: "npm:^5.0.0" + ignore: "npm:^7.0.5" + import-in-the-middle: "npm:^1.14.2" + istanbul-lib-coverage: "npm:^3.2.2" + jest-docblock: "npm:^29.7.0" + jsonpath-plus: "npm:^10.3.0" + limiter: "npm:^1.1.5" + lodash.sortby: "npm:^4.7.0" + lru-cache: "npm:^10.4.3" + module-details-from-path: "npm:^1.0.4" + mutexify: "npm:^1.4.0" + opentracing: "npm:>=0.14.7" + path-to-regexp: "npm:^0.1.12" + pprof-format: "npm:^2.1.1" + protobufjs: "npm:^7.5.3" + retry: "npm:^0.13.1" + rfdc: "npm:^1.4.1" + semifies: "npm:^1.0.0" + shell-quote: "npm:^1.8.2" + source-map: "npm:^0.7.4" + tlhunter-sorted-set: "npm:^0.1.0" + ttl-set: "npm:^1.0.0" + checksum: 10c0/0853b6c3fb36087f2ed9d36a2d2157cb9d32abe7ff073b2b719137bca7d05ad8edd728e70d9a6b3b4a4dc49ad60ee2184fd54a3ec9a3ce58f9598cc3b25dd008 + languageName: node + linkType: hard + "debug@npm:2.6.9": version: 2.6.9 resolution: "debug@npm:2.6.9" @@ -5008,6 +5494,15 @@ __metadata: languageName: node linkType: hard +"decompress-response@npm:^6.0.0": + version: 6.0.0 + resolution: "decompress-response@npm:6.0.0" + dependencies: + mimic-response: "npm:^3.1.0" + checksum: 10c0/bd89d23141b96d80577e70c54fb226b2f40e74a6817652b80a116d7befb8758261ad073a8895648a29cc0a5947021ab66705cb542fa9c143c82022b27c5b175e + languageName: node + linkType: hard + "dedent@npm:1.5.3": version: 1.5.3 resolution: "dedent@npm:1.5.3" @@ -5053,6 +5548,13 @@ __metadata: languageName: node linkType: hard +"defer-to-connect@npm:^2.0.0": + version: 2.0.1 + resolution: "defer-to-connect@npm:2.0.1" + checksum: 10c0/625ce28e1b5ad10cf77057b9a6a727bf84780c17660f6644dab61dd34c23de3001f03cedc401f7d30a4ed9965c2e8a7336e220a329146f2cf85d4eddea429782 + languageName: node + linkType: hard + "define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": version: 1.1.4 resolution: "define-data-property@npm:1.1.4" @@ -5100,6 +5602,13 @@ __metadata: languageName: node linkType: hard +"delay@npm:^5.0.0": + version: 5.0.0 + resolution: "delay@npm:5.0.0" + checksum: 10c0/01cdc4cd0cd35fb622518a3df848e67e09763a38e7cdada2232b6fda9ddda72eddcf74f0e24211200fbe718434f2335f2a2633875a6c96037fefa6de42896ad7 + languageName: node + linkType: hard + "delayed-stream@npm:~1.0.0": version: 1.0.0 resolution: "delayed-stream@npm:1.0.0" @@ -5142,6 +5651,13 @@ __metadata: languageName: node linkType: hard +"detect-newline@npm:^3.0.0": + version: 3.1.0 + resolution: "detect-newline@npm:3.1.0" + checksum: 10c0/c38cfc8eeb9fda09febb44bcd85e467c970d4e3bf526095394e5a4f18bc26dd0cf6b22c69c1fa9969261521c593836db335c2795218f6d781a512aea2fb8209d + languageName: node + linkType: hard + "detect-node-es@npm:^1.1.0": version: 1.1.0 resolution: "detect-node-es@npm:1.1.0" @@ -5352,6 +5868,19 @@ __metadata: languageName: node linkType: hard +"electron@npm:39": + version: 39.1.2 + resolution: "electron@npm:39.1.2" + dependencies: + "@electron/get": "npm:^2.0.0" + "@types/node": "npm:^22.7.7" + extract-zip: "npm:^2.0.1" + bin: + electron: cli.js + checksum: 10c0/9d475736d4885457135986262d29eeffa8aedf4ca760af067a0c5225c188db43b788f623b4d876d8d857ba36849147d228e9bfab94853b4e58ac2f8c247b2deb + languageName: node + linkType: hard + "emoji-name-map@npm:2.0.3": version: 2.0.3 resolution: "emoji-name-map@npm:2.0.3" @@ -5667,6 +6196,13 @@ __metadata: languageName: node linkType: hard +"es6-error@npm:^4.1.1": + version: 4.1.1 + resolution: "es6-error@npm:4.1.1" + checksum: 10c0/357663fb1e845c047d548c3d30f86e005db71e122678f4184ced0693f634688c3f3ef2d7de7d4af732f734de01f528b05954e270f06aa7d133679fb9fe6600ef + languageName: node + linkType: hard + "es6-iterator@npm:^2.0.3": version: 2.0.3 resolution: "es6-iterator@npm:2.0.3" @@ -5744,6 +6280,13 @@ __metadata: languageName: node linkType: hard +"escape-string-regexp@npm:^5.0.0": + version: 5.0.0 + resolution: "escape-string-regexp@npm:5.0.0" + checksum: 10c0/6366f474c6f37a802800a435232395e04e9885919873e382b157ab7e8f0feb8fed71497f84a6f6a81a49aab41815522f5839112bd38026d203aea0c91622df95 + languageName: node + linkType: hard + "escodegen@npm:^2.1.0": version: 2.1.0 resolution: "escodegen@npm:2.1.0" @@ -6946,6 +7489,20 @@ __metadata: languageName: node linkType: hard +"global-agent@npm:^3.0.0": + version: 3.0.0 + resolution: "global-agent@npm:3.0.0" + dependencies: + boolean: "npm:^3.0.1" + es6-error: "npm:^4.1.1" + matcher: "npm:^3.0.0" + roarr: "npm:^2.15.3" + semver: "npm:^7.3.2" + serialize-error: "npm:^7.0.1" + checksum: 10c0/bb8750d026b25da437072762fd739098bad92ff72f66483c3929db4579e072f5523960f7e7fd70ee0d75db48898067b5dc1c9c1d17888128cff008fcc34d1bd3 + languageName: node + linkType: hard + "globals@npm:16.4.0": version: 16.4.0 resolution: "globals@npm:16.4.0" @@ -6967,7 +7524,7 @@ __metadata: languageName: node linkType: hard -"globalthis@npm:^1.0.4": +"globalthis@npm:^1.0.1, globalthis@npm:^1.0.4": version: 1.0.4 resolution: "globalthis@npm:1.0.4" dependencies: @@ -6984,6 +7541,25 @@ __metadata: languageName: node linkType: hard +"got@npm:^11.8.5": + version: 11.8.6 + resolution: "got@npm:11.8.6" + dependencies: + "@sindresorhus/is": "npm:^4.0.0" + "@szmarczak/http-timer": "npm:^4.0.5" + "@types/cacheable-request": "npm:^6.0.1" + "@types/responselike": "npm:^1.0.0" + cacheable-lookup: "npm:^5.0.3" + cacheable-request: "npm:^7.0.2" + decompress-response: "npm:^6.0.0" + http2-wrapper: "npm:^1.0.0-beta.5.2" + lowercase-keys: "npm:^2.0.0" + p-cancelable: "npm:^2.0.0" + responselike: "npm:^2.0.0" + checksum: 10c0/754dd44877e5cf6183f1e989ff01c648d9a4719e357457bd4c78943911168881f1cfb7b2cb15d885e2105b3ad313adb8f017a67265dd7ade771afdb261ee8cb1 + languageName: node + linkType: hard + "graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" @@ -7222,7 +7798,7 @@ __metadata: languageName: node linkType: hard -"http-cache-semantics@npm:^4.1.1": +"http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.1": version: 4.2.0 resolution: "http-cache-semantics@npm:4.2.0" checksum: 10c0/45b66a945cf13ec2d1f29432277201313babf4a01d9e52f44b31ca923434083afeca03f18417f599c9ab3d0e7b618ceb21257542338b57c54b710463b4a53e37 @@ -7330,6 +7906,16 @@ __metadata: languageName: node linkType: hard +"http2-wrapper@npm:^1.0.0-beta.5.2": + version: 1.0.3 + resolution: "http2-wrapper@npm:1.0.3" + dependencies: + quick-lru: "npm:^5.1.1" + resolve-alpn: "npm:^1.0.0" + checksum: 10c0/6a9b72a033e9812e1476b9d776ce2f387bc94bc46c88aea0d5dab6bd47d0a539b8178830e77054dd26d1142c866d515a28a4dc7c3ff4232c88ff2ebe4f5d12d1 + languageName: node + linkType: hard + "https-proxy-agent@npm:^2.2.1": version: 2.2.4 resolution: "https-proxy-agent@npm:2.2.4" @@ -7433,7 +8019,7 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^7.0.0": +"ignore@npm:^7.0.0, ignore@npm:^7.0.5": version: 7.0.5 resolution: "ignore@npm:7.0.5" checksum: 10c0/ae00db89fe873064a093b8999fe4cc284b13ef2a178636211842cceb650b9c3e390d3339191acb145d81ed5379d2074840cf0c33a20bdbd6f32821f79eb4ad5d @@ -7450,6 +8036,18 @@ __metadata: languageName: node linkType: hard +"import-in-the-middle@npm:^1.14.2": + version: 1.15.0 + resolution: "import-in-the-middle@npm:1.15.0" + dependencies: + acorn: "npm:^8.14.0" + acorn-import-attributes: "npm:^1.9.5" + cjs-module-lexer: "npm:^1.2.2" + module-details-from-path: "npm:^1.0.3" + checksum: 10c0/43d4efbe75a89c04343fd052ca5d2193adc0e2df93325e50d8b32c31403b2f089a5e2b6e47f4e5413bc4058b9781aaaf61bfe3f0e5e6d7f9487eb112fd095e0d + languageName: node + linkType: hard + "import-local@npm:3.1.0": version: 3.1.0 resolution: "import-local@npm:3.1.0" @@ -8083,7 +8681,7 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-coverage@npm:^3.0.0": +"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.2": version: 3.2.2 resolution: "istanbul-lib-coverage@npm:3.2.2" checksum: 10c0/6c7ff2106769e5f592ded1fb418f9f73b4411fd5a084387a5410538332b6567cd1763ff6b6cadca9b9eb2c443cce2f7ea7d7f1b8d315f9ce58539793b1e0922b @@ -8190,6 +8788,15 @@ __metadata: languageName: node linkType: hard +"jest-docblock@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-docblock@npm:29.7.0" + dependencies: + detect-newline: "npm:^3.0.0" + checksum: 10c0/d932a8272345cf6b6142bb70a2bb63e0856cc0093f082821577ea5bdf4643916a98744dfc992189d2b1417c38a11fa42466f6111526bc1fb81366f56410f3be9 + languageName: node + linkType: hard + "jest-worker@npm:^27.4.5": version: 27.5.1 resolution: "jest-worker@npm:27.5.1" @@ -8238,6 +8845,13 @@ __metadata: languageName: node linkType: hard +"jsep@npm:^1.4.0": + version: 1.4.0 + resolution: "jsep@npm:1.4.0" + checksum: 10c0/fe60adf47e050e22eadced42514a51a15a3cf0e2d147896584486acd8ee670fc16641101b9aeb81f4aaba382043d29744b7aac41171e8106515b14f27e0c7116 + languageName: node + linkType: hard + "jsesc@npm:^3.0.2, jsesc@npm:^3.1.0": version: 3.1.0 resolution: "jsesc@npm:3.1.0" @@ -8409,6 +9023,20 @@ __metadata: languageName: node linkType: hard +"jsonpath-plus@npm:^10.3.0": + version: 10.3.0 + resolution: "jsonpath-plus@npm:10.3.0" + dependencies: + "@jsep-plugin/assignment": "npm:^1.3.0" + "@jsep-plugin/regex": "npm:^1.0.4" + jsep: "npm:^1.4.0" + bin: + jsonpath: bin/jsonpath-cli.js + jsonpath-plus: bin/jsonpath-cli.js + checksum: 10c0/f5ff53078ecab98e8afd1dcdb4488e528653fa5a03a32d671f52db1ae9c3236e6e072d75e1949a80929fd21b07603924a586f829b40ad35993fa0247fa4f7506 + languageName: node + linkType: hard + "junk@npm:^4.0.1": version: 4.0.1 resolution: "junk@npm:4.0.1" @@ -8555,7 +9183,7 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.5.4": +"keyv@npm:^4.0.0, keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" dependencies: @@ -8704,6 +9332,13 @@ __metadata: languageName: node linkType: hard +"limiter@npm:^1.1.5": + version: 1.1.5 + resolution: "limiter@npm:1.1.5" + checksum: 10c0/ebe2b20a820d1f67b8e1724051246434c419b2da041a7e9cd943f6daf113b8d17a52a1bd88fb79be5b624c10283ecb737f50edb5c1c88c71f4cd367108c97300 + languageName: node + linkType: hard + "lines-and-columns@npm:2.0.3": version: 2.0.3 resolution: "lines-and-columns@npm:2.0.3" @@ -8811,6 +9446,13 @@ __metadata: languageName: node linkType: hard +"lodash.sortby@npm:^4.7.0": + version: 4.7.0 + resolution: "lodash.sortby@npm:4.7.0" + checksum: 10c0/fc48fb54ff7669f33bb32997cab9460757ee99fafaf72400b261c3e10fde21538e47d8cfcbe6a25a31bcb5b7b727c27d52626386fc2de24eb059a6d64a89cdf5 + languageName: node + linkType: hard + "lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" @@ -8841,6 +9483,13 @@ __metadata: languageName: node linkType: hard +"long@npm:^5.0.0": + version: 5.3.2 + resolution: "long@npm:5.3.2" + checksum: 10c0/7130fe1cbce2dca06734b35b70d380ca3f70271c7f8852c922a7c62c86c4e35f0c39290565eca7133c625908d40e126ac57c02b1b1a4636b9457d77e1e60b981 + languageName: node + linkType: hard + "lower-case@npm:^2.0.2": version: 2.0.2 resolution: "lower-case@npm:2.0.2" @@ -8850,7 +9499,14 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0, lru-cache@npm:^10.2.2": +"lowercase-keys@npm:^2.0.0": + version: 2.0.0 + resolution: "lowercase-keys@npm:2.0.0" + checksum: 10c0/f82a2b3568910509da4b7906362efa40f5b54ea14c2584778ddb313226f9cbf21020a5db35f9b9a0e95847a9b781d548601f31793d736b22a2b8ae8eb9ab1082 + languageName: node + linkType: hard + +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0, lru-cache@npm:^10.2.2, lru-cache@npm:^10.4.3": version: 10.4.3 resolution: "lru-cache@npm:10.4.3" checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb @@ -8882,7 +9538,7 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^7.14.1": +"lru-cache@npm:^7.14.0, lru-cache@npm:^7.14.1": version: 7.18.3 resolution: "lru-cache@npm:7.18.3" checksum: 10c0/b3a452b491433db885beed95041eb104c157ef7794b9c9b4d647be503be91769d11206bb573849a16b4cc0d03cbd15ffd22df7960997788b74c1d399ac7a4fed @@ -9006,6 +9662,15 @@ __metadata: languageName: node linkType: hard +"matcher@npm:^3.0.0": + version: 3.0.0 + resolution: "matcher@npm:3.0.0" + dependencies: + escape-string-regexp: "npm:^4.0.0" + checksum: 10c0/2edf24194a2879690bcdb29985fc6bc0d003df44e04df21ebcac721fa6ce2f6201c579866bb92f9380bffe946f11ecd8cd31f34117fb67ebf8aca604918e127e + languageName: node + linkType: hard + "math-intrinsics@npm:^1.1.0": version: 1.1.0 resolution: "math-intrinsics@npm:1.1.0" @@ -9194,6 +9859,20 @@ __metadata: languageName: node linkType: hard +"mimic-response@npm:^1.0.0": + version: 1.0.1 + resolution: "mimic-response@npm:1.0.1" + checksum: 10c0/c5381a5eae997f1c3b5e90ca7f209ed58c3615caeee850e85329c598f0c000ae7bec40196580eef1781c60c709f47258131dab237cad8786f8f56750594f27fa + languageName: node + linkType: hard + +"mimic-response@npm:^3.1.0": + version: 3.1.0 + resolution: "mimic-response@npm:3.1.0" + checksum: 10c0/0d6f07ce6e03e9e4445bee655202153bdb8a98d67ee8dc965ac140900d7a2688343e6b4c9a72cfc9ef2f7944dfd76eef4ab2482eb7b293a68b84916bac735362 + languageName: node + linkType: hard + "min-indent@npm:^1.0.0": version: 1.0.1 resolution: "min-indent@npm:1.0.1" @@ -9432,6 +10111,13 @@ __metadata: languageName: node linkType: hard +"module-details-from-path@npm:^1.0.3, module-details-from-path@npm:^1.0.4": + version: 1.0.4 + resolution: "module-details-from-path@npm:1.0.4" + checksum: 10c0/10863413e96dab07dee917eae07afe46f7bf853065cc75a7d2a718adf67574857fb64f8a2c0c9af12ac733a9a8cf652db7ed39b95f7a355d08106cb9cc50c83b + languageName: node + linkType: hard + "ms@npm:2.0.0": version: 2.0.0 resolution: "ms@npm:2.0.0" @@ -9487,6 +10173,15 @@ __metadata: languageName: node linkType: hard +"mutexify@npm:^1.4.0": + version: 1.4.0 + resolution: "mutexify@npm:1.4.0" + dependencies: + queue-tick: "npm:^1.0.0" + checksum: 10c0/0b2fad0c671cef33ad3596d702b581e5bb3708ec7ba2913639cfb1642c7f5093af9d8793b38eafe1b723e7879d60419d2e96c5e7793271e0167833a7939ac66d + languageName: node + linkType: hard + "mz@npm:^2.7.0": version: 2.7.0 resolution: "mz@npm:2.7.0" @@ -9566,6 +10261,15 @@ __metadata: languageName: node linkType: hard +"node-addon-api@npm:^6.1.0": + version: 6.1.0 + resolution: "node-addon-api@npm:6.1.0" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/d2699c4ad15740fd31482a3b6fca789af7723ab9d393adc6ac45250faaee72edad8f0b10b2b9d087df0de93f1bdc16d97afdd179b26b9ebc9ed68b569faa4bac + languageName: node + linkType: hard + "node-forge@npm:1.3.1, node-forge@npm:^1": version: 1.3.1 resolution: "node-forge@npm:1.3.1" @@ -9573,6 +10277,28 @@ __metadata: languageName: node linkType: hard +"node-gyp-build@npm:<4.0, node-gyp-build@npm:^3.9.0": + version: 3.9.0 + resolution: "node-gyp-build@npm:3.9.0" + bin: + node-gyp-build: ./bin.js + node-gyp-build-optional: ./optional.js + node-gyp-build-test: ./build-test.js + checksum: 10c0/0e7e39e5746728e6adf58803d9c3c732b6107f1af3df5128c4c2a6c9c0fb99a6c981ad0a7514d707adccbcfe303b4a92da7949408f1d3ec281f70d37bec29f60 + languageName: node + linkType: hard + +"node-gyp-build@npm:^4.5.0": + version: 4.8.4 + resolution: "node-gyp-build@npm:4.8.4" + bin: + node-gyp-build: bin.js + node-gyp-build-optional: optional.js + node-gyp-build-test: build-test.js + checksum: 10c0/444e189907ece2081fe60e75368784f7782cfddb554b60123743dfb89509df89f1f29c03bbfa16b3a3e0be3f48799a4783f487da6203245fa5bed239ba7407e1 + languageName: node + linkType: hard + "node-gyp@npm:^11.0.0, node-gyp@npm:latest": version: 11.5.0 resolution: "node-gyp@npm:11.5.0" @@ -9649,6 +10375,13 @@ __metadata: languageName: node linkType: hard +"normalize-url@npm:^6.0.1": + version: 6.1.0 + resolution: "normalize-url@npm:6.1.0" + checksum: 10c0/95d948f9bdd2cfde91aa786d1816ae40f8262946e13700bf6628105994fe0ff361662c20af3961161c38a119dc977adeb41fc0b41b1745eb77edaaf9cb22db23 + languageName: node + linkType: hard + "npm-bundled@npm:^4.0.0": version: 4.0.0 resolution: "npm-bundled@npm:4.0.0" @@ -10079,6 +10812,13 @@ __metadata: languageName: node linkType: hard +"opentracing@npm:>=0.14.7": + version: 0.14.7 + resolution: "opentracing@npm:0.14.7" + checksum: 10c0/a7be8d697b1997548233423f5f4c196e285af8e864a24d7704fc6029beb73cd1f987651ca814e207629c6bc624cb03297a86601c0dc51cdca9a07a20f97b71ea + languageName: node + linkType: hard + "optionator@npm:^0.9.3": version: 0.9.4 resolution: "optionator@npm:0.9.4" @@ -10120,6 +10860,13 @@ __metadata: languageName: node linkType: hard +"p-cancelable@npm:^2.0.0": + version: 2.1.1 + resolution: "p-cancelable@npm:2.1.1" + checksum: 10c0/8c6dc1f8dd4154fd8b96a10e55a3a832684c4365fb9108056d89e79fbf21a2465027c04a59d0d797b5ffe10b54a61a32043af287d5c4860f1e996cbdbc847f01 + languageName: node + linkType: hard + "p-finally@npm:^1.0.0": version: 1.0.0 resolution: "p-finally@npm:1.0.0" @@ -10145,7 +10892,7 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^3.0.2": +"p-limit@npm:^3.0.2, p-limit@npm:^3.1.0": version: 3.1.0 resolution: "p-limit@npm:3.1.0" dependencies: @@ -10523,7 +11270,7 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:0.1.12": +"path-to-regexp@npm:0.1.12, path-to-regexp@npm:^0.1.12": version: 0.1.12 resolution: "path-to-regexp@npm:0.1.12" checksum: 10c0/1c6ff10ca169b773f3bba943bbc6a07182e332464704572962d277b900aeee81ac6aa5d060ff9e01149636c30b1f63af6e69dd7786ba6e0ddb39d4dee1f0645b @@ -10752,6 +11499,13 @@ __metadata: languageName: node linkType: hard +"pprof-format@npm:^2.1.1, pprof-format@npm:^2.2.1": + version: 2.2.1 + resolution: "pprof-format@npm:2.2.1" + checksum: 10c0/1c8051b3e3ebba1ac2b8d7cf0a84ce501fdabe5e72a803c7daa6ddf67cbee33e9b5d6dbc6ffbeb740e3e56600c875f372576304ed718a4ffa4c89c18185494ae + languageName: node + linkType: hard + "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" @@ -10866,6 +11620,26 @@ __metadata: languageName: node linkType: hard +"protobufjs@npm:^7.5.3": + version: 7.5.4 + resolution: "protobufjs@npm:7.5.4" + dependencies: + "@protobufjs/aspromise": "npm:^1.1.2" + "@protobufjs/base64": "npm:^1.1.2" + "@protobufjs/codegen": "npm:^2.0.4" + "@protobufjs/eventemitter": "npm:^1.1.0" + "@protobufjs/fetch": "npm:^1.1.0" + "@protobufjs/float": "npm:^1.0.2" + "@protobufjs/inquire": "npm:^1.1.0" + "@protobufjs/path": "npm:^1.1.2" + "@protobufjs/pool": "npm:^1.1.0" + "@protobufjs/utf8": "npm:^1.1.0" + "@types/node": "npm:>=13.7.0" + long: "npm:^5.0.0" + checksum: 10c0/913b676109ffb3c05d3d31e03a684e569be91f3bba8613da4a683d69d9dba948daa2afd7d2e7944d1aa6c417890c35d9d9a8883c1160affafb0f9670d59ef722 + languageName: node + linkType: hard + "protocols@npm:^2.0.0, protocols@npm:^2.0.1": version: 2.0.2 resolution: "protocols@npm:2.0.2" @@ -11018,6 +11792,13 @@ __metadata: languageName: node linkType: hard +"queue-tick@npm:^1.0.0": + version: 1.0.1 + resolution: "queue-tick@npm:1.0.1" + checksum: 10c0/0db998e2c9b15215317dbcf801e9b23e6bcde4044e115155dae34f8e7454b9a783f737c9a725528d677b7a66c775eb7a955cf144fe0b87f62b575ce5bfd515a9 + languageName: node + linkType: hard + "quick-lru@npm:^4.0.1": version: 4.0.1 resolution: "quick-lru@npm:4.0.1" @@ -11025,6 +11806,13 @@ __metadata: languageName: node linkType: hard +"quick-lru@npm:^5.1.1": + version: 5.1.1 + resolution: "quick-lru@npm:5.1.1" + checksum: 10c0/a24cba5da8cec30d70d2484be37622580f64765fb6390a928b17f60cd69e8dbd32a954b3ff9176fa1b86d86ff2ba05252fae55dc4d40d0291c60412b0ad096da + languageName: node + linkType: hard + "randombytes@npm:^2.1.0": version: 2.1.0 resolution: "randombytes@npm:2.1.0" @@ -11462,6 +12250,13 @@ __metadata: languageName: node linkType: hard +"resolve-alpn@npm:^1.0.0": + version: 1.2.1 + resolution: "resolve-alpn@npm:1.2.1" + checksum: 10c0/b70b29c1843bc39781ef946c8cd4482e6d425976599c0f9c138cec8209e4e0736161bf39319b01676a847000085dfdaf63583c6fb4427bf751a10635bd2aa0c4 + languageName: node + linkType: hard + "resolve-cwd@npm:^3.0.0": version: 3.0.0 resolution: "resolve-cwd@npm:3.0.0" @@ -11518,6 +12313,15 @@ __metadata: languageName: node linkType: hard +"responselike@npm:^2.0.0": + version: 2.0.1 + resolution: "responselike@npm:2.0.1" + dependencies: + lowercase-keys: "npm:^2.0.0" + checksum: 10c0/360b6deb5f101a9f8a4174f7837c523c3ec78b7ca8a7c1d45a1062b303659308a23757e318b1e91ed8684ad1205721142dd664d94771cd63499353fd4ee732b5 + languageName: node + linkType: hard + "restore-cursor@npm:^3.1.0": version: 3.1.0 resolution: "restore-cursor@npm:3.1.0" @@ -11549,7 +12353,7 @@ __metadata: languageName: node linkType: hard -"rfdc@npm:^1.3.0": +"rfdc@npm:^1.3.0, rfdc@npm:^1.4.1": version: 1.4.1 resolution: "rfdc@npm:1.4.1" checksum: 10c0/4614e4292356cafade0b6031527eea9bc90f2372a22c012313be1dcc69a3b90c7338158b414539be863fa95bfcb2ddcd0587be696841af4e6679d85e62c060c7 @@ -11600,6 +12404,20 @@ __metadata: languageName: node linkType: hard +"roarr@npm:^2.15.3": + version: 2.15.4 + resolution: "roarr@npm:2.15.4" + dependencies: + boolean: "npm:^3.0.1" + detect-node: "npm:^2.0.4" + globalthis: "npm:^1.0.1" + json-stringify-safe: "npm:^5.0.1" + semver-compare: "npm:^1.0.0" + sprintf-js: "npm:^1.1.2" + checksum: 10c0/7d01d4c14513c461778dd673a8f9e53255221f8d04173aafeb8e11b23d8b659bb83f1c90cfe81af7f9c213b8084b404b918108fd792bda76678f555340cc64ec + languageName: node + linkType: hard + "router@npm:^2.2.0": version: 2.2.0 resolution: "router@npm:2.2.0" @@ -11754,6 +12572,20 @@ __metadata: languageName: node linkType: hard +"semifies@npm:^1.0.0": + version: 1.0.0 + resolution: "semifies@npm:1.0.0" + checksum: 10c0/d93d5e8d2c0b7d5f972b9378736ed5cc1f2ab40d043234b4156665872f08cb0da914ee8c8b35c59dc6b17880a4c5502588c7515c6bb4dbc3ce5565746428d31d + languageName: node + linkType: hard + +"semver-compare@npm:^1.0.0": + version: 1.0.0 + resolution: "semver-compare@npm:1.0.0" + checksum: 10c0/9ef4d8b81847556f0865f46ddc4d276bace118c7cb46811867af82e837b7fc473911981d5a0abc561fa2db487065572217e5b06e18701c4281bcdd2a1affaff1 + languageName: node + linkType: hard + "semver@npm:2 || 3 || 4 || 5, semver@npm:^5.6.0": version: 5.7.2 resolution: "semver@npm:5.7.2" @@ -11772,7 +12604,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^6.3.0, semver@npm:^6.3.1": +"semver@npm:^6.2.0, semver@npm:^6.3.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" bin: @@ -11781,7 +12613,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.7.2, semver@npm:^7.7.3": +"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.7.2, semver@npm:^7.7.3": version: 7.7.3 resolution: "semver@npm:7.7.3" bin: @@ -11830,6 +12662,15 @@ __metadata: languageName: node linkType: hard +"serialize-error@npm:^7.0.1": + version: 7.0.1 + resolution: "serialize-error@npm:7.0.1" + dependencies: + type-fest: "npm:^0.13.1" + checksum: 10c0/7982937d578cd901276c8ab3e2c6ed8a4c174137730f1fb0402d005af209a0e84d04acc874e317c936724c7b5b26c7a96ff7e4b8d11a469f4924a4b0ea814c05 + languageName: node + linkType: hard + "serialize-javascript@npm:^6.0.2": version: 6.0.2 resolution: "serialize-javascript@npm:6.0.2" @@ -11968,7 +12809,7 @@ __metadata: languageName: node linkType: hard -"shell-quote@npm:^1.8.3": +"shell-quote@npm:^1.8.2, shell-quote@npm:^1.8.3": version: 1.8.3 resolution: "shell-quote@npm:1.8.3" checksum: 10c0/bee87c34e1e986cfb4c30846b8e6327d18874f10b535699866f368ade11ea4ee45433d97bf5eada22c4320c27df79c3a6a7eb1bf3ecfc47f2c997d9e5e2672fd @@ -12186,6 +13027,13 @@ __metadata: languageName: node linkType: hard +"spark-md5@npm:^3.0.2": + version: 3.0.2 + resolution: "spark-md5@npm:3.0.2" + checksum: 10c0/3fd11735eac5e7d60d6006d99ac0a055f148a89e9baf5f0b51ac103022dec30556b44190b37f6737ca50f81e8e50dc13e724f9edf6290c412ff5ab2101ce7780 + languageName: node + linkType: hard + "spdx-correct@npm:^3.0.0": version: 3.2.0 resolution: "spdx-correct@npm:3.2.0" @@ -12284,6 +13132,13 @@ __metadata: languageName: node linkType: hard +"sprintf-js@npm:^1.1.2": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: 10c0/09270dc4f30d479e666aee820eacd9e464215cdff53848b443964202bf4051490538e5dd1b42e1a65cf7296916ca17640aebf63dae9812749c7542ee5f288dec + languageName: node + linkType: hard + "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" @@ -12525,6 +13380,15 @@ __metadata: languageName: node linkType: hard +"sumchecker@npm:^3.0.1": + version: 3.0.1 + resolution: "sumchecker@npm:3.0.1" + dependencies: + debug: "npm:^4.1.0" + checksum: 10c0/43c387be9dfe22dbeaf39dfa4ffb279847aeb37a42a8988c0b066f548bbd209aa8c65e03da29f2b29be1a66b577801bf89fff0007df4183db2f286263a9569e5 + languageName: node + linkType: hard + "supports-color@npm:^7.1.0": version: 7.2.0 resolution: "supports-color@npm:7.2.0" @@ -12793,6 +13657,13 @@ __metadata: languageName: node linkType: hard +"tlhunter-sorted-set@npm:^0.1.0": + version: 0.1.0 + resolution: "tlhunter-sorted-set@npm:0.1.0" + checksum: 10c0/fd07870aa75331fb7823e68604fda3bafb6aaef5cea8d342a3c24096635fd2c70273a330b00013e51cbde25272ae599de1270edeff972bd3c32e1c78e714edc6 + languageName: node + linkType: hard + "tmp@npm:^0.2.1, tmp@npm:~0.2.1": version: 0.2.5 resolution: "tmp@npm:0.2.5" @@ -12963,6 +13834,15 @@ __metadata: languageName: node linkType: hard +"ttl-set@npm:^1.0.0": + version: 1.0.0 + resolution: "ttl-set@npm:1.0.0" + dependencies: + fast-fifo: "npm:^1.3.2" + checksum: 10c0/ef260c2a903c4ab05090d4dbc21ddb738d7f38fd9680570582414b9115a7c358796c82f5b19067262eabb7476e43b7a2f02e3bb4cace85edee3242aee745d4d3 + languageName: node + linkType: hard + "tuf-js@npm:^3.0.1": version: 3.1.0 resolution: "tuf-js@npm:3.1.0" @@ -12994,6 +13874,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^0.13.1": + version: 0.13.1 + resolution: "type-fest@npm:0.13.1" + checksum: 10c0/0c0fa07ae53d4e776cf4dac30d25ad799443e9eef9226f9fddbb69242db86b08584084a99885cfa5a9dfe4c063ebdc9aa7b69da348e735baede8d43f1aeae93b + languageName: node + linkType: hard + "type-fest@npm:^0.18.0": version: 0.18.1 resolution: "type-fest@npm:0.18.1" @@ -13213,6 +14100,13 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:~6.21.0": + version: 6.21.0 + resolution: "undici-types@npm:6.21.0" + checksum: 10c0/c01ed51829b10aa72fc3ce64b747f8e74ae9b60eafa19a7b46ef624403508a54c526ffab06a14a26b3120d055e1104d7abe7c9017e83ced038ea5cf52f8d5e04 + languageName: node + linkType: hard + "undici-types@npm:~7.16.0": version: 7.16.0 resolution: "undici-types@npm:7.16.0" From a16f3a60760fab0638878ca6924376f7dcf396e2 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Wed, 12 Nov 2025 17:30:45 +0100 Subject: [PATCH 10/58] Extract sendRumEvent + Add ApplicationLaunch view --- packages/electron/src/entries/main.ts | 80 +++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 12 deletions(-) diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index a4dd52619e..0eede705bc 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -15,20 +15,23 @@ import { createServer } from 'node:http' import { ipcMain } from 'electron' import type { RawError, PageMayExitEvent, Encoder, Context, InitConfiguration } from '@datadog/browser-core' import { + dateNow, Observable, DeflateEncoderStreamId, createBatch, createHttpRequest, createFlushController, createIdentityEncoder, + combine, } from '@datadog/browser-core' -import type { AllowedRawRumEvent, RumConfiguration, RumEvent, RumInitConfiguration } from '@datadog/browser-rum-core' +import type { RumConfiguration, RumEvent, RumInitConfiguration } from '@datadog/browser-rum-core' import { RumEventType } from '@datadog/browser-rum-core' import { validateAndBuildRumConfiguration } from '@datadog/browser-rum-core/cjs/domain/configuration' import type { Batch } from '@datadog/browser-core/cjs/transport/batch' import { decode } from '@msgpack/msgpack' import type { TrackType } from '@datadog/browser-core/cjs/domain/configuration' import { createEndpointBuilder } from '@datadog/browser-core/cjs/domain/configuration' +import type { RumViewEvent } from '@datadog/browser-rum' import tracer from '../tracer' const sessionId = crypto.randomUUID() @@ -58,6 +61,17 @@ function makeDatadogElectron() { sessionExpireObservable, createEncoder ) + + function sendRumEvent(event: RumEvent) { + if (event.type === RumEventType.VIEW) { + rumBatch.upsert(event as unknown as Context, event.view.id) + } else { + rumBatch.add(event as unknown as Context) + } + } + + startMainProcessTracking(sendRumEvent, configuration) + const spanBatch = startElectronSpanBatch( initConfiguration, configuration, @@ -68,7 +82,7 @@ function makeDatadogElectron() { sessionExpireObservable, createEncoder ) - setupIpcHandlers(rumBatch, configuration) + setupIpcHandlers(sendRumEvent, configuration) createDdTraceAgent(spanBatch) setInterval(() => { @@ -128,7 +142,7 @@ export function startElectronSpanBatch( return batch } -function setupIpcHandlers(batch: Batch, configuration: RumConfiguration) { +function setupIpcHandlers(sendRumEvent: (event: RumEvent) => void, configuration: RumConfiguration) { ipcMain.handle('datadog:send', (_event, msg: string) => { const serverRumEvent = JSON.parse(msg) as BridgeEvent @@ -138,14 +152,11 @@ function setupIpcHandlers(batch: Batch, configuration: RumConfiguration) { return } - serverRumEvent.event.session.id = sessionId - serverRumEvent.event.application.id = configuration.applicationId + const rumEvent = serverRumEvent.event + rumEvent.session.id = sessionId + rumEvent.application.id = configuration.applicationId - if (serverRumEvent.event.type === RumEventType.VIEW) { - batch.upsert(serverRumEvent.event as unknown as Context, serverRumEvent.event.view.id) - } else { - batch.add(serverRumEvent.event as unknown as Context) - } + sendRumEvent(rumEvent) }) } @@ -169,7 +180,7 @@ function createDdTraceAgent(batch: Batch) { const decoded = decode(buffer) as unknown[] for (const trace of decoded) { - console.log('trace', trace) + // console.log('trace', trace) batch.add(trace as Context) } }) @@ -198,9 +209,54 @@ function createDdTraceAgent(batch: Batch) { const { port } = addressInfo const url = `http://127.0.0.1:${port}` - console.log('agents url', url) + // console.log('agents url', url) tracer.setUrl(url) }) } +function startMainProcessTracking(sendRumEvent: (event: RumEvent) => void, configuration: RumConfiguration) { + // To have a view id for events generated from main process + const mainProcessContext = { + // TODO source electron + source: 'browser', + application: { + id: configuration.applicationId, + }, + session: { + id: sessionId, + type: 'user', + }, + _dd: { + format_version: 2, + }, + } + const applicationLaunch = { + type: RumEventType.VIEW, + date: dateNow(), + view: { + id: crypto.randomUUID(), + name: 'ApplicationLaunch', + // TODO get customer package name + url: 'com/datadog/application-launch/view', + // TODO update it + time_spent: 0, + action: { + count: 0, + }, + resource: { + count: 0, + }, + error: { + count: 0, + }, + }, + _dd: { + // TODO update it + document_version: 1, + }, + } as RumViewEvent + + sendRumEvent(combine(mainProcessContext, applicationLaunch)) +} + export { tracer } From ac4259c6da774a8e82f548e32c8b71f8e7ebc04b Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Thu, 13 Nov 2025 10:41:04 +0100 Subject: [PATCH 11/58] add dummy exception tracking to link with view / session context --- packages/electron/src/entries/main.ts | 48 ++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 0eede705bc..decf428f07 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -13,8 +13,15 @@ import crypto from 'node:crypto' import { createServer } from 'node:http' import { ipcMain } from 'electron' -import type { RawError, PageMayExitEvent, Encoder, Context, InitConfiguration } from '@datadog/browser-core' import { + type RawError, + type PageMayExitEvent, + type Encoder, + type Context, + type InitConfiguration, + computeRawError, + clocksNow, + NonErrorPrefix, dateNow, Observable, DeflateEncoderStreamId, @@ -23,6 +30,8 @@ import { createFlushController, createIdentityEncoder, combine, + ErrorHandling, + generateUUID, } from '@datadog/browser-core' import type { RumConfiguration, RumEvent, RumInitConfiguration } from '@datadog/browser-rum-core' import { RumEventType } from '@datadog/browser-rum-core' @@ -218,16 +227,16 @@ function startMainProcessTracking(sendRumEvent: (event: RumEvent) => void, confi // To have a view id for events generated from main process const mainProcessContext = { // TODO source electron - source: 'browser', + source: 'browser' as const, application: { id: configuration.applicationId, }, session: { id: sessionId, - type: 'user', + type: 'user' as const, }, _dd: { - format_version: 2, + format_version: 2 as const, }, } const applicationLaunch = { @@ -256,7 +265,38 @@ function startMainProcessTracking(sendRumEvent: (event: RumEvent) => void, confi }, } as RumViewEvent + // TODO activity tracking + // TODO session expiration / renewal + // TODO useragent + sendRumEvent(combine(mainProcessContext, applicationLaunch)) + + process.on('uncaughtException', (err) => { + const error = computeRawError({ + originalError: err, + startClocks: clocksNow(), + nonErrorPrefix: NonErrorPrefix.UNCAUGHT, + source: 'source', + handling: ErrorHandling.UNHANDLED, + }) + const rawRumEvent = { + type: RumEventType.ERROR, + date: error.startClocks.timeStamp, + error: { + id: generateUUID(), + message: error.message, + stack: error.stack, + source: error.source, + type: error.type, + handling: error.handling, + }, + view: { + id: applicationLaunch.view.id, + url: applicationLaunch.view.url, + }, + } + sendRumEvent(combine(mainProcessContext, rawRumEvent)) + }) } export { tracer } From e7fd56a27ebd058724f9abca50ab59ca53db5fcb Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Thu, 13 Nov 2025 14:01:29 +0100 Subject: [PATCH 12/58] Track activity and update view time spent --- packages/electron/src/entries/main.ts | 50 ++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index decf428f07..9fa110716e 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -19,10 +19,11 @@ import { type Encoder, type Context, type InitConfiguration, + elapsed, + timeStampNow, computeRawError, clocksNow, NonErrorPrefix, - dateNow, Observable, DeflateEncoderStreamId, createBatch, @@ -32,6 +33,7 @@ import { combine, ErrorHandling, generateUUID, + toServerDuration, } from '@datadog/browser-core' import type { RumConfiguration, RumEvent, RumInitConfiguration } from '@datadog/browser-rum-core' import { RumEventType } from '@datadog/browser-rum-core' @@ -59,6 +61,7 @@ function makeDatadogElectron() { const pageMayExitObservable = new Observable() const sessionExpireObservable = new Observable() + const onRumEventObservable = new Observable() const createEncoder = () => createIdentityEncoder() const rumBatch = startElectronRumBatch( @@ -77,9 +80,10 @@ function makeDatadogElectron() { } else { rumBatch.add(event as unknown as Context) } + onRumEventObservable.notify(event) } - - startMainProcessTracking(sendRumEvent, configuration) + const onActivityObservable = startActivityTracking(onRumEventObservable) + startMainProcessTracking(sendRumEvent, configuration, onActivityObservable) const spanBatch = startElectronSpanBatch( initConfiguration, @@ -223,7 +227,11 @@ function createDdTraceAgent(batch: Batch) { }) } -function startMainProcessTracking(sendRumEvent: (event: RumEvent) => void, configuration: RumConfiguration) { +function startMainProcessTracking( + sendRumEvent: (event: RumEvent) => void, + configuration: RumConfiguration, + onActivityObservable: Observable +) { // To have a view id for events generated from main process const mainProcessContext = { // TODO source electron @@ -239,11 +247,13 @@ function startMainProcessTracking(sendRumEvent: (event: RumEvent) => void, confi format_version: 2 as const, }, } - const applicationLaunch = { + const applicationStart = timeStampNow() + let applicationLaunch = { type: RumEventType.VIEW, - date: dateNow(), + date: applicationStart as number, view: { id: crypto.randomUUID(), + is_active: true, name: 'ApplicationLaunch', // TODO get customer package name url: 'com/datadog/application-launch/view', @@ -265,12 +275,20 @@ function startMainProcessTracking(sendRumEvent: (event: RumEvent) => void, confi }, } as RumViewEvent - // TODO activity tracking + onActivityObservable.subscribe(() => { + applicationLaunch = combine(applicationLaunch, { + view: { + time_spent: toServerDuration(elapsed(applicationStart, timeStampNow())), + }, + _dd: { + document_version: applicationLaunch._dd.document_version + 1, + }, + }) + sendRumEvent(combine(mainProcessContext, applicationLaunch)) + }) // TODO session expiration / renewal // TODO useragent - sendRumEvent(combine(mainProcessContext, applicationLaunch)) - process.on('uncaughtException', (err) => { const error = computeRawError({ originalError: err, @@ -299,4 +317,18 @@ function startMainProcessTracking(sendRumEvent: (event: RumEvent) => void, confi }) } +function startActivityTracking(onRumEventObservable: Observable) { + const onActivityObservable = new Observable() + const alreadySeenViewIds = new Set() + onRumEventObservable.subscribe((event) => { + if (event.type === RumEventType.VIEW && !alreadySeenViewIds.has(event.view.id)) { + alreadySeenViewIds.add(event.view.id) + onActivityObservable.notify() + } else if (event.type === RumEventType.ACTION && event.action.type === 'click') { + onActivityObservable.notify() + } + }) + return onActivityObservable +} + export { tracer } From 154ad4e3ba3fa06db5d28032305644deef2c9d27 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Thu, 13 Nov 2025 14:52:32 +0100 Subject: [PATCH 13/58] Use observable to send and assemble RUM events --- packages/electron/src/entries/main.ts | 135 +++++++++++++++++--------- packages/electron/src/hooks.ts | 28 ++++++ 2 files changed, 118 insertions(+), 45 deletions(-) create mode 100644 packages/electron/src/hooks.ts diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 9fa110716e..2cde49daaf 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -34,19 +34,29 @@ import { ErrorHandling, generateUUID, toServerDuration, + HookNames, + DISCARDED, } from '@datadog/browser-core' -import type { RumConfiguration, RumEvent, RumInitConfiguration } from '@datadog/browser-rum-core' -import { RumEventType } from '@datadog/browser-rum-core' +import { + type RumConfiguration, + type RumEvent, + type RumInitConfiguration, + createHooks, + RumEventType, +} from '@datadog/browser-rum-core' import { validateAndBuildRumConfiguration } from '@datadog/browser-rum-core/cjs/domain/configuration' import type { Batch } from '@datadog/browser-core/cjs/transport/batch' import { decode } from '@msgpack/msgpack' import type { TrackType } from '@datadog/browser-core/cjs/domain/configuration' import { createEndpointBuilder } from '@datadog/browser-core/cjs/domain/configuration' -import type { RumViewEvent } from '@datadog/browser-rum' +import type { RumViewEvent, RumErrorEvent } from '@datadog/browser-rum' import tracer from '../tracer' +import type { Hooks } from '../hooks' -const sessionId = crypto.randomUUID() -console.log('sessionId', sessionId) +interface CollectedRumEvent { + source: 'main-process' | 'renderer' + event: RumEvent +} function makeDatadogElectron() { return { @@ -61,7 +71,8 @@ function makeDatadogElectron() { const pageMayExitObservable = new Observable() const sessionExpireObservable = new Observable() - const onRumEventObservable = new Observable() + const onRumEventObservable = new Observable() + const hooks = createHooks() const createEncoder = () => createIdentityEncoder() const rumBatch = startElectronRumBatch( @@ -74,16 +85,9 @@ function makeDatadogElectron() { createEncoder ) - function sendRumEvent(event: RumEvent) { - if (event.type === RumEventType.VIEW) { - rumBatch.upsert(event as unknown as Context, event.view.id) - } else { - rumBatch.add(event as unknown as Context) - } - onRumEventObservable.notify(event) - } + startRumEventAssembleAndSend(configuration, onRumEventObservable, rumBatch, hooks) const onActivityObservable = startActivityTracking(onRumEventObservable) - startMainProcessTracking(sendRumEvent, configuration, onActivityObservable) + startMainProcessTracking(hooks, onRumEventObservable, onActivityObservable) const spanBatch = startElectronSpanBatch( initConfiguration, @@ -95,7 +99,7 @@ function makeDatadogElectron() { sessionExpireObservable, createEncoder ) - setupIpcHandlers(sendRumEvent, configuration) + setupIpcHandlers(onRumEventObservable) createDdTraceAgent(spanBatch) setInterval(() => { @@ -155,7 +159,7 @@ export function startElectronSpanBatch( return batch } -function setupIpcHandlers(sendRumEvent: (event: RumEvent) => void, configuration: RumConfiguration) { +function setupIpcHandlers(onRumEventObservable: Observable) { ipcMain.handle('datadog:send', (_event, msg: string) => { const serverRumEvent = JSON.parse(msg) as BridgeEvent @@ -165,11 +169,7 @@ function setupIpcHandlers(sendRumEvent: (event: RumEvent) => void, configuration return } - const rumEvent = serverRumEvent.event - rumEvent.session.id = sessionId - rumEvent.application.id = configuration.applicationId - - sendRumEvent(rumEvent) + onRumEventObservable.notify({ event: serverRumEvent.event, source: 'renderer' }) }) } @@ -227,38 +227,81 @@ function createDdTraceAgent(batch: Batch) { }) } -function startMainProcessTracking( - sendRumEvent: (event: RumEvent) => void, +function startRumEventAssembleAndSend( configuration: RumConfiguration, + onRumEventObservable: Observable, + rumBatch: Batch, + hooks: Hooks +) { + onRumEventObservable.subscribe(({ event, source }) => { + const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, { + eventType: event.type, + })! + + if (defaultRumEventAttributes === DISCARDED || defaultRumEventAttributes.session?.id === undefined) { + return + } + const commonContext = + source === 'renderer' + ? { + session: { id: defaultRumEventAttributes.session.id }, + application: { id: configuration.applicationId }, + } + : combine(defaultRumEventAttributes, { + // TODO source electron + source: 'browser' as const, + application: { id: configuration.applicationId }, + session: { + type: 'user' as const, + }, + _dd: { + format_version: 2 as const, + }, + }) + + const serverRumEvent = combine(event, commonContext) + + if (serverRumEvent.type === RumEventType.VIEW) { + rumBatch.upsert(serverRumEvent as unknown as Context, serverRumEvent.view.id) + } else { + rumBatch.add(serverRumEvent as unknown as Context) + } + }) +} + +function startMainProcessTracking( + hooks: Hooks, + onRumEventObservable: Observable, onActivityObservable: Observable ) { - // To have a view id for events generated from main process const mainProcessContext = { - // TODO source electron - source: 'browser' as const, - application: { - id: configuration.applicationId, - }, - session: { - id: sessionId, - type: 'user' as const, - }, - _dd: { - format_version: 2 as const, - }, + sessionId: crypto.randomUUID(), + viewId: crypto.randomUUID(), } + hooks.register(HookNames.Assemble, ({ eventType }) => { + return { + type: eventType, + session: { + id: mainProcessContext.sessionId, + }, + view: { + id: mainProcessContext.viewId, + }, + } + }) + console.log('sessionId', mainProcessContext.sessionId) const applicationStart = timeStampNow() let applicationLaunch = { type: RumEventType.VIEW, date: applicationStart as number, view: { - id: crypto.randomUUID(), + id: mainProcessContext.viewId, is_active: true, name: 'ApplicationLaunch', // TODO get customer package name url: 'com/datadog/application-launch/view', - // TODO update it time_spent: 0, + // TODO update counters action: { count: 0, }, @@ -270,11 +313,12 @@ function startMainProcessTracking( }, }, _dd: { - // TODO update it document_version: 1, }, } as RumViewEvent + onRumEventObservable.notify({ event: applicationLaunch, source: 'main-process' }) + onActivityObservable.subscribe(() => { applicationLaunch = combine(applicationLaunch, { view: { @@ -284,11 +328,12 @@ function startMainProcessTracking( document_version: applicationLaunch._dd.document_version + 1, }, }) - sendRumEvent(combine(mainProcessContext, applicationLaunch)) + onRumEventObservable.notify({ event: applicationLaunch, source: 'main-process' }) }) // TODO session expiration / renewal // TODO useragent + // TODO remove me when using dd-trace-js process.on('uncaughtException', (err) => { const error = computeRawError({ originalError: err, @@ -297,7 +342,7 @@ function startMainProcessTracking( source: 'source', handling: ErrorHandling.UNHANDLED, }) - const rawRumEvent = { + const errorEvent: Partial = { type: RumEventType.ERROR, date: error.startClocks.timeStamp, error: { @@ -313,14 +358,14 @@ function startMainProcessTracking( url: applicationLaunch.view.url, }, } - sendRumEvent(combine(mainProcessContext, rawRumEvent)) + onRumEventObservable.notify({ event: errorEvent as RumErrorEvent, source: 'main-process' }) }) } -function startActivityTracking(onRumEventObservable: Observable) { +function startActivityTracking(onRumEventObservable: Observable) { const onActivityObservable = new Observable() const alreadySeenViewIds = new Set() - onRumEventObservable.subscribe((event) => { + onRumEventObservable.subscribe(({ event }) => { if (event.type === RumEventType.VIEW && !alreadySeenViewIds.has(event.view.id)) { alreadySeenViewIds.add(event.view.id) onActivityObservable.notify() diff --git a/packages/electron/src/hooks.ts b/packages/electron/src/hooks.ts new file mode 100644 index 0000000000..50d635ee6e --- /dev/null +++ b/packages/electron/src/hooks.ts @@ -0,0 +1,28 @@ +import type { + DISCARDED, + HookNamesAsConst, + RecursivePartial, + RelativeTime, + SKIPPED, + TelemetryEvent, +} from '@datadog/browser-core' +import { abstractHooks } from '@datadog/browser-core' +import type { RumEvent } from '@datadog/browser-rum-core' + +// Define a partial RUM event type. +// Ensuring the `type` field is always present improves type checking, especially in conditional logic in hooks (e.g., `if (eventType === 'view')`). +export type DefaultRumEventAttributes = RecursivePartial & { type: RumEvent['type'] } +export type DefaultTelemetryEventAttributes = RecursivePartial + +export interface HookCallbackMap { + [HookNamesAsConst.ASSEMBLE]: (param: { + eventType: RumEvent['type'] + }) => DefaultRumEventAttributes | SKIPPED | DISCARDED + [HookNamesAsConst.ASSEMBLE_TELEMETRY]: (param: { + startTime: RelativeTime + }) => DefaultTelemetryEventAttributes | SKIPPED | DISCARDED +} + +export type Hooks = ReturnType + +export const createHooks = abstractHooks From 949f56350bcaf468da628cf4d3a0bd3510e1a49a Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Thu, 13 Nov 2025 17:18:59 +0100 Subject: [PATCH 14/58] Generate RUM errors from error spans --- packages/electron/src/entries/main.ts | 85 +++++++++++++++------------ 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 2cde49daaf..7a9a7f4726 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -21,9 +21,6 @@ import { type InitConfiguration, elapsed, timeStampNow, - computeRawError, - clocksNow, - NonErrorPrefix, Observable, DeflateEncoderStreamId, createBatch, @@ -31,11 +28,11 @@ import { createFlushController, createIdentityEncoder, combine, - ErrorHandling, - generateUUID, toServerDuration, HookNames, DISCARDED, + ErrorHandling, + generateUUID, } from '@datadog/browser-core' import { type RumConfiguration, @@ -58,6 +55,8 @@ interface CollectedRumEvent { event: RumEvent } +type Span = any + function makeDatadogElectron() { return { init(initConfiguration: RumInitConfiguration) { @@ -72,6 +71,7 @@ function makeDatadogElectron() { const pageMayExitObservable = new Observable() const sessionExpireObservable = new Observable() const onRumEventObservable = new Observable() + const onSpanObservable = new Observable() const hooks = createHooks() const createEncoder = () => createIdentityEncoder() @@ -88,6 +88,7 @@ function makeDatadogElectron() { startRumEventAssembleAndSend(configuration, onRumEventObservable, rumBatch, hooks) const onActivityObservable = startActivityTracking(onRumEventObservable) startMainProcessTracking(hooks, onRumEventObservable, onActivityObservable) + startConvertSpanToRumEvent(onSpanObservable, onRumEventObservable) const spanBatch = startElectronSpanBatch( initConfiguration, @@ -99,8 +100,11 @@ function makeDatadogElectron() { sessionExpireObservable, createEncoder ) + onSpanObservable.subscribe((span) => { + spanBatch.add(span) + }) setupIpcHandlers(onRumEventObservable) - createDdTraceAgent(spanBatch) + createDdTraceAgent(onSpanObservable) setInterval(() => { pageMayExitObservable.notify({ reason: 'page_hide' }) @@ -178,7 +182,7 @@ interface BridgeEvent { event: RumEvent & { session: { id: string } } & { application: { id: string } } } -function createDdTraceAgent(batch: Batch) { +function createDdTraceAgent(onSpanObservable: Observable) { const server = createServer() server.on('request', (req, res) => { @@ -193,8 +197,12 @@ function createDdTraceAgent(batch: Batch) { const decoded = decode(buffer) as unknown[] for (const trace of decoded) { - // console.log('trace', trace) - batch.add(trace as Context) + for (const span of trace as any) { + if (!isSdkRequest(span)) { + console.log('span', span) + onSpanObservable.notify(span) + } + } } }) @@ -227,6 +235,16 @@ function createDdTraceAgent(batch: Batch) { }) } +function isSdkRequest(span: any) { + const spanRequestUrl = span.meta['http.url'] as string | undefined + return ( + (spanRequestUrl && + (spanRequestUrl.startsWith('http://127.0.0.1') || + spanRequestUrl.startsWith('https://browser-intake-datadoghq.com/'))) || + (span.resource as string).startsWith('browser-intake-datadoghq.com') + ) +} + function startRumEventAssembleAndSend( configuration: RumConfiguration, onRumEventObservable: Observable, @@ -286,6 +304,8 @@ function startMainProcessTracking( }, view: { id: mainProcessContext.viewId, + // TODO get customer package name + url: 'com/datadog/application-launch/view', }, } }) @@ -298,8 +318,6 @@ function startMainProcessTracking( id: mainProcessContext.viewId, is_active: true, name: 'ApplicationLaunch', - // TODO get customer package name - url: 'com/datadog/application-launch/view', time_spent: 0, // TODO update counters action: { @@ -332,33 +350,28 @@ function startMainProcessTracking( }) // TODO session expiration / renewal // TODO useragent +} - // TODO remove me when using dd-trace-js - process.on('uncaughtException', (err) => { - const error = computeRawError({ - originalError: err, - startClocks: clocksNow(), - nonErrorPrefix: NonErrorPrefix.UNCAUGHT, - source: 'source', - handling: ErrorHandling.UNHANDLED, - }) - const errorEvent: Partial = { - type: RumEventType.ERROR, - date: error.startClocks.timeStamp, - error: { - id: generateUUID(), - message: error.message, - stack: error.stack, - source: error.source, - type: error.type, - handling: error.handling, - }, - view: { - id: applicationLaunch.view.id, - url: applicationLaunch.view.url, - }, +function startConvertSpanToRumEvent( + onSpanObservable: Observable, + onRumEventObservable: Observable +) { + onSpanObservable.subscribe((span) => { + if (span.error) { + const rumError: Partial = { + type: RumEventType.ERROR, + date: span.start / 1e6, + error: { + id: generateUUID(), + message: span.meta['error.message'], + stack: span.meta['error.stack'], + type: span.meta['error.type'], + source: 'source', + handling: ErrorHandling.UNHANDLED, + }, + } + onRumEventObservable.notify({ event: rumError as RumErrorEvent, source: 'main-process' }) } - onRumEventObservable.notify({ event: errorEvent as RumErrorEvent, source: 'main-process' }) }) } From 0ef6e03551edd6bccb97dd0a0f30c2c268b54710 Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Fri, 14 Nov 2025 08:01:06 +0100 Subject: [PATCH 15/58] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20rename=20bride.ts=20?= =?UTF-8?q?to=20renderer=20and=20move=20expoerted=20function=20in=20separa?= =?UTF-8?q?te=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/electron/bridge/package.json | 6 --- packages/electron/renderer/package.json | 6 +++ .../{entries => domain/renderer}/bridge.ts | 6 +-- .../src/domain/renderer/ipcRenderer.ts | 39 +++++++++++++++++ packages/electron/src/entries/main.ts | 43 ++++++++----------- packages/electron/src/entries/renderer.ts | 5 +++ 6 files changed, 69 insertions(+), 36 deletions(-) delete mode 100644 packages/electron/bridge/package.json create mode 100644 packages/electron/renderer/package.json rename packages/electron/src/{entries => domain/renderer}/bridge.ts (79%) create mode 100644 packages/electron/src/domain/renderer/ipcRenderer.ts create mode 100644 packages/electron/src/entries/renderer.ts diff --git a/packages/electron/bridge/package.json b/packages/electron/bridge/package.json deleted file mode 100644 index 494c5afc44..0000000000 --- a/packages/electron/bridge/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "private": true, - "main": "../cjs/entries/bridge.js", - "module": "../esm/entries/bridge.js", - "types": "../cjs/entries/bridge.d.ts" -} diff --git a/packages/electron/renderer/package.json b/packages/electron/renderer/package.json new file mode 100644 index 0000000000..ade81e8b79 --- /dev/null +++ b/packages/electron/renderer/package.json @@ -0,0 +1,6 @@ +{ + "private": true, + "main": "../cjs/entries/renderer.js", + "module": "../esm/entries/renderer.js", + "types": "../cjs/entries/renderer.d.ts" +} diff --git a/packages/electron/src/entries/bridge.ts b/packages/electron/src/domain/renderer/bridge.ts similarity index 79% rename from packages/electron/src/entries/bridge.ts rename to packages/electron/src/domain/renderer/bridge.ts index 3090a02203..d49d399b05 100644 --- a/packages/electron/src/entries/bridge.ts +++ b/packages/electron/src/domain/renderer/bridge.ts @@ -1,12 +1,10 @@ import { contextBridge, ipcRenderer } from 'electron' import type { DatadogEventBridge } from '@datadog/browser-core/src/transport' -export function setupElectronBridge() { - console.log('setupElectronBridge') - +export function setupRendererBridge() { contextBridge.exposeInMainWorld('DatadogEventBridge', { getCapabilities() { - return JSON.stringify(['electron']) + return '[]' }, getPrivacyLevel() { return 'mask' diff --git a/packages/electron/src/domain/renderer/ipcRenderer.ts b/packages/electron/src/domain/renderer/ipcRenderer.ts new file mode 100644 index 0000000000..a9b306135d --- /dev/null +++ b/packages/electron/src/domain/renderer/ipcRenderer.ts @@ -0,0 +1,39 @@ +import type { IpcRenderer } from 'electron' +import { createSpanIdentifier, createTraceIdentifier } from '@datadog/browser-rum-core/src/domain/tracing/identifier' +import { ipcRenderer } from 'electron' + +function createDatadogCarrier() { + const spanId = createSpanIdentifier().toString() + const traceId = createTraceIdentifier().toString() + + return { + __dd_carrier: true, + 'x-datadog-origin': 'rum', + 'x-datadog-parent-id': spanId, + 'x-datadog-sampling-priority': '1', + 'x-datadog-trace-id': traceId, + } +} + +function withDatadogCarrier R, R>(fn: T): (...args: Parameters) => R { + return (...args: Parameters) => fn(...args, createDatadogCarrier()) +} + +export function createIpcRenderer(): IpcRenderer { + const ddIpcRenderer = { ...ipcRenderer } + + ddIpcRenderer.on = withDatadogCarrier(ipcRenderer.on.bind(ipcRenderer)) + ddIpcRenderer.off = withDatadogCarrier(ipcRenderer.off.bind(ipcRenderer)) + ddIpcRenderer.once = withDatadogCarrier(ipcRenderer.once.bind(ipcRenderer)) + ddIpcRenderer.addListener = withDatadogCarrier(ipcRenderer.addListener.bind(ipcRenderer)) + ddIpcRenderer.removeListener = withDatadogCarrier(ipcRenderer.removeListener.bind(ipcRenderer)) + ddIpcRenderer.send = withDatadogCarrier(ipcRenderer.send.bind(ipcRenderer)) + ddIpcRenderer.invoke = withDatadogCarrier(ipcRenderer.invoke.bind(ipcRenderer)) + ddIpcRenderer.sendSync = withDatadogCarrier(ipcRenderer.sendSync.bind(ipcRenderer)) + ddIpcRenderer.sendToHost = withDatadogCarrier(ipcRenderer.sendToHost.bind(ipcRenderer)) + + // TODO: Do something for ipcRenderer.postMessage + // see https://www.electronjs.org/docs/latest/api/ipc-renderer#ipcrendererpostmessagechannel-message-transfer + + return ddIpcRenderer +} diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 7a9a7f4726..873cc4bdcd 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -13,12 +13,8 @@ import crypto from 'node:crypto' import { createServer } from 'node:http' import { ipcMain } from 'electron' +import type { RawError, PageMayExitEvent, Encoder, Context, InitConfiguration } from '@datadog/browser-core' import { - type RawError, - type PageMayExitEvent, - type Encoder, - type Context, - type InitConfiguration, elapsed, timeStampNow, Observable, @@ -34,13 +30,8 @@ import { ErrorHandling, generateUUID, } from '@datadog/browser-core' -import { - type RumConfiguration, - type RumEvent, - type RumInitConfiguration, - createHooks, - RumEventType, -} from '@datadog/browser-rum-core' +import { createHooks, RumEventType } from '@datadog/browser-rum-core' +import type { RumConfiguration, RumEvent, RumInitConfiguration } from '@datadog/browser-rum-core' import { validateAndBuildRumConfiguration } from '@datadog/browser-rum-core/cjs/domain/configuration' import type { Batch } from '@datadog/browser-core/cjs/transport/batch' import { decode } from '@msgpack/msgpack' @@ -194,7 +185,9 @@ function createDdTraceAgent(onSpanObservable: Observable) { req.on('end', () => { const buffer = Buffer.concat(chunks) - const decoded = decode(buffer) as unknown[] + const decoded = decode(buffer) as Array< + Array<{ name: string; type: string; meta: { [key: string]: unknown }; [key: string]: unknown }> + > for (const trace of decoded) { for (const span of trace as any) { @@ -296,19 +289,17 @@ function startMainProcessTracking( sessionId: crypto.randomUUID(), viewId: crypto.randomUUID(), } - hooks.register(HookNames.Assemble, ({ eventType }) => { - return { - type: eventType, - session: { - id: mainProcessContext.sessionId, - }, - view: { - id: mainProcessContext.viewId, - // TODO get customer package name - url: 'com/datadog/application-launch/view', - }, - } - }) + hooks.register(HookNames.Assemble, ({ eventType }) => ({ + type: eventType, + session: { + id: mainProcessContext.sessionId, + }, + view: { + id: mainProcessContext.viewId, + // TODO get customer package name + url: 'com/datadog/application-launch/view', + }, + })) console.log('sessionId', mainProcessContext.sessionId) const applicationStart = timeStampNow() let applicationLaunch = { diff --git a/packages/electron/src/entries/renderer.ts b/packages/electron/src/entries/renderer.ts new file mode 100644 index 0000000000..1a2dff3fea --- /dev/null +++ b/packages/electron/src/entries/renderer.ts @@ -0,0 +1,5 @@ +import { createIpcRenderer } from '../domain/renderer/ipcRenderer' +export { setupRendererBridge } from '../domain/renderer/bridge' + +// eslint-disable-next-line local-rules/disallow-side-effects +export const ipcRenderer = createIpcRenderer() From 19dfc924bc0936e6c149150ce891c096ec2d7658 Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Fri, 14 Nov 2025 08:35:13 +0100 Subject: [PATCH 16/58] =?UTF-8?q?=E2=9C=A8=20add=20ipcMain=20and=20move=20?= =?UTF-8?q?tracer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/electron/src/domain/main/ipcMain.ts | 48 +++++++++++++++++++ .../src/domain/renderer/ipcRenderer.ts | 3 +- packages/electron/src/domain/trace.ts | 7 +++ packages/electron/src/{ => domain}/tracer.ts | 3 +- packages/electron/src/entries/main.ts | 8 ++-- 5 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 packages/electron/src/domain/main/ipcMain.ts create mode 100644 packages/electron/src/domain/trace.ts rename packages/electron/src/{ => domain}/tracer.ts (88%) diff --git a/packages/electron/src/domain/main/ipcMain.ts b/packages/electron/src/domain/main/ipcMain.ts new file mode 100644 index 0000000000..edf3078209 --- /dev/null +++ b/packages/electron/src/domain/main/ipcMain.ts @@ -0,0 +1,48 @@ +import { ipcMain } from 'electron' +import type { IpcMain } from 'electron' +import tracer from '../tracer' +import type { DatadogCarrier } from '../trace' + +const SPAN_NAME_PREFIX = 'electron.main.ipc' + +const isDatadogCarrier = (arg: any): arg is DatadogCarrier => typeof arg === 'object' && arg?.__dd_carrier === true + +export function createIpcMain(): IpcMain { + const ddIpcMain = { ...ipcMain } + + ddIpcMain.on = withDatadogCarrier('on', ipcMain.on.bind(ipcMain)) + ddIpcMain.off = withDatadogCarrier('off', ipcMain.off.bind(ipcMain)) + ddIpcMain.once = withDatadogCarrier('once', ipcMain.once.bind(ipcMain)) + ddIpcMain.addListener = withDatadogCarrier('addListener', ipcMain.addListener.bind(ipcMain)) + ddIpcMain.removeListener = withDatadogCarrier('removeListener', ipcMain.removeListener.bind(ipcMain)) + ddIpcMain.handle = withDatadogCarrier('handle', ipcMain.handle.bind(ipcMain)) + ddIpcMain.handleOnce = withDatadogCarrier('handleOnce', ipcMain.handleOnce.bind(ipcMain)) + + ddIpcMain.removeAllListeners = ipcMain.removeAllListeners.bind(ipcMain) + ddIpcMain.removeHandler = ipcMain.removeHandler.bind(ipcMain) + + return ddIpcMain +} + +function withDatadogCarrier R, R>(name: string, fn: T): (...args: Parameters) => R { + const spanName = `${SPAN_NAME_PREFIX}.${name}` + + return (...args: Parameters) => { + const channel = args[0] + const listener = args[1] + + return fn(channel, (...args: Parameters) => { + const lastArg = args[args.length - 1] + if (isDatadogCarrier(lastArg)) { + const parentContext = tracer.extract('text_map', lastArg) + args.pop() // remove the carrier from the args + + if (parentContext) { + return tracer.trace(spanName, { childOf: parentContext }, () => listener(...args)) as R + } + } + + return tracer.trace(spanName, () => listener(...args)) as R + }) + } +} diff --git a/packages/electron/src/domain/renderer/ipcRenderer.ts b/packages/electron/src/domain/renderer/ipcRenderer.ts index a9b306135d..44b348aba7 100644 --- a/packages/electron/src/domain/renderer/ipcRenderer.ts +++ b/packages/electron/src/domain/renderer/ipcRenderer.ts @@ -1,8 +1,9 @@ import type { IpcRenderer } from 'electron' import { createSpanIdentifier, createTraceIdentifier } from '@datadog/browser-rum-core/src/domain/tracing/identifier' import { ipcRenderer } from 'electron' +import type { DatadogCarrier } from '../trace' -function createDatadogCarrier() { +function createDatadogCarrier(): DatadogCarrier { const spanId = createSpanIdentifier().toString() const traceId = createTraceIdentifier().toString() diff --git a/packages/electron/src/domain/trace.ts b/packages/electron/src/domain/trace.ts new file mode 100644 index 0000000000..933e6efbc9 --- /dev/null +++ b/packages/electron/src/domain/trace.ts @@ -0,0 +1,7 @@ +export interface DatadogCarrier { + __dd_carrier: true + 'x-datadog-origin': string + 'x-datadog-parent-id': string + 'x-datadog-sampling-priority': string + 'x-datadog-trace-id': string +} diff --git a/packages/electron/src/tracer.ts b/packages/electron/src/domain/tracer.ts similarity index 88% rename from packages/electron/src/tracer.ts rename to packages/electron/src/domain/tracer.ts index 3846d6f37c..057be0ea69 100644 --- a/packages/electron/src/tracer.ts +++ b/packages/electron/src/domain/tracer.ts @@ -1,3 +1,4 @@ +/* eslint-disable local-rules/disallow-side-effects */ import tracer from 'dd-trace' import { app } from 'electron' @@ -37,4 +38,4 @@ tracer.init({ }, }) // initialized in a different file to avoid hoisting. -export default tracer +export default tracer // eslint-disable-line import/no-default-export diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 873cc4bdcd..5a44c811b5 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -12,7 +12,6 @@ */ import crypto from 'node:crypto' import { createServer } from 'node:http' -import { ipcMain } from 'electron' import type { RawError, PageMayExitEvent, Encoder, Context, InitConfiguration } from '@datadog/browser-core' import { elapsed, @@ -38,8 +37,9 @@ import { decode } from '@msgpack/msgpack' import type { TrackType } from '@datadog/browser-core/cjs/domain/configuration' import { createEndpointBuilder } from '@datadog/browser-core/cjs/domain/configuration' import type { RumViewEvent, RumErrorEvent } from '@datadog/browser-rum' -import tracer from '../tracer' +import tracer from '../domain/tracer' import type { Hooks } from '../hooks' +import { createIpcMain } from '../domain/main/ipcMain' interface CollectedRumEvent { source: 'main-process' | 'renderer' @@ -105,6 +105,8 @@ function makeDatadogElectron() { } export const ddElectron = makeDatadogElectron() +export { tracer } +export const ipcMain = createIpcMain() export function startElectronRumBatch( configuration: RumConfiguration, @@ -379,5 +381,3 @@ function startActivityTracking(onRumEventObservable: Observable Date: Fri, 14 Nov 2025 09:34:43 +0100 Subject: [PATCH 17/58] refactor: move setupMainBridge in it's own file --- packages/electron/src/domain/events.ts | 6 +++++ packages/electron/src/domain/main/bridge.ts | 23 ++++++++++++++++ packages/electron/src/entries/main.ts | 30 +++------------------ 3 files changed, 33 insertions(+), 26 deletions(-) create mode 100644 packages/electron/src/domain/events.ts create mode 100644 packages/electron/src/domain/main/bridge.ts diff --git a/packages/electron/src/domain/events.ts b/packages/electron/src/domain/events.ts new file mode 100644 index 0000000000..e5b2615d08 --- /dev/null +++ b/packages/electron/src/domain/events.ts @@ -0,0 +1,6 @@ +import { RumEvent } from '@datadog/browser-rum-core' + +export interface CollectedRumEvent { + source: 'main-process' | 'renderer' + event: RumEvent +} diff --git a/packages/electron/src/domain/main/bridge.ts b/packages/electron/src/domain/main/bridge.ts new file mode 100644 index 0000000000..2bf22cf0c3 --- /dev/null +++ b/packages/electron/src/domain/main/bridge.ts @@ -0,0 +1,23 @@ +import type { Observable } from '@datadog/browser-core' +import type { RumEvent } from '@datadog/browser-rum-core' +import { ipcMain } from 'electron' +import type { CollectedRumEvent } from '../events' + +interface BridgeEvent { + eventType: 'rum' + event: RumEvent & { session: { id: string } } & { application: { id: string } } +} + +export function setupMainBridge(rumEventObservable: Observable) { + ipcMain.handle('datadog:send', (_event, msg: string) => { + const serverRumEvent = JSON.parse(msg) as BridgeEvent + + if (serverRumEvent.eventType !== 'rum') { + console.log('not a rum event', serverRumEvent) + + return + } + + rumEventObservable.notify({ event: serverRumEvent.event, source: 'renderer' }) + }) +} diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 5a44c811b5..3f3fb1e2fd 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -30,7 +30,7 @@ import { generateUUID, } from '@datadog/browser-core' import { createHooks, RumEventType } from '@datadog/browser-rum-core' -import type { RumConfiguration, RumEvent, RumInitConfiguration } from '@datadog/browser-rum-core' +import type { RumConfiguration, RumInitConfiguration } from '@datadog/browser-rum-core' import { validateAndBuildRumConfiguration } from '@datadog/browser-rum-core/cjs/domain/configuration' import type { Batch } from '@datadog/browser-core/cjs/transport/batch' import { decode } from '@msgpack/msgpack' @@ -40,11 +40,8 @@ import type { RumViewEvent, RumErrorEvent } from '@datadog/browser-rum' import tracer from '../domain/tracer' import type { Hooks } from '../hooks' import { createIpcMain } from '../domain/main/ipcMain' - -interface CollectedRumEvent { - source: 'main-process' | 'renderer' - event: RumEvent -} +import type { CollectedRumEvent } from '../domain/events' +import { setupMainBridge } from '../domain/main/bridge' type Span = any @@ -94,7 +91,7 @@ function makeDatadogElectron() { onSpanObservable.subscribe((span) => { spanBatch.add(span) }) - setupIpcHandlers(onRumEventObservable) + setupMainBridge(onRumEventObservable) createDdTraceAgent(onSpanObservable) setInterval(() => { @@ -156,25 +153,6 @@ export function startElectronSpanBatch( return batch } -function setupIpcHandlers(onRumEventObservable: Observable) { - ipcMain.handle('datadog:send', (_event, msg: string) => { - const serverRumEvent = JSON.parse(msg) as BridgeEvent - - if (serverRumEvent.eventType !== 'rum') { - console.log('not a rum event', serverRumEvent) - - return - } - - onRumEventObservable.notify({ event: serverRumEvent.event, source: 'renderer' }) - }) -} - -interface BridgeEvent { - eventType: 'rum' - event: RumEvent & { session: { id: string } } & { application: { id: string } } -} - function createDdTraceAgent(onSpanObservable: Observable) { const server = createServer() From 7134ff56f8cafc9defc85789b68eef487f33a5ab Mon Sep 17 00:00:00 2001 From: Adrian de la Rosa Date: Fri, 14 Nov 2025 11:45:52 +0100 Subject: [PATCH 18/58] =?UTF-8?q?=F0=9F=9A=A7=20send=20trace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/electron/package.json | 4 +- packages/electron/src/entries/main.ts | 157 ++++++++++++++++++++------ scripts/lib/computeBundleSize.ts | 2 +- yarn.lock | 16 +++ 4 files changed, 140 insertions(+), 39 deletions(-) diff --git a/packages/electron/package.json b/packages/electron/package.json index 55ffbd284c..8e71467195 100644 --- a/packages/electron/package.json +++ b/packages/electron/package.json @@ -15,7 +15,9 @@ "@datadog/browser-core": "6.23.0", "@datadog/browser-rum-core": "6.23.0", "@msgpack/msgpack": "3.1.2", - "dd-trace": "^5.76.0" + "@openfeature/core": "1.9.1", + "dd-trace": "^5.76.0", + "graphql": "16.12.0" }, "peerDependencies": { "@datadog/browser-logs": "6.23.0", diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 3f3fb1e2fd..66f0ea1217 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -14,6 +14,10 @@ import crypto from 'node:crypto' import { createServer } from 'node:http' import type { RawError, PageMayExitEvent, Encoder, Context, InitConfiguration } from '@datadog/browser-core' import { + computeRawError, + clocksNow, + NonErrorPrefix, + dateNow, elapsed, timeStampNow, Observable, @@ -37,6 +41,7 @@ import { decode } from '@msgpack/msgpack' import type { TrackType } from '@datadog/browser-core/cjs/domain/configuration' import { createEndpointBuilder } from '@datadog/browser-core/cjs/domain/configuration' import type { RumViewEvent, RumErrorEvent } from '@datadog/browser-rum' +import { createSpanIdentifier, createTraceIdentifier } from '@datadog/browser-rum-core/src/domain/tracing/identifier' import tracer from '../domain/tracer' import type { Hooks } from '../hooks' import { createIpcMain } from '../domain/main/ipcMain' @@ -44,6 +49,7 @@ import type { CollectedRumEvent } from '../domain/events' import { setupMainBridge } from '../domain/main/bridge' type Span = any +type Trace = Span[] function makeDatadogElectron() { return { @@ -85,8 +91,7 @@ function makeDatadogElectron() { console.error('Error reporting to Datadog') }, pageMayExitObservable, - sessionExpireObservable, - createEncoder + sessionExpireObservable ) onSpanObservable.subscribe((span) => { spanBatch.add(span) @@ -128,29 +133,98 @@ export function startElectronRumBatch( return batch } +// TODO change it by a single event fetch export function startElectronSpanBatch( initConfiguration: InitConfiguration, configuration: RumConfiguration, reportError: (error: RawError) => void, pageMayExitObservable: Observable, - sessionExpireObservable: Observable, - createEncoder: (streamId: DeflateEncoderStreamId) => Encoder + sessionExpireObservable: Observable ) { + const flushController = createFlushController({ + messagesLimit: configuration.batchMessagesLimit, + bytesLimit: configuration.batchBytesLimit, + durationLimit: configuration.flushTimeout, + pageMayExitObservable, + sessionExpireObservable, + }) + const endpoints = [createEndpointBuilder(initConfiguration, 'spans' as TrackType)] - const batch = createBatch({ - encoder: createEncoder(DeflateEncoderStreamId.RUM), - request: createHttpRequest(endpoints, configuration.batchBytesLimit, reportError), - flushController: createFlushController({ - messagesLimit: configuration.batchMessagesLimit, - bytesLimit: configuration.batchBytesLimit, - durationLimit: configuration.flushTimeout, - pageMayExitObservable, - sessionExpireObservable, - }), - messageBytesLimit: configuration.messageBytesLimit, + const request = createHttpRequest(endpoints, configuration.batchBytesLimit, reportError) + + const items: any[] = [] + + // eslint-disable-next-line @typescript-eslint/no-misused-promises + const flushSubscription = flushController.flushObservable.subscribe(async () => { + if (items.length === 0) { + return + } + + const payload = items + .map((trace: any[]) => + JSON.stringify({ + env: 'prod', + spans: trace.map((span) => ({ + ...span, + trace_id: span.trace_id?.toString(16), + span_id: span.span_id?.toString(16), + parent_id: span.parent_id?.toString(16), + })), + }) + ) + .join('\n') + + console.log('>>>', { payload }) + fetch('https://browser-intake-datadoghq.com/api/v2/spans', { + method: 'POST', + headers: { + 'DD-API-KEY': initConfiguration.clientToken, + 'DD-EVP-ORIGIN': 'electron', + 'DD-EVP-ORIGIN-VERSION': '1.0.0', + 'DD-REQUEST-ID': crypto.randomUUID(), + 'Content-Type': 'text/plain;charset=UTF-8', + }, + body: payload, + }) + .then(async (response) => { + console.log('>>>', response, await response.json()) + }) + .catch((error) => { + throw new Error(`Network error occurred: ${error.message}`) + }) + items.length = 0 }) + // const size = new Blob([JSON.stringify({ env: 'prod', spans: items.flat() })], { type: 'application/json' }) + // const bytes = (await size.bytes()).length + // + // const payload = new FormData() + // payload.set('env', 'prod') + // payload.set('spans', JSON.stringify(items.flat())) + // + // console.log('>>>', { env: 'prod', spans: items.flat() }) + // + // request.send({ + // data: payload, + // bytesCount: bytes, + // }) + // }) - return batch + return { + flushController, + add(message: Context): void { + flushController.notifyBeforeAddMessage(items.length) + items.push(message) + flushController.notifyAfterAddMessage(items.length) + }, + upsert(message: Context): void { + flushController.notifyBeforeAddMessage(items.length) + items.push(message) + flushController.notifyAfterAddMessage(items.length) + }, + stop(): void { + flushSubscription.unsubscribe() + }, + } } function createDdTraceAgent(onSpanObservable: Observable) { @@ -170,11 +244,18 @@ function createDdTraceAgent(onSpanObservable: Observable) { > for (const trace of decoded) { - for (const span of trace as any) { - if (!isSdkRequest(span)) { - console.log('span', span) - onSpanObservable.notify(span) - } + const filteredTrace = trace + .filter((span) => !isSdkRequest(span)) + .map((span) => ({ + // rewrite id + ...span, + trace_id: Number(span.trace_id)?.toString(16), + span_id: Number(span.span_id)?.toString(16), + parent_id: Number(span.parent_id)?.toString(16), + })) + + if (filteredTrace.length > 0) { + onSpanObservable.notify(filteredTrace) } } }) @@ -324,25 +405,27 @@ function startMainProcessTracking( } function startConvertSpanToRumEvent( - onSpanObservable: Observable, + onSpanObservable: Observable, onRumEventObservable: Observable ) { - onSpanObservable.subscribe((span) => { - if (span.error) { - const rumError: Partial = { - type: RumEventType.ERROR, - date: span.start / 1e6, - error: { - id: generateUUID(), - message: span.meta['error.message'], - stack: span.meta['error.stack'], - type: span.meta['error.type'], - source: 'source', - handling: ErrorHandling.UNHANDLED, - }, + onSpanObservable.subscribe((trace) => { + trace.forEach((span) => { + if (span.error) { + const rumError: Partial = { + type: RumEventType.ERROR, + date: span.start / 1e6, + error: { + id: generateUUID(), + message: span.meta['error.message'], + stack: span.meta['error.stack'], + type: span.meta['error.type'], + source: 'source', + handling: ErrorHandling.UNHANDLED, + }, + } + onRumEventObservable.notify({ event: rumError as RumErrorEvent, source: 'main-process' }) } - onRumEventObservable.notify({ event: rumError as RumErrorEvent, source: 'main-process' }) - } + }) }) } diff --git a/scripts/lib/computeBundleSize.ts b/scripts/lib/computeBundleSize.ts index 407bbb8939..f0efa8c0a5 100644 --- a/scripts/lib/computeBundleSize.ts +++ b/scripts/lib/computeBundleSize.ts @@ -2,7 +2,7 @@ import path from 'node:path' import fs from 'node:fs' import zlib from 'node:zlib' -const packages = ['rum', 'logs', 'flagging', 'rum-slim', 'worker'] as const +const packages = ['rum', 'logs', 'flagging', 'rum-slim', 'worker', 'electron'] as const interface BundleSize { uncompressed: number diff --git a/yarn.lock b/yarn.lock index a2509ac1aa..5e1fb9e287 100644 --- a/yarn.lock +++ b/yarn.lock @@ -376,9 +376,11 @@ __metadata: "@datadog/browser-core": "npm:6.23.0" "@datadog/browser-rum-core": "npm:6.23.0" "@msgpack/msgpack": "npm:3.1.2" + "@openfeature/core": "npm:1.9.1" "@types/pako": "npm:2.0.4" dd-trace: "npm:^5.76.0" electron: "npm:39" + graphql: "npm:16.12.0" pako: "npm:2.1.0" peerDependencies: "@datadog/browser-logs": 6.23.0 @@ -1933,6 +1935,13 @@ __metadata: languageName: node linkType: hard +"@openfeature/core@npm:1.9.1": + version: 1.9.1 + resolution: "@openfeature/core@npm:1.9.1" + checksum: 10c0/983c651484621e6e5a3b4bf83fce5398a1adc2ace6162ff5a13a8eaf6d285b7c6b15f5c0a477ece9010ca88b28799985d810047ea0c18324d7a51ac4d04e18d6 + languageName: node + linkType: hard + "@openfeature/server-sdk@npm:~1.18.0": version: 1.18.0 resolution: "@openfeature/server-sdk@npm:1.18.0" @@ -7574,6 +7583,13 @@ __metadata: languageName: node linkType: hard +"graphql@npm:16.12.0": + version: 16.12.0 + resolution: "graphql@npm:16.12.0" + checksum: 10c0/b6fffa4e8a4e4a9933ebe85e7470b346dbf49050c1a482fac5e03e4a1a7bed2ecd3a4c97e29f04457af929464bc5e4f2aac991090c2f320111eef26e902a5c75 + languageName: node + linkType: hard + "handle-thing@npm:^2.0.0": version: 2.0.1 resolution: "handle-thing@npm:2.0.1" From 16787503efeafddab550e2bac2d06983baa69389 Mon Sep 17 00:00:00 2001 From: Adrian de la Rosa Date: Fri, 14 Nov 2025 12:23:51 +0100 Subject: [PATCH 19/58] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20put=20back=20batchin?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/electron/src/entries/main.ts | 115 +++++--------------------- 1 file changed, 22 insertions(+), 93 deletions(-) diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 66f0ea1217..a3a5950918 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -6,7 +6,7 @@ * - [x] Transport layer (for the bridge from webview, from dd-trace) * - [x] handle rum events * - [ ] handle routing for other type of events - * - [ ] handle dd-trace events (forwards APM spans to trace intake) + * - [x] handle dd-trace events (forwards APM spans to trace intake) * - [x] setup bridge client with ipc from webviews (renderer processes) * - [x] use `exposeInMainWorld` to setup the bridge function that will setup the ipc to the main process */ @@ -14,10 +14,6 @@ import crypto from 'node:crypto' import { createServer } from 'node:http' import type { RawError, PageMayExitEvent, Encoder, Context, InitConfiguration } from '@datadog/browser-core' import { - computeRawError, - clocksNow, - NonErrorPrefix, - dateNow, elapsed, timeStampNow, Observable, @@ -41,7 +37,6 @@ import { decode } from '@msgpack/msgpack' import type { TrackType } from '@datadog/browser-core/cjs/domain/configuration' import { createEndpointBuilder } from '@datadog/browser-core/cjs/domain/configuration' import type { RumViewEvent, RumErrorEvent } from '@datadog/browser-rum' -import { createSpanIdentifier, createTraceIdentifier } from '@datadog/browser-rum-core/src/domain/tracing/identifier' import tracer from '../domain/tracer' import type { Hooks } from '../hooks' import { createIpcMain } from '../domain/main/ipcMain' @@ -65,7 +60,7 @@ function makeDatadogElectron() { const pageMayExitObservable = new Observable() const sessionExpireObservable = new Observable() const onRumEventObservable = new Observable() - const onSpanObservable = new Observable() + const onTraceObservable = new Observable() const hooks = createHooks() const createEncoder = () => createIdentityEncoder() @@ -82,7 +77,7 @@ function makeDatadogElectron() { startRumEventAssembleAndSend(configuration, onRumEventObservable, rumBatch, hooks) const onActivityObservable = startActivityTracking(onRumEventObservable) startMainProcessTracking(hooks, onRumEventObservable, onActivityObservable) - startConvertSpanToRumEvent(onSpanObservable, onRumEventObservable) + startConvertSpanToRumEvent(onTraceObservable, onRumEventObservable) const spanBatch = startElectronSpanBatch( initConfiguration, @@ -91,13 +86,14 @@ function makeDatadogElectron() { console.error('Error reporting to Datadog') }, pageMayExitObservable, - sessionExpireObservable + sessionExpireObservable, + createEncoder ) - onSpanObservable.subscribe((span) => { - spanBatch.add(span) + onTraceObservable.subscribe((trace) => { + spanBatch.add({ env: 'prod', spans: trace }) }) setupMainBridge(onRumEventObservable) - createDdTraceAgent(onSpanObservable) + createDdTraceAgent(onTraceObservable) setInterval(() => { pageMayExitObservable.notify({ reason: 'page_hide' }) @@ -139,92 +135,25 @@ export function startElectronSpanBatch( configuration: RumConfiguration, reportError: (error: RawError) => void, pageMayExitObservable: Observable, - sessionExpireObservable: Observable + sessionExpireObservable: Observable, + createEncoder: (streamId: DeflateEncoderStreamId) => Encoder ) { - const flushController = createFlushController({ - messagesLimit: configuration.batchMessagesLimit, - bytesLimit: configuration.batchBytesLimit, - durationLimit: configuration.flushTimeout, - pageMayExitObservable, - sessionExpireObservable, - }) - const endpoints = [createEndpointBuilder(initConfiguration, 'spans' as TrackType)] - const request = createHttpRequest(endpoints, configuration.batchBytesLimit, reportError) - - const items: any[] = [] - - // eslint-disable-next-line @typescript-eslint/no-misused-promises - const flushSubscription = flushController.flushObservable.subscribe(async () => { - if (items.length === 0) { - return - } - const payload = items - .map((trace: any[]) => - JSON.stringify({ - env: 'prod', - spans: trace.map((span) => ({ - ...span, - trace_id: span.trace_id?.toString(16), - span_id: span.span_id?.toString(16), - parent_id: span.parent_id?.toString(16), - })), - }) - ) - .join('\n') - - console.log('>>>', { payload }) - fetch('https://browser-intake-datadoghq.com/api/v2/spans', { - method: 'POST', - headers: { - 'DD-API-KEY': initConfiguration.clientToken, - 'DD-EVP-ORIGIN': 'electron', - 'DD-EVP-ORIGIN-VERSION': '1.0.0', - 'DD-REQUEST-ID': crypto.randomUUID(), - 'Content-Type': 'text/plain;charset=UTF-8', - }, - body: payload, - }) - .then(async (response) => { - console.log('>>>', response, await response.json()) - }) - .catch((error) => { - throw new Error(`Network error occurred: ${error.message}`) - }) - items.length = 0 + const batch = createBatch({ + encoder: createEncoder(DeflateEncoderStreamId.RUM), + request: createHttpRequest(endpoints, configuration.batchBytesLimit, reportError), + flushController: createFlushController({ + messagesLimit: configuration.batchMessagesLimit, + bytesLimit: configuration.batchBytesLimit, + durationLimit: configuration.flushTimeout, + pageMayExitObservable, + sessionExpireObservable, + }), + messageBytesLimit: configuration.messageBytesLimit, }) - // const size = new Blob([JSON.stringify({ env: 'prod', spans: items.flat() })], { type: 'application/json' }) - // const bytes = (await size.bytes()).length - // - // const payload = new FormData() - // payload.set('env', 'prod') - // payload.set('spans', JSON.stringify(items.flat())) - // - // console.log('>>>', { env: 'prod', spans: items.flat() }) - // - // request.send({ - // data: payload, - // bytesCount: bytes, - // }) - // }) - return { - flushController, - add(message: Context): void { - flushController.notifyBeforeAddMessage(items.length) - items.push(message) - flushController.notifyAfterAddMessage(items.length) - }, - upsert(message: Context): void { - flushController.notifyBeforeAddMessage(items.length) - items.push(message) - flushController.notifyAfterAddMessage(items.length) - }, - stop(): void { - flushSubscription.unsubscribe() - }, - } + return batch } function createDdTraceAgent(onSpanObservable: Observable) { From a5144527de60e5211b089cc5cf5c063589bb0a43 Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Fri, 14 Nov 2025 13:00:50 +0100 Subject: [PATCH 20/58] refactor: better ipc span name --- packages/electron/src/domain/main/ipcMain.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/electron/src/domain/main/ipcMain.ts b/packages/electron/src/domain/main/ipcMain.ts index edf3078209..3603f8beee 100644 --- a/packages/electron/src/domain/main/ipcMain.ts +++ b/packages/electron/src/domain/main/ipcMain.ts @@ -3,7 +3,7 @@ import type { IpcMain } from 'electron' import tracer from '../tracer' import type { DatadogCarrier } from '../trace' -const SPAN_NAME_PREFIX = 'electron.main.ipc' +const SPAN_NAME_PREFIX = 'ipcMain' const isDatadogCarrier = (arg: any): arg is DatadogCarrier => typeof arg === 'object' && arg?.__dd_carrier === true @@ -25,11 +25,10 @@ export function createIpcMain(): IpcMain { } function withDatadogCarrier R, R>(name: string, fn: T): (...args: Parameters) => R { - const spanName = `${SPAN_NAME_PREFIX}.${name}` - return (...args: Parameters) => { const channel = args[0] const listener = args[1] + const spanName = `${SPAN_NAME_PREFIX}.${name}.${channel}` return fn(channel, (...args: Parameters) => { const lastArg = args[args.length - 1] From 08d9503c9043ebc868275abfb1acf44cbd785abc Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Fri, 14 Nov 2025 13:59:33 +0100 Subject: [PATCH 21/58] attach RUM context to spans --- packages/electron/src/entries/main.ts | 43 +++++++++++++++++++-------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index a3a5950918..afc8d90d02 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -29,8 +29,8 @@ import { ErrorHandling, generateUUID, } from '@datadog/browser-core' -import { createHooks, RumEventType } from '@datadog/browser-rum-core' import type { RumConfiguration, RumInitConfiguration } from '@datadog/browser-rum-core' +import { createHooks, RumEventType } from '@datadog/browser-rum-core' import { validateAndBuildRumConfiguration } from '@datadog/browser-rum-core/cjs/domain/configuration' import type { Batch } from '@datadog/browser-core/cjs/transport/batch' import { decode } from '@msgpack/msgpack' @@ -74,9 +74,9 @@ function makeDatadogElectron() { createEncoder ) - startRumEventAssembleAndSend(configuration, onRumEventObservable, rumBatch, hooks) + startRumEventAssembleAndSend(onRumEventObservable, rumBatch, hooks) const onActivityObservable = startActivityTracking(onRumEventObservable) - startMainProcessTracking(hooks, onRumEventObservable, onActivityObservable) + startMainProcessTracking(hooks, configuration, onRumEventObservable, onActivityObservable) startConvertSpanToRumEvent(onTraceObservable, onRumEventObservable) const spanBatch = startElectronSpanBatch( @@ -93,7 +93,7 @@ function makeDatadogElectron() { spanBatch.add({ env: 'prod', spans: trace }) }) setupMainBridge(onRumEventObservable) - createDdTraceAgent(onTraceObservable) + createDdTraceAgent(onTraceObservable, hooks) setInterval(() => { pageMayExitObservable.notify({ reason: 'page_hide' }) @@ -156,7 +156,7 @@ export function startElectronSpanBatch( return batch } -function createDdTraceAgent(onSpanObservable: Observable) { +function createDdTraceAgent(onTraceObservable: Observable, hooks: Hooks) { const server = createServer() server.on('request', (req, res) => { @@ -172,6 +172,14 @@ function createDdTraceAgent(onSpanObservable: Observable) { Array<{ name: string; type: string; meta: { [key: string]: unknown }; [key: string]: unknown }> > + const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, { + eventType: 'span' as any, + })! + + if (defaultRumEventAttributes === DISCARDED) { + return + } + for (const trace of decoded) { const filteredTrace = trace .filter((span) => !isSdkRequest(span)) @@ -181,10 +189,16 @@ function createDdTraceAgent(onSpanObservable: Observable) { trace_id: Number(span.trace_id)?.toString(16), span_id: Number(span.span_id)?.toString(16), parent_id: Number(span.parent_id)?.toString(16), + meta: { + ...span.meta, + '_dd.application.id': defaultRumEventAttributes.application!.id, + '_dd.session.id': defaultRumEventAttributes.session!.id, + '_dd.view.id': defaultRumEventAttributes.view!.id, + }, })) if (filteredTrace.length > 0) { - onSpanObservable.notify(filteredTrace) + onTraceObservable.notify(filteredTrace) } } }) @@ -229,7 +243,6 @@ function isSdkRequest(span: any) { } function startRumEventAssembleAndSend( - configuration: RumConfiguration, onRumEventObservable: Observable, rumBatch: Batch, hooks: Hooks @@ -239,19 +252,19 @@ function startRumEventAssembleAndSend( eventType: event.type, })! - if (defaultRumEventAttributes === DISCARDED || defaultRumEventAttributes.session?.id === undefined) { + if (defaultRumEventAttributes === DISCARDED) { return } const commonContext = source === 'renderer' ? { - session: { id: defaultRumEventAttributes.session.id }, - application: { id: configuration.applicationId }, + session: { id: defaultRumEventAttributes.session!.id }, + application: { id: defaultRumEventAttributes.application!.id }, } : combine(defaultRumEventAttributes, { // TODO source electron source: 'browser' as const, - application: { id: configuration.applicationId }, + application: { id: defaultRumEventAttributes.application!.id }, session: { type: 'user' as const, }, @@ -272,6 +285,7 @@ function startRumEventAssembleAndSend( function startMainProcessTracking( hooks: Hooks, + configuration: RumConfiguration, onRumEventObservable: Observable, onActivityObservable: Observable ) { @@ -281,6 +295,9 @@ function startMainProcessTracking( } hooks.register(HookNames.Assemble, ({ eventType }) => ({ type: eventType, + application: { + id: configuration.applicationId, + }, session: { id: mainProcessContext.sessionId, }, @@ -334,10 +351,10 @@ function startMainProcessTracking( } function startConvertSpanToRumEvent( - onSpanObservable: Observable, + onTraceObservable: Observable, onRumEventObservable: Observable ) { - onSpanObservable.subscribe((trace) => { + onTraceObservable.subscribe((trace) => { trace.forEach((span) => { if (span.error) { const rumError: Partial = { From 200a387b276d2625db92bd6a644516039e23ffa6 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Fri, 14 Nov 2025 14:56:05 +0100 Subject: [PATCH 22/58] extract rum files --- packages/electron/src/domain/main/bridge.ts | 2 +- packages/electron/src/domain/rum/activity.ts | 17 ++ packages/electron/src/domain/rum/assembly.ts | 47 +++++ .../electron/src/domain/rum/convertSpans.ts | 31 ++++ .../electron/src/domain/{ => rum}/events.ts | 0 .../src/domain/rum/mainProcessTracking.ts | 74 ++++++++ packages/electron/src/domain/trace.ts | 3 + packages/electron/src/entries/main.ts | 172 +----------------- 8 files changed, 182 insertions(+), 164 deletions(-) create mode 100644 packages/electron/src/domain/rum/activity.ts create mode 100644 packages/electron/src/domain/rum/assembly.ts create mode 100644 packages/electron/src/domain/rum/convertSpans.ts rename packages/electron/src/domain/{ => rum}/events.ts (100%) create mode 100644 packages/electron/src/domain/rum/mainProcessTracking.ts diff --git a/packages/electron/src/domain/main/bridge.ts b/packages/electron/src/domain/main/bridge.ts index 2bf22cf0c3..fd4ec4c351 100644 --- a/packages/electron/src/domain/main/bridge.ts +++ b/packages/electron/src/domain/main/bridge.ts @@ -1,7 +1,7 @@ import type { Observable } from '@datadog/browser-core' import type { RumEvent } from '@datadog/browser-rum-core' import { ipcMain } from 'electron' -import type { CollectedRumEvent } from '../events' +import type { CollectedRumEvent } from '../rum/events' interface BridgeEvent { eventType: 'rum' diff --git a/packages/electron/src/domain/rum/activity.ts b/packages/electron/src/domain/rum/activity.ts new file mode 100644 index 0000000000..b555c65dcf --- /dev/null +++ b/packages/electron/src/domain/rum/activity.ts @@ -0,0 +1,17 @@ +import { Observable } from '@datadog/browser-core' +import { RumEventType } from '@datadog/browser-rum-core' +import type { CollectedRumEvent } from './events' + +export function startActivityTracking(onRumEventObservable: Observable) { + const onActivityObservable = new Observable() + const alreadySeenViewIds = new Set() + onRumEventObservable.subscribe(({ event }) => { + if (event.type === RumEventType.VIEW && !alreadySeenViewIds.has(event.view.id)) { + alreadySeenViewIds.add(event.view.id) + onActivityObservable.notify() + } else if (event.type === RumEventType.ACTION && event.action.type === 'click') { + onActivityObservable.notify() + } + }) + return onActivityObservable +} diff --git a/packages/electron/src/domain/rum/assembly.ts b/packages/electron/src/domain/rum/assembly.ts new file mode 100644 index 0000000000..0ce1c56019 --- /dev/null +++ b/packages/electron/src/domain/rum/assembly.ts @@ -0,0 +1,47 @@ +import type { Observable, Context } from '@datadog/browser-core' +import { HookNames, DISCARDED, combine } from '@datadog/browser-core' +import { RumEventType } from '@datadog/browser-rum-core' +import type { Hooks } from '../../hooks' +import type { CollectedRumEvent } from './events' +import type { Batch } from '@datadog/browser-core/cjs/transport/batch' + +export function startRumEventAssembleAndSend( + onRumEventObservable: Observable, + rumBatch: Batch, + hooks: Hooks +) { + onRumEventObservable.subscribe(({ event, source }) => { + const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, { + eventType: event.type, + })! + + if (defaultRumEventAttributes === DISCARDED) { + return + } + const commonContext = + source === 'renderer' + ? { + session: { id: defaultRumEventAttributes.session!.id }, + application: { id: defaultRumEventAttributes.application!.id }, + } + : combine(defaultRumEventAttributes, { + // TODO source electron + source: 'browser' as const, + application: { id: defaultRumEventAttributes.application!.id }, + session: { + type: 'user' as const, + }, + _dd: { + format_version: 2 as const, + }, + }) + + const serverRumEvent = combine(event, commonContext) + + if (serverRumEvent.type === RumEventType.VIEW) { + rumBatch.upsert(serverRumEvent as unknown as Context, serverRumEvent.view.id) + } else { + rumBatch.add(serverRumEvent as unknown as Context) + } + }) +} diff --git a/packages/electron/src/domain/rum/convertSpans.ts b/packages/electron/src/domain/rum/convertSpans.ts new file mode 100644 index 0000000000..2c0e561f31 --- /dev/null +++ b/packages/electron/src/domain/rum/convertSpans.ts @@ -0,0 +1,31 @@ +import type { Observable } from '@datadog/browser-core' +import { generateUUID, ErrorHandling } from '@datadog/browser-core' +import type { RumErrorEvent } from '@datadog/browser-rum-core' +import { RumEventType } from '@datadog/browser-rum-core' +import type { Trace } from '../trace' +import type { CollectedRumEvent } from './events' + +export function startConvertSpanToRumEvent( + onTraceObservable: Observable, + onRumEventObservable: Observable +) { + onTraceObservable.subscribe((trace) => { + trace.forEach((span) => { + if (span.error) { + const rumError: Partial = { + type: RumEventType.ERROR, + date: span.start / 1e6, + error: { + id: generateUUID(), + message: span.meta['error.message'], + stack: span.meta['error.stack'], + type: span.meta['error.type'], + source: 'source', + handling: ErrorHandling.UNHANDLED, + }, + } + onRumEventObservable.notify({ event: rumError as RumErrorEvent, source: 'main-process' }) + } + }) + }) +} diff --git a/packages/electron/src/domain/events.ts b/packages/electron/src/domain/rum/events.ts similarity index 100% rename from packages/electron/src/domain/events.ts rename to packages/electron/src/domain/rum/events.ts diff --git a/packages/electron/src/domain/rum/mainProcessTracking.ts b/packages/electron/src/domain/rum/mainProcessTracking.ts new file mode 100644 index 0000000000..6a0aaae38b --- /dev/null +++ b/packages/electron/src/domain/rum/mainProcessTracking.ts @@ -0,0 +1,74 @@ +import crypto from 'node:crypto' +import type { RumConfiguration, RumViewEvent } from '@datadog/browser-rum-core' +import { RumEventType } from '@datadog/browser-rum-core' +import type { Observable } from '@datadog/browser-core' +import { HookNames, timeStampNow, combine, toServerDuration, elapsed } from '@datadog/browser-core' +import type { Hooks } from '../../hooks' +import type { CollectedRumEvent } from './events' + +export function startMainProcessTracking( + hooks: Hooks, + configuration: RumConfiguration, + onRumEventObservable: Observable, + onActivityObservable: Observable +) { + const mainProcessContext = { + sessionId: crypto.randomUUID(), + viewId: crypto.randomUUID(), + } + hooks.register(HookNames.Assemble, ({ eventType }) => ({ + type: eventType, + application: { + id: configuration.applicationId, + }, + session: { + id: mainProcessContext.sessionId, + }, + view: { + id: mainProcessContext.viewId, + // TODO get customer package name + url: 'com/datadog/application-launch/view', + }, + })) + console.log('sessionId', mainProcessContext.sessionId) + const applicationStart = timeStampNow() + let applicationLaunch = { + type: RumEventType.VIEW, + date: applicationStart as number, + view: { + id: mainProcessContext.viewId, + is_active: true, + name: 'ApplicationLaunch', + time_spent: 0, + // TODO update counters + action: { + count: 0, + }, + resource: { + count: 0, + }, + error: { + count: 0, + }, + }, + _dd: { + document_version: 1, + }, + } as RumViewEvent + + onRumEventObservable.notify({ event: applicationLaunch, source: 'main-process' }) + + onActivityObservable.subscribe(() => { + applicationLaunch = combine(applicationLaunch, { + view: { + time_spent: toServerDuration(elapsed(applicationStart, timeStampNow())), + }, + _dd: { + document_version: applicationLaunch._dd.document_version + 1, + }, + }) + onRumEventObservable.notify({ event: applicationLaunch, source: 'main-process' }) + }) + // TODO session expiration / renewal + // TODO useragent +} diff --git a/packages/electron/src/domain/trace.ts b/packages/electron/src/domain/trace.ts index 933e6efbc9..9a5bbd7e66 100644 --- a/packages/electron/src/domain/trace.ts +++ b/packages/electron/src/domain/trace.ts @@ -5,3 +5,6 @@ export interface DatadogCarrier { 'x-datadog-sampling-priority': string 'x-datadog-trace-id': string } + +export type Span = any +export type Trace = Span[] diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index afc8d90d02..7ce9cee1f2 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -10,41 +10,34 @@ * - [x] setup bridge client with ipc from webviews (renderer processes) * - [x] use `exposeInMainWorld` to setup the bridge function that will setup the ipc to the main process */ -import crypto from 'node:crypto' import { createServer } from 'node:http' -import type { RawError, PageMayExitEvent, Encoder, Context, InitConfiguration } from '@datadog/browser-core' +import type { RawError, PageMayExitEvent, Encoder, InitConfiguration } from '@datadog/browser-core' import { - elapsed, - timeStampNow, Observable, DeflateEncoderStreamId, createBatch, createHttpRequest, createFlushController, createIdentityEncoder, - combine, - toServerDuration, HookNames, DISCARDED, - ErrorHandling, - generateUUID, } from '@datadog/browser-core' import type { RumConfiguration, RumInitConfiguration } from '@datadog/browser-rum-core' -import { createHooks, RumEventType } from '@datadog/browser-rum-core' +import { createHooks } from '@datadog/browser-rum-core' import { validateAndBuildRumConfiguration } from '@datadog/browser-rum-core/cjs/domain/configuration' -import type { Batch } from '@datadog/browser-core/cjs/transport/batch' import { decode } from '@msgpack/msgpack' import type { TrackType } from '@datadog/browser-core/cjs/domain/configuration' import { createEndpointBuilder } from '@datadog/browser-core/cjs/domain/configuration' -import type { RumViewEvent, RumErrorEvent } from '@datadog/browser-rum' import tracer from '../domain/tracer' import type { Hooks } from '../hooks' import { createIpcMain } from '../domain/main/ipcMain' -import type { CollectedRumEvent } from '../domain/events' +import type { CollectedRumEvent } from '../domain/rum/events' import { setupMainBridge } from '../domain/main/bridge' - -type Span = any -type Trace = Span[] +import { startActivityTracking } from '../domain/rum/activity' +import { startRumEventAssembleAndSend } from '../domain/rum/assembly' +import { startMainProcessTracking } from '../domain/rum/mainProcessTracking' +import { startConvertSpanToRumEvent } from '../domain/rum/convertSpans' +import type { Trace } from '../domain/trace' function makeDatadogElectron() { return { @@ -60,7 +53,7 @@ function makeDatadogElectron() { const pageMayExitObservable = new Observable() const sessionExpireObservable = new Observable() const onRumEventObservable = new Observable() - const onTraceObservable = new Observable() + const onTraceObservable = new Observable() const hooks = createHooks() const createEncoder = () => createIdentityEncoder() @@ -241,150 +234,3 @@ function isSdkRequest(span: any) { (span.resource as string).startsWith('browser-intake-datadoghq.com') ) } - -function startRumEventAssembleAndSend( - onRumEventObservable: Observable, - rumBatch: Batch, - hooks: Hooks -) { - onRumEventObservable.subscribe(({ event, source }) => { - const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, { - eventType: event.type, - })! - - if (defaultRumEventAttributes === DISCARDED) { - return - } - const commonContext = - source === 'renderer' - ? { - session: { id: defaultRumEventAttributes.session!.id }, - application: { id: defaultRumEventAttributes.application!.id }, - } - : combine(defaultRumEventAttributes, { - // TODO source electron - source: 'browser' as const, - application: { id: defaultRumEventAttributes.application!.id }, - session: { - type: 'user' as const, - }, - _dd: { - format_version: 2 as const, - }, - }) - - const serverRumEvent = combine(event, commonContext) - - if (serverRumEvent.type === RumEventType.VIEW) { - rumBatch.upsert(serverRumEvent as unknown as Context, serverRumEvent.view.id) - } else { - rumBatch.add(serverRumEvent as unknown as Context) - } - }) -} - -function startMainProcessTracking( - hooks: Hooks, - configuration: RumConfiguration, - onRumEventObservable: Observable, - onActivityObservable: Observable -) { - const mainProcessContext = { - sessionId: crypto.randomUUID(), - viewId: crypto.randomUUID(), - } - hooks.register(HookNames.Assemble, ({ eventType }) => ({ - type: eventType, - application: { - id: configuration.applicationId, - }, - session: { - id: mainProcessContext.sessionId, - }, - view: { - id: mainProcessContext.viewId, - // TODO get customer package name - url: 'com/datadog/application-launch/view', - }, - })) - console.log('sessionId', mainProcessContext.sessionId) - const applicationStart = timeStampNow() - let applicationLaunch = { - type: RumEventType.VIEW, - date: applicationStart as number, - view: { - id: mainProcessContext.viewId, - is_active: true, - name: 'ApplicationLaunch', - time_spent: 0, - // TODO update counters - action: { - count: 0, - }, - resource: { - count: 0, - }, - error: { - count: 0, - }, - }, - _dd: { - document_version: 1, - }, - } as RumViewEvent - - onRumEventObservable.notify({ event: applicationLaunch, source: 'main-process' }) - - onActivityObservable.subscribe(() => { - applicationLaunch = combine(applicationLaunch, { - view: { - time_spent: toServerDuration(elapsed(applicationStart, timeStampNow())), - }, - _dd: { - document_version: applicationLaunch._dd.document_version + 1, - }, - }) - onRumEventObservable.notify({ event: applicationLaunch, source: 'main-process' }) - }) - // TODO session expiration / renewal - // TODO useragent -} - -function startConvertSpanToRumEvent( - onTraceObservable: Observable, - onRumEventObservable: Observable -) { - onTraceObservable.subscribe((trace) => { - trace.forEach((span) => { - if (span.error) { - const rumError: Partial = { - type: RumEventType.ERROR, - date: span.start / 1e6, - error: { - id: generateUUID(), - message: span.meta['error.message'], - stack: span.meta['error.stack'], - type: span.meta['error.type'], - source: 'source', - handling: ErrorHandling.UNHANDLED, - }, - } - onRumEventObservable.notify({ event: rumError as RumErrorEvent, source: 'main-process' }) - } - }) - }) -} - -function startActivityTracking(onRumEventObservable: Observable) { - const onActivityObservable = new Observable() - const alreadySeenViewIds = new Set() - onRumEventObservable.subscribe(({ event }) => { - if (event.type === RumEventType.VIEW && !alreadySeenViewIds.has(event.view.id)) { - alreadySeenViewIds.add(event.view.id) - onActivityObservable.notify() - } else if (event.type === RumEventType.ACTION && event.action.type === 'click') { - onActivityObservable.notify() - } - }) - return onActivityObservable -} From 8562721dca3dc5ee1e750912ba5a3d9a39936bf2 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Fri, 14 Nov 2025 15:04:54 +0100 Subject: [PATCH 23/58] extract trace directory --- packages/electron/src/domain/main/ipcMain.ts | 6 +- .../src/domain/renderer/ipcRenderer.ts | 4 +- .../electron/src/domain/rum/convertSpans.ts | 2 +- .../electron/src/domain/{ => trace}/trace.ts | 0 .../electron/src/domain/trace/traceAgent.ts | 93 ++++++++++++++++++ .../electron/src/domain/{ => trace}/tracer.ts | 0 packages/electron/src/entries/main.ts | 96 +------------------ 7 files changed, 102 insertions(+), 99 deletions(-) rename packages/electron/src/domain/{ => trace}/trace.ts (100%) create mode 100644 packages/electron/src/domain/trace/traceAgent.ts rename packages/electron/src/domain/{ => trace}/tracer.ts (100%) diff --git a/packages/electron/src/domain/main/ipcMain.ts b/packages/electron/src/domain/main/ipcMain.ts index 3603f8beee..5c8fa76891 100644 --- a/packages/electron/src/domain/main/ipcMain.ts +++ b/packages/electron/src/domain/main/ipcMain.ts @@ -1,7 +1,7 @@ -import { ipcMain } from 'electron' import type { IpcMain } from 'electron' -import tracer from '../tracer' -import type { DatadogCarrier } from '../trace' +import { ipcMain } from 'electron' +import tracer from '../trace/tracer' +import type { DatadogCarrier } from '../trace/trace' const SPAN_NAME_PREFIX = 'ipcMain' diff --git a/packages/electron/src/domain/renderer/ipcRenderer.ts b/packages/electron/src/domain/renderer/ipcRenderer.ts index 44b348aba7..ca9423afba 100644 --- a/packages/electron/src/domain/renderer/ipcRenderer.ts +++ b/packages/electron/src/domain/renderer/ipcRenderer.ts @@ -1,7 +1,7 @@ import type { IpcRenderer } from 'electron' -import { createSpanIdentifier, createTraceIdentifier } from '@datadog/browser-rum-core/src/domain/tracing/identifier' import { ipcRenderer } from 'electron' -import type { DatadogCarrier } from '../trace' +import { createSpanIdentifier, createTraceIdentifier } from '@datadog/browser-rum-core/src/domain/tracing/identifier' +import type { DatadogCarrier } from '../trace/trace' function createDatadogCarrier(): DatadogCarrier { const spanId = createSpanIdentifier().toString() diff --git a/packages/electron/src/domain/rum/convertSpans.ts b/packages/electron/src/domain/rum/convertSpans.ts index 2c0e561f31..7270d61d16 100644 --- a/packages/electron/src/domain/rum/convertSpans.ts +++ b/packages/electron/src/domain/rum/convertSpans.ts @@ -2,7 +2,7 @@ import type { Observable } from '@datadog/browser-core' import { generateUUID, ErrorHandling } from '@datadog/browser-core' import type { RumErrorEvent } from '@datadog/browser-rum-core' import { RumEventType } from '@datadog/browser-rum-core' -import type { Trace } from '../trace' +import type { Trace } from '../trace/trace' import type { CollectedRumEvent } from './events' export function startConvertSpanToRumEvent( diff --git a/packages/electron/src/domain/trace.ts b/packages/electron/src/domain/trace/trace.ts similarity index 100% rename from packages/electron/src/domain/trace.ts rename to packages/electron/src/domain/trace/trace.ts diff --git a/packages/electron/src/domain/trace/traceAgent.ts b/packages/electron/src/domain/trace/traceAgent.ts new file mode 100644 index 0000000000..7f76548762 --- /dev/null +++ b/packages/electron/src/domain/trace/traceAgent.ts @@ -0,0 +1,93 @@ +import { createServer } from 'node:http' +import type { Observable } from '@datadog/browser-core' +import { HookNames, DISCARDED } from '@datadog/browser-core' +import { decode } from '@msgpack/msgpack' +import type { Hooks } from '../../hooks' +import type { Trace } from './trace' +import tracer from './tracer' + +export function createDdTraceAgent(onTraceObservable: Observable, hooks: Hooks) { + const server = createServer() + + server.on('request', (req, res) => { + // Collect binary data chunks + const chunks: Buffer[] = [] + req.on('data', (chunk: Buffer) => { + chunks.push(chunk) + }) + req.on('end', () => { + const buffer = Buffer.concat(chunks) + + const decoded = decode(buffer) as Array< + Array<{ name: string; type: string; meta: { [key: string]: unknown }; [key: string]: unknown }> + > + + const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, { + eventType: 'span' as any, + })! + + if (defaultRumEventAttributes === DISCARDED) { + return + } + + for (const trace of decoded) { + const filteredTrace = trace + .filter((span) => !isSdkRequest(span)) + .map((span) => ({ + // rewrite id + ...span, + trace_id: Number(span.trace_id)?.toString(16), + span_id: Number(span.span_id)?.toString(16), + parent_id: Number(span.parent_id)?.toString(16), + meta: { + ...span.meta, + '_dd.application.id': defaultRumEventAttributes.application!.id, + '_dd.session.id': defaultRumEventAttributes.session!.id, + '_dd.view.id': defaultRumEventAttributes.view!.id, + }, + })) + + if (filteredTrace.length > 0) { + onTraceObservable.notify(filteredTrace) + } + } + }) + + // Respond with the agent API format that dd-trace expects + res.writeHead(200, { 'Content-Type': 'application/json' }) + res.end( + JSON.stringify({ + rate_by_service: { + 'service:dd-trace,env:prod': 1, + }, + }) + ) + }) + + server.listen(0, () => { + const addressInfo = server.address() + if (!addressInfo) { + throw new Error('Failed to get server address') + } + + if (typeof addressInfo === 'string') { + throw new Error(`Address is a string: ${addressInfo}`) + } + + const { port } = addressInfo + const url = `http://127.0.0.1:${port}` + + // console.log('agents url', url) + tracer.setUrl(url) + }) +} + +function isSdkRequest(span: any) { + const spanRequestUrl = span.meta['http.url'] as string | undefined + return ( + (spanRequestUrl && + (spanRequestUrl.startsWith('http://127.0.0.1') || + spanRequestUrl.startsWith('https://browser-intake-datadoghq.com/'))) || + (span.resource as string).startsWith('browser-intake-datadoghq.com') + ) +} diff --git a/packages/electron/src/domain/tracer.ts b/packages/electron/src/domain/trace/tracer.ts similarity index 100% rename from packages/electron/src/domain/tracer.ts rename to packages/electron/src/domain/trace/tracer.ts diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 7ce9cee1f2..cb40d66c93 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -10,7 +10,6 @@ * - [x] setup bridge client with ipc from webviews (renderer processes) * - [x] use `exposeInMainWorld` to setup the bridge function that will setup the ipc to the main process */ -import { createServer } from 'node:http' import type { RawError, PageMayExitEvent, Encoder, InitConfiguration } from '@datadog/browser-core' import { Observable, @@ -19,17 +18,13 @@ import { createHttpRequest, createFlushController, createIdentityEncoder, - HookNames, - DISCARDED, } from '@datadog/browser-core' import type { RumConfiguration, RumInitConfiguration } from '@datadog/browser-rum-core' import { createHooks } from '@datadog/browser-rum-core' import { validateAndBuildRumConfiguration } from '@datadog/browser-rum-core/cjs/domain/configuration' -import { decode } from '@msgpack/msgpack' import type { TrackType } from '@datadog/browser-core/cjs/domain/configuration' import { createEndpointBuilder } from '@datadog/browser-core/cjs/domain/configuration' -import tracer from '../domain/tracer' -import type { Hooks } from '../hooks' +import tracer from '../domain/trace/tracer' import { createIpcMain } from '../domain/main/ipcMain' import type { CollectedRumEvent } from '../domain/rum/events' import { setupMainBridge } from '../domain/main/bridge' @@ -37,7 +32,8 @@ import { startActivityTracking } from '../domain/rum/activity' import { startRumEventAssembleAndSend } from '../domain/rum/assembly' import { startMainProcessTracking } from '../domain/rum/mainProcessTracking' import { startConvertSpanToRumEvent } from '../domain/rum/convertSpans' -import type { Trace } from '../domain/trace' +import type { Trace } from '../domain/trace/trace' +import { createDdTraceAgent } from '../domain/trace/traceAgent' function makeDatadogElectron() { return { @@ -148,89 +144,3 @@ export function startElectronSpanBatch( return batch } - -function createDdTraceAgent(onTraceObservable: Observable, hooks: Hooks) { - const server = createServer() - - server.on('request', (req, res) => { - // Collect binary data chunks - const chunks: Buffer[] = [] - req.on('data', (chunk: Buffer) => { - chunks.push(chunk) - }) - req.on('end', () => { - const buffer = Buffer.concat(chunks) - - const decoded = decode(buffer) as Array< - Array<{ name: string; type: string; meta: { [key: string]: unknown }; [key: string]: unknown }> - > - - const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, { - eventType: 'span' as any, - })! - - if (defaultRumEventAttributes === DISCARDED) { - return - } - - for (const trace of decoded) { - const filteredTrace = trace - .filter((span) => !isSdkRequest(span)) - .map((span) => ({ - // rewrite id - ...span, - trace_id: Number(span.trace_id)?.toString(16), - span_id: Number(span.span_id)?.toString(16), - parent_id: Number(span.parent_id)?.toString(16), - meta: { - ...span.meta, - '_dd.application.id': defaultRumEventAttributes.application!.id, - '_dd.session.id': defaultRumEventAttributes.session!.id, - '_dd.view.id': defaultRumEventAttributes.view!.id, - }, - })) - - if (filteredTrace.length > 0) { - onTraceObservable.notify(filteredTrace) - } - } - }) - - // Respond with the agent API format that dd-trace expects - res.writeHead(200, { 'Content-Type': 'application/json' }) - res.end( - JSON.stringify({ - rate_by_service: { - 'service:dd-trace,env:prod': 1, - }, - }) - ) - }) - - server.listen(0, () => { - const addressInfo = server.address() - if (!addressInfo) { - throw new Error('Failed to get server address') - } - - if (typeof addressInfo === 'string') { - throw new Error(`Address is a string: ${addressInfo}`) - } - - const { port } = addressInfo - const url = `http://127.0.0.1:${port}` - - // console.log('agents url', url) - tracer.setUrl(url) - }) -} - -function isSdkRequest(span: any) { - const spanRequestUrl = span.meta['http.url'] as string | undefined - return ( - (spanRequestUrl && - (spanRequestUrl.startsWith('http://127.0.0.1') || - spanRequestUrl.startsWith('https://browser-intake-datadoghq.com/'))) || - (span.resource as string).startsWith('browser-intake-datadoghq.com') - ) -} From dbaeeff1230903bac55d355ec7830ee44e6cabeb Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Fri, 14 Nov 2025 19:00:47 +0100 Subject: [PATCH 24/58] feat: add electron plugin for browser-rum --- packages/core/src/domain/resourceUtils.ts | 1 + packages/electron/plugin/package.json | 6 + packages/electron/src/domain/main/bridge.ts | 1 + packages/electron/src/domain/plugin/plugin.ts | 131 ++++++++++++++++++ .../src/domain/renderer/ipcRenderer.ts | 82 +++++++++-- packages/electron/src/domain/trace/trace.ts | 10 ++ packages/electron/src/entries/main.ts | 1 - packages/electron/src/entries/plugin.ts | 2 + 8 files changed, 219 insertions(+), 15 deletions(-) create mode 100644 packages/electron/plugin/package.json create mode 100644 packages/electron/src/domain/plugin/plugin.ts create mode 100644 packages/electron/src/entries/plugin.ts diff --git a/packages/core/src/domain/resourceUtils.ts b/packages/core/src/domain/resourceUtils.ts index f5849134c0..34528a7e06 100644 --- a/packages/core/src/domain/resourceUtils.ts +++ b/packages/core/src/domain/resourceUtils.ts @@ -9,6 +9,7 @@ export const ResourceType = { FONT: 'font', MEDIA: 'media', OTHER: 'other', + NATIVE: 'native', } as const export type ResourceType = (typeof ResourceType)[keyof typeof ResourceType] diff --git a/packages/electron/plugin/package.json b/packages/electron/plugin/package.json new file mode 100644 index 0000000000..1033253946 --- /dev/null +++ b/packages/electron/plugin/package.json @@ -0,0 +1,6 @@ +{ + "private": true, + "main": "../cjs/entries/plugin.js", + "module": "../esm/entries/plugin.js", + "types": "../cjs/entries/plugin.d.ts" +} diff --git a/packages/electron/src/domain/main/bridge.ts b/packages/electron/src/domain/main/bridge.ts index fd4ec4c351..95d775c585 100644 --- a/packages/electron/src/domain/main/bridge.ts +++ b/packages/electron/src/domain/main/bridge.ts @@ -13,6 +13,7 @@ export function setupMainBridge(rumEventObservable: Observable void +type StartSubscriber = (addEvent: StartRumResult['addEvent']) => void + +const onRumInitSubscribers: InitSubscriber[] = [] +const onRumStartSubscribers: StartSubscriber[] = [] + +/** + * Electron plugin configuration. + * + * @category Main + */ +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface ElectronPluginConfiguration {} + +/** + * Electron plugin type. + * + * The plugins API is unstable and experimental, and may change without notice. Please don't use this type directly. + * + * @internal + */ +export type ElectronPlugin = Required + +// eslint-disable-next-line no-restricted-syntax +declare global { + interface Window { + dd_electron_internal_api: { + onSpan: (callback: (spanInfo: SpanInfo) => void) => void + } + } +} + +/** + * Electron plugin constructor. + * + * @category Main + * @example + * ```ts + * import { datadogRum } from '@datadog/browser-rum' + * import { electronPlugin } from '@datadog/electron/renderer' + * + * datadogRum.init({ + * applicationId: '', + * clientToken: '', + * site: '', + * plugins: [electronPlugin()], + * // ... + * }) + * ``` + */ +export function electronPlugin(configuration: ElectronPluginConfiguration = {}): ElectronPlugin { + return { + name: 'electron', + onInit({ publicApi }) { + globalPublicApi = publicApi + globalConfiguration = configuration + for (const subscriber of onRumInitSubscribers) { + subscriber(globalConfiguration, globalPublicApi) + } + }, + onRumStart({ addEvent }) { + globalAddEvent = addEvent + + if (!addEvent) { + return + } + + for (const subscriber of onRumStartSubscribers) { + subscriber(addEvent) + } + + window.dd_electron_internal_api.onSpan((spanInfo: SpanInfo) => { + const event: RawRumResourceEvent = { + date: spanInfo.startClocks.timeStamp, + type: 'resource', + _dd: { + span_id: spanInfo.spanId, + trace_id: spanInfo.traceId, + discarded: false, + rule_psr: 1, + }, + resource: { + type: 'native', + id: generateUUID(), + url: spanInfo.name, + method: 'GET', + duration: spanInfo.duration, + }, + } + + // @ts-expect-error - TODO: fix this - probably also due to deep imports - it break at build time + addEvent(spanInfo.startClocks.relative, event, {}, spanInfo.duration) + }) + }, + getConfigurationTelemetry() { + return {} + }, + } satisfies RumPlugin +} + +export function onRumInit(callback: InitSubscriber) { + if (globalConfiguration && globalPublicApi) { + callback(globalConfiguration, globalPublicApi) + } else { + onRumInitSubscribers.push(callback) + } +} + +export function onRumStart(callback: StartSubscriber) { + if (globalAddEvent) { + callback(globalAddEvent) + } else { + onRumStartSubscribers.push(callback) + } +} + +export function resetElectronPlugin() { + globalPublicApi = undefined + globalConfiguration = undefined + globalAddEvent = undefined + onRumInitSubscribers.length = 0 + onRumStartSubscribers.length = 0 +} diff --git a/packages/electron/src/domain/renderer/ipcRenderer.ts b/packages/electron/src/domain/renderer/ipcRenderer.ts index ca9423afba..cd0b94ae4a 100644 --- a/packages/electron/src/domain/renderer/ipcRenderer.ts +++ b/packages/electron/src/domain/renderer/ipcRenderer.ts @@ -1,7 +1,16 @@ import type { IpcRenderer } from 'electron' import { ipcRenderer } from 'electron' import { createSpanIdentifier, createTraceIdentifier } from '@datadog/browser-rum-core/src/domain/tracing/identifier' -import type { DatadogCarrier } from '../trace/trace' +import { contextBridge, ipcRenderer } from 'electron' +import type { Observable } from '@datadog/browser-core' +import { BufferedObservable, clocksNow, elapsed, toServerDuration } from '@datadog/browser-core' +import type { DatadogCarrier, SpanInfo } from '../trace/trace' + +function isThenable(value: any): value is Promise { + return typeof value === 'object' && value !== null && 'then' in value +} + +const SPAN_NAME_PREFIX = 'ipcRenderer' function createDatadogCarrier(): DatadogCarrier { const spanId = createSpanIdentifier().toString() @@ -16,24 +25,69 @@ function createDatadogCarrier(): DatadogCarrier { } } -function withDatadogCarrier R, R>(fn: T): (...args: Parameters) => R { - return (...args: Parameters) => fn(...args, createDatadogCarrier()) +function withDatadogCarrier R, R>( + observable: Observable, + method: string, + fn: T +): (...args: Parameters) => R { + return (...args: Parameters) => { + const carrier = createDatadogCarrier() + const startClock = clocksNow() + const channel = args[0] + + const result = fn(...args, carrier) + + const notifySpan = () => { + observable.notify({ + spanId: carrier['x-datadog-parent-id'], + traceId: carrier['x-datadog-trace-id'], + startClocks: startClock, + duration: toServerDuration(elapsed(startClock.timeStamp, clocksNow().timeStamp)), + name: `${SPAN_NAME_PREFIX}.${method}.${channel}`, + }) + } + + if (isThenable(result)) { + return result.then((data: any) => { + notifySpan() + + return data // eslint-disable-line @typescript-eslint/no-unsafe-return + }) as R + } + + notifySpan() + + return result + } } export function createIpcRenderer(): IpcRenderer { const ddIpcRenderer = { ...ipcRenderer } + const observable = new BufferedObservable(100) + + contextBridge.exposeInMainWorld('dd_electron_internal_api', { + onSpan: (callback: (spanInfo: SpanInfo) => void) => { + const subscription = observable.subscribe((spanInfo) => callback(spanInfo)) + + return () => subscription.unsubscribe() + }, + }) + + ddIpcRenderer.on = withDatadogCarrier(observable, 'on', ipcRenderer.on.bind(ipcRenderer)) + ddIpcRenderer.off = withDatadogCarrier(observable, 'off', ipcRenderer.off.bind(ipcRenderer)) + ddIpcRenderer.once = withDatadogCarrier(observable, 'once', ipcRenderer.once.bind(ipcRenderer)) + ddIpcRenderer.addListener = withDatadogCarrier(observable, 'addListener', ipcRenderer.addListener.bind(ipcRenderer)) + ddIpcRenderer.removeListener = withDatadogCarrier( + observable, + 'removeListener', + ipcRenderer.removeListener.bind(ipcRenderer) + ) + ddIpcRenderer.send = withDatadogCarrier(observable, 'send', ipcRenderer.send.bind(ipcRenderer)) + ddIpcRenderer.invoke = withDatadogCarrier(observable, 'invoke', ipcRenderer.invoke.bind(ipcRenderer)) + ddIpcRenderer.sendSync = withDatadogCarrier(observable, 'sendSync', ipcRenderer.sendSync.bind(ipcRenderer)) + ddIpcRenderer.sendToHost = withDatadogCarrier(observable, 'sendToHost', ipcRenderer.sendToHost.bind(ipcRenderer)) - ddIpcRenderer.on = withDatadogCarrier(ipcRenderer.on.bind(ipcRenderer)) - ddIpcRenderer.off = withDatadogCarrier(ipcRenderer.off.bind(ipcRenderer)) - ddIpcRenderer.once = withDatadogCarrier(ipcRenderer.once.bind(ipcRenderer)) - ddIpcRenderer.addListener = withDatadogCarrier(ipcRenderer.addListener.bind(ipcRenderer)) - ddIpcRenderer.removeListener = withDatadogCarrier(ipcRenderer.removeListener.bind(ipcRenderer)) - ddIpcRenderer.send = withDatadogCarrier(ipcRenderer.send.bind(ipcRenderer)) - ddIpcRenderer.invoke = withDatadogCarrier(ipcRenderer.invoke.bind(ipcRenderer)) - ddIpcRenderer.sendSync = withDatadogCarrier(ipcRenderer.sendSync.bind(ipcRenderer)) - ddIpcRenderer.sendToHost = withDatadogCarrier(ipcRenderer.sendToHost.bind(ipcRenderer)) - - // TODO: Do something for ipcRenderer.postMessage + // TODO: Do something for ipcRenderer.postMessage ?? // see https://www.electronjs.org/docs/latest/api/ipc-renderer#ipcrendererpostmessagechannel-message-transfer return ddIpcRenderer diff --git a/packages/electron/src/domain/trace/trace.ts b/packages/electron/src/domain/trace/trace.ts index 9a5bbd7e66..490ac59bc8 100644 --- a/packages/electron/src/domain/trace/trace.ts +++ b/packages/electron/src/domain/trace/trace.ts @@ -1,3 +1,5 @@ +import type { ClocksState, ServerDuration } from '@datadog/browser-core' + export interface DatadogCarrier { __dd_carrier: true 'x-datadog-origin': string @@ -6,5 +8,13 @@ export interface DatadogCarrier { 'x-datadog-trace-id': string } +export interface SpanInfo { + spanId: string + traceId: string + startClocks: ClocksState + duration: ServerDuration + name: string +} + export type Span = any export type Trace = Span[] diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index cb40d66c93..794ceaa041 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -1,4 +1,3 @@ -/* eslint-disable local-rules/enforce-prod-deps-imports */ /* eslint-disable local-rules/disallow-side-effects */ /** * TODO: diff --git a/packages/electron/src/entries/plugin.ts b/packages/electron/src/entries/plugin.ts new file mode 100644 index 0000000000..8df927b5d0 --- /dev/null +++ b/packages/electron/src/entries/plugin.ts @@ -0,0 +1,2 @@ +export type * from './plugin' +export { electronPlugin } from '../domain/plugin/plugin' From 11e5c0524d084dba6d98b4279acbd74bcbba9ad5 Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Fri, 14 Nov 2025 19:06:52 +0100 Subject: [PATCH 25/58] fix: conflicts --- packages/electron/src/domain/plugin/plugin.ts | 2 +- packages/electron/src/domain/renderer/ipcRenderer.ts | 1 - packages/electron/src/domain/rum/mainProcessTracking.ts | 4 ++++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/electron/src/domain/plugin/plugin.ts b/packages/electron/src/domain/plugin/plugin.ts index 7eb9e94892..5c362fb175 100644 --- a/packages/electron/src/domain/plugin/plugin.ts +++ b/packages/electron/src/domain/plugin/plugin.ts @@ -1,7 +1,7 @@ import { generateUUID } from '@datadog/browser-core' import type { RumPlugin, RumPublicApi, StartRumResult } from '@datadog/browser-rum-core' import type { RawRumResourceEvent } from '@datadog/browser-rum-core/src/rawRumEvent.types' -import type { SpanInfo } from '../trace' +import type { SpanInfo } from '../trace/trace' let globalPublicApi: RumPublicApi | undefined let globalConfiguration: ElectronPluginConfiguration | undefined diff --git a/packages/electron/src/domain/renderer/ipcRenderer.ts b/packages/electron/src/domain/renderer/ipcRenderer.ts index cd0b94ae4a..8c0899ef1f 100644 --- a/packages/electron/src/domain/renderer/ipcRenderer.ts +++ b/packages/electron/src/domain/renderer/ipcRenderer.ts @@ -1,5 +1,4 @@ import type { IpcRenderer } from 'electron' -import { ipcRenderer } from 'electron' import { createSpanIdentifier, createTraceIdentifier } from '@datadog/browser-rum-core/src/domain/tracing/identifier' import { contextBridge, ipcRenderer } from 'electron' import type { Observable } from '@datadog/browser-core' diff --git a/packages/electron/src/domain/rum/mainProcessTracking.ts b/packages/electron/src/domain/rum/mainProcessTracking.ts index 6a0aaae38b..19ab87eb65 100644 --- a/packages/electron/src/domain/rum/mainProcessTracking.ts +++ b/packages/electron/src/domain/rum/mainProcessTracking.ts @@ -31,6 +31,10 @@ export function startMainProcessTracking( }, })) console.log('sessionId', mainProcessContext.sessionId) + console.log( + '\x1b[34m%s\x1b[0m', + `https://app.datadoghq.com/rum/sessions?query=%40type%3Asession%20%40session.id%3A${mainProcessContext.sessionId}` + ) const applicationStart = timeStampNow() let applicationLaunch = { type: RumEventType.VIEW, From 50a9e3dd7de2b49077b346d191dd76291d905768 Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Fri, 14 Nov 2025 21:21:56 +0100 Subject: [PATCH 26/58] fix: disable side-effect-free check for electron package --- eslint-local-rules/disallowSideEffects.js | 1 + 1 file changed, 1 insertion(+) diff --git a/eslint-local-rules/disallowSideEffects.js b/eslint-local-rules/disallowSideEffects.js index 4a12764642..2225d7a504 100644 --- a/eslint-local-rules/disallowSideEffects.js +++ b/eslint-local-rules/disallowSideEffects.js @@ -38,6 +38,7 @@ const packagesWithoutSideEffect = new Set([ '@datadog/browser-rum-core', 'react', 'react-router-dom', + 'electron', ]) /** From 11ec945e92c2bed6c5b73d3c700bc625d03205d3 Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Fri, 14 Nov 2025 21:22:46 +0100 Subject: [PATCH 27/58] fix(eslint): specify listener type in withDatadogCarrier function --- packages/electron/src/domain/main/ipcMain.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/electron/src/domain/main/ipcMain.ts b/packages/electron/src/domain/main/ipcMain.ts index 5c8fa76891..7341ad19e5 100644 --- a/packages/electron/src/domain/main/ipcMain.ts +++ b/packages/electron/src/domain/main/ipcMain.ts @@ -27,7 +27,7 @@ export function createIpcMain(): IpcMain { function withDatadogCarrier R, R>(name: string, fn: T): (...args: Parameters) => R { return (...args: Parameters) => { const channel = args[0] - const listener = args[1] + const listener = args[1] as (...args: any[]) => R const spanName = `${SPAN_NAME_PREFIX}.${name}.${channel}` return fn(channel, (...args: Parameters) => { @@ -37,11 +37,11 @@ function withDatadogCarrier R, R>(name: string, fn args.pop() // remove the carrier from the args if (parentContext) { - return tracer.trace(spanName, { childOf: parentContext }, () => listener(...args)) as R + return tracer.trace(spanName, { childOf: parentContext }, () => listener(...args)) } } - return tracer.trace(spanName, () => listener(...args)) as R + return tracer.trace(spanName, () => listener(...args)) }) } } From 4cc417e3914ba399ddf8b1a7d9b757b2097d090a Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Fri, 14 Nov 2025 21:31:13 +0100 Subject: [PATCH 28/58] fix(lint): no more deep imports --- eslint-local-rules/enforceProdDepsImports.js | 2 +- eslint.config.mjs | 12 ++++++++++++ packages/core/src/index.ts | 15 +++++++++++++-- packages/core/src/transport/index.ts | 1 + packages/electron/src/domain/plugin/plugin.ts | 3 +-- packages/electron/src/domain/renderer/bridge.ts | 2 +- .../electron/src/domain/renderer/ipcRenderer.ts | 2 +- packages/electron/src/domain/rum/assembly.ts | 3 +-- packages/electron/src/entries/main.ts | 11 +++++------ .../rum-core/src/domain/tracing/identifier.ts | 2 +- packages/rum-core/src/index.ts | 5 ++++- 11 files changed, 41 insertions(+), 17 deletions(-) diff --git a/eslint-local-rules/enforceProdDepsImports.js b/eslint-local-rules/enforceProdDepsImports.js index 42ca104bef..a475b1e202 100644 --- a/eslint-local-rules/enforceProdDepsImports.js +++ b/eslint-local-rules/enforceProdDepsImports.js @@ -38,7 +38,7 @@ export default { return moduleVisitor((source) => { const importTypeResult = importType(source.value, context) // Use an allow list instead of a deny list to make the rule more future-proof. - if (importTypeResult === 'parent' || importTypeResult === 'sibling') { + if (importTypeResult === 'parent' || importTypeResult === 'sibling' || importTypeResult === 'builtin') { return } diff --git a/eslint.config.mjs b/eslint.config.mjs index a30445031d..8ac82e0ae3 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -415,6 +415,18 @@ export default tseslint.config( }, }, + { + files: ['packages/electron/src/**/*.ts'], + ignores: [SPEC_FILES], + rules: { + // TODO: verify this is safe + 'local-rules/disallow-side-effects': 'off', + + // TODO: remove before merging this to main: quick dev only + 'no-console': 'off', + }, + }, + { // Files executed by nodejs files: [ diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 57494abca8..a2a55169fd 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,4 +1,4 @@ -export type { Configuration, InitConfiguration, EndpointBuilder, ProxyFn } from './domain/configuration' +export type { Configuration, InitConfiguration, EndpointBuilder, ProxyFn, TrackType } from './domain/configuration' export { validateAndBuildConfiguration, DefaultPrivacyLevel, @@ -7,6 +7,7 @@ export { isSampleRate, buildEndpointHost, isIntakeUrl, + createEndpointBuilder, } from './domain/configuration' export * from './domain/intakeSites' export type { TrackingConsentState } from './domain/trackingConsent' @@ -59,7 +60,17 @@ export { SESSION_NOT_TRACKED, SessionPersistence, } from './domain/session/sessionConstants' -export type { BandwidthStats, HttpRequest, HttpRequestEvent, Payload, FlushEvent, FlushReason } from './transport' +export type { + BandwidthStats, + HttpRequest, + HttpRequestEvent, + Payload, + FlushEvent, + FlushReason, + DatadogEventBridge, + BrowserWindowWithEventBridge, + Batch, +} from './transport' export { createHttpRequest, canUseEventBridge, diff --git a/packages/core/src/transport/index.ts b/packages/core/src/transport/index.ts index 08c8bd94aa..c31ee4790e 100644 --- a/packages/core/src/transport/index.ts +++ b/packages/core/src/transport/index.ts @@ -2,6 +2,7 @@ export type { BandwidthStats, HttpRequest, HttpRequestEvent, Payload, RetryInfo export { createHttpRequest } from './httpRequest' export type { BrowserWindowWithEventBridge, DatadogEventBridge } from './eventBridge' export { canUseEventBridge, bridgeSupports, getEventBridge, BridgeCapability } from './eventBridge' +export type { Batch } from './batch' export { createBatch } from './batch' export type { FlushController, FlushEvent, FlushReason } from './flushController' export { createFlushController } from './flushController' diff --git a/packages/electron/src/domain/plugin/plugin.ts b/packages/electron/src/domain/plugin/plugin.ts index 5c362fb175..fb999055f0 100644 --- a/packages/electron/src/domain/plugin/plugin.ts +++ b/packages/electron/src/domain/plugin/plugin.ts @@ -1,6 +1,5 @@ import { generateUUID } from '@datadog/browser-core' -import type { RumPlugin, RumPublicApi, StartRumResult } from '@datadog/browser-rum-core' -import type { RawRumResourceEvent } from '@datadog/browser-rum-core/src/rawRumEvent.types' +import type { RumPlugin, RumPublicApi, StartRumResult, RawRumResourceEvent } from '@datadog/browser-rum-core' import type { SpanInfo } from '../trace/trace' let globalPublicApi: RumPublicApi | undefined diff --git a/packages/electron/src/domain/renderer/bridge.ts b/packages/electron/src/domain/renderer/bridge.ts index d49d399b05..8da8b80633 100644 --- a/packages/electron/src/domain/renderer/bridge.ts +++ b/packages/electron/src/domain/renderer/bridge.ts @@ -1,5 +1,5 @@ import { contextBridge, ipcRenderer } from 'electron' -import type { DatadogEventBridge } from '@datadog/browser-core/src/transport' +import type { DatadogEventBridge } from '@datadog/browser-core' export function setupRendererBridge() { contextBridge.exposeInMainWorld('DatadogEventBridge', { diff --git a/packages/electron/src/domain/renderer/ipcRenderer.ts b/packages/electron/src/domain/renderer/ipcRenderer.ts index 8c0899ef1f..eea859adcf 100644 --- a/packages/electron/src/domain/renderer/ipcRenderer.ts +++ b/packages/electron/src/domain/renderer/ipcRenderer.ts @@ -1,5 +1,5 @@ import type { IpcRenderer } from 'electron' -import { createSpanIdentifier, createTraceIdentifier } from '@datadog/browser-rum-core/src/domain/tracing/identifier' +import { createSpanIdentifier, createTraceIdentifier } from '@datadog/browser-rum-core' import { contextBridge, ipcRenderer } from 'electron' import type { Observable } from '@datadog/browser-core' import { BufferedObservable, clocksNow, elapsed, toServerDuration } from '@datadog/browser-core' diff --git a/packages/electron/src/domain/rum/assembly.ts b/packages/electron/src/domain/rum/assembly.ts index 0ce1c56019..86c96520dc 100644 --- a/packages/electron/src/domain/rum/assembly.ts +++ b/packages/electron/src/domain/rum/assembly.ts @@ -1,9 +1,8 @@ -import type { Observable, Context } from '@datadog/browser-core' +import type { Observable, Context, Batch } from '@datadog/browser-core' import { HookNames, DISCARDED, combine } from '@datadog/browser-core' import { RumEventType } from '@datadog/browser-rum-core' import type { Hooks } from '../../hooks' import type { CollectedRumEvent } from './events' -import type { Batch } from '@datadog/browser-core/cjs/transport/batch' export function startRumEventAssembleAndSend( onRumEventObservable: Observable, diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 794ceaa041..ab6abd9e05 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -1,4 +1,4 @@ -/* eslint-disable local-rules/disallow-side-effects */ +/* eslint-disable jsdoc/check-indentation */ /** * TODO: * - [ ] Basic session management @@ -9,7 +9,7 @@ * - [x] setup bridge client with ipc from webviews (renderer processes) * - [x] use `exposeInMainWorld` to setup the bridge function that will setup the ipc to the main process */ -import type { RawError, PageMayExitEvent, Encoder, InitConfiguration } from '@datadog/browser-core' +import type { RawError, PageMayExitEvent, Encoder, InitConfiguration, TrackType } from '@datadog/browser-core' import { Observable, DeflateEncoderStreamId, @@ -17,12 +17,10 @@ import { createHttpRequest, createFlushController, createIdentityEncoder, + createEndpointBuilder, } from '@datadog/browser-core' import type { RumConfiguration, RumInitConfiguration } from '@datadog/browser-rum-core' -import { createHooks } from '@datadog/browser-rum-core' -import { validateAndBuildRumConfiguration } from '@datadog/browser-rum-core/cjs/domain/configuration' -import type { TrackType } from '@datadog/browser-core/cjs/domain/configuration' -import { createEndpointBuilder } from '@datadog/browser-core/cjs/domain/configuration' +import { createHooks, validateAndBuildRumConfiguration } from '@datadog/browser-rum-core' import tracer from '../domain/trace/tracer' import { createIpcMain } from '../domain/main/ipcMain' import type { CollectedRumEvent } from '../domain/rum/events' @@ -83,6 +81,7 @@ function makeDatadogElectron() { setupMainBridge(onRumEventObservable) createDdTraceAgent(onTraceObservable, hooks) + // eslint-disable-next-line setInterval(() => { pageMayExitObservable.notify({ reason: 'page_hide' }) }, 1000) diff --git a/packages/rum-core/src/domain/tracing/identifier.ts b/packages/rum-core/src/domain/tracing/identifier.ts index e506016631..cc3e8b7d0a 100644 --- a/packages/rum-core/src/domain/tracing/identifier.ts +++ b/packages/rum-core/src/domain/tracing/identifier.ts @@ -1,4 +1,4 @@ -interface BaseIdentifier { +export interface BaseIdentifier { toString(radix?: number): string } diff --git a/packages/rum-core/src/index.ts b/packages/rum-core/src/index.ts index c00a6b0ff2..b30e908aa0 100644 --- a/packages/rum-core/src/index.ts +++ b/packages/rum-core/src/index.ts @@ -23,7 +23,7 @@ export type { RumEventDomainContext, RumVitalEventDomainContext, } from './domainContext.types' -export type { ReplayStats, RawRumActionEvent, RawRumEvent } from './rawRumEvent.types' +export type { ReplayStats, RawRumActionEvent, RawRumEvent, RawRumResourceEvent } from './rawRumEvent.types' export { ActionType, RumEventType, FrustrationType } from './rawRumEvent.types' export { startRum } from './boot/startRum' export type { RawRumEventCollectedData } from './domain/lifeCycle' @@ -48,6 +48,7 @@ export type { FeatureFlagsForEvents, RemoteConfiguration, } from './domain/configuration' +export { validateAndBuildRumConfiguration } from './domain/configuration' export { DEFAULT_PROGRAMMATIC_ACTION_NAME_ATTRIBUTE } from './domain/action/actionNameConstants' export { STABLE_ATTRIBUTES } from './domain/getSelectorFromElement' export * from './browser/htmlDomUtils' @@ -71,5 +72,7 @@ export type { Hooks, DefaultRumEventAttributes, DefaultTelemetryEventAttributes export { createHooks } from './domain/hooks' export { isSampled } from './domain/sampler/sampler' export type { TracingOption, PropagatorType } from './domain/tracing/tracer.types' +export type { BaseIdentifier, TraceIdentifier, SpanIdentifier } from './domain/tracing/identifier' +export { createTraceIdentifier, createSpanIdentifier } from './domain/tracing/identifier' export type { TransportPayload } from './transport/formDataTransport' export { createFormDataTransport } from './transport/formDataTransport' From 225dc46590e11ac923550ec201e32b3931a1d74d Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Mon, 17 Nov 2025 10:58:29 +0100 Subject: [PATCH 29/58] Generate RUM resources from resources spans --- .../electron/src/domain/rum/convertSpans.ts | 25 ++- packages/electron/src/domain/trace/id.ts | 198 ++++++++++++++++++ .../electron/src/domain/trace/traceAgent.ts | 9 +- 3 files changed, 226 insertions(+), 6 deletions(-) create mode 100644 packages/electron/src/domain/trace/id.ts diff --git a/packages/electron/src/domain/rum/convertSpans.ts b/packages/electron/src/domain/rum/convertSpans.ts index 7270d61d16..41f2e8055d 100644 --- a/packages/electron/src/domain/rum/convertSpans.ts +++ b/packages/electron/src/domain/rum/convertSpans.ts @@ -1,8 +1,9 @@ import type { Observable } from '@datadog/browser-core' -import { generateUUID, ErrorHandling } from '@datadog/browser-core' -import type { RumErrorEvent } from '@datadog/browser-rum-core' +import { ResourceType, generateUUID, ErrorHandling } from '@datadog/browser-core' +import type { RumErrorEvent, RumResourceEvent } from '@datadog/browser-rum-core' import { RumEventType } from '@datadog/browser-rum-core' import type { Trace } from '../trace/trace' +import { createIdentifier } from '../trace/id' import type { CollectedRumEvent } from './events' export function startConvertSpanToRumEvent( @@ -26,6 +27,26 @@ export function startConvertSpanToRumEvent( } onRumEventObservable.notify({ event: rumError as RumErrorEvent, source: 'main-process' }) } + if (span.name === 'http.request') { + const rumResource: Partial = { + type: RumEventType.RESOURCE, + date: span.start / 1e6, + resource: { + id: generateUUID(), + duration: span.duration, + type: ResourceType.NATIVE, + method: span.meta['http.method'], + status_code: span.meta['http.status'], + url: span.meta['http.url'], + }, + _dd: { + trace_id: createIdentifier(span.trace_id, 16).toString(10), + span_id: createIdentifier(span.span_id, 16).toString(10), + format_version: 2, + }, + } + onRumEventObservable.notify({ event: rumResource as RumResourceEvent, source: 'main-process' }) + } }) }) } diff --git a/packages/electron/src/domain/trace/id.ts b/packages/electron/src/domain/trace/id.ts new file mode 100644 index 0000000000..b68574b41b --- /dev/null +++ b/packages/electron/src/domain/trace/id.ts @@ -0,0 +1,198 @@ +// Duplicated from https://github.com/DataDog/dd-trace-js/blob/f40cdf96/packages/dd-trace/src/id.js + +'use strict' + +import crypto from 'node:crypto' + +const UINT_MAX = 4_294_967_296 + +const data = new Uint8Array(8 * 8192) +const zeroId = new Uint8Array(8) + +const map = Array.prototype.map +const pad = (byte: number) => `${byte < 16 ? '0' : ''}${byte.toString(16)}` + +let batch = 0 + +// Internal representation of a trace or span ID. +// eslint-disable-next-line no-restricted-syntax +class Identifier { + _buffer: any[] | Uint8Array + + constructor(value: string, radix = 16) { + this._buffer = radix === 16 ? createBuffer(value) : fromString(value, radix) + } + + toString(radix = 16) { + return radix === 16 ? toHexString(this._buffer) : toNumberString(this._buffer, radix) + } + + toBigInt() { + return Buffer.from(this._buffer).readBigUInt64BE(0) + } + + toBuffer() { + return this._buffer + } + + toArray() { + if (this._buffer.length === 8) { + return this._buffer + } + return this._buffer.slice(-8) + } + + toJSON() { + return this.toString() + } + + equals(other: Identifier) { + const length = this._buffer.length + const otherLength = other._buffer.length + + // Only compare the bytes available in both IDs. + for (let i = length, j = otherLength; i >= 0 && j >= 0; i--, j--) { + if (this._buffer[i] !== other._buffer[j]) { + return false + } + } + + return true + } +} + +// Create a buffer, using an optional hexadecimal value if provided. +function createBuffer(value: string) { + if (value === '0') { + return zeroId + } + if (!value) { + return pseudoRandom() + } + + const size = Math.ceil(value.length / 16) * 16 + const bytes = size / 2 + const buffer = [] + + value = value.padStart(size, '0') + + for (let i = 0; i < bytes; i++) { + buffer[i] = Number.parseInt(value.slice(i * 2, i * 2 + 2), 16) + } + + return buffer +} + +// Convert a numerical string to a buffer using the specified radix. +function fromString(str: string, raddix: number) { + const buffer = new Array(8) + const len = str.length + + let pos = 0 + let high = 0 + let low = 0 + + if (str[0] === '-') { + pos++ + } + + const sign = pos + + while (pos < len) { + const chr = Number.parseInt(str[pos++], raddix) + + if (!(chr >= 0)) { + break + } // NaN + + low = low * raddix + chr + high = high * raddix + Math.floor(low / UINT_MAX) + low %= UINT_MAX + } + + if (sign) { + // eslint-disable-next-line no-bitwise + high = ~high + + if (low) { + low = UINT_MAX - low + } else { + high++ + } + } + + writeUInt32BE(buffer, high, 0) + writeUInt32BE(buffer, low, 4) + + return buffer +} + +// Convert a buffer to a numerical string. +function toNumberString(buffer: any, radix: number) { + let high = readInt32(buffer, buffer.length - 8) + let low = readInt32(buffer, buffer.length - 4) + let str = '' + + radix = radix || 10 + + while (1) { + const mod = (high % radix) * UINT_MAX + low + + high = Math.floor(high / radix) + low = Math.floor(mod / radix) + str = (mod % radix).toString(radix) + str + + if (!high && !low) { + break + } + } + + return str +} + +// Convert a buffer to a hexadecimal string. +function toHexString(buffer: any) { + return map.call(buffer, pad).join('') +} + +// Simple pseudo-random 64-bit ID generator. +function pseudoRandom() { + if (batch === 0) { + crypto.randomFillSync(data) + } + + batch = (batch + 1) % 8192 + + const offset = batch * 8 + + return [ + data[offset] & 0x7f, // only positive int64, + data[offset + 1], + data[offset + 2], + data[offset + 3], + data[offset + 4], + data[offset + 5], + data[offset + 6], + data[offset + 7], + ] +} + +// Read a buffer to unsigned integer bytes. +function readInt32(buffer: any, offset: any) { + return buffer[offset + 0] * 16_777_216 + (buffer[offset + 1] << 16) + (buffer[offset + 2] << 8) + buffer[offset + 3] +} + +// Write unsigned integer bytes to a buffer. +function writeUInt32BE(buffer: any, value: any, offset: any) { + buffer[3 + offset] = value & 255 + value >>= 8 + buffer[2 + offset] = value & 255 + value >>= 8 + buffer[1 + offset] = value & 255 + value >>= 8 + buffer[0 + offset] = value & 255 +} + +export function createIdentifier(value: any, radix: number) { + return new Identifier(value, radix) +} diff --git a/packages/electron/src/domain/trace/traceAgent.ts b/packages/electron/src/domain/trace/traceAgent.ts index 7f76548762..2a310f0798 100644 --- a/packages/electron/src/domain/trace/traceAgent.ts +++ b/packages/electron/src/domain/trace/traceAgent.ts @@ -5,6 +5,7 @@ import { decode } from '@msgpack/msgpack' import type { Hooks } from '../../hooks' import type { Trace } from './trace' import tracer from './tracer' +import { createIdentifier } from './id' export function createDdTraceAgent(onTraceObservable: Observable, hooks: Hooks) { const server = createServer() @@ -34,11 +35,11 @@ export function createDdTraceAgent(onTraceObservable: Observable, hooks: const filteredTrace = trace .filter((span) => !isSdkRequest(span)) .map((span) => ({ - // rewrite id + // rewrite ids ...span, - trace_id: Number(span.trace_id)?.toString(16), - span_id: Number(span.span_id)?.toString(16), - parent_id: Number(span.parent_id)?.toString(16), + trace_id: createIdentifier(`${span.trace_id as number}`, 10).toString(16), + span_id: createIdentifier(`${span.span_id as number}`, 10).toString(16), + parent_id: createIdentifier(`${span.parent_id as number}`, 10).toString(16), meta: { ...span.meta, '_dd.application.id': defaultRumEventAttributes.application!.id, From bdec71af735b1cd005a954b200e0c5e43c648749 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Mon, 17 Nov 2025 11:56:20 +0100 Subject: [PATCH 30/58] Increment error and resource counter --- .../src/domain/rum/mainProcessTracking.ts | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/electron/src/domain/rum/mainProcessTracking.ts b/packages/electron/src/domain/rum/mainProcessTracking.ts index 19ab87eb65..25f06ee885 100644 --- a/packages/electron/src/domain/rum/mainProcessTracking.ts +++ b/packages/electron/src/domain/rum/mainProcessTracking.ts @@ -56,13 +56,30 @@ export function startMainProcessTracking( }, }, _dd: { - document_version: 1, + document_version: 0, }, } as RumViewEvent - onRumEventObservable.notify({ event: applicationLaunch, source: 'main-process' }) + onRumEventObservable.subscribe(({ event, source }) => { + if (source === 'renderer') { + return + } + switch (event.type) { + case RumEventType.RESOURCE: + ;(applicationLaunch.view.resource.count as any) += 1 + updateView() + break + case RumEventType.ERROR: + ;(applicationLaunch.view.error.count as any) += 1 + updateView() + break + } + }) + + updateView() + onActivityObservable.subscribe(updateView) - onActivityObservable.subscribe(() => { + function updateView() { applicationLaunch = combine(applicationLaunch, { view: { time_spent: toServerDuration(elapsed(applicationStart, timeStampNow())), @@ -72,7 +89,7 @@ export function startMainProcessTracking( }, }) onRumEventObservable.notify({ event: applicationLaunch, source: 'main-process' }) - }) + } // TODO session expiration / renewal // TODO useragent } From 93277324cfc4561aef7220a6753907b99916257b Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Mon, 17 Nov 2025 16:27:56 +0100 Subject: [PATCH 31/58] fix: parse span and trace IDs as integers in ipcRenderer --- packages/electron/src/domain/renderer/ipcRenderer.ts | 4 ++-- packages/electron/src/domain/rum/mainProcessTracking.ts | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/electron/src/domain/renderer/ipcRenderer.ts b/packages/electron/src/domain/renderer/ipcRenderer.ts index eea859adcf..6770235045 100644 --- a/packages/electron/src/domain/renderer/ipcRenderer.ts +++ b/packages/electron/src/domain/renderer/ipcRenderer.ts @@ -38,9 +38,9 @@ function withDatadogCarrier R, R>( const notifySpan = () => { observable.notify({ - spanId: carrier['x-datadog-parent-id'], - traceId: carrier['x-datadog-trace-id'], startClocks: startClock, + spanId: parseInt(carrier['x-datadog-parent-id'], 10).toString(), + traceId: parseInt(carrier['x-datadog-trace-id'], 10).toString(), duration: toServerDuration(elapsed(startClock.timeStamp, clocksNow().timeStamp)), name: `${SPAN_NAME_PREFIX}.${method}.${channel}`, }) diff --git a/packages/electron/src/domain/rum/mainProcessTracking.ts b/packages/electron/src/domain/rum/mainProcessTracking.ts index 25f06ee885..25f1f56868 100644 --- a/packages/electron/src/domain/rum/mainProcessTracking.ts +++ b/packages/electron/src/domain/rum/mainProcessTracking.ts @@ -35,6 +35,10 @@ export function startMainProcessTracking( '\x1b[34m%s\x1b[0m', `https://app.datadoghq.com/rum/sessions?query=%40type%3Asession%20%40session.id%3A${mainProcessContext.sessionId}` ) + console.log( + '\x1b[34m%s\x1b[0m', + `https://app.datadoghq.com/apm/traces?query=%40_dd.session.id%3A${mainProcessContext.sessionId}` + ) const applicationStart = timeStampNow() let applicationLaunch = { type: RumEventType.VIEW, From c2605b86bb6b9e18bc493c5e770387c4ef4ec0b7 Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Mon, 17 Nov 2025 16:54:44 +0100 Subject: [PATCH 32/58] chore: update TODOs in main.ts for IPC, telemetry, and testing improvements --- packages/electron/src/entries/main.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index ab6abd9e05..994c342d71 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -5,9 +5,23 @@ * - [x] Transport layer (for the bridge from webview, from dd-trace) * - [x] handle rum events * - [ ] handle routing for other type of events + * - [ ] telemetry + * - [ ] session replays + * - [ ] logs * - [x] handle dd-trace events (forwards APM spans to trace intake) * - [x] setup bridge client with ipc from webviews (renderer processes) * - [x] use `exposeInMainWorld` to setup the bridge function that will setup the ipc to the main process + * - [ ] verify the IPCMain / IpcRenderer are generating correct spans (sync/async/callback/...) + * - [ ] check with APM for wraping IPCMain and net + * - [ ] crash reporting + * - [ ] Test bundling on Windows + * - [ ] Setup the build so we can measure the bundle sizes + * - [ ] check with APM how we can reduce the dd-trace-size + * - [ ] found a real world electron app to try and see how it looks + * - [ ] does the app uses IPC + * - [ ] look at all the TODOs around the electron SDK + * - [ ] add tests + * - [ ] add documentation */ import type { RawError, PageMayExitEvent, Encoder, InitConfiguration, TrackType } from '@datadog/browser-core' import { From f6dc90707717480c07e60ae6c250e0fe7e7e0dba Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Tue, 18 Nov 2025 09:07:17 +0100 Subject: [PATCH 33/58] chore: update TODOs in main.ts to include source and user agent in the UI --- packages/electron/src/entries/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 994c342d71..662a0a3886 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -21,7 +21,7 @@ * - [ ] does the app uses IPC * - [ ] look at all the TODOs around the electron SDK * - [ ] add tests - * - [ ] add documentation + * - [ ] source + user agent in the UI (electron app) */ import type { RawError, PageMayExitEvent, Encoder, InitConfiguration, TrackType } from '@datadog/browser-core' import { From fb5713aa9cef401e65bb2d957a1ecbc8b071f2bd Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Tue, 18 Nov 2025 11:15:12 +0100 Subject: [PATCH 34/58] fix licenses --- LICENSE-3rdparty.csv | 2 ++ packages/electron/package.json | 4 +--- yarn.lock | 16 ---------------- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 8af282d6f5..3b6c074b8f 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -10,6 +10,8 @@ prod,@tabler/icons-react,MIT,Copyright (c) 2020-2023 Paweł Kuna prod,clsx,MIT,Copyright (c) Luke Edwards (lukeed.com) prod,react,MIT,Copyright (c) Facebook, Inc. and its affiliates. prod,react-dom,MIT,Copyright (c) Facebook, Inc. and its affiliates. +prod,@msgpack/msgpack,Apache-2.0,Copyright (c) 2010 Peter Griess +prod,dd-trace,Apache-2.0,Copyright (c) 2018, Datadog Inc. dev,typedoc,Apache-2.0,TypeStrong dev,@eslint/js,MIT,Copyright OpenJS Foundation and other contributors, dev,@jsdevtools/coverage-istanbul-loader,MIT,Copyright (c) 2015 James Messinger diff --git a/packages/electron/package.json b/packages/electron/package.json index 52f1088fd0..fc6f4aa3c0 100644 --- a/packages/electron/package.json +++ b/packages/electron/package.json @@ -15,9 +15,7 @@ "@datadog/browser-core": "6.24.0", "@datadog/browser-rum-core": "6.24.0", "@msgpack/msgpack": "3.1.2", - "@openfeature/core": "1.9.1", - "dd-trace": "^5.76.0", - "graphql": "16.12.0" + "dd-trace": "^5.76.0" }, "peerDependencies": { "@datadog/browser-logs": "6.23.0", diff --git a/yarn.lock b/yarn.lock index cd3b59ea0a..afe9957cb8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -376,11 +376,9 @@ __metadata: "@datadog/browser-core": "npm:6.24.0" "@datadog/browser-rum-core": "npm:6.24.0" "@msgpack/msgpack": "npm:3.1.2" - "@openfeature/core": "npm:1.9.1" "@types/pako": "npm:2.0.4" dd-trace: "npm:^5.76.0" electron: "npm:39" - graphql: "npm:16.12.0" pako: "npm:2.1.0" peerDependencies: "@datadog/browser-logs": 6.23.0 @@ -1914,13 +1912,6 @@ __metadata: languageName: node linkType: hard -"@openfeature/core@npm:1.9.1": - version: 1.9.1 - resolution: "@openfeature/core@npm:1.9.1" - checksum: 10c0/983c651484621e6e5a3b4bf83fce5398a1adc2ace6162ff5a13a8eaf6d285b7c6b15f5c0a477ece9010ca88b28799985d810047ea0c18324d7a51ac4d04e18d6 - languageName: node - linkType: hard - "@openfeature/server-sdk@npm:~1.18.0": version: 1.18.0 resolution: "@openfeature/server-sdk@npm:1.18.0" @@ -7521,13 +7512,6 @@ __metadata: languageName: node linkType: hard -"graphql@npm:16.12.0": - version: 16.12.0 - resolution: "graphql@npm:16.12.0" - checksum: 10c0/b6fffa4e8a4e4a9933ebe85e7470b346dbf49050c1a482fac5e03e4a1a7bed2ecd3a4c97e29f04457af929464bc5e4f2aac991090c2f320111eef26e902a5c75 - languageName: node - linkType: hard - "handle-thing@npm:^2.0.0": version: 2.0.1 resolution: "handle-thing@npm:2.0.1" From 9b78148768ab1ecfb093690095df681927b0e882 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Tue, 18 Nov 2025 11:41:05 +0100 Subject: [PATCH 35/58] fix peerDeps --- packages/electron/package.json | 2 +- yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/electron/package.json b/packages/electron/package.json index fc6f4aa3c0..40613aba28 100644 --- a/packages/electron/package.json +++ b/packages/electron/package.json @@ -18,7 +18,7 @@ "dd-trace": "^5.76.0" }, "peerDependencies": { - "@datadog/browser-logs": "6.23.0", + "@datadog/browser-logs": "6.24.0", "electron": "39" }, "peerDependenciesMeta": { diff --git a/yarn.lock b/yarn.lock index afe9957cb8..dffe59a567 100644 --- a/yarn.lock +++ b/yarn.lock @@ -381,7 +381,7 @@ __metadata: electron: "npm:39" pako: "npm:2.1.0" peerDependencies: - "@datadog/browser-logs": 6.23.0 + "@datadog/browser-logs": 6.24.0 electron: 39 peerDependenciesMeta: "@datadog/browser-logs": From d401f7ec80ce17df7e5a4c2a4d7d7ea2960263d8 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Tue, 18 Nov 2025 14:00:49 +0100 Subject: [PATCH 36/58] fix license --- LICENSE-3rdparty.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 3b6c074b8f..d7fe05a1e5 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -86,3 +86,4 @@ dev,react-refresh-typescript,MIT,Copyright (c) Piotr Monwid-Olechnowicz dev,webpack-dev-server,MIT,Copyright JS Foundation and other contributors dev,http-server,MIT,Copyright http-party contributors dev,react-router,MIT,Copyright (c) React Training LLC 2015-2019 Copyright (c) Remix Software Inc. 2020-2021 Copyright (c) Shopify Inc. 2022-2023 +dev,electron,MIT,Copyright (c) Electron contributors Copyright (c) 2013-2020 GitHub Inc. From 098aeecd7c03c117fb15de0b643dc3c97bb53d30 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Wed, 19 Nov 2025 14:50:42 +0100 Subject: [PATCH 37/58] attach service/env/version --- packages/electron/src/domain/rum/mainProcessTracking.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/electron/src/domain/rum/mainProcessTracking.ts b/packages/electron/src/domain/rum/mainProcessTracking.ts index 25f1f56868..860c999fcc 100644 --- a/packages/electron/src/domain/rum/mainProcessTracking.ts +++ b/packages/electron/src/domain/rum/mainProcessTracking.ts @@ -29,6 +29,9 @@ export function startMainProcessTracking( // TODO get customer package name url: 'com/datadog/application-launch/view', }, + service: configuration.service, + env: configuration.env, + version: configuration.version, })) console.log('sessionId', mainProcessContext.sessionId) console.log( From b720a9383b98e85d989a44fe5c44eeae6519bd5c Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Thu, 20 Nov 2025 11:42:15 +0100 Subject: [PATCH 38/58] add required deps to package with dd-trace --- LICENSE-3rdparty.csv | 2 ++ packages/electron/package.json | 4 +++- yarn.lock | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index d7fe05a1e5..891c1e071b 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -12,6 +12,8 @@ prod,react,MIT,Copyright (c) Facebook, Inc. and its affiliates. prod,react-dom,MIT,Copyright (c) Facebook, Inc. and its affiliates. prod,@msgpack/msgpack,Apache-2.0,Copyright (c) 2010 Peter Griess prod,dd-trace,Apache-2.0,Copyright (c) 2018, Datadog Inc. +prod,graphql,MIT,Copyright (c) GraphQL Contributors +prod,@openfeature/core,Apache-2.0,Copyright OpenFeature Maintainers dev,typedoc,Apache-2.0,TypeStrong dev,@eslint/js,MIT,Copyright OpenJS Foundation and other contributors, dev,@jsdevtools/coverage-istanbul-loader,MIT,Copyright (c) 2015 James Messinger diff --git a/packages/electron/package.json b/packages/electron/package.json index 40613aba28..4c9b9f819d 100644 --- a/packages/electron/package.json +++ b/packages/electron/package.json @@ -15,7 +15,9 @@ "@datadog/browser-core": "6.24.0", "@datadog/browser-rum-core": "6.24.0", "@msgpack/msgpack": "3.1.2", - "dd-trace": "^5.76.0" + "@openfeature/core": "1.9.1", + "dd-trace": "^5.76.0", + "graphql": "16.12.0" }, "peerDependencies": { "@datadog/browser-logs": "6.24.0", diff --git a/yarn.lock b/yarn.lock index dffe59a567..307bc876b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -376,9 +376,11 @@ __metadata: "@datadog/browser-core": "npm:6.24.0" "@datadog/browser-rum-core": "npm:6.24.0" "@msgpack/msgpack": "npm:3.1.2" + "@openfeature/core": "npm:1.9.1" "@types/pako": "npm:2.0.4" dd-trace: "npm:^5.76.0" electron: "npm:39" + graphql: "npm:16.12.0" pako: "npm:2.1.0" peerDependencies: "@datadog/browser-logs": 6.24.0 @@ -1912,6 +1914,13 @@ __metadata: languageName: node linkType: hard +"@openfeature/core@npm:1.9.1": + version: 1.9.1 + resolution: "@openfeature/core@npm:1.9.1" + checksum: 10c0/983c651484621e6e5a3b4bf83fce5398a1adc2ace6162ff5a13a8eaf6d285b7c6b15f5c0a477ece9010ca88b28799985d810047ea0c18324d7a51ac4d04e18d6 + languageName: node + linkType: hard + "@openfeature/server-sdk@npm:~1.18.0": version: 1.18.0 resolution: "@openfeature/server-sdk@npm:1.18.0" @@ -7512,6 +7521,13 @@ __metadata: languageName: node linkType: hard +"graphql@npm:16.12.0": + version: 16.12.0 + resolution: "graphql@npm:16.12.0" + checksum: 10c0/b6fffa4e8a4e4a9933ebe85e7470b346dbf49050c1a482fac5e03e4a1a7bed2ecd3a4c97e29f04457af929464bc5e4f2aac991090c2f320111eef26e902a5c75 + languageName: node + linkType: hard + "handle-thing@npm:^2.0.0": version: 2.0.1 resolution: "handle-thing@npm:2.0.1" From f32666f63bdb597dcc6ad7406c3878c6bbd3e0cb Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Thu, 20 Nov 2025 11:43:27 +0100 Subject: [PATCH 39/58] attach same service,env,version to traces --- packages/electron/src/domain/trace/tracer.ts | 59 ++++++++------------ packages/electron/src/entries/main.ts | 3 +- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/packages/electron/src/domain/trace/tracer.ts b/packages/electron/src/domain/trace/tracer.ts index 057be0ea69..d6991db208 100644 --- a/packages/electron/src/domain/trace/tracer.ts +++ b/packages/electron/src/domain/trace/tracer.ts @@ -1,41 +1,30 @@ -/* eslint-disable local-rules/disallow-side-effects */ import tracer from 'dd-trace' import { app } from 'electron' -/* -// configuring metrics can help troubleshoot the setup -// but will generate spans for each request to the metrics intake -import metrics from 'datadog-metrics' -metrics.init({ prefix: 'electron-main-ps.' }); - -function collectMemoryStats() { - const memUsage = process.memoryUsage(); - metrics.gauge('memory.rss', memUsage.rss); - metrics.gauge('memory.heapTotal', memUsage.heapTotal); - metrics.gauge('memory.heapUsed', memUsage.heapUsed); -} - -setInterval(collectMemoryStats, 5000); -*/ -tracer.init({ - tags: { - electron: { - appName: app.getName(), - appVersion: app.getVersion(), - version: process.versions.electron, - }, - node: { - version: process.versions.node, +export function initTracer(service: string, env: string, version: string) { + tracer.init({ + service, + env, + version, + tags: { + electron: { + appName: app.getName(), + appVersion: app.getVersion(), + version: process.versions.electron, + }, + node: { + version: process.versions.node, + }, + os: { + platform: process.platform, + release: process.release, + }, + chrome: { + version: process.versions.chrome, + }, + env: 'prod', }, - os: { - platform: process.platform, - release: process.release, - }, - chrome: { - version: process.versions.chrome, - }, - env: 'prod', - }, -}) + }) +} // initialized in a different file to avoid hoisting. export default tracer // eslint-disable-line import/no-default-export diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 248aef4d55..b399e26ef0 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -35,7 +35,7 @@ import { } from '@datadog/browser-core' import type { RumConfiguration, RumInitConfiguration } from '@datadog/browser-rum-core' import { createHooks, validateAndBuildRumConfiguration } from '@datadog/browser-rum-core' -import tracer from '../domain/trace/tracer' +import tracer, { initTracer } from '../domain/trace/tracer' import { createIpcMain } from '../domain/main/ipcMain' import type { CollectedRumEvent } from '../domain/rum/events' import { setupMainBridge } from '../domain/main/bridge' @@ -92,6 +92,7 @@ function makeDatadogElectron() { spanBatch.add({ env: 'prod', spans: trace }) }) setupMainBridge(onRumEventObservable) + initTracer(configuration.service!, configuration.env!, configuration.version!) createDdTraceAgent(onTraceObservable, hooks) // eslint-disable-next-line From 73d283e7c4b8efa68721fbea25f4eef0016f8f59 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Thu, 20 Nov 2025 11:44:40 +0100 Subject: [PATCH 40/58] allow to provide renderer variable with or without context isolation + auto setup bridge --- packages/electron/src/domain/renderer/bridge.ts | 9 +++++++-- packages/electron/src/domain/renderer/ipcRenderer.ts | 11 ++++++++--- packages/electron/src/entries/renderer.ts | 4 ++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/electron/src/domain/renderer/bridge.ts b/packages/electron/src/domain/renderer/bridge.ts index 8da8b80633..17e780052b 100644 --- a/packages/electron/src/domain/renderer/bridge.ts +++ b/packages/electron/src/domain/renderer/bridge.ts @@ -2,7 +2,7 @@ import { contextBridge, ipcRenderer } from 'electron' import type { DatadogEventBridge } from '@datadog/browser-core' export function setupRendererBridge() { - contextBridge.exposeInMainWorld('DatadogEventBridge', { + ;(window as any).DatadogEventBridge = { getCapabilities() { return '[]' }, @@ -15,5 +15,10 @@ export function setupRendererBridge() { send(msg: string) { void ipcRenderer.invoke('datadog:send', msg) }, - } satisfies DatadogEventBridge) + } satisfies DatadogEventBridge + try { + contextBridge.exposeInMainWorld('DatadogEventBridge', (window as any).DatadogEventBridge) + } catch { + // contextBridge API can only be used when contextIsolation is enabled + } } diff --git a/packages/electron/src/domain/renderer/ipcRenderer.ts b/packages/electron/src/domain/renderer/ipcRenderer.ts index 6770235045..be18869cd0 100644 --- a/packages/electron/src/domain/renderer/ipcRenderer.ts +++ b/packages/electron/src/domain/renderer/ipcRenderer.ts @@ -1,6 +1,6 @@ import type { IpcRenderer } from 'electron' -import { createSpanIdentifier, createTraceIdentifier } from '@datadog/browser-rum-core' import { contextBridge, ipcRenderer } from 'electron' +import { createSpanIdentifier, createTraceIdentifier } from '@datadog/browser-rum-core' import type { Observable } from '@datadog/browser-core' import { BufferedObservable, clocksNow, elapsed, toServerDuration } from '@datadog/browser-core' import type { DatadogCarrier, SpanInfo } from '../trace/trace' @@ -64,13 +64,18 @@ export function createIpcRenderer(): IpcRenderer { const ddIpcRenderer = { ...ipcRenderer } const observable = new BufferedObservable(100) - contextBridge.exposeInMainWorld('dd_electron_internal_api', { + window.dd_electron_internal_api = { onSpan: (callback: (spanInfo: SpanInfo) => void) => { const subscription = observable.subscribe((spanInfo) => callback(spanInfo)) return () => subscription.unsubscribe() }, - }) + } + try { + contextBridge.exposeInMainWorld('dd_electron_internal_api', window.dd_electron_internal_api) + } catch { + // contextBridge API can only be used when contextIsolation is enabled + } ddIpcRenderer.on = withDatadogCarrier(observable, 'on', ipcRenderer.on.bind(ipcRenderer)) ddIpcRenderer.off = withDatadogCarrier(observable, 'off', ipcRenderer.off.bind(ipcRenderer)) diff --git a/packages/electron/src/entries/renderer.ts b/packages/electron/src/entries/renderer.ts index 1a2dff3fea..450bf90c56 100644 --- a/packages/electron/src/entries/renderer.ts +++ b/packages/electron/src/entries/renderer.ts @@ -1,5 +1,5 @@ import { createIpcRenderer } from '../domain/renderer/ipcRenderer' -export { setupRendererBridge } from '../domain/renderer/bridge' +import { setupRendererBridge } from '../domain/renderer/bridge' -// eslint-disable-next-line local-rules/disallow-side-effects +setupRendererBridge() export const ipcRenderer = createIpcRenderer() From 1dbb4a0ae53e07d61d9f6173d0f7dae444218405 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Mon, 24 Nov 2025 10:11:41 +0100 Subject: [PATCH 41/58] Setup electron e2e test --- .gitignore | 4 +- packages/core/src/tools/utils/urlPolyfill.ts | 3 +- scripts/build/build-test-apps.ts | 1 + test/apps/electron/.gitignore | 3 + test/apps/electron/README.md | 3 + test/apps/electron/package.json | 24 + test/apps/electron/public/index.html | 10 + test/apps/electron/src/main.ts | 38 + test/apps/electron/src/renderer.ts | 0 test/apps/electron/webpack.main.js | 22 + test/apps/electron/webpack.renderer.js | 28 + test/apps/electron/yarn.lock | 3502 ++++++++++++++++++ test/e2e/lib/framework/createTest.ts | 81 +- test/e2e/lib/framework/flushEvents.ts | 6 + test/e2e/lib/framework/index.ts | 2 +- test/e2e/lib/framework/pageSetups.ts | 48 +- test/e2e/scenario/electron.scenario.ts | 17 + 17 files changed, 3754 insertions(+), 38 deletions(-) create mode 100644 test/apps/electron/.gitignore create mode 100644 test/apps/electron/README.md create mode 100644 test/apps/electron/package.json create mode 100644 test/apps/electron/public/index.html create mode 100644 test/apps/electron/src/main.ts create mode 100644 test/apps/electron/src/renderer.ts create mode 100644 test/apps/electron/webpack.main.js create mode 100644 test/apps/electron/webpack.renderer.js create mode 100644 test/apps/electron/yarn.lock create mode 100644 test/e2e/scenario/electron.scenario.ts diff --git a/.gitignore b/.gitignore index c2f7e8fd3b..f7c5dc265c 100644 --- a/.gitignore +++ b/.gitignore @@ -20,8 +20,8 @@ docs/ !.yarn/releases !.yarn/sdks !.yarn/versions -/test-results/ -/playwright-report/ +**/test-results/ +**/playwright-report/ /blob-report/ /playwright/.cache/ .vscode diff --git a/packages/core/src/tools/utils/urlPolyfill.ts b/packages/core/src/tools/utils/urlPolyfill.ts index a118546328..0eeda6c7cd 100644 --- a/packages/core/src/tools/utils/urlPolyfill.ts +++ b/packages/core/src/tools/utils/urlPolyfill.ts @@ -1,7 +1,8 @@ import { globalObject } from '../globalObject' export function normalizeUrl(url: string) { - return buildUrl(url, location.href).href + const base = typeof location !== 'undefined' ? location.href : undefined + return buildUrl(url, base).href } export function isValidUrl(url: string) { diff --git a/scripts/build/build-test-apps.ts b/scripts/build/build-test-apps.ts index 376d95d934..885cd84b28 100644 --- a/scripts/build/build-test-apps.ts +++ b/scripts/build/build-test-apps.ts @@ -18,6 +18,7 @@ runMain(async () => { buildApp('test/apps/react-router-v6-app') buildApp('test/apps/react-heavy-spa') buildApp('test/apps/react-shopist-like') + buildApp('test/apps/electron') await buildReactRouterv7App() await buildExtensions() diff --git a/test/apps/electron/.gitignore b/test/apps/electron/.gitignore new file mode 100644 index 0000000000..37cfcf3632 --- /dev/null +++ b/test/apps/electron/.gitignore @@ -0,0 +1,3 @@ +.yarn/* +node_modules +dist \ No newline at end of file diff --git a/test/apps/electron/README.md b/test/apps/electron/README.md new file mode 100644 index 0000000000..7309e8b448 --- /dev/null +++ b/test/apps/electron/README.md @@ -0,0 +1,3 @@ +# electron + +Sample electron app for e2e tests diff --git a/test/apps/electron/package.json b/test/apps/electron/package.json new file mode 100644 index 0000000000..df78b9cb7b --- /dev/null +++ b/test/apps/electron/package.json @@ -0,0 +1,24 @@ +{ + "name": "electron", + "version": "0.0.0", + "private": true, + "main": "src/main.ts", + "scripts": { + "start": "electron ./dist/main.js", + "build": "webpack --config webpack.main.js && webpack --config webpack.renderer.js" + }, + "devDependencies": { + "electron": "39.2.3", + "html-webpack-plugin": "5.6.5", + "ts-loader": "9.5.4", + "webpack": "5.103.0", + "webpack-cli": "6.0.1" + }, + "dependencies": { + "@datadog/electron": "file:../../../packages/electron/package.tgz" + }, + "resolutions": { + "@datadog/browser-rum-core": "file:../../../packages/rum-core/package.tgz", + "@datadog/browser-core": "file:../../../packages/core/package.tgz" + } +} diff --git a/test/apps/electron/public/index.html b/test/apps/electron/public/index.html new file mode 100644 index 0000000000..5e4aac3471 --- /dev/null +++ b/test/apps/electron/public/index.html @@ -0,0 +1,10 @@ + + + + + Sample Electron App + + +

Electron sample app

+ + diff --git a/test/apps/electron/src/main.ts b/test/apps/electron/src/main.ts new file mode 100644 index 0000000000..fcd82c3f1a --- /dev/null +++ b/test/apps/electron/src/main.ts @@ -0,0 +1,38 @@ +import { app, BrowserWindow } from 'electron' +import { ddElectron } from '@datadog/electron' + +// Delay startup to not miss early logs in playwright +setTimeout(startApp, 200) + +function startApp() { + ddElectron.init(retrieveRumConfiguration()) + + app.whenReady().then(() => { + createWindow() + }) + + app.on('window-all-closed', () => { + app.quit() + }) +} + +function createWindow() { + const win = new BrowserWindow({ + width: 800, + height: 600, + }) + + win.loadFile('index.html') +} + +function retrieveRumConfiguration(): any { + const namespace = 'RUM_' + const rumConfiguration = {} + Object.entries(process.env) + .filter(([key]) => key.startsWith(namespace)) + .forEach(([key, value]) => { + rumConfiguration[key.replace(namespace, '')] = Number.isNaN(Number(value)) ? value : Number(value) + }) + console.log(rumConfiguration) + return rumConfiguration +} diff --git a/test/apps/electron/src/renderer.ts b/test/apps/electron/src/renderer.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/apps/electron/webpack.main.js b/test/apps/electron/webpack.main.js new file mode 100644 index 0000000000..97d13d9aa6 --- /dev/null +++ b/test/apps/electron/webpack.main.js @@ -0,0 +1,22 @@ +const path = require('path') + +module.exports = { + mode: 'development', + target: 'electron-main', + entry: './src/main.ts', + output: { + filename: 'main.js', + path: path.resolve(__dirname, 'dist'), + }, + resolve: { + extensions: ['.ts', '.js'], + }, + module: { + rules: [ + { + test: /\.ts$/, + loader: 'ts-loader', + }, + ], + }, +} diff --git a/test/apps/electron/webpack.renderer.js b/test/apps/electron/webpack.renderer.js new file mode 100644 index 0000000000..1dc723ed7d --- /dev/null +++ b/test/apps/electron/webpack.renderer.js @@ -0,0 +1,28 @@ +const path = require('path') +const HtmlWebpackPlugin = require('html-webpack-plugin') + +module.exports = { + mode: 'development', + target: 'electron-renderer', + entry: './src/renderer.ts', + output: { + filename: 'renderer.js', + path: path.resolve(__dirname, 'dist'), + }, + resolve: { + extensions: ['.ts', '.js'], + }, + module: { + rules: [ + { + test: /\.ts$/, + loader: 'ts-loader', + }, + ], + }, + plugins: [ + new HtmlWebpackPlugin({ + template: 'public/index.html', + }), + ], +} diff --git a/test/apps/electron/yarn.lock b/test/apps/electron/yarn.lock new file mode 100644 index 0000000000..049747e264 --- /dev/null +++ b/test/apps/electron/yarn.lock @@ -0,0 +1,3502 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10c0 + +"@datadog/browser-core@file:../../../packages/core/package.tgz::locator=electron%40workspace%3A.": + version: 6.24.0 + resolution: "@datadog/browser-core@file:../../../packages/core/package.tgz#../../../packages/core/package.tgz::hash=580731&locator=electron%40workspace%3A." + checksum: 10c0/b51788104ecf8d7df3f8b5ba7ead4bb69f2fb1281004a8c9afcb0bc034bf07a715b99b5d345a2045401fba370258248f78d3d6ff949895c232d7a24f8f533b48 + languageName: node + linkType: hard + +"@datadog/browser-rum-core@file:../../../packages/rum-core/package.tgz::locator=electron%40workspace%3A.": + version: 6.24.0 + resolution: "@datadog/browser-rum-core@file:../../../packages/rum-core/package.tgz#../../../packages/rum-core/package.tgz::hash=9f99a4&locator=electron%40workspace%3A." + dependencies: + "@datadog/browser-core": "npm:6.24.0" + checksum: 10c0/15da4a2dc2a686c1befb4dde7b48e8578be2a037b38a0dd33163c7dcbdfc91e0eab4817171389b9ef2cd6f608b21da495bb0754adf6452b8c147ab4500ba446e + languageName: node + linkType: hard + +"@datadog/electron@file:../../../packages/electron/package.tgz::locator=electron%40workspace%3A.": + version: 6.23.0 + resolution: "@datadog/electron@file:../../../packages/electron/package.tgz#../../../packages/electron/package.tgz::hash=526e80&locator=electron%40workspace%3A." + dependencies: + "@datadog/browser-core": "npm:6.24.0" + "@datadog/browser-rum-core": "npm:6.24.0" + "@msgpack/msgpack": "npm:3.1.2" + "@openfeature/core": "npm:1.9.1" + dd-trace: "npm:^5.76.0" + graphql: "npm:16.12.0" + peerDependencies: + "@datadog/browser-logs": 6.24.0 + electron: 39 + peerDependenciesMeta: + "@datadog/browser-logs": + optional: true + checksum: 10c0/8580cd9c38d5059894d827eb9fb6a0bb521bdff370cfb67a68f30791c143bd92ce5750f71c86e007dd3424ebd2530a65d8695b2d367f7aa9f043f986f24a8f2a + languageName: node + linkType: hard + +"@datadog/flagging-core@npm:0.2.0": + version: 0.2.0 + resolution: "@datadog/flagging-core@npm:0.2.0" + dependencies: + spark-md5: "npm:^3.0.2" + peerDependencies: + "@openfeature/core": ^1.8.1 + checksum: 10c0/e3a837bdb6186a0a0a22a692afc6289d8527b43f6fc9fe87c152d99a79ba546c1574d48fb84fe9cf05067c7a911844aa6708eddf60213eb5e1f029c0f9881e20 + languageName: node + linkType: hard + +"@datadog/libdatadog@npm:0.7.0": + version: 0.7.0 + resolution: "@datadog/libdatadog@npm:0.7.0" + checksum: 10c0/04ca10b1f3a393e3a6356c80ca257c79c9ebca98923b88fd55d11e732f3721b4fd6fba134737b19d56da1b579c8633824364c724303f33106db461ad7f61c669 + languageName: node + linkType: hard + +"@datadog/native-appsec@npm:10.3.0": + version: 10.3.0 + resolution: "@datadog/native-appsec@npm:10.3.0" + dependencies: + node-gyp: "npm:latest" + node-gyp-build: "npm:^3.9.0" + checksum: 10c0/a1c5eac27d566148c58559e1e3d481efb0bf336b14a2e2a4bcdef6d7137b3fd6401781deac0271b5aa71634796af3f6ffcc1608609268355d4632c6f99dc338f + languageName: node + linkType: hard + +"@datadog/native-iast-taint-tracking@npm:4.0.0": + version: 4.0.0 + resolution: "@datadog/native-iast-taint-tracking@npm:4.0.0" + dependencies: + node-gyp: "npm:latest" + node-gyp-build: "npm:^3.9.0" + checksum: 10c0/72a18959a9eccfeff4b791ff9929a384df84385596232685a65ca9a0225306f376e85bd44540e98467d8058e54bc776b3fd52ed029c04eebb9ef7d3ae73c5df7 + languageName: node + linkType: hard + +"@datadog/native-metrics@npm:3.1.1": + version: 3.1.1 + resolution: "@datadog/native-metrics@npm:3.1.1" + dependencies: + node-addon-api: "npm:^6.1.0" + node-gyp: "npm:latest" + node-gyp-build: "npm:^3.9.0" + checksum: 10c0/05757cd34fca5f129130dba95be32012a9693ac59e7517145560d71275dd9b7592aad60e8f0d1d805b99d74ea834d8ae1e5db00b0de75bc6faba84419cb35393 + languageName: node + linkType: hard + +"@datadog/openfeature-node-server@npm:^0.2.0": + version: 0.2.0 + resolution: "@datadog/openfeature-node-server@npm:0.2.0" + dependencies: + "@datadog/flagging-core": "npm:0.2.0" + "@openfeature/server-sdk": "npm:~1.18.0" + peerDependencies: + "@openfeature/server-sdk": ~1.18.0 + checksum: 10c0/9465f7b109bd39604cd62bfa184d6ea0fc4b526de566b010f2f0e6ebeac4d50773486b66a0adca340377538b30bb6fe875085acfce87c56f2ee1d7d431f413c1 + languageName: node + linkType: hard + +"@datadog/pprof@npm:5.12.0": + version: 5.12.0 + resolution: "@datadog/pprof@npm:5.12.0" + dependencies: + delay: "npm:^5.0.0" + node-gyp: "npm:latest" + node-gyp-build: "npm:<4.0" + p-limit: "npm:^3.1.0" + pprof-format: "npm:^2.2.1" + source-map: "npm:^0.7.4" + checksum: 10c0/e18e9e941fbd7ba6de52f3e8d92d7b4612ab054b302d2b2581932be41d1f4bb03d27b753ab9242364b897ba2773c105b1badb2d760db4b1fe633e1b8c23c1013 + languageName: node + linkType: hard + +"@datadog/sketches-js@npm:2.1.1": + version: 2.1.1 + resolution: "@datadog/sketches-js@npm:2.1.1" + checksum: 10c0/4b930240202e4e94ac49fc95298a7111202492566f76672e0ec43425a1710a0e3650a20f858a6358509ab08363d39fce5db210c88d94b4225f96b3bfe645cc5c + languageName: node + linkType: hard + +"@datadog/wasm-js-rewriter@npm:5.0.1": + version: 5.0.1 + resolution: "@datadog/wasm-js-rewriter@npm:5.0.1" + dependencies: + js-yaml: "npm:^4.1.0" + lru-cache: "npm:^7.14.0" + module-details-from-path: "npm:^1.0.3" + node-gyp-build: "npm:^4.5.0" + checksum: 10c0/e5f665f53b8d292efe85ac401f56923112860cfd14c5d84097ad22e1b86c8a30f3cd39cc92e1ec6e8f5f9de5fef028af46554752d8ae2d0f80b7c3a44827f0db + languageName: node + linkType: hard + +"@discoveryjs/json-ext@npm:^0.6.1": + version: 0.6.3 + resolution: "@discoveryjs/json-ext@npm:0.6.3" + checksum: 10c0/778a9f9d5c3696da3c1f9fa4186613db95a1090abbfb6c2601430645c0d0158cd5e4ba4f32c05904e2dd2747d57710f6aab22bd2f8aa3c4e8feab9b247c65d85 + languageName: node + linkType: hard + +"@electron/get@npm:^2.0.0": + version: 2.0.3 + resolution: "@electron/get@npm:2.0.3" + dependencies: + debug: "npm:^4.1.1" + env-paths: "npm:^2.2.0" + fs-extra: "npm:^8.1.0" + global-agent: "npm:^3.0.0" + got: "npm:^11.8.5" + progress: "npm:^2.0.3" + semver: "npm:^6.2.0" + sumchecker: "npm:^3.0.1" + dependenciesMeta: + global-agent: + optional: true + checksum: 10c0/148957d531bac50c29541515f2483c3e5c9c6ba9f0269a5d536540d2b8d849188a89588f18901f3a84c2b4fd376d1e0c5ea2159eb2d17bda68558f57df19015e + languageName: node + linkType: hard + +"@isaacs/balanced-match@npm:^4.0.1": + version: 4.0.1 + resolution: "@isaacs/balanced-match@npm:4.0.1" + checksum: 10c0/7da011805b259ec5c955f01cee903da72ad97c5e6f01ca96197267d3f33103d5b2f8a1af192140f3aa64526c593c8d098ae366c2b11f7f17645d12387c2fd420 + languageName: node + linkType: hard + +"@isaacs/brace-expansion@npm:^5.0.0": + version: 5.0.0 + resolution: "@isaacs/brace-expansion@npm:5.0.0" + dependencies: + "@isaacs/balanced-match": "npm:^4.0.1" + checksum: 10c0/b4d4812f4be53afc2c5b6c545001ff7a4659af68d4484804e9d514e183d20269bb81def8682c01a22b17c4d6aed14292c8494f7d2ac664e547101c1a905aa977 + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e + languageName: node + linkType: hard + +"@isaacs/fs-minipass@npm:^4.0.0": + version: 4.0.1 + resolution: "@isaacs/fs-minipass@npm:4.0.1" + dependencies: + minipass: "npm:^7.0.4" + checksum: 10c0/c25b6dc1598790d5b55c0947a9b7d111cfa92594db5296c3b907e2f533c033666f692a3939eadac17b1c7c40d362d0b0635dc874cbfe3e70db7c2b07cc97a5d2 + languageName: node + linkType: hard + +"@isaacs/ttlcache@npm:^2.0.1": + version: 2.1.2 + resolution: "@isaacs/ttlcache@npm:2.1.2" + checksum: 10c0/91875a1b2b3be915333e69b890fd92b766bfece3c5080cfafa57df883910fe34d54a270f57bec05df72df4c356a4be2841f65b522a9d217a0b219c78aaae8aa5 + languageName: node + linkType: hard + +"@jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.13 + resolution: "@jridgewell/gen-mapping@npm:0.3.13" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.0" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10c0/9a7d65fb13bd9aec1fbab74cda08496839b7e2ceb31f5ab922b323e94d7c481ce0fc4fd7e12e2610915ed8af51178bdc61e168e92a8c8b8303b030b03489b13b + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e + languageName: node + linkType: hard + +"@jridgewell/source-map@npm:^0.3.3": + version: 0.3.11 + resolution: "@jridgewell/source-map@npm:0.3.11" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" + checksum: 10c0/50a4fdafe0b8f655cb2877e59fe81320272eaa4ccdbe6b9b87f10614b2220399ae3e05c16137a59db1f189523b42c7f88bd097ee991dbd7bc0e01113c583e844 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0": + version: 1.5.5 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" + checksum: 10c0/f9e538f302b63c0ebc06eecb1dd9918dd4289ed36147a0ddce35d6ea4d7ebbda243cda7b2213b6a5e1d8087a298d5cf630fb2bd39329cdecb82017023f6081a0 + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": + version: 0.3.31 + resolution: "@jridgewell/trace-mapping@npm:0.3.31" + dependencies: + "@jridgewell/resolve-uri": "npm:^3.1.0" + "@jridgewell/sourcemap-codec": "npm:^1.4.14" + checksum: 10c0/4b30ec8cd56c5fd9a661f088230af01e0c1a3888d11ffb6b47639700f71225be21d1f7e168048d6d4f9449207b978a235c07c8f15c07705685d16dc06280e9d9 + languageName: node + linkType: hard + +"@jsep-plugin/assignment@npm:^1.3.0": + version: 1.3.0 + resolution: "@jsep-plugin/assignment@npm:1.3.0" + peerDependencies: + jsep: ^0.4.0||^1.0.0 + checksum: 10c0/d749554dc691798116eb068eebe2d9bcb0b0d89ef6c7cc7c2a9f37d03da15fdbf8053407e97008090cd1bd6f256ea6c26abbada7399cf79f0b6b502e164b084b + languageName: node + linkType: hard + +"@jsep-plugin/regex@npm:^1.0.4": + version: 1.0.4 + resolution: "@jsep-plugin/regex@npm:1.0.4" + peerDependencies: + jsep: ^0.4.0||^1.0.0 + checksum: 10c0/bec7eb7ea6ab453a2672edc808644c5be3dc06b2a9d77182e18cd595b37deba6dcdb3760849d8684afc5779a86b7d2604dd525cb612a548f9ed9f31a8032ec24 + languageName: node + linkType: hard + +"@msgpack/msgpack@npm:3.1.2": + version: 3.1.2 + resolution: "@msgpack/msgpack@npm:3.1.2" + checksum: 10c0/4fee6dbea70a485d3a787ac76dd43687f489d662f22919237db1f2abbc3c88070c1d3ad78417ce6e764bcd041051680284654021f52068e0aff82d570cb942d5 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^4.0.0": + version: 4.0.0 + resolution: "@npmcli/agent@npm:4.0.0" + dependencies: + agent-base: "npm:^7.1.0" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.1" + lru-cache: "npm:^11.2.1" + socks-proxy-agent: "npm:^8.0.3" + checksum: 10c0/f7b5ce0f3dd42c3f8c6546e8433573d8049f67ef11ec22aa4704bc41483122f68bf97752e06302c455ead667af5cb753e6a09bff06632bc465c1cfd4c4b75a53 + languageName: node + linkType: hard + +"@npmcli/fs@npm:^4.0.0": + version: 4.0.0 + resolution: "@npmcli/fs@npm:4.0.0" + dependencies: + semver: "npm:^7.3.5" + checksum: 10c0/c90935d5ce670c87b6b14fab04a965a3b8137e585f8b2a6257263bd7f97756dd736cb165bb470e5156a9e718ecd99413dccc54b1138c1a46d6ec7cf325982fe5 + languageName: node + linkType: hard + +"@openfeature/core@npm:1.9.1": + version: 1.9.1 + resolution: "@openfeature/core@npm:1.9.1" + checksum: 10c0/983c651484621e6e5a3b4bf83fce5398a1adc2ace6162ff5a13a8eaf6d285b7c6b15f5c0a477ece9010ca88b28799985d810047ea0c18324d7a51ac4d04e18d6 + languageName: node + linkType: hard + +"@openfeature/server-sdk@npm:~1.18.0": + version: 1.18.0 + resolution: "@openfeature/server-sdk@npm:1.18.0" + peerDependencies: + "@openfeature/core": ^1.7.0 + checksum: 10c0/5c3aa8fee5ec4ad9ec40ee74094fe0377b28cadfcc6f71414fa1762035cb994891184cc491a59dbaade71afe0139cd39c193e3897b05df8fa21f0e7b84b67c53 + languageName: node + linkType: hard + +"@opentelemetry/api-logs@npm:<1.0.0": + version: 0.208.0 + resolution: "@opentelemetry/api-logs@npm:0.208.0" + dependencies: + "@opentelemetry/api": "npm:^1.3.0" + checksum: 10c0/dc1fbee6219df4166509f43b74ea936bb18b6d594565b0bcf56b654a1c958b50d6046b8739dc36c98149fe890c02150ff3814e963f5ea439a07ff3c562555b99 + languageName: node + linkType: hard + +"@opentelemetry/api@npm:>=1.0.0 <1.10.0, @opentelemetry/api@npm:^1.3.0": + version: 1.9.0 + resolution: "@opentelemetry/api@npm:1.9.0" + checksum: 10c0/9aae2fe6e8a3a3eeb6c1fdef78e1939cf05a0f37f8a4fae4d6bf2e09eb1e06f966ece85805626e01ba5fab48072b94f19b835449e58b6d26720ee19a58298add + languageName: node + linkType: hard + +"@opentelemetry/core@npm:1.30.1, @opentelemetry/core@npm:>=1.14.0 <1.31.0": + version: 1.30.1 + resolution: "@opentelemetry/core@npm:1.30.1" + dependencies: + "@opentelemetry/semantic-conventions": "npm:1.28.0" + peerDependencies: + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: 10c0/4c25ba50a6137c2ba9ca563fb269378f3c9ca6fd1b3f15dbb6eff78eebf5656f281997cbb7be8e51c01649fd6ad091083fcd8a42dd9b5dfac907dc06d7cfa092 + languageName: node + linkType: hard + +"@opentelemetry/resources@npm:>=1.0.0 <1.31.0": + version: 1.30.1 + resolution: "@opentelemetry/resources@npm:1.30.1" + dependencies: + "@opentelemetry/core": "npm:1.30.1" + "@opentelemetry/semantic-conventions": "npm:1.28.0" + peerDependencies: + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: 10c0/688e73258283c80662bfa9a858aaf73bf3b832a18d96e546d0dddfa6dcec556cdfa087a1d0df643435293406009e4122d7fb7eeea69aa87b539d3bab756fba74 + languageName: node + linkType: hard + +"@opentelemetry/semantic-conventions@npm:1.28.0": + version: 1.28.0 + resolution: "@opentelemetry/semantic-conventions@npm:1.28.0" + checksum: 10c0/deb8a0f744198071e70fea27143cf7c9f7ecb7e4d7b619488c917834ea09b31543c1c2bcea4ec5f3cf68797f0ef3549609c14e859013d9376400ac1499c2b9cb + languageName: node + linkType: hard + +"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/aspromise@npm:1.1.2" + checksum: 10c0/a83343a468ff5b5ec6bff36fd788a64c839e48a07ff9f4f813564f58caf44d011cd6504ed2147bf34835bd7a7dd2107052af755961c6b098fd8902b4f6500d0f + languageName: node + linkType: hard + +"@protobufjs/base64@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/base64@npm:1.1.2" + checksum: 10c0/eec925e681081af190b8ee231f9bad3101e189abbc182ff279da6b531e7dbd2a56f1f306f37a80b1be9e00aa2d271690d08dcc5f326f71c9eed8546675c8caf6 + languageName: node + linkType: hard + +"@protobufjs/codegen@npm:^2.0.4": + version: 2.0.4 + resolution: "@protobufjs/codegen@npm:2.0.4" + checksum: 10c0/26ae337c5659e41f091606d16465bbcc1df1f37cc1ed462438b1f67be0c1e28dfb2ca9f294f39100c52161aef82edf758c95d6d75650a1ddf31f7ddee1440b43 + languageName: node + linkType: hard + +"@protobufjs/eventemitter@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/eventemitter@npm:1.1.0" + checksum: 10c0/1eb0a75180e5206d1033e4138212a8c7089a3d418c6dfa5a6ce42e593a4ae2e5892c4ef7421f38092badba4040ea6a45f0928869989411001d8c1018ea9a6e70 + languageName: node + linkType: hard + +"@protobufjs/fetch@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/fetch@npm:1.1.0" + dependencies: + "@protobufjs/aspromise": "npm:^1.1.1" + "@protobufjs/inquire": "npm:^1.1.0" + checksum: 10c0/cda6a3dc2d50a182c5865b160f72077aac197046600091dbb005dd0a66db9cce3c5eaed6d470ac8ed49d7bcbeef6ee5f0bc288db5ff9a70cbd003e5909065233 + languageName: node + linkType: hard + +"@protobufjs/float@npm:^1.0.2": + version: 1.0.2 + resolution: "@protobufjs/float@npm:1.0.2" + checksum: 10c0/18f2bdede76ffcf0170708af15c9c9db6259b771e6b84c51b06df34a9c339dbbeec267d14ce0bddd20acc142b1d980d983d31434398df7f98eb0c94a0eb79069 + languageName: node + linkType: hard + +"@protobufjs/inquire@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/inquire@npm:1.1.0" + checksum: 10c0/64372482efcba1fb4d166a2664a6395fa978b557803857c9c03500e0ac1013eb4b1aacc9ed851dd5fc22f81583670b4f4431bae186f3373fedcfde863ef5921a + languageName: node + linkType: hard + +"@protobufjs/path@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/path@npm:1.1.2" + checksum: 10c0/cece0a938e7f5dfd2fa03f8c14f2f1cf8b0d6e13ac7326ff4c96ea311effd5fb7ae0bba754fbf505312af2e38500250c90e68506b97c02360a43793d88a0d8b4 + languageName: node + linkType: hard + +"@protobufjs/pool@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/pool@npm:1.1.0" + checksum: 10c0/eda2718b7f222ac6e6ad36f758a92ef90d26526026a19f4f17f668f45e0306a5bd734def3f48f51f8134ae0978b6262a5c517c08b115a551756d1a3aadfcf038 + languageName: node + linkType: hard + +"@protobufjs/utf8@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/utf8@npm:1.1.0" + checksum: 10c0/a3fe31fe3fa29aa3349e2e04ee13dc170cc6af7c23d92ad49e3eeaf79b9766264544d3da824dba93b7855bd6a2982fb40032ef40693da98a136d835752beb487 + languageName: node + linkType: hard + +"@sindresorhus/is@npm:^4.0.0": + version: 4.6.0 + resolution: "@sindresorhus/is@npm:4.6.0" + checksum: 10c0/33b6fb1d0834ec8dd7689ddc0e2781c2bfd8b9c4e4bacbcb14111e0ae00621f2c264b8a7d36541799d74888b5dccdf422a891a5cb5a709ace26325eedc81e22e + languageName: node + linkType: hard + +"@szmarczak/http-timer@npm:^4.0.5": + version: 4.0.6 + resolution: "@szmarczak/http-timer@npm:4.0.6" + dependencies: + defer-to-connect: "npm:^2.0.0" + checksum: 10c0/73946918c025339db68b09abd91fa3001e87fc749c619d2e9c2003a663039d4c3cb89836c98a96598b3d47dec2481284ba85355392644911f5ecd2336536697f + languageName: node + linkType: hard + +"@types/cacheable-request@npm:^6.0.1": + version: 6.0.3 + resolution: "@types/cacheable-request@npm:6.0.3" + dependencies: + "@types/http-cache-semantics": "npm:*" + "@types/keyv": "npm:^3.1.4" + "@types/node": "npm:*" + "@types/responselike": "npm:^1.0.0" + checksum: 10c0/10816a88e4e5b144d43c1d15a81003f86d649776c7f410c9b5e6579d0ad9d4ca71c541962fb403077388b446e41af7ae38d313e46692144985f006ac5e11fa03 + languageName: node + linkType: hard + +"@types/eslint-scope@npm:^3.7.7": + version: 3.7.7 + resolution: "@types/eslint-scope@npm:3.7.7" + dependencies: + "@types/eslint": "npm:*" + "@types/estree": "npm:*" + checksum: 10c0/a0ecbdf2f03912679440550817ff77ef39a30fa8bfdacaf6372b88b1f931828aec392f52283240f0d648cf3055c5ddc564544a626bcf245f3d09fcb099ebe3cc + languageName: node + linkType: hard + +"@types/eslint@npm:*": + version: 9.6.1 + resolution: "@types/eslint@npm:9.6.1" + dependencies: + "@types/estree": "npm:*" + "@types/json-schema": "npm:*" + checksum: 10c0/69ba24fee600d1e4c5abe0df086c1a4d798abf13792d8cfab912d76817fe1a894359a1518557d21237fbaf6eda93c5ab9309143dee4c59ef54336d1b3570420e + languageName: node + linkType: hard + +"@types/estree@npm:*, @types/estree@npm:^1.0.8": + version: 1.0.8 + resolution: "@types/estree@npm:1.0.8" + checksum: 10c0/39d34d1afaa338ab9763f37ad6066e3f349444f9052b9676a7cc0252ef9485a41c6d81c9c4e0d26e9077993354edf25efc853f3224dd4b447175ef62bdcc86a5 + languageName: node + linkType: hard + +"@types/html-minifier-terser@npm:^6.0.0": + version: 6.1.0 + resolution: "@types/html-minifier-terser@npm:6.1.0" + checksum: 10c0/a62fb8588e2f3818d82a2d7b953ad60a4a52fd767ae04671de1c16f5788bd72f1ed3a6109ed63fd190c06a37d919e3c39d8adbc1793a005def76c15a3f5f5dab + languageName: node + linkType: hard + +"@types/http-cache-semantics@npm:*": + version: 4.0.4 + resolution: "@types/http-cache-semantics@npm:4.0.4" + checksum: 10c0/51b72568b4b2863e0fe8d6ce8aad72a784b7510d72dc866215642da51d84945a9459fa89f49ec48f1e9a1752e6a78e85a4cda0ded06b1c73e727610c925f9ce6 + languageName: node + linkType: hard + +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.9": + version: 7.0.15 + resolution: "@types/json-schema@npm:7.0.15" + checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db + languageName: node + linkType: hard + +"@types/keyv@npm:^3.1.4": + version: 3.1.4 + resolution: "@types/keyv@npm:3.1.4" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/ff8f54fc49621210291f815fe5b15d809fd7d032941b3180743440bd507ecdf08b9e844625fa346af568c84bf34114eb378dcdc3e921a08ba1e2a08d7e3c809c + languageName: node + linkType: hard + +"@types/node@npm:*, @types/node@npm:>=13.7.0": + version: 24.10.1 + resolution: "@types/node@npm:24.10.1" + dependencies: + undici-types: "npm:~7.16.0" + checksum: 10c0/d6bca7a78f550fbb376f236f92b405d676003a8a09a1b411f55920ef34286ee3ee51f566203920e835478784df52662b5b2af89159d9d319352e9ea21801c002 + languageName: node + linkType: hard + +"@types/node@npm:^22.7.7": + version: 22.19.1 + resolution: "@types/node@npm:22.19.1" + dependencies: + undici-types: "npm:~6.21.0" + checksum: 10c0/6edd93aea86da740cb7872626839cd6f4a67a049d3a3a6639cb592c620ec591408a30989ab7410008d1a0b2d4985ce50f1e488e79c033e4476d3bec6833b0a2f + languageName: node + linkType: hard + +"@types/responselike@npm:^1.0.0": + version: 1.0.3 + resolution: "@types/responselike@npm:1.0.3" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/a58ba341cb9e7d74f71810a88862da7b2a6fa42e2a1fc0ce40498f6ea1d44382f0640117057da779f74c47039f7166bf48fad02dc876f94e005c7afa50f5e129 + languageName: node + linkType: hard + +"@types/yauzl@npm:^2.9.1": + version: 2.10.3 + resolution: "@types/yauzl@npm:2.10.3" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/f1b7c1b99fef9f2fe7f1985ef7426d0cebe48cd031f1780fcdc7451eec7e31ac97028f16f50121a59bcf53086a1fc8c856fd5b7d3e00970e43d92ae27d6b43dc + languageName: node + linkType: hard + +"@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/ast@npm:1.14.1" + dependencies: + "@webassemblyjs/helper-numbers": "npm:1.13.2" + "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" + checksum: 10c0/67a59be8ed50ddd33fbb2e09daa5193ac215bf7f40a9371be9a0d9797a114d0d1196316d2f3943efdb923a3d809175e1563a3cb80c814fb8edccd1e77494972b + languageName: node + linkType: hard + +"@webassemblyjs/floating-point-hex-parser@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.13.2" + checksum: 10c0/0e88bdb8b50507d9938be64df0867f00396b55eba9df7d3546eb5dc0ca64d62e06f8d881ec4a6153f2127d0f4c11d102b6e7d17aec2f26bb5ff95a5e60652412 + languageName: node + linkType: hard + +"@webassemblyjs/helper-api-error@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/helper-api-error@npm:1.13.2" + checksum: 10c0/31be497f996ed30aae4c08cac3cce50c8dcd5b29660383c0155fce1753804fc55d47fcba74e10141c7dd2899033164e117b3bcfcda23a6b043e4ded4f1003dfb + languageName: node + linkType: hard + +"@webassemblyjs/helper-buffer@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/helper-buffer@npm:1.14.1" + checksum: 10c0/0d54105dc373c0fe6287f1091e41e3a02e36cdc05e8cf8533cdc16c59ff05a646355415893449d3768cda588af451c274f13263300a251dc11a575bc4c9bd210 + languageName: node + linkType: hard + +"@webassemblyjs/helper-numbers@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/helper-numbers@npm:1.13.2" + dependencies: + "@webassemblyjs/floating-point-hex-parser": "npm:1.13.2" + "@webassemblyjs/helper-api-error": "npm:1.13.2" + "@xtuc/long": "npm:4.2.2" + checksum: 10c0/9c46852f31b234a8fb5a5a9d3f027bc542392a0d4de32f1a9c0075d5e8684aa073cb5929b56df565500b3f9cc0a2ab983b650314295b9bf208d1a1651bfc825a + languageName: node + linkType: hard + +"@webassemblyjs/helper-wasm-bytecode@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.13.2" + checksum: 10c0/c4355d14f369b30cf3cbdd3acfafc7d0488e086be6d578e3c9780bd1b512932352246be96e034e2a7fcfba4f540ec813352f312bfcbbfe5bcfbf694f82ccc682 + languageName: node + linkType: hard + +"@webassemblyjs/helper-wasm-section@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/helper-wasm-section@npm:1.14.1" + dependencies: + "@webassemblyjs/ast": "npm:1.14.1" + "@webassemblyjs/helper-buffer": "npm:1.14.1" + "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" + "@webassemblyjs/wasm-gen": "npm:1.14.1" + checksum: 10c0/1f9b33731c3c6dbac3a9c483269562fa00d1b6a4e7133217f40e83e975e636fd0f8736e53abd9a47b06b66082ecc976c7384391ab0a68e12d509ea4e4b948d64 + languageName: node + linkType: hard + +"@webassemblyjs/ieee754@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/ieee754@npm:1.13.2" + dependencies: + "@xtuc/ieee754": "npm:^1.2.0" + checksum: 10c0/2e732ca78c6fbae3c9b112f4915d85caecdab285c0b337954b180460290ccd0fb00d2b1dc4bb69df3504abead5191e0d28d0d17dfd6c9d2f30acac8c4961c8a7 + languageName: node + linkType: hard + +"@webassemblyjs/leb128@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/leb128@npm:1.13.2" + dependencies: + "@xtuc/long": "npm:4.2.2" + checksum: 10c0/dad5ef9e383c8ab523ce432dfd80098384bf01c45f70eb179d594f85ce5db2f80fa8c9cba03adafd85684e6d6310f0d3969a882538975989919329ac4c984659 + languageName: node + linkType: hard + +"@webassemblyjs/utf8@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/utf8@npm:1.13.2" + checksum: 10c0/d3fac9130b0e3e5a1a7f2886124a278e9323827c87a2b971e6d0da22a2ba1278ac9f66a4f2e363ecd9fac8da42e6941b22df061a119e5c0335f81006de9ee799 + languageName: node + linkType: hard + +"@webassemblyjs/wasm-edit@npm:^1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wasm-edit@npm:1.14.1" + dependencies: + "@webassemblyjs/ast": "npm:1.14.1" + "@webassemblyjs/helper-buffer": "npm:1.14.1" + "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" + "@webassemblyjs/helper-wasm-section": "npm:1.14.1" + "@webassemblyjs/wasm-gen": "npm:1.14.1" + "@webassemblyjs/wasm-opt": "npm:1.14.1" + "@webassemblyjs/wasm-parser": "npm:1.14.1" + "@webassemblyjs/wast-printer": "npm:1.14.1" + checksum: 10c0/5ac4781086a2ca4b320bdbfd965a209655fe8a208ca38d89197148f8597e587c9a2c94fb6bd6f1a7dbd4527c49c6844fcdc2af981f8d793a97bf63a016aa86d2 + languageName: node + linkType: hard + +"@webassemblyjs/wasm-gen@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wasm-gen@npm:1.14.1" + dependencies: + "@webassemblyjs/ast": "npm:1.14.1" + "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" + "@webassemblyjs/ieee754": "npm:1.13.2" + "@webassemblyjs/leb128": "npm:1.13.2" + "@webassemblyjs/utf8": "npm:1.13.2" + checksum: 10c0/d678810d7f3f8fecb2e2bdadfb9afad2ec1d2bc79f59e4711ab49c81cec578371e22732d4966f59067abe5fba8e9c54923b57060a729d28d408e608beef67b10 + languageName: node + linkType: hard + +"@webassemblyjs/wasm-opt@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wasm-opt@npm:1.14.1" + dependencies: + "@webassemblyjs/ast": "npm:1.14.1" + "@webassemblyjs/helper-buffer": "npm:1.14.1" + "@webassemblyjs/wasm-gen": "npm:1.14.1" + "@webassemblyjs/wasm-parser": "npm:1.14.1" + checksum: 10c0/515bfb15277ee99ba6b11d2232ddbf22aed32aad6d0956fe8a0a0a004a1b5a3a277a71d9a3a38365d0538ac40d1b7b7243b1a244ad6cd6dece1c1bb2eb5de7ee + languageName: node + linkType: hard + +"@webassemblyjs/wasm-parser@npm:1.14.1, @webassemblyjs/wasm-parser@npm:^1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wasm-parser@npm:1.14.1" + dependencies: + "@webassemblyjs/ast": "npm:1.14.1" + "@webassemblyjs/helper-api-error": "npm:1.13.2" + "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" + "@webassemblyjs/ieee754": "npm:1.13.2" + "@webassemblyjs/leb128": "npm:1.13.2" + "@webassemblyjs/utf8": "npm:1.13.2" + checksum: 10c0/95427b9e5addbd0f647939bd28e3e06b8deefdbdadcf892385b5edc70091bf9b92fa5faac3fce8333554437c5d85835afef8c8a7d9d27ab6ba01ffab954db8c6 + languageName: node + linkType: hard + +"@webassemblyjs/wast-printer@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wast-printer@npm:1.14.1" + dependencies: + "@webassemblyjs/ast": "npm:1.14.1" + "@xtuc/long": "npm:4.2.2" + checksum: 10c0/8d7768608996a052545251e896eac079c98e0401842af8dd4de78fba8d90bd505efb6c537e909cd6dae96e09db3fa2e765a6f26492553a675da56e2db51f9d24 + languageName: node + linkType: hard + +"@webpack-cli/configtest@npm:^3.0.1": + version: 3.0.1 + resolution: "@webpack-cli/configtest@npm:3.0.1" + peerDependencies: + webpack: ^5.82.0 + webpack-cli: 6.x.x + checksum: 10c0/edd24ecfc429298fe86446f7d7daedfe82d72e7f6236c81420605484fdadade5d59c6bcef3d76bd724e11d9727f74e75de183223ae62d3a568b2d54199688cbe + languageName: node + linkType: hard + +"@webpack-cli/info@npm:^3.0.1": + version: 3.0.1 + resolution: "@webpack-cli/info@npm:3.0.1" + peerDependencies: + webpack: ^5.82.0 + webpack-cli: 6.x.x + checksum: 10c0/b23b94e7dc8c93e79248f20d5f1bd0fbb7b9ba4b012803e2fdc5440b8f2ee1f3eca7f4933bbca346c8168673bf572b1858169a3cb2c17d9b8bcd833d480c2170 + languageName: node + linkType: hard + +"@webpack-cli/serve@npm:^3.0.1": + version: 3.0.1 + resolution: "@webpack-cli/serve@npm:3.0.1" + peerDependencies: + webpack: ^5.82.0 + webpack-cli: 6.x.x + peerDependenciesMeta: + webpack-dev-server: + optional: true + checksum: 10c0/65245e45bfa35e11a5b30631b99cfed0c1b39b2cc8320fa2d2a4185264535618827d349ec032c58af4201d6236cbc43bec894fcb840fdd06314611537a80e210 + languageName: node + linkType: hard + +"@xtuc/ieee754@npm:^1.2.0": + version: 1.2.0 + resolution: "@xtuc/ieee754@npm:1.2.0" + checksum: 10c0/a8565d29d135039bd99ae4b2220d3e167d22cf53f867e491ed479b3f84f895742d0097f935b19aab90265a23d5d46711e4204f14c479ae3637fbf06c4666882f + languageName: node + linkType: hard + +"@xtuc/long@npm:4.2.2": + version: 4.2.2 + resolution: "@xtuc/long@npm:4.2.2" + checksum: 10c0/8582cbc69c79ad2d31568c412129bf23d2b1210a1dfb60c82d5a1df93334da4ee51f3057051658569e2c196d8dc33bc05ae6b974a711d0d16e801e1d0647ccd1 + languageName: node + linkType: hard + +"abbrev@npm:^4.0.0": + version: 4.0.0 + resolution: "abbrev@npm:4.0.0" + checksum: 10c0/b4cc16935235e80702fc90192e349e32f8ef0ed151ef506aa78c81a7c455ec18375c4125414b99f84b2e055199d66383e787675f0bcd87da7a4dbd59f9eac1d5 + languageName: node + linkType: hard + +"acorn-import-attributes@npm:^1.9.5": + version: 1.9.5 + resolution: "acorn-import-attributes@npm:1.9.5" + peerDependencies: + acorn: ^8 + checksum: 10c0/5926eaaead2326d5a86f322ff1b617b0f698aa61dc719a5baa0e9d955c9885cc71febac3fb5bacff71bbf2c4f9c12db2056883c68c53eb962c048b952e1e013d + languageName: node + linkType: hard + +"acorn-import-phases@npm:^1.0.3": + version: 1.0.4 + resolution: "acorn-import-phases@npm:1.0.4" + peerDependencies: + acorn: ^8.14.0 + checksum: 10c0/338eb46fc1aed5544f628344cb9af189450b401d152ceadbf1f5746901a5d923016cd0e7740d5606062d374fdf6941c29bb515d2bd133c4f4242d5d4cd73a3c7 + languageName: node + linkType: hard + +"acorn@npm:^8.14.0, acorn@npm:^8.15.0": + version: 8.15.0 + resolution: "acorn@npm:8.15.0" + bin: + acorn: bin/acorn + checksum: 10c0/dec73ff59b7d6628a01eebaece7f2bdb8bb62b9b5926dcad0f8931f2b8b79c2be21f6c68ac095592adb5adb15831a3635d9343e6a91d028bbe85d564875ec3ec + languageName: node + linkType: hard + +"agent-base@npm:^7.1.0, agent-base@npm:^7.1.2": + version: 7.1.4 + resolution: "agent-base@npm:7.1.4" + checksum: 10c0/c2c9ab7599692d594b6a161559ada307b7a624fa4c7b03e3afdb5a5e31cd0e53269115b620fcab024c5ac6a6f37fa5eb2e004f076ad30f5f7e6b8b671f7b35fe + languageName: node + linkType: hard + +"ajv-formats@npm:^2.1.1": + version: 2.1.1 + resolution: "ajv-formats@npm:2.1.1" + dependencies: + ajv: "npm:^8.0.0" + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + checksum: 10c0/e43ba22e91b6a48d96224b83d260d3a3a561b42d391f8d3c6d2c1559f9aa5b253bfb306bc94bbeca1d967c014e15a6efe9a207309e95b3eaae07fcbcdc2af662 + languageName: node + linkType: hard + +"ajv-keywords@npm:^5.1.0": + version: 5.1.0 + resolution: "ajv-keywords@npm:5.1.0" + dependencies: + fast-deep-equal: "npm:^3.1.3" + peerDependencies: + ajv: ^8.8.2 + checksum: 10c0/18bec51f0171b83123ba1d8883c126e60c6f420cef885250898bf77a8d3e65e3bfb9e8564f497e30bdbe762a83e0d144a36931328616a973ee669dc74d4a9590 + languageName: node + linkType: hard + +"ajv@npm:^8.0.0, ajv@npm:^8.9.0": + version: 8.17.1 + resolution: "ajv@npm:8.17.1" + dependencies: + fast-deep-equal: "npm:^3.1.3" + fast-uri: "npm:^3.0.1" + json-schema-traverse: "npm:^1.0.0" + require-from-string: "npm:^2.0.2" + checksum: 10c0/ec3ba10a573c6b60f94639ffc53526275917a2df6810e4ab5a6b959d87459f9ef3f00d5e7865b82677cb7d21590355b34da14d1d0b9c32d75f95a187e76fff35 + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737 + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.2.2 + resolution: "ansi-regex@npm:6.2.2" + checksum: 10c0/05d4acb1d2f59ab2cf4b794339c7b168890d44dda4bf0ce01152a8da0213aca207802f930442ce8cd22d7a92f44907664aac6508904e75e038fa944d2601b30f + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: 10c0/895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041 + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.3 + resolution: "ansi-styles@npm:6.2.3" + checksum: 10c0/23b8a4ce14e18fb854693b95351e286b771d23d8844057ed2e7d083cd3e708376c3323707ec6a24365f7d7eda3ca00327fe04092e29e551499ec4c8b7bfac868 + languageName: node + linkType: hard + +"argparse@npm:^2.0.1": + version: 2.0.1 + resolution: "argparse@npm:2.0.1" + checksum: 10c0/c5640c2d89045371c7cedd6a70212a04e360fd34d6edeae32f6952c63949e3525ea77dbec0289d8213a99bbaeab5abfa860b5c12cf88a2e6cf8106e90dd27a7e + languageName: node + linkType: hard + +"baseline-browser-mapping@npm:^2.8.25": + version: 2.8.30 + resolution: "baseline-browser-mapping@npm:2.8.30" + bin: + baseline-browser-mapping: dist/cli.js + checksum: 10c0/724e2a71dc18af1555953278544d60d3677ad1413d19b4c68f0b1d16cb075186035125cad38d93c1ccc2df8dc8520e6d47452b76b265898ad7ac480630f12cae + languageName: node + linkType: hard + +"boolbase@npm:^1.0.0": + version: 1.0.0 + resolution: "boolbase@npm:1.0.0" + checksum: 10c0/e4b53deb4f2b85c52be0e21a273f2045c7b6a6ea002b0e139c744cb6f95e9ec044439a52883b0d74dedd1ff3da55ed140cfdddfed7fb0cccbed373de5dce1bcf + languageName: node + linkType: hard + +"boolean@npm:^3.0.1": + version: 3.2.0 + resolution: "boolean@npm:3.2.0" + checksum: 10c0/6a0dc9668f6f3dda42a53c181fcbdad223169c8d87b6c4011b87a8b14a21770efb2934a778f063d7ece17280f8c06d313c87f7b834bb1dd526a867ffcd00febf + languageName: node + linkType: hard + +"braces@npm:^3.0.3": + version: 3.0.3 + resolution: "braces@npm:3.0.3" + dependencies: + fill-range: "npm:^7.1.1" + checksum: 10c0/7c6dfd30c338d2997ba77500539227b9d1f85e388a5f43220865201e407e076783d0881f2d297b9f80951b4c957fcf0b51c1d2d24227631643c3f7c284b0aa04 + languageName: node + linkType: hard + +"browserslist@npm:^4.26.3": + version: 4.28.0 + resolution: "browserslist@npm:4.28.0" + dependencies: + baseline-browser-mapping: "npm:^2.8.25" + caniuse-lite: "npm:^1.0.30001754" + electron-to-chromium: "npm:^1.5.249" + node-releases: "npm:^2.0.27" + update-browserslist-db: "npm:^1.1.4" + bin: + browserslist: cli.js + checksum: 10c0/4284fd568f7d40a496963083860d488cb2a89fb055b6affd316bebc59441fec938e090b3e62c0ee065eb0bc88cd1bc145f4300a16c75f3f565621c5823715ae1 + languageName: node + linkType: hard + +"buffer-crc32@npm:~0.2.3": + version: 0.2.13 + resolution: "buffer-crc32@npm:0.2.13" + checksum: 10c0/cb0a8ddf5cf4f766466db63279e47761eb825693eeba6a5a95ee4ec8cb8f81ede70aa7f9d8aeec083e781d47154290eb5d4d26b3f7a465ec57fb9e7d59c47150 + languageName: node + linkType: hard + +"buffer-from@npm:^1.0.0": + version: 1.1.2 + resolution: "buffer-from@npm:1.1.2" + checksum: 10c0/124fff9d66d691a86d3b062eff4663fe437a9d9ee4b47b1b9e97f5a5d14f6d5399345db80f796827be7c95e70a8e765dd404b7c3ff3b3324f98e9b0c8826cc34 + languageName: node + linkType: hard + +"cacache@npm:^20.0.1": + version: 20.0.2 + resolution: "cacache@npm:20.0.2" + dependencies: + "@npmcli/fs": "npm:^4.0.0" + fs-minipass: "npm:^3.0.0" + glob: "npm:^11.0.3" + lru-cache: "npm:^11.1.0" + minipass: "npm:^7.0.3" + minipass-collect: "npm:^2.0.1" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + p-map: "npm:^7.0.2" + ssri: "npm:^13.0.0" + unique-filename: "npm:^4.0.0" + checksum: 10c0/11db56f35167f66661e63901427a198775ecf431583c7bfef1dd2fcb970ac826d7cec725ba39b7f389bf8fd3d8ea3290b22c14630e875df913d36e35cdd99df6 + languageName: node + linkType: hard + +"cacheable-lookup@npm:^5.0.3": + version: 5.0.4 + resolution: "cacheable-lookup@npm:5.0.4" + checksum: 10c0/a6547fb4954b318aa831cbdd2f7b376824bc784fb1fa67610e4147099e3074726072d9af89f12efb69121415a0e1f2918a8ddd4aafcbcf4e91fbeef4a59cd42c + languageName: node + linkType: hard + +"cacheable-request@npm:^7.0.2": + version: 7.0.4 + resolution: "cacheable-request@npm:7.0.4" + dependencies: + clone-response: "npm:^1.0.2" + get-stream: "npm:^5.1.0" + http-cache-semantics: "npm:^4.0.0" + keyv: "npm:^4.0.0" + lowercase-keys: "npm:^2.0.0" + normalize-url: "npm:^6.0.1" + responselike: "npm:^2.0.0" + checksum: 10c0/0834a7d17ae71a177bc34eab06de112a43f9b5ad05ebe929bec983d890a7d9f2bc5f1aa8bb67ea2b65e07a3bc74bea35fa62dd36dbac52876afe36fdcf83da41 + languageName: node + linkType: hard + +"camel-case@npm:^4.1.2": + version: 4.1.2 + resolution: "camel-case@npm:4.1.2" + dependencies: + pascal-case: "npm:^3.1.2" + tslib: "npm:^2.0.3" + checksum: 10c0/bf9eefaee1f20edbed2e9a442a226793bc72336e2b99e5e48c6b7252b6f70b080fc46d8246ab91939e2af91c36cdd422e0af35161e58dd089590f302f8f64c8a + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.30001754": + version: 1.0.30001756 + resolution: "caniuse-lite@npm:1.0.30001756" + checksum: 10c0/863df07bd8d5139371ce7d4e582f03fef38141726282dcd532421bbd95ea298c7f953a8e1a9790db89ca1816bd8ce3cce638a66361b769dd1f2dc8d4c721d546 + languageName: node + linkType: hard + +"chalk@npm:^4.1.0": + version: 4.1.2 + resolution: "chalk@npm:4.1.2" + dependencies: + ansi-styles: "npm:^4.1.0" + supports-color: "npm:^7.1.0" + checksum: 10c0/4a3fef5cc34975c898ffe77141450f679721df9dde00f6c304353fa9c8b571929123b26a0e4617bde5018977eb655b31970c297b91b63ee83bb82aeb04666880 + languageName: node + linkType: hard + +"chownr@npm:^3.0.0": + version: 3.0.0 + resolution: "chownr@npm:3.0.0" + checksum: 10c0/43925b87700f7e3893296c8e9c56cc58f926411cce3a6e5898136daaf08f08b9a8eb76d37d3267e707d0dcc17aed2e2ebdf5848c0c3ce95cf910a919935c1b10 + languageName: node + linkType: hard + +"chrome-trace-event@npm:^1.0.2": + version: 1.0.4 + resolution: "chrome-trace-event@npm:1.0.4" + checksum: 10c0/3058da7a5f4934b87cf6a90ef5fb68ebc5f7d06f143ed5a4650208e5d7acae47bc03ec844b29fbf5ba7e46e8daa6acecc878f7983a4f4bb7271593da91e61ff5 + languageName: node + linkType: hard + +"cjs-module-lexer@npm:^1.2.2": + version: 1.4.3 + resolution: "cjs-module-lexer@npm:1.4.3" + checksum: 10c0/076b3af85adc4d65dbdab1b5b240fe5b45d44fcf0ef9d429044dd94d19be5589376805c44fb2d4b3e684e5fe6a9b7cf3e426476a6507c45283c5fc6ff95240be + languageName: node + linkType: hard + +"clean-css@npm:^5.2.2": + version: 5.3.3 + resolution: "clean-css@npm:5.3.3" + dependencies: + source-map: "npm:~0.6.0" + checksum: 10c0/381de7523e23f3762eb180e327dcc0cedafaf8cb1cd8c26b7cc1fc56e0829a92e734729c4f955394d65ed72fb62f82d8baf78af34b33b8a7d41ebad2accdd6fb + languageName: node + linkType: hard + +"clone-deep@npm:^4.0.1": + version: 4.0.1 + resolution: "clone-deep@npm:4.0.1" + dependencies: + is-plain-object: "npm:^2.0.4" + kind-of: "npm:^6.0.2" + shallow-clone: "npm:^3.0.0" + checksum: 10c0/637753615aa24adf0f2d505947a1bb75e63964309034a1cf56ba4b1f30af155201edd38d26ffe26911adaae267a3c138b344a4947d39f5fc1b6d6108125aa758 + languageName: node + linkType: hard + +"clone-response@npm:^1.0.2": + version: 1.0.3 + resolution: "clone-response@npm:1.0.3" + dependencies: + mimic-response: "npm:^1.0.0" + checksum: 10c0/06a2b611824efb128810708baee3bd169ec9a1bf5976a5258cd7eb3f7db25f00166c6eee5961f075c7e38e194f373d4fdf86b8166ad5b9c7e82bbd2e333a6087 + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: 10c0/37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95 + languageName: node + linkType: hard + +"colorette@npm:^2.0.14": + version: 2.0.20 + resolution: "colorette@npm:2.0.20" + checksum: 10c0/e94116ff33b0ff56f3b83b9ace895e5bf87c2a7a47b3401b8c3f3226e050d5ef76cf4072fb3325f9dc24d1698f9b730baf4e05eeaf861d74a1883073f4c98a40 + languageName: node + linkType: hard + +"commander@npm:^12.1.0": + version: 12.1.0 + resolution: "commander@npm:12.1.0" + checksum: 10c0/6e1996680c083b3b897bfc1cfe1c58dfbcd9842fd43e1aaf8a795fbc237f65efcc860a3ef457b318e73f29a4f4a28f6403c3d653d021d960e4632dd45bde54a9 + languageName: node + linkType: hard + +"commander@npm:^2.20.0": + version: 2.20.3 + resolution: "commander@npm:2.20.3" + checksum: 10c0/74c781a5248c2402a0a3e966a0a2bba3c054aad144f5c023364be83265e796b20565aa9feff624132ff629aa64e16999fa40a743c10c12f7c61e96a794b99288 + languageName: node + linkType: hard + +"commander@npm:^8.3.0": + version: 8.3.0 + resolution: "commander@npm:8.3.0" + checksum: 10c0/8b043bb8322ea1c39664a1598a95e0495bfe4ca2fad0d84a92d7d1d8d213e2a155b441d2470c8e08de7c4a28cf2bc6e169211c49e1b21d9f7edc6ae4d9356060 + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: 10c0/053ea8b2135caff68a9e81470e845613e374e7309a47731e81639de3eaeb90c3d01af0e0b44d2ab9d50b43467223b88567dfeb3262db942dc063b9976718ffc1 + languageName: node + linkType: hard + +"crypto-randomuuid@npm:^1.0.0": + version: 1.0.0 + resolution: "crypto-randomuuid@npm:1.0.0" + checksum: 10c0/6c8f7513f3b0c38b876b5011d91e21c284f7a695d27b6ef25a2a1ca89c362af23e321bf47953069b9fe56bc384de7880a13c390a4663ac5dcf525a1b4f937a1f + languageName: node + linkType: hard + +"css-select@npm:^4.1.3": + version: 4.3.0 + resolution: "css-select@npm:4.3.0" + dependencies: + boolbase: "npm:^1.0.0" + css-what: "npm:^6.0.1" + domhandler: "npm:^4.3.1" + domutils: "npm:^2.8.0" + nth-check: "npm:^2.0.1" + checksum: 10c0/a489d8e5628e61063d5a8fe0fa1cc7ae2478cb334a388a354e91cf2908154be97eac9fa7ed4dffe87a3e06cf6fcaa6016553115335c4fd3377e13dac7bd5a8e1 + languageName: node + linkType: hard + +"css-what@npm:^6.0.1": + version: 6.2.2 + resolution: "css-what@npm:6.2.2" + checksum: 10c0/91e24c26fb977b4ccef30d7007d2668c1c10ac0154cc3f42f7304410e9594fb772aea4f30c832d2993b132ca8d99338050866476210316345ec2e7d47b248a56 + languageName: node + linkType: hard + +"dc-polyfill@npm:^0.1.10": + version: 0.1.10 + resolution: "dc-polyfill@npm:0.1.10" + checksum: 10c0/b4a847b5883fb3bc1173d48b98d2aa554af12b427b13d3f5fbd31a4d4cbfc733d8134e261e442ac890df3606f97e5440b603ff72d0c9cd62ac2e5f3cbc52aa6d + languageName: node + linkType: hard + +"dd-trace@npm:^5.76.0": + version: 5.80.0 + resolution: "dd-trace@npm:5.80.0" + dependencies: + "@datadog/libdatadog": "npm:0.7.0" + "@datadog/native-appsec": "npm:10.3.0" + "@datadog/native-iast-taint-tracking": "npm:4.0.0" + "@datadog/native-metrics": "npm:3.1.1" + "@datadog/openfeature-node-server": "npm:^0.2.0" + "@datadog/pprof": "npm:5.12.0" + "@datadog/sketches-js": "npm:2.1.1" + "@datadog/wasm-js-rewriter": "npm:5.0.1" + "@isaacs/ttlcache": "npm:^2.0.1" + "@opentelemetry/api": "npm:>=1.0.0 <1.10.0" + "@opentelemetry/api-logs": "npm:<1.0.0" + "@opentelemetry/core": "npm:>=1.14.0 <1.31.0" + "@opentelemetry/resources": "npm:>=1.0.0 <1.31.0" + crypto-randomuuid: "npm:^1.0.0" + dc-polyfill: "npm:^0.1.10" + escape-string-regexp: "npm:^5.0.0" + ignore: "npm:^7.0.5" + import-in-the-middle: "npm:^1.14.2" + istanbul-lib-coverage: "npm:^3.2.2" + jest-docblock: "npm:^29.7.0" + jsonpath-plus: "npm:^10.3.0" + limiter: "npm:^1.1.5" + lodash.sortby: "npm:^4.7.0" + lru-cache: "npm:^10.4.3" + module-details-from-path: "npm:^1.0.4" + mutexify: "npm:^1.4.0" + opentracing: "npm:>=0.14.7" + path-to-regexp: "npm:^0.1.12" + pprof-format: "npm:^2.1.1" + protobufjs: "npm:^7.5.3" + retry: "npm:^0.13.1" + rfdc: "npm:^1.4.1" + semifies: "npm:^1.0.0" + shell-quote: "npm:^1.8.2" + source-map: "npm:^0.7.4" + tlhunter-sorted-set: "npm:^0.1.0" + ttl-set: "npm:^1.0.0" + checksum: 10c0/94220c45d27a5a4bb8cee571385181fb32b973eacbf5149098e55d7f8e53e7bfb8114e73502e2c97e148b6753eb8eb6da7f75aa2a308d2ca17ab94a3af429e52 + languageName: node + linkType: hard + +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.4": + version: 4.4.3 + resolution: "debug@npm:4.4.3" + dependencies: + ms: "npm:^2.1.3" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10c0/d79136ec6c83ecbefd0f6a5593da6a9c91ec4d7ddc4b54c883d6e71ec9accb5f67a1a5e96d00a328196b5b5c86d365e98d8a3a70856aaf16b4e7b1985e67f5a6 + languageName: node + linkType: hard + +"decompress-response@npm:^6.0.0": + version: 6.0.0 + resolution: "decompress-response@npm:6.0.0" + dependencies: + mimic-response: "npm:^3.1.0" + checksum: 10c0/bd89d23141b96d80577e70c54fb226b2f40e74a6817652b80a116d7befb8758261ad073a8895648a29cc0a5947021ab66705cb542fa9c143c82022b27c5b175e + languageName: node + linkType: hard + +"defer-to-connect@npm:^2.0.0": + version: 2.0.1 + resolution: "defer-to-connect@npm:2.0.1" + checksum: 10c0/625ce28e1b5ad10cf77057b9a6a727bf84780c17660f6644dab61dd34c23de3001f03cedc401f7d30a4ed9965c2e8a7336e220a329146f2cf85d4eddea429782 + languageName: node + linkType: hard + +"define-data-property@npm:^1.0.1": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.0.1" + checksum: 10c0/dea0606d1483eb9db8d930d4eac62ca0fa16738b0b3e07046cddfacf7d8c868bbe13fa0cb263eb91c7d0d527960dc3f2f2471a69ed7816210307f6744fe62e37 + languageName: node + linkType: hard + +"define-properties@npm:^1.2.1": + version: 1.2.1 + resolution: "define-properties@npm:1.2.1" + dependencies: + define-data-property: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.0" + object-keys: "npm:^1.1.1" + checksum: 10c0/88a152319ffe1396ccc6ded510a3896e77efac7a1bfbaa174a7b00414a1747377e0bb525d303794a47cf30e805c2ec84e575758512c6e44a993076d29fd4e6c3 + languageName: node + linkType: hard + +"delay@npm:^5.0.0": + version: 5.0.0 + resolution: "delay@npm:5.0.0" + checksum: 10c0/01cdc4cd0cd35fb622518a3df848e67e09763a38e7cdada2232b6fda9ddda72eddcf74f0e24211200fbe718434f2335f2a2633875a6c96037fefa6de42896ad7 + languageName: node + linkType: hard + +"detect-newline@npm:^3.0.0": + version: 3.1.0 + resolution: "detect-newline@npm:3.1.0" + checksum: 10c0/c38cfc8eeb9fda09febb44bcd85e467c970d4e3bf526095394e5a4f18bc26dd0cf6b22c69c1fa9969261521c593836db335c2795218f6d781a512aea2fb8209d + languageName: node + linkType: hard + +"detect-node@npm:^2.0.4": + version: 2.1.0 + resolution: "detect-node@npm:2.1.0" + checksum: 10c0/f039f601790f2e9d4654e499913259a798b1f5246ae24f86ab5e8bd4aaf3bce50484234c494f11fb00aecb0c6e2733aa7b1cf3f530865640b65fbbd65b2c4e09 + languageName: node + linkType: hard + +"dom-converter@npm:^0.2.0": + version: 0.2.0 + resolution: "dom-converter@npm:0.2.0" + dependencies: + utila: "npm:~0.4" + checksum: 10c0/e96aa63bd8c6ee3cd9ce19c3aecfc2c42e50a460e8087114794d4f5ecf3a4f052b34ea3bf2d73b5d80b4da619073b49905e6d7d788ceb7814ca4c29be5354a11 + languageName: node + linkType: hard + +"dom-serializer@npm:^1.0.1": + version: 1.4.1 + resolution: "dom-serializer@npm:1.4.1" + dependencies: + domelementtype: "npm:^2.0.1" + domhandler: "npm:^4.2.0" + entities: "npm:^2.0.0" + checksum: 10c0/67d775fa1ea3de52035c98168ddcd59418356943b5eccb80e3c8b3da53adb8e37edb2cc2f885802b7b1765bf5022aec21dfc32910d7f9e6de4c3148f095ab5e0 + languageName: node + linkType: hard + +"domelementtype@npm:^2.0.1, domelementtype@npm:^2.2.0": + version: 2.3.0 + resolution: "domelementtype@npm:2.3.0" + checksum: 10c0/686f5a9ef0fff078c1412c05db73a0dce096190036f33e400a07e2a4518e9f56b1e324f5c576a0a747ef0e75b5d985c040b0d51945ce780c0dd3c625a18cd8c9 + languageName: node + linkType: hard + +"domhandler@npm:^4.0.0, domhandler@npm:^4.2.0, domhandler@npm:^4.3.1": + version: 4.3.1 + resolution: "domhandler@npm:4.3.1" + dependencies: + domelementtype: "npm:^2.2.0" + checksum: 10c0/5c199c7468cb052a8b5ab80b13528f0db3d794c64fc050ba793b574e158e67c93f8336e87fd81e9d5ee43b0e04aea4d8b93ed7be4899cb726a1601b3ba18538b + languageName: node + linkType: hard + +"domutils@npm:^2.5.2, domutils@npm:^2.8.0": + version: 2.8.0 + resolution: "domutils@npm:2.8.0" + dependencies: + dom-serializer: "npm:^1.0.1" + domelementtype: "npm:^2.2.0" + domhandler: "npm:^4.2.0" + checksum: 10c0/d58e2ae01922f0dd55894e61d18119924d88091837887bf1438f2327f32c65eb76426bd9384f81e7d6dcfb048e0f83c19b222ad7101176ad68cdc9c695b563db + languageName: node + linkType: hard + +"dot-case@npm:^3.0.4": + version: 3.0.4 + resolution: "dot-case@npm:3.0.4" + dependencies: + no-case: "npm:^3.0.4" + tslib: "npm:^2.0.3" + checksum: 10c0/5b859ea65097a7ea870e2c91b5768b72ddf7fa947223fd29e167bcdff58fe731d941c48e47a38ec8aa8e43044c8fbd15cd8fa21689a526bc34b6548197cd5b05 + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 10c0/26f364ebcdb6395f95124fda411f63137a4bfb5d3a06453f7f23dfe52502905bd84e0488172e0f9ec295fdc45f05c23d5d91baf16bd26f0fe9acd777a188dc39 + languageName: node + linkType: hard + +"electron-to-chromium@npm:^1.5.249": + version: 1.5.259 + resolution: "electron-to-chromium@npm:1.5.259" + checksum: 10c0/a6600ff20d513e1acce29cd04af5fcb338295ebe5a13fa9802009464d9c269a4a092218c8ea8c9b85017a1efd75606fe0cdf5f36216979f7c8462af7df2f530d + languageName: node + linkType: hard + +"electron@npm:39.2.3": + version: 39.2.3 + resolution: "electron@npm:39.2.3" + dependencies: + "@electron/get": "npm:^2.0.0" + "@types/node": "npm:^22.7.7" + extract-zip: "npm:^2.0.1" + bin: + electron: cli.js + checksum: 10c0/4ebfd932cabaf2b49859b1437661941e1a4475ac5b8a7f8e7be02276ea6ba0f901889b02a39cdaab7803c41f87afa46216e626397687140df5eb7978caade595 + languageName: node + linkType: hard + +"electron@workspace:.": + version: 0.0.0-use.local + resolution: "electron@workspace:." + dependencies: + "@datadog/electron": "file:../../../packages/electron/package.tgz" + electron: "npm:39.2.3" + html-webpack-plugin: "npm:5.6.5" + ts-loader: "npm:9.5.4" + webpack: "npm:5.103.0" + webpack-cli: "npm:6.0.1" + languageName: unknown + linkType: soft + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: 10c0/b6053ad39951c4cf338f9092d7bfba448cdfd46fe6a2a034700b149ac9ffbc137e361cbd3c442297f86bed2e5f7576c1b54cc0a6bf8ef5106cc62f496af35010 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 10c0/af014e759a72064cf66e6e694a7fc6b0ed3d8db680427b021a89727689671cefe9d04151b2cad51dbaf85d5ba790d061cd167f1cf32eb7b281f6368b3c181639 + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: "npm:^0.6.2" + checksum: 10c0/36d938712ff00fe1f4bac88b43bcffb5930c1efa57bbcdca9d67e1d9d6c57cfb1200fb01efe0f3109b2ce99b231f90779532814a81370a1bd3274a0f58585039 + languageName: node + linkType: hard + +"end-of-stream@npm:^1.1.0": + version: 1.4.5 + resolution: "end-of-stream@npm:1.4.5" + dependencies: + once: "npm:^1.4.0" + checksum: 10c0/b0701c92a10b89afb1cb45bf54a5292c6f008d744eb4382fa559d54775ff31617d1d7bc3ef617575f552e24fad2c7c1a1835948c66b3f3a4be0a6c1f35c883d8 + languageName: node + linkType: hard + +"enhanced-resolve@npm:^5.0.0, enhanced-resolve@npm:^5.17.3": + version: 5.18.3 + resolution: "enhanced-resolve@npm:5.18.3" + dependencies: + graceful-fs: "npm:^4.2.4" + tapable: "npm:^2.2.0" + checksum: 10c0/d413c23c2d494e4c1c9c9ac7d60b812083dc6d446699ed495e69c920988af0a3c66bf3f8d0e7a45cb1686c2d4c1df9f4e7352d973f5b56fe63d8d711dd0ccc54 + languageName: node + linkType: hard + +"entities@npm:^2.0.0": + version: 2.2.0 + resolution: "entities@npm:2.2.0" + checksum: 10c0/7fba6af1f116300d2ba1c5673fc218af1961b20908638391b4e1e6d5850314ee2ac3ec22d741b3a8060479911c99305164aed19b6254bde75e7e6b1b2c3f3aa3 + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 + languageName: node + linkType: hard + +"envinfo@npm:^7.14.0": + version: 7.20.0 + resolution: "envinfo@npm:7.20.0" + bin: + envinfo: dist/cli.js + checksum: 10c0/2afa8085f9952d3afe6893098ef9cadc991aa38ed5ed5a0fd953ddb72a7543f425fbf46e8c02c4fa0ecad3c03a93381b0a212f799c2a8db8dc8886d8d7d5dc05 + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 10c0/b642f7b4dd4a376e954947550a3065a9ece6733ab8e51ad80db727aaae0817c2e99b02a97a3d6cecc648a97848305e728289cf312d09af395403a90c9d4d8a66 + languageName: node + linkType: hard + +"es-define-property@npm:^1.0.0": + version: 1.0.1 + resolution: "es-define-property@npm:1.0.1" + checksum: 10c0/3f54eb49c16c18707949ff25a1456728c883e81259f045003499efba399c08bad00deebf65cccde8c0e07908c1a225c9d472b7107e558f2a48e28d530e34527c + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: 10c0/0a61325670072f98d8ae3b914edab3559b6caa980f08054a3b872052640d91da01d38df55df797fcc916389d77fc92b8d5906cf028f4db46d7e3003abecbca85 + languageName: node + linkType: hard + +"es-module-lexer@npm:^1.2.1": + version: 1.7.0 + resolution: "es-module-lexer@npm:1.7.0" + checksum: 10c0/4c935affcbfeba7fb4533e1da10fa8568043df1e3574b869385980de9e2d475ddc36769891936dbb07036edb3c3786a8b78ccf44964cd130dedc1f2c984b6c7b + languageName: node + linkType: hard + +"es6-error@npm:^4.1.1": + version: 4.1.1 + resolution: "es6-error@npm:4.1.1" + checksum: 10c0/357663fb1e845c047d548c3d30f86e005db71e122678f4184ced0693f634688c3f3ef2d7de7d4af732f734de01f528b05954e270f06aa7d133679fb9fe6600ef + languageName: node + linkType: hard + +"escalade@npm:^3.2.0": + version: 3.2.0 + resolution: "escalade@npm:3.2.0" + checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^4.0.0": + version: 4.0.0 + resolution: "escape-string-regexp@npm:4.0.0" + checksum: 10c0/9497d4dd307d845bd7f75180d8188bb17ea8c151c1edbf6b6717c100e104d629dc2dfb687686181b0f4b7d732c7dfdc4d5e7a8ff72de1b0ca283a75bbb3a9cd9 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^5.0.0": + version: 5.0.0 + resolution: "escape-string-regexp@npm:5.0.0" + checksum: 10c0/6366f474c6f37a802800a435232395e04e9885919873e382b157ab7e8f0feb8fed71497f84a6f6a81a49aab41815522f5839112bd38026d203aea0c91622df95 + languageName: node + linkType: hard + +"eslint-scope@npm:5.1.1": + version: 5.1.1 + resolution: "eslint-scope@npm:5.1.1" + dependencies: + esrecurse: "npm:^4.3.0" + estraverse: "npm:^4.1.1" + checksum: 10c0/d30ef9dc1c1cbdece34db1539a4933fe3f9b14e1ffb27ecc85987902ee663ad7c9473bbd49a9a03195a373741e62e2f807c4938992e019b511993d163450e70a + languageName: node + linkType: hard + +"esrecurse@npm:^4.3.0": + version: 4.3.0 + resolution: "esrecurse@npm:4.3.0" + dependencies: + estraverse: "npm:^5.2.0" + checksum: 10c0/81a37116d1408ded88ada45b9fb16dbd26fba3aadc369ce50fcaf82a0bac12772ebd7b24cd7b91fc66786bf2c1ac7b5f196bc990a473efff972f5cb338877cf5 + languageName: node + linkType: hard + +"estraverse@npm:^4.1.1": + version: 4.3.0 + resolution: "estraverse@npm:4.3.0" + checksum: 10c0/9cb46463ef8a8a4905d3708a652d60122a0c20bb58dec7e0e12ab0e7235123d74214fc0141d743c381813e1b992767e2708194f6f6e0f9fd00c1b4e0887b8b6d + languageName: node + linkType: hard + +"estraverse@npm:^5.2.0": + version: 5.3.0 + resolution: "estraverse@npm:5.3.0" + checksum: 10c0/1ff9447b96263dec95d6d67431c5e0771eb9776427421260a3e2f0fdd5d6bd4f8e37a7338f5ad2880c9f143450c9b1e4fc2069060724570a49cf9cf0312bd107 + languageName: node + linkType: hard + +"events@npm:^3.2.0": + version: 3.3.0 + resolution: "events@npm:3.3.0" + checksum: 10c0/d6b6f2adbccbcda74ddbab52ed07db727ef52e31a61ed26db9feb7dc62af7fc8e060defa65e5f8af9449b86b52cc1a1f6a79f2eafcf4e62add2b7a1fa4a432f6 + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.3 + resolution: "exponential-backoff@npm:3.1.3" + checksum: 10c0/77e3ae682b7b1f4972f563c6dbcd2b0d54ac679e62d5d32f3e5085feba20483cf28bd505543f520e287a56d4d55a28d7874299941faf637e779a1aa5994d1267 + languageName: node + linkType: hard + +"extract-zip@npm:^2.0.1": + version: 2.0.1 + resolution: "extract-zip@npm:2.0.1" + dependencies: + "@types/yauzl": "npm:^2.9.1" + debug: "npm:^4.1.1" + get-stream: "npm:^5.1.0" + yauzl: "npm:^2.10.0" + dependenciesMeta: + "@types/yauzl": + optional: true + bin: + extract-zip: cli.js + checksum: 10c0/9afbd46854aa15a857ae0341a63a92743a7b89c8779102c3b4ffc207516b2019337353962309f85c66ee3d9092202a83cdc26dbf449a11981272038443974aee + languageName: node + linkType: hard + +"fast-deep-equal@npm:^3.1.3": + version: 3.1.3 + resolution: "fast-deep-equal@npm:3.1.3" + checksum: 10c0/40dedc862eb8992c54579c66d914635afbec43350afbbe991235fdcb4e3a8d5af1b23ae7e79bef7d4882d0ecee06c3197488026998fb19f72dc95acff1d1b1d0 + languageName: node + linkType: hard + +"fast-fifo@npm:^1.3.2": + version: 1.3.2 + resolution: "fast-fifo@npm:1.3.2" + checksum: 10c0/d53f6f786875e8b0529f784b59b4b05d4b5c31c651710496440006a398389a579c8dbcd2081311478b5bf77f4b0b21de69109c5a4eabea9d8e8783d1eb864e4c + languageName: node + linkType: hard + +"fast-uri@npm:^3.0.1": + version: 3.1.0 + resolution: "fast-uri@npm:3.1.0" + checksum: 10c0/44364adca566f70f40d1e9b772c923138d47efeac2ae9732a872baafd77061f26b097ba2f68f0892885ad177becd065520412b8ffeec34b16c99433c5b9e2de7 + languageName: node + linkType: hard + +"fastest-levenshtein@npm:^1.0.12": + version: 1.0.16 + resolution: "fastest-levenshtein@npm:1.0.16" + checksum: 10c0/7e3d8ae812a7f4fdf8cad18e9cde436a39addf266a5986f653ea0d81e0de0900f50c0f27c6d5aff3f686bcb48acbd45be115ae2216f36a6a13a7dbbf5cad878b + languageName: node + linkType: hard + +"fd-slicer@npm:~1.1.0": + version: 1.1.0 + resolution: "fd-slicer@npm:1.1.0" + dependencies: + pend: "npm:~1.2.0" + checksum: 10c0/304dd70270298e3ffe3bcc05e6f7ade2511acc278bc52d025f8918b48b6aa3b77f10361bddfadfe2a28163f7af7adbdce96f4d22c31b2f648ba2901f0c5fc20e + languageName: node + linkType: hard + +"fdir@npm:^6.5.0": + version: 6.5.0 + resolution: "fdir@npm:6.5.0" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: 10c0/e345083c4306b3aed6cb8ec551e26c36bab5c511e99ea4576a16750ddc8d3240e63826cc624f5ae17ad4dc82e68a253213b60d556c11bfad064b7607847ed07f + languageName: node + linkType: hard + +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018 + languageName: node + linkType: hard + +"find-up@npm:^4.0.0": + version: 4.1.0 + resolution: "find-up@npm:4.1.0" + dependencies: + locate-path: "npm:^5.0.0" + path-exists: "npm:^4.0.0" + checksum: 10c0/0406ee89ebeefa2d507feb07ec366bebd8a6167ae74aa4e34fb4c4abd06cf782a3ce26ae4194d70706f72182841733f00551c209fe575cb00bd92104056e78c1 + languageName: node + linkType: hard + +"flat@npm:^5.0.2": + version: 5.0.2 + resolution: "flat@npm:5.0.2" + bin: + flat: cli.js + checksum: 10c0/f178b13482f0cd80c7fede05f4d10585b1f2fdebf26e12edc138e32d3150c6ea6482b7f12813a1091143bad52bb6d3596bca51a162257a21163c0ff438baa5fe + languageName: node + linkType: hard + +"foreground-child@npm:^3.3.1": + version: 3.3.1 + resolution: "foreground-child@npm:3.3.1" + dependencies: + cross-spawn: "npm:^7.0.6" + signal-exit: "npm:^4.0.1" + checksum: 10c0/8986e4af2430896e65bc2788d6679067294d6aee9545daefc84923a0a4b399ad9c7a3ea7bd8c0b2b80fdf4a92de4c69df3f628233ff3224260e9c1541a9e9ed3 + languageName: node + linkType: hard + +"fs-extra@npm:^8.1.0": + version: 8.1.0 + resolution: "fs-extra@npm:8.1.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^4.0.0" + universalify: "npm:^0.1.0" + checksum: 10c0/259f7b814d9e50d686899550c4f9ded85c46c643f7fe19be69504888e007fcbc08f306fae8ec495b8b998635e997c9e3e175ff2eeed230524ef1c1684cc96423 + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10c0/63e80da2ff9b621e2cb1596abcb9207f1cf82b968b116ccd7b959e3323144cce7fb141462200971c38bbf2ecca51695069db45265705bed09a7cd93ae5b89f94 + languageName: node + linkType: hard + +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 10c0/d8680ee1e5fcd4c197e4ac33b2b4dce03c71f4d91717292785703db200f5c21f977c568d28061226f9b5900cbcd2c84463646134fd5337e7925e0942bc3f46d5 + languageName: node + linkType: hard + +"get-stream@npm:^5.1.0": + version: 5.2.0 + resolution: "get-stream@npm:5.2.0" + dependencies: + pump: "npm:^3.0.0" + checksum: 10c0/43797ffd815fbb26685bf188c8cfebecb8af87b3925091dd7b9a9c915993293d78e3c9e1bce125928ff92f2d0796f3889b92b5ec6d58d1041b574682132e0a80 + languageName: node + linkType: hard + +"glob-to-regexp@npm:^0.4.1": + version: 0.4.1 + resolution: "glob-to-regexp@npm:0.4.1" + checksum: 10c0/0486925072d7a916f052842772b61c3e86247f0a80cc0deb9b5a3e8a1a9faad5b04fb6f58986a09f34d3e96cd2a22a24b7e9882fb1cf904c31e9a310de96c429 + languageName: node + linkType: hard + +"glob@npm:^11.0.3": + version: 11.1.0 + resolution: "glob@npm:11.1.0" + dependencies: + foreground-child: "npm:^3.3.1" + jackspeak: "npm:^4.1.1" + minimatch: "npm:^10.1.1" + minipass: "npm:^7.1.2" + package-json-from-dist: "npm:^1.0.0" + path-scurry: "npm:^2.0.0" + bin: + glob: dist/esm/bin.mjs + checksum: 10c0/1ceae07f23e316a6fa74581d9a74be6e8c2e590d2f7205034dd5c0435c53f5f7b712c2be00c3b65bf0a49294a1c6f4b98cd84c7637e29453b5aa13b79f1763a2 + languageName: node + linkType: hard + +"global-agent@npm:^3.0.0": + version: 3.0.0 + resolution: "global-agent@npm:3.0.0" + dependencies: + boolean: "npm:^3.0.1" + es6-error: "npm:^4.1.1" + matcher: "npm:^3.0.0" + roarr: "npm:^2.15.3" + semver: "npm:^7.3.2" + serialize-error: "npm:^7.0.1" + checksum: 10c0/bb8750d026b25da437072762fd739098bad92ff72f66483c3929db4579e072f5523960f7e7fd70ee0d75db48898067b5dc1c9c1d17888128cff008fcc34d1bd3 + languageName: node + linkType: hard + +"globalthis@npm:^1.0.1": + version: 1.0.4 + resolution: "globalthis@npm:1.0.4" + dependencies: + define-properties: "npm:^1.2.1" + gopd: "npm:^1.0.1" + checksum: 10c0/9d156f313af79d80b1566b93e19285f481c591ad6d0d319b4be5e03750d004dde40a39a0f26f7e635f9007a3600802f53ecd85a759b86f109e80a5f705e01846 + languageName: node + linkType: hard + +"gopd@npm:^1.0.1": + version: 1.2.0 + resolution: "gopd@npm:1.2.0" + checksum: 10c0/50fff1e04ba2b7737c097358534eacadad1e68d24cccee3272e04e007bed008e68d2614f3987788428fd192a5ae3889d08fb2331417e4fc4a9ab366b2043cead + languageName: node + linkType: hard + +"got@npm:^11.8.5": + version: 11.8.6 + resolution: "got@npm:11.8.6" + dependencies: + "@sindresorhus/is": "npm:^4.0.0" + "@szmarczak/http-timer": "npm:^4.0.5" + "@types/cacheable-request": "npm:^6.0.1" + "@types/responselike": "npm:^1.0.0" + cacheable-lookup: "npm:^5.0.3" + cacheable-request: "npm:^7.0.2" + decompress-response: "npm:^6.0.0" + http2-wrapper: "npm:^1.0.0-beta.5.2" + lowercase-keys: "npm:^2.0.0" + p-cancelable: "npm:^2.0.0" + responselike: "npm:^2.0.0" + checksum: 10c0/754dd44877e5cf6183f1e989ff01c648d9a4719e357457bd4c78943911168881f1cfb7b2cb15d885e2105b3ad313adb8f017a67265dd7ade771afdb261ee8cb1 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 + languageName: node + linkType: hard + +"graphql@npm:16.12.0": + version: 16.12.0 + resolution: "graphql@npm:16.12.0" + checksum: 10c0/b6fffa4e8a4e4a9933ebe85e7470b346dbf49050c1a482fac5e03e4a1a7bed2ecd3a4c97e29f04457af929464bc5e4f2aac991090c2f320111eef26e902a5c75 + languageName: node + linkType: hard + +"has-flag@npm:^4.0.0": + version: 4.0.0 + resolution: "has-flag@npm:4.0.0" + checksum: 10c0/2e789c61b7888d66993e14e8331449e525ef42aac53c627cc53d1c3334e768bcb6abdc4f5f0de1478a25beec6f0bd62c7549058b7ac53e924040d4f301f02fd1 + languageName: node + linkType: hard + +"has-property-descriptors@npm:^1.0.0": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" + dependencies: + es-define-property: "npm:^1.0.0" + checksum: 10c0/253c1f59e80bb476cf0dde8ff5284505d90c3bdb762983c3514d36414290475fe3fd6f574929d84de2a8eec00d35cf07cb6776205ff32efd7c50719125f00236 + languageName: node + linkType: hard + +"hasown@npm:^2.0.2": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" + dependencies: + function-bind: "npm:^1.1.2" + checksum: 10c0/3769d434703b8ac66b209a4cca0737519925bbdb61dd887f93a16372b14694c63ff4e797686d87c90f08168e81082248b9b028bad60d4da9e0d1148766f56eb9 + languageName: node + linkType: hard + +"he@npm:^1.2.0": + version: 1.2.0 + resolution: "he@npm:1.2.0" + bin: + he: bin/he + checksum: 10c0/a27d478befe3c8192f006cdd0639a66798979dfa6e2125c6ac582a19a5ebfec62ad83e8382e6036170d873f46e4536a7e795bf8b95bf7c247f4cc0825ccc8c17 + languageName: node + linkType: hard + +"html-minifier-terser@npm:^6.0.2": + version: 6.1.0 + resolution: "html-minifier-terser@npm:6.1.0" + dependencies: + camel-case: "npm:^4.1.2" + clean-css: "npm:^5.2.2" + commander: "npm:^8.3.0" + he: "npm:^1.2.0" + param-case: "npm:^3.0.4" + relateurl: "npm:^0.2.7" + terser: "npm:^5.10.0" + bin: + html-minifier-terser: cli.js + checksum: 10c0/1aa4e4f01cf7149e3ac5ea84fb7a1adab86da40d38d77a6fff42852b5ee3daccb78b615df97264e3a6a5c33e57f0c77f471d607ca1e1debd1dab9b58286f4b5a + languageName: node + linkType: hard + +"html-webpack-plugin@npm:5.6.5": + version: 5.6.5 + resolution: "html-webpack-plugin@npm:5.6.5" + dependencies: + "@types/html-minifier-terser": "npm:^6.0.0" + html-minifier-terser: "npm:^6.0.2" + lodash: "npm:^4.17.21" + pretty-error: "npm:^4.0.0" + tapable: "npm:^2.0.0" + peerDependencies: + "@rspack/core": 0.x || 1.x + webpack: ^5.20.0 + peerDependenciesMeta: + "@rspack/core": + optional: true + webpack: + optional: true + checksum: 10c0/4ae0ae48fec6337e4eb055e730e46340172ec1967bd383d897d03cb3c4e385a8128e8d5179c4658536b00e432c2d3f026d97eb5fdb4cf9dc710498d2e871b84e + languageName: node + linkType: hard + +"htmlparser2@npm:^6.1.0": + version: 6.1.0 + resolution: "htmlparser2@npm:6.1.0" + dependencies: + domelementtype: "npm:^2.0.1" + domhandler: "npm:^4.0.0" + domutils: "npm:^2.5.2" + entities: "npm:^2.0.0" + checksum: 10c0/3058499c95634f04dc66be8c2e0927cd86799413b2d6989d8ae542ca4dbf5fa948695d02c27d573acf44843af977aec6d9a7bdd0f6faa6b2d99e2a729b2a31b6 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.1": + version: 4.2.0 + resolution: "http-cache-semantics@npm:4.2.0" + checksum: 10c0/45b66a945cf13ec2d1f29432277201313babf4a01d9e52f44b31ca923434083afeca03f18417f599c9ab3d0e7b618ceb21257542338b57c54b710463b4a53e37 + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: "npm:^7.1.0" + debug: "npm:^4.3.4" + checksum: 10c0/4207b06a4580fb85dd6dff521f0abf6db517489e70863dca1a0291daa7f2d3d2d6015a57bd702af068ea5cf9f1f6ff72314f5f5b4228d299c0904135d2aef921 + languageName: node + linkType: hard + +"http2-wrapper@npm:^1.0.0-beta.5.2": + version: 1.0.3 + resolution: "http2-wrapper@npm:1.0.3" + dependencies: + quick-lru: "npm:^5.1.1" + resolve-alpn: "npm:^1.0.0" + checksum: 10c0/6a9b72a033e9812e1476b9d776ce2f387bc94bc46c88aea0d5dab6bd47d0a539b8178830e77054dd26d1142c866d515a28a4dc7c3ff4232c88ff2ebe4f5d12d1 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.6 + resolution: "https-proxy-agent@npm:7.0.6" + dependencies: + agent-base: "npm:^7.1.2" + debug: "npm:4" + checksum: 10c0/f729219bc735edb621fa30e6e84e60ee5d00802b8247aac0d7b79b0bd6d4b3294737a337b93b86a0bd9e68099d031858a39260c976dc14cdbba238ba1f8779ac + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1 + languageName: node + linkType: hard + +"ignore@npm:^7.0.5": + version: 7.0.5 + resolution: "ignore@npm:7.0.5" + checksum: 10c0/ae00db89fe873064a093b8999fe4cc284b13ef2a178636211842cceb650b9c3e390d3339191acb145d81ed5379d2074840cf0c33a20bdbd6f32821f79eb4ad5d + languageName: node + linkType: hard + +"import-in-the-middle@npm:^1.14.2": + version: 1.15.0 + resolution: "import-in-the-middle@npm:1.15.0" + dependencies: + acorn: "npm:^8.14.0" + acorn-import-attributes: "npm:^1.9.5" + cjs-module-lexer: "npm:^1.2.2" + module-details-from-path: "npm:^1.0.3" + checksum: 10c0/43d4efbe75a89c04343fd052ca5d2193adc0e2df93325e50d8b32c31403b2f089a5e2b6e47f4e5413bc4058b9781aaaf61bfe3f0e5e6d7f9487eb112fd095e0d + languageName: node + linkType: hard + +"import-local@npm:^3.0.2": + version: 3.2.0 + resolution: "import-local@npm:3.2.0" + dependencies: + pkg-dir: "npm:^4.2.0" + resolve-cwd: "npm:^3.0.0" + bin: + import-local-fixture: fixtures/cli.js + checksum: 10c0/94cd6367a672b7e0cb026970c85b76902d2710a64896fa6de93bd5c571dd03b228c5759308959de205083e3b1c61e799f019c9e36ee8e9c523b993e1057f0433 + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6 + languageName: node + linkType: hard + +"interpret@npm:^3.1.1": + version: 3.1.1 + resolution: "interpret@npm:3.1.1" + checksum: 10c0/6f3c4d0aa6ec1b43a8862375588a249e3c917739895cbe67fe12f0a76260ea632af51e8e2431b50fbcd0145356dc28ca147be08dbe6a523739fd55c0f91dc2a5 + languageName: node + linkType: hard + +"ip-address@npm:^10.0.1": + version: 10.1.0 + resolution: "ip-address@npm:10.1.0" + checksum: 10c0/0103516cfa93f6433b3bd7333fa876eb21263912329bfa47010af5e16934eeeff86f3d2ae700a3744a137839ddfad62b900c7a445607884a49b5d1e32a3d7566 + languageName: node + linkType: hard + +"is-core-module@npm:^2.16.1": + version: 2.16.1 + resolution: "is-core-module@npm:2.16.1" + dependencies: + hasown: "npm:^2.0.2" + checksum: 10c0/898443c14780a577e807618aaae2b6f745c8538eca5c7bc11388a3f2dc6de82b9902bcc7eb74f07be672b11bbe82dd6a6edded44a00cb3d8f933d0459905eedd + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 10c0/bb11d825e049f38e04c06373a8d72782eee0205bda9d908cc550ccb3c59b99d750ff9537982e01733c1c94a58e35400661f57042158ff5e8f3e90cf936daf0fc + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 10c0/b4686d0d3053146095ccd45346461bc8e53b80aeb7671cc52a4de02dbbf7dc0d1d2a986e2fe4ae206984b4d34ef37e8b795ebc4f4295c978373e6575e295d811 + languageName: node + linkType: hard + +"is-plain-object@npm:^2.0.4": + version: 2.0.4 + resolution: "is-plain-object@npm:2.0.4" + dependencies: + isobject: "npm:^3.0.1" + checksum: 10c0/f050fdd5203d9c81e8c4df1b3ff461c4bc64e8b5ca383bcdde46131361d0a678e80bcf00b5257646f6c636197629644d53bd8e2375aea633de09a82d57e942f4 + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d + languageName: node + linkType: hard + +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 10c0/9ec257654093443eb0a528a9c8cbba9c0ca7616ccb40abd6dde7202734d96bb86e4ac0d764f0f8cd965856aacbff2f4ce23e730dc19dfb41e3b0d865ca6fdcc7 + languageName: node + linkType: hard + +"isobject@npm:^3.0.1": + version: 3.0.1 + resolution: "isobject@npm:3.0.1" + checksum: 10c0/03344f5064a82f099a0cd1a8a407f4c0d20b7b8485e8e816c39f249e9416b06c322e8dec5b842b6bb8a06de0af9cb48e7bc1b5352f0fadc2f0abac033db3d4db + languageName: node + linkType: hard + +"istanbul-lib-coverage@npm:^3.2.2": + version: 3.2.2 + resolution: "istanbul-lib-coverage@npm:3.2.2" + checksum: 10c0/6c7ff2106769e5f592ded1fb418f9f73b4411fd5a084387a5410538332b6567cd1763ff6b6cadca9b9eb2c443cce2f7ea7d7f1b8d315f9ce58539793b1e0922b + languageName: node + linkType: hard + +"jackspeak@npm:^4.1.1": + version: 4.1.1 + resolution: "jackspeak@npm:4.1.1" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + checksum: 10c0/84ec4f8e21d6514db24737d9caf65361511f75e5e424980eebca4199f400874f45e562ac20fa8aeb1dd20ca2f3f81f0788b6e9c3e64d216a5794fd6f30e0e042 + languageName: node + linkType: hard + +"jest-docblock@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-docblock@npm:29.7.0" + dependencies: + detect-newline: "npm:^3.0.0" + checksum: 10c0/d932a8272345cf6b6142bb70a2bb63e0856cc0093f082821577ea5bdf4643916a98744dfc992189d2b1417c38a11fa42466f6111526bc1fb81366f56410f3be9 + languageName: node + linkType: hard + +"jest-worker@npm:^27.4.5": + version: 27.5.1 + resolution: "jest-worker@npm:27.5.1" + dependencies: + "@types/node": "npm:*" + merge-stream: "npm:^2.0.0" + supports-color: "npm:^8.0.0" + checksum: 10c0/8c4737ffd03887b3c6768e4cc3ca0269c0336c1e4b1b120943958ddb035ed2a0fc6acab6dc99631720a3720af4e708ff84fb45382ad1e83c27946adf3623969b + languageName: node + linkType: hard + +"js-yaml@npm:^4.1.0": + version: 4.1.1 + resolution: "js-yaml@npm:4.1.1" + dependencies: + argparse: "npm:^2.0.1" + bin: + js-yaml: bin/js-yaml.js + checksum: 10c0/561c7d7088c40a9bb53cc75becbfb1df6ae49b34b5e6e5a81744b14ae8667ec564ad2527709d1a6e7d5e5fa6d483aa0f373a50ad98d42fde368ec4a190d4fae7 + languageName: node + linkType: hard + +"jsep@npm:^1.4.0": + version: 1.4.0 + resolution: "jsep@npm:1.4.0" + checksum: 10c0/fe60adf47e050e22eadced42514a51a15a3cf0e2d147896584486acd8ee670fc16641101b9aeb81f4aaba382043d29744b7aac41171e8106515b14f27e0c7116 + languageName: node + linkType: hard + +"json-buffer@npm:3.0.1": + version: 3.0.1 + resolution: "json-buffer@npm:3.0.1" + checksum: 10c0/0d1c91569d9588e7eef2b49b59851f297f3ab93c7b35c7c221e288099322be6b562767d11e4821da500f3219542b9afd2e54c5dc573107c1126ed1080f8e96d7 + languageName: node + linkType: hard + +"json-parse-even-better-errors@npm:^2.3.1": + version: 2.3.1 + resolution: "json-parse-even-better-errors@npm:2.3.1" + checksum: 10c0/140932564c8f0b88455432e0f33c4cb4086b8868e37524e07e723f4eaedb9425bdc2bafd71bd1d9765bd15fd1e2d126972bc83990f55c467168c228c24d665f3 + languageName: node + linkType: hard + +"json-schema-traverse@npm:^1.0.0": + version: 1.0.0 + resolution: "json-schema-traverse@npm:1.0.0" + checksum: 10c0/71e30015d7f3d6dc1c316d6298047c8ef98a06d31ad064919976583eb61e1018a60a0067338f0f79cabc00d84af3fcc489bd48ce8a46ea165d9541ba17fb30c6 + languageName: node + linkType: hard + +"json-stringify-safe@npm:^5.0.1": + version: 5.0.1 + resolution: "json-stringify-safe@npm:5.0.1" + checksum: 10c0/7dbf35cd0411d1d648dceb6d59ce5857ec939e52e4afc37601aa3da611f0987d5cee5b38d58329ceddf3ed48bd7215229c8d52059ab01f2444a338bf24ed0f37 + languageName: node + linkType: hard + +"jsonfile@npm:^4.0.0": + version: 4.0.0 + resolution: "jsonfile@npm:4.0.0" + dependencies: + graceful-fs: "npm:^4.1.6" + dependenciesMeta: + graceful-fs: + optional: true + checksum: 10c0/7dc94b628d57a66b71fb1b79510d460d662eb975b5f876d723f81549c2e9cd316d58a2ddf742b2b93a4fa6b17b2accaf1a738a0e2ea114bdfb13a32e5377e480 + languageName: node + linkType: hard + +"jsonpath-plus@npm:^10.3.0": + version: 10.3.0 + resolution: "jsonpath-plus@npm:10.3.0" + dependencies: + "@jsep-plugin/assignment": "npm:^1.3.0" + "@jsep-plugin/regex": "npm:^1.0.4" + jsep: "npm:^1.4.0" + bin: + jsonpath: bin/jsonpath-cli.js + jsonpath-plus: bin/jsonpath-cli.js + checksum: 10c0/f5ff53078ecab98e8afd1dcdb4488e528653fa5a03a32d671f52db1ae9c3236e6e072d75e1949a80929fd21b07603924a586f829b40ad35993fa0247fa4f7506 + languageName: node + linkType: hard + +"keyv@npm:^4.0.0": + version: 4.5.4 + resolution: "keyv@npm:4.5.4" + dependencies: + json-buffer: "npm:3.0.1" + checksum: 10c0/aa52f3c5e18e16bb6324876bb8b59dd02acf782a4b789c7b2ae21107fab95fab3890ed448d4f8dba80ce05391eeac4bfabb4f02a20221342982f806fa2cf271e + languageName: node + linkType: hard + +"kind-of@npm:^6.0.2": + version: 6.0.3 + resolution: "kind-of@npm:6.0.3" + checksum: 10c0/61cdff9623dabf3568b6445e93e31376bee1cdb93f8ba7033d86022c2a9b1791a1d9510e026e6465ebd701a6dd2f7b0808483ad8838341ac52f003f512e0b4c4 + languageName: node + linkType: hard + +"limiter@npm:^1.1.5": + version: 1.1.5 + resolution: "limiter@npm:1.1.5" + checksum: 10c0/ebe2b20a820d1f67b8e1724051246434c419b2da041a7e9cd943f6daf113b8d17a52a1bd88fb79be5b624c10283ecb737f50edb5c1c88c71f4cd367108c97300 + languageName: node + linkType: hard + +"loader-runner@npm:^4.3.1": + version: 4.3.1 + resolution: "loader-runner@npm:4.3.1" + checksum: 10c0/a523b6329f114e0a98317158e30a7dfce044b731521be5399464010472a93a15ece44757d1eaed1d8845019869c5390218bc1c7c3110f4eeaef5157394486eac + languageName: node + linkType: hard + +"locate-path@npm:^5.0.0": + version: 5.0.0 + resolution: "locate-path@npm:5.0.0" + dependencies: + p-locate: "npm:^4.1.0" + checksum: 10c0/33a1c5247e87e022f9713e6213a744557a3e9ec32c5d0b5efb10aa3a38177615bf90221a5592674857039c1a0fd2063b82f285702d37b792d973e9e72ace6c59 + languageName: node + linkType: hard + +"lodash.sortby@npm:^4.7.0": + version: 4.7.0 + resolution: "lodash.sortby@npm:4.7.0" + checksum: 10c0/fc48fb54ff7669f33bb32997cab9460757ee99fafaf72400b261c3e10fde21538e47d8cfcbe6a25a31bcb5b7b727c27d52626386fc2de24eb059a6d64a89cdf5 + languageName: node + linkType: hard + +"lodash@npm:^4.17.20, lodash@npm:^4.17.21": + version: 4.17.21 + resolution: "lodash@npm:4.17.21" + checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c + languageName: node + linkType: hard + +"long@npm:^5.0.0": + version: 5.3.2 + resolution: "long@npm:5.3.2" + checksum: 10c0/7130fe1cbce2dca06734b35b70d380ca3f70271c7f8852c922a7c62c86c4e35f0c39290565eca7133c625908d40e126ac57c02b1b1a4636b9457d77e1e60b981 + languageName: node + linkType: hard + +"lower-case@npm:^2.0.2": + version: 2.0.2 + resolution: "lower-case@npm:2.0.2" + dependencies: + tslib: "npm:^2.0.3" + checksum: 10c0/3d925e090315cf7dc1caa358e0477e186ffa23947740e4314a7429b6e62d72742e0bbe7536a5ae56d19d7618ce998aba05caca53c2902bd5742fdca5fc57fd7b + languageName: node + linkType: hard + +"lowercase-keys@npm:^2.0.0": + version: 2.0.0 + resolution: "lowercase-keys@npm:2.0.0" + checksum: 10c0/f82a2b3568910509da4b7906362efa40f5b54ea14c2584778ddb313226f9cbf21020a5db35f9b9a0e95847a9b781d548601f31793d736b22a2b8ae8eb9ab1082 + languageName: node + linkType: hard + +"lru-cache@npm:^10.4.3": + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb + languageName: node + linkType: hard + +"lru-cache@npm:^11.0.0, lru-cache@npm:^11.1.0, lru-cache@npm:^11.2.1": + version: 11.2.2 + resolution: "lru-cache@npm:11.2.2" + checksum: 10c0/72d7831bbebc85e2bdefe01047ee5584db69d641c48d7a509e86f66f6ee111b30af7ec3bd68a967d47b69a4b1fa8bbf3872630bd06a63b6735e6f0a5f1c8e83d + languageName: node + linkType: hard + +"lru-cache@npm:^7.14.0": + version: 7.18.3 + resolution: "lru-cache@npm:7.18.3" + checksum: 10c0/b3a452b491433db885beed95041eb104c157ef7794b9c9b4d647be503be91769d11206bb573849a16b4cc0d03cbd15ffd22df7960997788b74c1d399ac7a4fed + languageName: node + linkType: hard + +"make-fetch-happen@npm:^15.0.0": + version: 15.0.3 + resolution: "make-fetch-happen@npm:15.0.3" + dependencies: + "@npmcli/agent": "npm:^4.0.0" + cacache: "npm:^20.0.1" + http-cache-semantics: "npm:^4.1.1" + minipass: "npm:^7.0.2" + minipass-fetch: "npm:^5.0.0" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + negotiator: "npm:^1.0.0" + proc-log: "npm:^6.0.0" + promise-retry: "npm:^2.0.1" + ssri: "npm:^13.0.0" + checksum: 10c0/525f74915660be60b616bcbd267c4a5b59481b073ba125e45c9c3a041bb1a47a2bd0ae79d028eb6f5f95bf9851a4158423f5068539c3093621abb64027e8e461 + languageName: node + linkType: hard + +"matcher@npm:^3.0.0": + version: 3.0.0 + resolution: "matcher@npm:3.0.0" + dependencies: + escape-string-regexp: "npm:^4.0.0" + checksum: 10c0/2edf24194a2879690bcdb29985fc6bc0d003df44e04df21ebcac721fa6ce2f6201c579866bb92f9380bffe946f11ecd8cd31f34117fb67ebf8aca604918e127e + languageName: node + linkType: hard + +"merge-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-stream@npm:2.0.0" + checksum: 10c0/867fdbb30a6d58b011449b8885601ec1690c3e41c759ecd5a9d609094f7aed0096c37823ff4a7190ef0b8f22cc86beb7049196ff68c016e3b3c671d0dac91ce5 + languageName: node + linkType: hard + +"micromatch@npm:^4.0.0": + version: 4.0.8 + resolution: "micromatch@npm:4.0.8" + dependencies: + braces: "npm:^3.0.3" + picomatch: "npm:^2.3.1" + checksum: 10c0/166fa6eb926b9553f32ef81f5f531d27b4ce7da60e5baf8c021d043b27a388fb95e46a8038d5045877881e673f8134122b59624d5cecbd16eb50a42e7a6b5ca8 + languageName: node + linkType: hard + +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 10c0/0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa + languageName: node + linkType: hard + +"mime-types@npm:^2.1.27": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: "npm:1.52.0" + checksum: 10c0/82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2 + languageName: node + linkType: hard + +"mimic-response@npm:^1.0.0": + version: 1.0.1 + resolution: "mimic-response@npm:1.0.1" + checksum: 10c0/c5381a5eae997f1c3b5e90ca7f209ed58c3615caeee850e85329c598f0c000ae7bec40196580eef1781c60c709f47258131dab237cad8786f8f56750594f27fa + languageName: node + linkType: hard + +"mimic-response@npm:^3.1.0": + version: 3.1.0 + resolution: "mimic-response@npm:3.1.0" + checksum: 10c0/0d6f07ce6e03e9e4445bee655202153bdb8a98d67ee8dc965ac140900d7a2688343e6b4c9a72cfc9ef2f7944dfd76eef4ab2482eb7b293a68b84916bac735362 + languageName: node + linkType: hard + +"minimatch@npm:^10.1.1": + version: 10.1.1 + resolution: "minimatch@npm:10.1.1" + dependencies: + "@isaacs/brace-expansion": "npm:^5.0.0" + checksum: 10c0/c85d44821c71973d636091fddbfbffe62370f5ee3caf0241c5b60c18cd289e916200acb2361b7e987558cd06896d153e25d505db9fc1e43e6b4b6752e2702902 + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10c0/5167e73f62bb74cc5019594709c77e6a742051a647fe9499abf03c71dca75515b7959d67a764bdc4f8b361cf897fbf25e2d9869ee039203ed45240f48b9aa06e + languageName: node + linkType: hard + +"minipass-fetch@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass-fetch@npm:5.0.0" + dependencies: + encoding: "npm:^0.1.13" + minipass: "npm:^7.0.3" + minipass-sized: "npm:^1.0.3" + minizlib: "npm:^3.0.1" + dependenciesMeta: + encoding: + optional: true + checksum: 10c0/9443aab5feab190972f84b64116e54e58dd87a58e62399cae0a4a7461b80568281039b7c3a38ba96453431ebc799d1e26999e548540156216729a4967cd5ef06 + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/2a51b63feb799d2bb34669205eee7c0eaf9dce01883261a5b77410c9408aa447e478efd191b4de6fc1101e796ff5892f8443ef20d9544385819093dbb32d36bd + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/cbda57cea20b140b797505dc2cac71581a70b3247b84480c1fed5ca5ba46c25ecc25f68bfc9e6dcb1a6e9017dab5c7ada5eab73ad4f0a49d84e35093e0c643f2 + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/298f124753efdc745cfe0f2bdfdd81ba25b9f4e753ca4a2066eb17c821f25d48acea607dfc997633ee5bf7b6dfffb4eee4f2051eb168663f0b99fad2fa4829cb + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: "npm:^4.0.0" + checksum: 10c0/a114746943afa1dbbca8249e706d1d38b85ed1298b530f5808ce51f8e9e941962e2a5ad2e00eae7dd21d8a4aae6586a66d4216d1a259385e9d0358f0c1eba16c + languageName: node + linkType: hard + +"minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: 10c0/b0fd20bb9fb56e5fa9a8bfac539e8915ae07430a619e4b86ff71f5fc757ef3924b23b2c4230393af1eda647ed3d75739e4e0acb250a6b1eb277cf7f8fe449557 + languageName: node + linkType: hard + +"minizlib@npm:^3.0.1, minizlib@npm:^3.1.0": + version: 3.1.0 + resolution: "minizlib@npm:3.1.0" + dependencies: + minipass: "npm:^7.1.2" + checksum: 10c0/5aad75ab0090b8266069c9aabe582c021ae53eb33c6c691054a13a45db3b4f91a7fb1bd79151e6b4e9e9a86727b522527c0a06ec7d45206b745d54cd3097bcec + languageName: node + linkType: hard + +"module-details-from-path@npm:^1.0.3, module-details-from-path@npm:^1.0.4": + version: 1.0.4 + resolution: "module-details-from-path@npm:1.0.4" + checksum: 10c0/10863413e96dab07dee917eae07afe46f7bf853065cc75a7d2a718adf67574857fb64f8a2c0c9af12ac733a9a8cf652db7ed39b95f7a355d08106cb9cc50c83b + languageName: node + linkType: hard + +"ms@npm:^2.1.3": + version: 2.1.3 + resolution: "ms@npm:2.1.3" + checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 + languageName: node + linkType: hard + +"mutexify@npm:^1.4.0": + version: 1.4.0 + resolution: "mutexify@npm:1.4.0" + dependencies: + queue-tick: "npm:^1.0.0" + checksum: 10c0/0b2fad0c671cef33ad3596d702b581e5bb3708ec7ba2913639cfb1642c7f5093af9d8793b38eafe1b723e7879d60419d2e96c5e7793271e0167833a7939ac66d + languageName: node + linkType: hard + +"negotiator@npm:^1.0.0": + version: 1.0.0 + resolution: "negotiator@npm:1.0.0" + checksum: 10c0/4c559dd52669ea48e1914f9d634227c561221dd54734070791f999c52ed0ff36e437b2e07d5c1f6e32909fc625fe46491c16e4a8f0572567d4dd15c3a4fda04b + languageName: node + linkType: hard + +"neo-async@npm:^2.6.2": + version: 2.6.2 + resolution: "neo-async@npm:2.6.2" + checksum: 10c0/c2f5a604a54a8ec5438a342e1f356dff4bc33ccccdb6dc668d94fe8e5eccfc9d2c2eea6064b0967a767ba63b33763f51ccf2cd2441b461a7322656c1f06b3f5d + languageName: node + linkType: hard + +"no-case@npm:^3.0.4": + version: 3.0.4 + resolution: "no-case@npm:3.0.4" + dependencies: + lower-case: "npm:^2.0.2" + tslib: "npm:^2.0.3" + checksum: 10c0/8ef545f0b3f8677c848f86ecbd42ca0ff3cd9dd71c158527b344c69ba14710d816d8489c746b6ca225e7b615108938a0bda0a54706f8c255933703ac1cf8e703 + languageName: node + linkType: hard + +"node-addon-api@npm:^6.1.0": + version: 6.1.0 + resolution: "node-addon-api@npm:6.1.0" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/d2699c4ad15740fd31482a3b6fca789af7723ab9d393adc6ac45250faaee72edad8f0b10b2b9d087df0de93f1bdc16d97afdd179b26b9ebc9ed68b569faa4bac + languageName: node + linkType: hard + +"node-gyp-build@npm:<4.0, node-gyp-build@npm:^3.9.0": + version: 3.9.0 + resolution: "node-gyp-build@npm:3.9.0" + bin: + node-gyp-build: ./bin.js + node-gyp-build-optional: ./optional.js + node-gyp-build-test: ./build-test.js + checksum: 10c0/0e7e39e5746728e6adf58803d9c3c732b6107f1af3df5128c4c2a6c9c0fb99a6c981ad0a7514d707adccbcfe303b4a92da7949408f1d3ec281f70d37bec29f60 + languageName: node + linkType: hard + +"node-gyp-build@npm:^4.5.0": + version: 4.8.4 + resolution: "node-gyp-build@npm:4.8.4" + bin: + node-gyp-build: bin.js + node-gyp-build-optional: optional.js + node-gyp-build-test: build-test.js + checksum: 10c0/444e189907ece2081fe60e75368784f7782cfddb554b60123743dfb89509df89f1f29c03bbfa16b3a3e0be3f48799a4783f487da6203245fa5bed239ba7407e1 + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 12.1.0 + resolution: "node-gyp@npm:12.1.0" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^15.0.0" + nopt: "npm:^9.0.0" + proc-log: "npm:^6.0.0" + semver: "npm:^7.3.5" + tar: "npm:^7.5.2" + tinyglobby: "npm:^0.2.12" + which: "npm:^6.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 10c0/f43efea8aaf0beb6b2f6184e533edad779b2ae38062953e21951f46221dd104006cc574154f2ad4a135467a5aae92c49e84ef289311a82e08481c5df0e8dc495 + languageName: node + linkType: hard + +"node-releases@npm:^2.0.27": + version: 2.0.27 + resolution: "node-releases@npm:2.0.27" + checksum: 10c0/f1e6583b7833ea81880627748d28a3a7ff5703d5409328c216ae57befbced10ce2c991bea86434e8ec39003bd017f70481e2e5f8c1f7e0a7663241f81d6e00e2 + languageName: node + linkType: hard + +"nopt@npm:^9.0.0": + version: 9.0.0 + resolution: "nopt@npm:9.0.0" + dependencies: + abbrev: "npm:^4.0.0" + bin: + nopt: bin/nopt.js + checksum: 10c0/1822eb6f9b020ef6f7a7516d7b64a8036e09666ea55ac40416c36e4b2b343122c3cff0e2f085675f53de1d2db99a2a89a60ccea1d120bcd6a5347bf6ceb4a7fd + languageName: node + linkType: hard + +"normalize-url@npm:^6.0.1": + version: 6.1.0 + resolution: "normalize-url@npm:6.1.0" + checksum: 10c0/95d948f9bdd2cfde91aa786d1816ae40f8262946e13700bf6628105994fe0ff361662c20af3961161c38a119dc977adeb41fc0b41b1745eb77edaaf9cb22db23 + languageName: node + linkType: hard + +"nth-check@npm:^2.0.1": + version: 2.1.1 + resolution: "nth-check@npm:2.1.1" + dependencies: + boolbase: "npm:^1.0.0" + checksum: 10c0/5fee7ff309727763689cfad844d979aedd2204a817fbaaf0e1603794a7c20db28548d7b024692f953557df6ce4a0ee4ae46cd8ebd9b36cfb300b9226b567c479 + languageName: node + linkType: hard + +"object-keys@npm:^1.1.1": + version: 1.1.1 + resolution: "object-keys@npm:1.1.1" + checksum: 10c0/b11f7ccdbc6d406d1f186cdadb9d54738e347b2692a14439ca5ac70c225fa6db46db809711b78589866d47b25fc3e8dee0b4c722ac751e11180f9380e3d8601d + languageName: node + linkType: hard + +"once@npm:^1.3.1, once@npm:^1.4.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0 + languageName: node + linkType: hard + +"opentracing@npm:>=0.14.7": + version: 0.14.7 + resolution: "opentracing@npm:0.14.7" + checksum: 10c0/a7be8d697b1997548233423f5f4c196e285af8e864a24d7704fc6029beb73cd1f987651ca814e207629c6bc624cb03297a86601c0dc51cdca9a07a20f97b71ea + languageName: node + linkType: hard + +"p-cancelable@npm:^2.0.0": + version: 2.1.1 + resolution: "p-cancelable@npm:2.1.1" + checksum: 10c0/8c6dc1f8dd4154fd8b96a10e55a3a832684c4365fb9108056d89e79fbf21a2465027c04a59d0d797b5ffe10b54a61a32043af287d5c4860f1e996cbdbc847f01 + languageName: node + linkType: hard + +"p-limit@npm:^2.2.0": + version: 2.3.0 + resolution: "p-limit@npm:2.3.0" + dependencies: + p-try: "npm:^2.0.0" + checksum: 10c0/8da01ac53efe6a627080fafc127c873da40c18d87b3f5d5492d465bb85ec7207e153948df6b9cbaeb130be70152f874229b8242ee2be84c0794082510af97f12 + languageName: node + linkType: hard + +"p-limit@npm:^3.1.0": + version: 3.1.0 + resolution: "p-limit@npm:3.1.0" + dependencies: + yocto-queue: "npm:^0.1.0" + checksum: 10c0/9db675949dbdc9c3763c89e748d0ef8bdad0afbb24d49ceaf4c46c02c77d30db4e0652ed36d0a0a7a95154335fab810d95c86153105bb73b3a90448e2bb14e1a + languageName: node + linkType: hard + +"p-locate@npm:^4.1.0": + version: 4.1.0 + resolution: "p-locate@npm:4.1.0" + dependencies: + p-limit: "npm:^2.2.0" + checksum: 10c0/1b476ad69ad7f6059744f343b26d51ce091508935c1dbb80c4e0a2f397ffce0ca3a1f9f5cd3c7ce19d7929a09719d5c65fe70d8ee289c3f267cd36f2881813e9 + languageName: node + linkType: hard + +"p-map@npm:^7.0.2": + version: 7.0.4 + resolution: "p-map@npm:7.0.4" + checksum: 10c0/a5030935d3cb2919d7e89454d1ce82141e6f9955413658b8c9403cfe379283770ed3048146b44cde168aa9e8c716505f196d5689db0ae3ce9a71521a2fef3abd + languageName: node + linkType: hard + +"p-try@npm:^2.0.0": + version: 2.2.0 + resolution: "p-try@npm:2.2.0" + checksum: 10c0/c36c19907734c904b16994e6535b02c36c2224d433e01a2f1ab777237f4d86e6289fd5fd464850491e940379d4606ed850c03e0f9ab600b0ebddb511312e177f + languageName: node + linkType: hard + +"package-json-from-dist@npm:^1.0.0": + version: 1.0.1 + resolution: "package-json-from-dist@npm:1.0.1" + checksum: 10c0/62ba2785eb655fec084a257af34dbe24292ab74516d6aecef97ef72d4897310bc6898f6c85b5cd22770eaa1ce60d55a0230e150fb6a966e3ecd6c511e23d164b + languageName: node + linkType: hard + +"param-case@npm:^3.0.4": + version: 3.0.4 + resolution: "param-case@npm:3.0.4" + dependencies: + dot-case: "npm:^3.0.4" + tslib: "npm:^2.0.3" + checksum: 10c0/ccc053f3019f878eca10e70ec546d92f51a592f762917dafab11c8b532715dcff58356118a6f350976e4ab109e321756f05739643ed0ca94298e82291e6f9e76 + languageName: node + linkType: hard + +"pascal-case@npm:^3.1.2": + version: 3.1.2 + resolution: "pascal-case@npm:3.1.2" + dependencies: + no-case: "npm:^3.0.4" + tslib: "npm:^2.0.3" + checksum: 10c0/05ff7c344809fd272fc5030ae0ee3da8e4e63f36d47a1e0a4855ca59736254192c5a27b5822ed4bae96e54048eec5f6907713cfcfff7cdf7a464eaf7490786d8 + languageName: node + linkType: hard + +"path-exists@npm:^4.0.0": + version: 4.0.0 + resolution: "path-exists@npm:4.0.0" + checksum: 10c0/8c0bd3f5238188197dc78dced15207a4716c51cc4e3624c44fc97acf69558f5ebb9a2afff486fe1b4ee148e0c133e96c5e11a9aa5c48a3006e3467da070e5e1b + languageName: node + linkType: hard + +"path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c + languageName: node + linkType: hard + +"path-parse@npm:^1.0.7": + version: 1.0.7 + resolution: "path-parse@npm:1.0.7" + checksum: 10c0/11ce261f9d294cc7a58d6a574b7f1b935842355ec66fba3c3fd79e0f036462eaf07d0aa95bb74ff432f9afef97ce1926c720988c6a7451d8a584930ae7de86e1 + languageName: node + linkType: hard + +"path-scurry@npm:^2.0.0": + version: 2.0.1 + resolution: "path-scurry@npm:2.0.1" + dependencies: + lru-cache: "npm:^11.0.0" + minipass: "npm:^7.1.2" + checksum: 10c0/2a16ed0e81fbc43513e245aa5763354e25e787dab0d539581a6c3f0f967461a159ed6236b2559de23aa5b88e7dc32b469b6c47568833dd142a4b24b4f5cd2620 + languageName: node + linkType: hard + +"path-to-regexp@npm:^0.1.12": + version: 0.1.12 + resolution: "path-to-regexp@npm:0.1.12" + checksum: 10c0/1c6ff10ca169b773f3bba943bbc6a07182e332464704572962d277b900aeee81ac6aa5d060ff9e01149636c30b1f63af6e69dd7786ba6e0ddb39d4dee1f0645b + languageName: node + linkType: hard + +"pend@npm:~1.2.0": + version: 1.2.0 + resolution: "pend@npm:1.2.0" + checksum: 10c0/8a87e63f7a4afcfb0f9f77b39bb92374afc723418b9cb716ee4257689224171002e07768eeade4ecd0e86f1fa3d8f022994219fb45634f2dbd78c6803e452458 + languageName: node + linkType: hard + +"picocolors@npm:^1.1.1": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 + languageName: node + linkType: hard + +"picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be + languageName: node + linkType: hard + +"picomatch@npm:^4.0.3": + version: 4.0.3 + resolution: "picomatch@npm:4.0.3" + checksum: 10c0/9582c951e95eebee5434f59e426cddd228a7b97a0161a375aed4be244bd3fe8e3a31b846808ea14ef2c8a2527a6eeab7b3946a67d5979e81694654f939473ae2 + languageName: node + linkType: hard + +"pkg-dir@npm:^4.2.0": + version: 4.2.0 + resolution: "pkg-dir@npm:4.2.0" + dependencies: + find-up: "npm:^4.0.0" + checksum: 10c0/c56bda7769e04907a88423feb320babaed0711af8c436ce3e56763ab1021ba107c7b0cafb11cde7529f669cfc22bffcaebffb573645cbd63842ea9fb17cd7728 + languageName: node + linkType: hard + +"pprof-format@npm:^2.1.1, pprof-format@npm:^2.2.1": + version: 2.2.1 + resolution: "pprof-format@npm:2.2.1" + checksum: 10c0/1c8051b3e3ebba1ac2b8d7cf0a84ce501fdabe5e72a803c7daa6ddf67cbee33e9b5d6dbc6ffbeb740e3e56600c875f372576304ed718a4ffa4c89c18185494ae + languageName: node + linkType: hard + +"pretty-error@npm:^4.0.0": + version: 4.0.0 + resolution: "pretty-error@npm:4.0.0" + dependencies: + lodash: "npm:^4.17.20" + renderkid: "npm:^3.0.0" + checksum: 10c0/dc292c087e2857b2e7592784ab31e37a40f3fa918caa11eba51f9fb2853e1d4d6e820b219917e35f5721d833cfd20fdf4f26ae931a90fd1ad0cae2125c345138 + languageName: node + linkType: hard + +"proc-log@npm:^6.0.0": + version: 6.0.0 + resolution: "proc-log@npm:6.0.0" + checksum: 10c0/40c5e2b4c55e395a3bd72e38cba9c26e58598a1f4844fa6a115716d5231a0919f46aa8e351147035d91583ad39a794593615078c948bc001fe3beb99276be776 + languageName: node + linkType: hard + +"progress@npm:^2.0.3": + version: 2.0.3 + resolution: "progress@npm:2.0.3" + checksum: 10c0/1697e07cb1068055dbe9fe858d242368ff5d2073639e652b75a7eb1f2a1a8d4afd404d719de23c7b48481a6aa0040686310e2dac2f53d776daa2176d3f96369c + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: "npm:^2.0.2" + retry: "npm:^0.12.0" + checksum: 10c0/9c7045a1a2928094b5b9b15336dcd2a7b1c052f674550df63cc3f36cd44028e5080448175b6f6ca32b642de81150f5e7b1a98b728f15cb069f2dd60ac2616b96 + languageName: node + linkType: hard + +"protobufjs@npm:^7.5.3": + version: 7.5.4 + resolution: "protobufjs@npm:7.5.4" + dependencies: + "@protobufjs/aspromise": "npm:^1.1.2" + "@protobufjs/base64": "npm:^1.1.2" + "@protobufjs/codegen": "npm:^2.0.4" + "@protobufjs/eventemitter": "npm:^1.1.0" + "@protobufjs/fetch": "npm:^1.1.0" + "@protobufjs/float": "npm:^1.0.2" + "@protobufjs/inquire": "npm:^1.1.0" + "@protobufjs/path": "npm:^1.1.2" + "@protobufjs/pool": "npm:^1.1.0" + "@protobufjs/utf8": "npm:^1.1.0" + "@types/node": "npm:>=13.7.0" + long: "npm:^5.0.0" + checksum: 10c0/913b676109ffb3c05d3d31e03a684e569be91f3bba8613da4a683d69d9dba948daa2afd7d2e7944d1aa6c417890c35d9d9a8883c1160affafb0f9670d59ef722 + languageName: node + linkType: hard + +"pump@npm:^3.0.0": + version: 3.0.3 + resolution: "pump@npm:3.0.3" + dependencies: + end-of-stream: "npm:^1.1.0" + once: "npm:^1.3.1" + checksum: 10c0/ada5cdf1d813065bbc99aa2c393b8f6beee73b5de2890a8754c9f488d7323ffd2ca5f5a0943b48934e3fcbd97637d0337369c3c631aeb9614915db629f1c75c9 + languageName: node + linkType: hard + +"queue-tick@npm:^1.0.0": + version: 1.0.1 + resolution: "queue-tick@npm:1.0.1" + checksum: 10c0/0db998e2c9b15215317dbcf801e9b23e6bcde4044e115155dae34f8e7454b9a783f737c9a725528d677b7a66c775eb7a955cf144fe0b87f62b575ce5bfd515a9 + languageName: node + linkType: hard + +"quick-lru@npm:^5.1.1": + version: 5.1.1 + resolution: "quick-lru@npm:5.1.1" + checksum: 10c0/a24cba5da8cec30d70d2484be37622580f64765fb6390a928b17f60cd69e8dbd32a954b3ff9176fa1b86d86ff2ba05252fae55dc4d40d0291c60412b0ad096da + languageName: node + linkType: hard + +"randombytes@npm:^2.1.0": + version: 2.1.0 + resolution: "randombytes@npm:2.1.0" + dependencies: + safe-buffer: "npm:^5.1.0" + checksum: 10c0/50395efda7a8c94f5dffab564f9ff89736064d32addf0cc7e8bf5e4166f09f8ded7a0849ca6c2d2a59478f7d90f78f20d8048bca3cdf8be09d8e8a10790388f3 + languageName: node + linkType: hard + +"rechoir@npm:^0.8.0": + version: 0.8.0 + resolution: "rechoir@npm:0.8.0" + dependencies: + resolve: "npm:^1.20.0" + checksum: 10c0/1a30074124a22abbd5d44d802dac26407fa72a0a95f162aa5504ba8246bc5452f8b1a027b154d9bdbabcd8764920ff9333d934c46a8f17479c8912e92332f3ff + languageName: node + linkType: hard + +"relateurl@npm:^0.2.7": + version: 0.2.7 + resolution: "relateurl@npm:0.2.7" + checksum: 10c0/c248b4e3b32474f116a804b537fa6343d731b80056fb506dffd91e737eef4cac6be47a65aae39b522b0db9d0b1011d1a12e288d82a109ecd94a5299d82f6573a + languageName: node + linkType: hard + +"renderkid@npm:^3.0.0": + version: 3.0.0 + resolution: "renderkid@npm:3.0.0" + dependencies: + css-select: "npm:^4.1.3" + dom-converter: "npm:^0.2.0" + htmlparser2: "npm:^6.1.0" + lodash: "npm:^4.17.21" + strip-ansi: "npm:^6.0.1" + checksum: 10c0/24a9fae4cc50e731d059742d1b3eec163dc9e3872b12010d120c3fcbd622765d9cda41f79a1bbb4bf63c1d3442f18a08f6e1642cb5d7ebf092a0ce3f7a3bd143 + languageName: node + linkType: hard + +"require-from-string@npm:^2.0.2": + version: 2.0.2 + resolution: "require-from-string@npm:2.0.2" + checksum: 10c0/aaa267e0c5b022fc5fd4eef49d8285086b15f2a1c54b28240fdf03599cbd9c26049fee3eab894f2e1f6ca65e513b030a7c264201e3f005601e80c49fb2937ce2 + languageName: node + linkType: hard + +"resolve-alpn@npm:^1.0.0": + version: 1.2.1 + resolution: "resolve-alpn@npm:1.2.1" + checksum: 10c0/b70b29c1843bc39781ef946c8cd4482e6d425976599c0f9c138cec8209e4e0736161bf39319b01676a847000085dfdaf63583c6fb4427bf751a10635bd2aa0c4 + languageName: node + linkType: hard + +"resolve-cwd@npm:^3.0.0": + version: 3.0.0 + resolution: "resolve-cwd@npm:3.0.0" + dependencies: + resolve-from: "npm:^5.0.0" + checksum: 10c0/e608a3ebd15356264653c32d7ecbc8fd702f94c6703ea4ac2fb81d9c359180cba0ae2e6b71faa446631ed6145454d5a56b227efc33a2d40638ac13f8beb20ee4 + languageName: node + linkType: hard + +"resolve-from@npm:^5.0.0": + version: 5.0.0 + resolution: "resolve-from@npm:5.0.0" + checksum: 10c0/b21cb7f1fb746de8107b9febab60095187781137fd803e6a59a76d421444b1531b641bba5857f5dc011974d8a5c635d61cec49e6bd3b7fc20e01f0fafc4efbf2 + languageName: node + linkType: hard + +"resolve@npm:^1.20.0": + version: 1.22.11 + resolution: "resolve@npm:1.22.11" + dependencies: + is-core-module: "npm:^2.16.1" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10c0/f657191507530f2cbecb5815b1ee99b20741ea6ee02a59c57028e9ec4c2c8d7681afcc35febbd554ac0ded459db6f2d8153382c53a2f266cee2575e512674409 + languageName: node + linkType: hard + +"resolve@patch:resolve@npm%3A^1.20.0#optional!builtin": + version: 1.22.11 + resolution: "resolve@patch:resolve@npm%3A1.22.11#optional!builtin::version=1.22.11&hash=c3c19d" + dependencies: + is-core-module: "npm:^2.16.1" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10c0/ee5b182f2e37cb1165465e58c6abc797fec0a80b5ba3231607beb4677db0c9291ac010c47cf092b6daa2b7f518d69a0e21888e7e2b633f68d501a874212a8c63 + languageName: node + linkType: hard + +"responselike@npm:^2.0.0": + version: 2.0.1 + resolution: "responselike@npm:2.0.1" + dependencies: + lowercase-keys: "npm:^2.0.0" + checksum: 10c0/360b6deb5f101a9f8a4174f7837c523c3ec78b7ca8a7c1d45a1062b303659308a23757e318b1e91ed8684ad1205721142dd664d94771cd63499353fd4ee732b5 + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 10c0/59933e8501727ba13ad73ef4a04d5280b3717fd650408460c987392efe9d7be2040778ed8ebe933c5cbd63da3dcc37919c141ef8af0a54a6e4fca5a2af177bfe + languageName: node + linkType: hard + +"retry@npm:^0.13.1": + version: 0.13.1 + resolution: "retry@npm:0.13.1" + checksum: 10c0/9ae822ee19db2163497e074ea919780b1efa00431d197c7afdb950e42bf109196774b92a49fc9821f0b8b328a98eea6017410bfc5e8a0fc19c85c6d11adb3772 + languageName: node + linkType: hard + +"rfdc@npm:^1.4.1": + version: 1.4.1 + resolution: "rfdc@npm:1.4.1" + checksum: 10c0/4614e4292356cafade0b6031527eea9bc90f2372a22c012313be1dcc69a3b90c7338158b414539be863fa95bfcb2ddcd0587be696841af4e6679d85e62c060c7 + languageName: node + linkType: hard + +"roarr@npm:^2.15.3": + version: 2.15.4 + resolution: "roarr@npm:2.15.4" + dependencies: + boolean: "npm:^3.0.1" + detect-node: "npm:^2.0.4" + globalthis: "npm:^1.0.1" + json-stringify-safe: "npm:^5.0.1" + semver-compare: "npm:^1.0.0" + sprintf-js: "npm:^1.1.2" + checksum: 10c0/7d01d4c14513c461778dd673a8f9e53255221f8d04173aafeb8e11b23d8b659bb83f1c90cfe81af7f9c213b8084b404b918108fd792bda76678f555340cc64ec + languageName: node + linkType: hard + +"safe-buffer@npm:^5.1.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4 + languageName: node + linkType: hard + +"schema-utils@npm:^4.3.0, schema-utils@npm:^4.3.3": + version: 4.3.3 + resolution: "schema-utils@npm:4.3.3" + dependencies: + "@types/json-schema": "npm:^7.0.9" + ajv: "npm:^8.9.0" + ajv-formats: "npm:^2.1.1" + ajv-keywords: "npm:^5.1.0" + checksum: 10c0/1c8d2c480a026d7c02ab2ecbe5919133a096d6a721a3f201fa50663e4f30f6d6ba020dfddd93cb828b66b922e76b342e103edd19a62c95c8f60e9079cc403202 + languageName: node + linkType: hard + +"semifies@npm:^1.0.0": + version: 1.0.0 + resolution: "semifies@npm:1.0.0" + checksum: 10c0/d93d5e8d2c0b7d5f972b9378736ed5cc1f2ab40d043234b4156665872f08cb0da914ee8c8b35c59dc6b17880a4c5502588c7515c6bb4dbc3ce5565746428d31d + languageName: node + linkType: hard + +"semver-compare@npm:^1.0.0": + version: 1.0.0 + resolution: "semver-compare@npm:1.0.0" + checksum: 10c0/9ef4d8b81847556f0865f46ddc4d276bace118c7cb46811867af82e837b7fc473911981d5a0abc561fa2db487065572217e5b06e18701c4281bcdd2a1affaff1 + languageName: node + linkType: hard + +"semver@npm:^6.2.0": + version: 6.3.1 + resolution: "semver@npm:6.3.1" + bin: + semver: bin/semver.js + checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d + languageName: node + linkType: hard + +"semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5": + version: 7.7.3 + resolution: "semver@npm:7.7.3" + bin: + semver: bin/semver.js + checksum: 10c0/4afe5c986567db82f44c8c6faef8fe9df2a9b1d98098fc1721f57c696c4c21cebd572f297fc21002f81889492345b8470473bc6f4aff5fb032a6ea59ea2bc45e + languageName: node + linkType: hard + +"serialize-error@npm:^7.0.1": + version: 7.0.1 + resolution: "serialize-error@npm:7.0.1" + dependencies: + type-fest: "npm:^0.13.1" + checksum: 10c0/7982937d578cd901276c8ab3e2c6ed8a4c174137730f1fb0402d005af209a0e84d04acc874e317c936724c7b5b26c7a96ff7e4b8d11a469f4924a4b0ea814c05 + languageName: node + linkType: hard + +"serialize-javascript@npm:^6.0.2": + version: 6.0.2 + resolution: "serialize-javascript@npm:6.0.2" + dependencies: + randombytes: "npm:^2.1.0" + checksum: 10c0/2dd09ef4b65a1289ba24a788b1423a035581bef60817bea1f01eda8e3bda623f86357665fe7ac1b50f6d4f583f97db9615b3f07b2a2e8cbcb75033965f771dd2 + languageName: node + linkType: hard + +"shallow-clone@npm:^3.0.0": + version: 3.0.1 + resolution: "shallow-clone@npm:3.0.1" + dependencies: + kind-of: "npm:^6.0.2" + checksum: 10c0/7bab09613a1b9f480c85a9823aebec533015579fa055ba6634aa56ba1f984380670eaf33b8217502931872aa1401c9fcadaa15f9f604d631536df475b05bcf1e + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: 10c0/a41692e7d89a553ef21d324a5cceb5f686d1f3c040759c50aab69688634688c5c327f26f3ecf7001ebfd78c01f3c7c0a11a7c8bfd0a8bc9f6240d4f40b224e4e + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 10c0/1dbed0726dd0e1152a92696c76c7f06084eb32a90f0528d11acd764043aacf76994b2fb30aa1291a21bd019d6699164d048286309a278855ee7bec06cf6fb690 + languageName: node + linkType: hard + +"shell-quote@npm:^1.8.2": + version: 1.8.3 + resolution: "shell-quote@npm:1.8.3" + checksum: 10c0/bee87c34e1e986cfb4c30846b8e6327d18874f10b535699866f368ade11ea4ee45433d97bf5eada22c4320c27df79c3a6a7eb1bf3ecfc47f2c997d9e5e2672fd + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83 + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: 10c0/a16775323e1404dd43fabafe7460be13a471e021637bc7889468eb45ce6a6b207261f454e4e530a19500cc962c4cc5348583520843b363f4193cee5c00e1e539 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.5 + resolution: "socks-proxy-agent@npm:8.0.5" + dependencies: + agent-base: "npm:^7.1.2" + debug: "npm:^4.3.4" + socks: "npm:^2.8.3" + checksum: 10c0/5d2c6cecba6821389aabf18728325730504bf9bb1d9e342e7987a5d13badd7a98838cc9a55b8ed3cb866ad37cc23e1086f09c4d72d93105ce9dfe76330e9d2a6 + languageName: node + linkType: hard + +"socks@npm:^2.8.3": + version: 2.8.7 + resolution: "socks@npm:2.8.7" + dependencies: + ip-address: "npm:^10.0.1" + smart-buffer: "npm:^4.2.0" + checksum: 10c0/2805a43a1c4bcf9ebf6e018268d87b32b32b06fbbc1f9282573583acc155860dc361500f89c73bfbb157caa1b4ac78059eac0ef15d1811eb0ca75e0bdadbc9d2 + languageName: node + linkType: hard + +"source-map-support@npm:~0.5.20": + version: 0.5.21 + resolution: "source-map-support@npm:0.5.21" + dependencies: + buffer-from: "npm:^1.0.0" + source-map: "npm:^0.6.0" + checksum: 10c0/9ee09942f415e0f721d6daad3917ec1516af746a8120bba7bb56278707a37f1eb8642bde456e98454b8a885023af81a16e646869975f06afc1a711fb90484e7d + languageName: node + linkType: hard + +"source-map@npm:^0.6.0, source-map@npm:~0.6.0": + version: 0.6.1 + resolution: "source-map@npm:0.6.1" + checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 + languageName: node + linkType: hard + +"source-map@npm:^0.7.4": + version: 0.7.6 + resolution: "source-map@npm:0.7.6" + checksum: 10c0/59f6f05538539b274ba771d2e9e32f6c65451982510564438e048bc1352f019c6efcdc6dd07909b1968144941c14015c2c7d4369fb7c4d7d53ae769716dcc16c + languageName: node + linkType: hard + +"spark-md5@npm:^3.0.2": + version: 3.0.2 + resolution: "spark-md5@npm:3.0.2" + checksum: 10c0/3fd11735eac5e7d60d6006d99ac0a055f148a89e9baf5f0b51ac103022dec30556b44190b37f6737ca50f81e8e50dc13e724f9edf6290c412ff5ab2101ce7780 + languageName: node + linkType: hard + +"sprintf-js@npm:^1.1.2": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: 10c0/09270dc4f30d479e666aee820eacd9e464215cdff53848b443964202bf4051490538e5dd1b42e1a65cf7296916ca17640aebf63dae9812749c7542ee5f288dec + languageName: node + linkType: hard + +"ssri@npm:^13.0.0": + version: 13.0.0 + resolution: "ssri@npm:13.0.0" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10c0/405f3a531cd98b013cecb355d63555dca42fd12c7bc6671738aaa9a82882ff41cdf0ef9a2b734ca4f9a760338f114c29d01d9238a65db3ccac27929bd6e6d4b2 + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: 10c0/1e525e92e5eae0afd7454086eed9c818ee84374bb80328fc41217ae72ff5f065ef1c9d7f72da41de40c75fa8bb3dee63d92373fd492c84260a552c636392a47b + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: 10c0/ab9c4264443d35b8b923cbdd513a089a60de339216d3b0ed3be3ba57d6880e1a192b70ae17225f764d7adbf5994e9bb8df253a944736c15a0240eff553c678ca + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952 + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.1.2 + resolution: "strip-ansi@npm:7.1.2" + dependencies: + ansi-regex: "npm:^6.0.1" + checksum: 10c0/0d6d7a023de33368fd042aab0bf48f4f4077abdfd60e5393e73c7c411e85e1b3a83507c11af2e656188511475776215df9ca589b4da2295c9455cc399ce1858b + languageName: node + linkType: hard + +"sumchecker@npm:^3.0.1": + version: 3.0.1 + resolution: "sumchecker@npm:3.0.1" + dependencies: + debug: "npm:^4.1.0" + checksum: 10c0/43c387be9dfe22dbeaf39dfa4ffb279847aeb37a42a8988c0b066f548bbd209aa8c65e03da29f2b29be1a66b577801bf89fff0007df4183db2f286263a9569e5 + languageName: node + linkType: hard + +"supports-color@npm:^7.1.0": + version: 7.2.0 + resolution: "supports-color@npm:7.2.0" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10c0/afb4c88521b8b136b5f5f95160c98dee7243dc79d5432db7efc27efb219385bbc7d9427398e43dd6cc730a0f87d5085ce1652af7efbe391327bc0a7d0f7fc124 + languageName: node + linkType: hard + +"supports-color@npm:^8.0.0": + version: 8.1.1 + resolution: "supports-color@npm:8.1.1" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10c0/ea1d3c275dd604c974670f63943ed9bd83623edc102430c05adb8efc56ba492746b6e95386e7831b872ec3807fd89dd8eb43f735195f37b5ec343e4234cc7e89 + languageName: node + linkType: hard + +"supports-preserve-symlinks-flag@npm:^1.0.0": + version: 1.0.0 + resolution: "supports-preserve-symlinks-flag@npm:1.0.0" + checksum: 10c0/6c4032340701a9950865f7ae8ef38578d8d7053f5e10518076e6554a9381fa91bd9c6850193695c141f32b21f979c985db07265a758867bac95de05f7d8aeb39 + languageName: node + linkType: hard + +"tapable@npm:^2.0.0, tapable@npm:^2.2.0, tapable@npm:^2.3.0": + version: 2.3.0 + resolution: "tapable@npm:2.3.0" + checksum: 10c0/cb9d67cc2c6a74dedc812ef3085d9d681edd2c1fa18e4aef57a3c0605fdbe44e6b8ea00bd9ef21bc74dd45314e39d31227aa031ebf2f5e38164df514136f2681 + languageName: node + linkType: hard + +"tar@npm:^7.5.2": + version: 7.5.2 + resolution: "tar@npm:7.5.2" + dependencies: + "@isaacs/fs-minipass": "npm:^4.0.0" + chownr: "npm:^3.0.0" + minipass: "npm:^7.1.2" + minizlib: "npm:^3.1.0" + yallist: "npm:^5.0.0" + checksum: 10c0/a7d8b801139b52f93a7e34830db0de54c5aa45487c7cb551f6f3d44a112c67f1cb8ffdae856b05fd4f17b1749911f1c26f1e3a23bbe0279e17fd96077f13f467 + languageName: node + linkType: hard + +"terser-webpack-plugin@npm:^5.3.11": + version: 5.3.14 + resolution: "terser-webpack-plugin@npm:5.3.14" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.25" + jest-worker: "npm:^27.4.5" + schema-utils: "npm:^4.3.0" + serialize-javascript: "npm:^6.0.2" + terser: "npm:^5.31.1" + peerDependencies: + webpack: ^5.1.0 + peerDependenciesMeta: + "@swc/core": + optional: true + esbuild: + optional: true + uglify-js: + optional: true + checksum: 10c0/9b060947241af43bd6fd728456f60e646186aef492163672a35ad49be6fbc7f63b54a7356c3f6ff40a8f83f00a977edc26f044b8e106cc611c053c8c0eaf8569 + languageName: node + linkType: hard + +"terser@npm:^5.10.0, terser@npm:^5.31.1": + version: 5.44.1 + resolution: "terser@npm:5.44.1" + dependencies: + "@jridgewell/source-map": "npm:^0.3.3" + acorn: "npm:^8.15.0" + commander: "npm:^2.20.0" + source-map-support: "npm:~0.5.20" + bin: + terser: bin/terser + checksum: 10c0/ee7a76692cb39b1ed22c30ff366c33ff3c977d9bb769575338ff5664676168fcba59192fb5168ef80c7cd901ef5411a1b0351261f5eaa50decf0fc71f63bde75 + languageName: node + linkType: hard + +"tinyglobby@npm:^0.2.12": + version: 0.2.15 + resolution: "tinyglobby@npm:0.2.15" + dependencies: + fdir: "npm:^6.5.0" + picomatch: "npm:^4.0.3" + checksum: 10c0/869c31490d0d88eedb8305d178d4c75e7463e820df5a9b9d388291daf93e8b1eb5de1dad1c1e139767e4269fe75f3b10d5009b2cc14db96ff98986920a186844 + languageName: node + linkType: hard + +"tlhunter-sorted-set@npm:^0.1.0": + version: 0.1.0 + resolution: "tlhunter-sorted-set@npm:0.1.0" + checksum: 10c0/fd07870aa75331fb7823e68604fda3bafb6aaef5cea8d342a3c24096635fd2c70273a330b00013e51cbde25272ae599de1270edeff972bd3c32e1c78e714edc6 + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: 10c0/487988b0a19c654ff3e1961b87f471702e708fa8a8dd02a298ef16da7206692e8552a0250e8b3e8759270f62e9d8314616f6da274734d3b558b1fc7b7724e892 + languageName: node + linkType: hard + +"ts-loader@npm:9.5.4": + version: 9.5.4 + resolution: "ts-loader@npm:9.5.4" + dependencies: + chalk: "npm:^4.1.0" + enhanced-resolve: "npm:^5.0.0" + micromatch: "npm:^4.0.0" + semver: "npm:^7.3.4" + source-map: "npm:^0.7.4" + peerDependencies: + typescript: "*" + webpack: ^5.0.0 + checksum: 10c0/f0982404b43628c335d3b3a60ac3f1738385da7b97c3f04cb5ad2ebad791597be39b25c8a4e158a66173f9bd9f5aa72e285b046b0573e4beed8ecd032d418e4d + languageName: node + linkType: hard + +"tslib@npm:^2.0.3": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 + languageName: node + linkType: hard + +"ttl-set@npm:^1.0.0": + version: 1.0.0 + resolution: "ttl-set@npm:1.0.0" + dependencies: + fast-fifo: "npm:^1.3.2" + checksum: 10c0/ef260c2a903c4ab05090d4dbc21ddb738d7f38fd9680570582414b9115a7c358796c82f5b19067262eabb7476e43b7a2f02e3bb4cace85edee3242aee745d4d3 + languageName: node + linkType: hard + +"type-fest@npm:^0.13.1": + version: 0.13.1 + resolution: "type-fest@npm:0.13.1" + checksum: 10c0/0c0fa07ae53d4e776cf4dac30d25ad799443e9eef9226f9fddbb69242db86b08584084a99885cfa5a9dfe4c063ebdc9aa7b69da348e735baede8d43f1aeae93b + languageName: node + linkType: hard + +"undici-types@npm:~6.21.0": + version: 6.21.0 + resolution: "undici-types@npm:6.21.0" + checksum: 10c0/c01ed51829b10aa72fc3ce64b747f8e74ae9b60eafa19a7b46ef624403508a54c526ffab06a14a26b3120d055e1104d7abe7c9017e83ced038ea5cf52f8d5e04 + languageName: node + linkType: hard + +"undici-types@npm:~7.16.0": + version: 7.16.0 + resolution: "undici-types@npm:7.16.0" + checksum: 10c0/3033e2f2b5c9f1504bdc5934646cb54e37ecaca0f9249c983f7b1fc2e87c6d18399ebb05dc7fd5419e02b2e915f734d872a65da2e3eeed1813951c427d33cc9a + languageName: node + linkType: hard + +"unique-filename@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-filename@npm:4.0.0" + dependencies: + unique-slug: "npm:^5.0.0" + checksum: 10c0/38ae681cceb1408ea0587b6b01e29b00eee3c84baee1e41fd5c16b9ed443b80fba90c40e0ba69627e30855570a34ba8b06702d4a35035d4b5e198bf5a64c9ddc + languageName: node + linkType: hard + +"unique-slug@npm:^5.0.0": + version: 5.0.0 + resolution: "unique-slug@npm:5.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: 10c0/d324c5a44887bd7e105ce800fcf7533d43f29c48757ac410afd42975de82cc38ea2035c0483f4de82d186691bf3208ef35c644f73aa2b1b20b8e651be5afd293 + languageName: node + linkType: hard + +"universalify@npm:^0.1.0": + version: 0.1.2 + resolution: "universalify@npm:0.1.2" + checksum: 10c0/e70e0339f6b36f34c9816f6bf9662372bd241714dc77508d231d08386d94f2c4aa1ba1318614f92015f40d45aae1b9075cd30bd490efbe39387b60a76ca3f045 + languageName: node + linkType: hard + +"update-browserslist-db@npm:^1.1.4": + version: 1.1.4 + resolution: "update-browserslist-db@npm:1.1.4" + dependencies: + escalade: "npm:^3.2.0" + picocolors: "npm:^1.1.1" + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 10c0/db0c9aaecf1258a6acda5e937fc27a7996ccca7a7580a1b4aa8bba6a9b0e283e5e65c49ebbd74ec29288ef083f1b88d4da13e3d4d326c1e5fc55bf72d7390702 + languageName: node + linkType: hard + +"utila@npm:~0.4": + version: 0.4.0 + resolution: "utila@npm:0.4.0" + checksum: 10c0/2791604e09ca4f77ae314df83e80d1805f867eb5c7e13e7413caee01273c278cf2c9a3670d8d25c889a877f7b149d892fe61b0181a81654b425e9622ab23d42e + languageName: node + linkType: hard + +"watchpack@npm:^2.4.4": + version: 2.4.4 + resolution: "watchpack@npm:2.4.4" + dependencies: + glob-to-regexp: "npm:^0.4.1" + graceful-fs: "npm:^4.1.2" + checksum: 10c0/6c0901f75ce245d33991225af915eea1c5ae4ba087f3aee2b70dd377d4cacb34bef02a48daf109da9d59b2d31ec6463d924a0d72f8618ae1643dd07b95de5275 + languageName: node + linkType: hard + +"webpack-cli@npm:6.0.1": + version: 6.0.1 + resolution: "webpack-cli@npm:6.0.1" + dependencies: + "@discoveryjs/json-ext": "npm:^0.6.1" + "@webpack-cli/configtest": "npm:^3.0.1" + "@webpack-cli/info": "npm:^3.0.1" + "@webpack-cli/serve": "npm:^3.0.1" + colorette: "npm:^2.0.14" + commander: "npm:^12.1.0" + cross-spawn: "npm:^7.0.3" + envinfo: "npm:^7.14.0" + fastest-levenshtein: "npm:^1.0.12" + import-local: "npm:^3.0.2" + interpret: "npm:^3.1.1" + rechoir: "npm:^0.8.0" + webpack-merge: "npm:^6.0.1" + peerDependencies: + webpack: ^5.82.0 + peerDependenciesMeta: + webpack-bundle-analyzer: + optional: true + webpack-dev-server: + optional: true + bin: + webpack-cli: ./bin/cli.js + checksum: 10c0/2aaca78e277427f03f528602abd707d224696048fb46286ea636c7975592409c4381ca94d68bbbb3900f195ca97f256e619583e8feb34a80da531461323bf3e2 + languageName: node + linkType: hard + +"webpack-merge@npm:^6.0.1": + version: 6.0.1 + resolution: "webpack-merge@npm:6.0.1" + dependencies: + clone-deep: "npm:^4.0.1" + flat: "npm:^5.0.2" + wildcard: "npm:^2.0.1" + checksum: 10c0/bf1429567858b353641801b8a2696ca0aac270fc8c55d4de8a7b586fe07d27fdcfc83099a98ab47e6162383db8dd63bb8cc25b1beb2ec82150422eec843b0dc0 + languageName: node + linkType: hard + +"webpack-sources@npm:^3.3.3": + version: 3.3.3 + resolution: "webpack-sources@npm:3.3.3" + checksum: 10c0/ab732f6933b513ba4d505130418995ddef6df988421fccf3289e53583c6a39e205c4a0739cee98950964552d3006604912679c736031337fb4a9d78d8576ed40 + languageName: node + linkType: hard + +"webpack@npm:5.103.0": + version: 5.103.0 + resolution: "webpack@npm:5.103.0" + dependencies: + "@types/eslint-scope": "npm:^3.7.7" + "@types/estree": "npm:^1.0.8" + "@types/json-schema": "npm:^7.0.15" + "@webassemblyjs/ast": "npm:^1.14.1" + "@webassemblyjs/wasm-edit": "npm:^1.14.1" + "@webassemblyjs/wasm-parser": "npm:^1.14.1" + acorn: "npm:^8.15.0" + acorn-import-phases: "npm:^1.0.3" + browserslist: "npm:^4.26.3" + chrome-trace-event: "npm:^1.0.2" + enhanced-resolve: "npm:^5.17.3" + es-module-lexer: "npm:^1.2.1" + eslint-scope: "npm:5.1.1" + events: "npm:^3.2.0" + glob-to-regexp: "npm:^0.4.1" + graceful-fs: "npm:^4.2.11" + json-parse-even-better-errors: "npm:^2.3.1" + loader-runner: "npm:^4.3.1" + mime-types: "npm:^2.1.27" + neo-async: "npm:^2.6.2" + schema-utils: "npm:^4.3.3" + tapable: "npm:^2.3.0" + terser-webpack-plugin: "npm:^5.3.11" + watchpack: "npm:^2.4.4" + webpack-sources: "npm:^3.3.3" + peerDependenciesMeta: + webpack-cli: + optional: true + bin: + webpack: bin/webpack.js + checksum: 10c0/d0cf86f8cac249874d6f36292e25011413ebb5bae82c48fa78a165a217e63db00b1a1f563f5195070eb17a055c6da4b6ab89fbdd37f781abdda862aa8c0bd623 + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 10c0/66522872a768b60c2a65a57e8ad184e5372f5b6a9ca6d5f033d4b0dc98aff63995655a7503b9c0a2598936f532120e81dd8cc155e2e92ed662a2b9377cc4374f + languageName: node + linkType: hard + +"which@npm:^6.0.0": + version: 6.0.0 + resolution: "which@npm:6.0.0" + dependencies: + isexe: "npm:^3.1.1" + bin: + node-which: bin/which.js + checksum: 10c0/fe9d6463fe44a76232bb6e3b3181922c87510a5b250a98f1e43a69c99c079b3f42ddeca7e03d3e5f2241bf2d334f5a7657cfa868b97c109f3870625842f4cc15 + languageName: node + linkType: hard + +"wildcard@npm:^2.0.1": + version: 2.0.1 + resolution: "wildcard@npm:2.0.1" + checksum: 10c0/08f70cd97dd9a20aea280847a1fe8148e17cae7d231640e41eb26d2388697cbe65b67fd9e68715251c39b080c5ae4f76d71a9a69fa101d897273efdfb1b58bf7 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: 10c0/d15fc12c11e4cbc4044a552129ebc75ee3f57aa9c1958373a4db0292d72282f54373b536103987a4a7594db1ef6a4f10acf92978f79b98c49306a4b58c77d4da + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 10c0/138ff58a41d2f877eae87e3282c0630fc2789012fc1af4d6bd626eeb9a2f9a65ca92005e6e69a75c7b85a68479fe7443c7dbe1eb8fbaa681a4491364b7c55c60 + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0 + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a + languageName: node + linkType: hard + +"yallist@npm:^5.0.0": + version: 5.0.0 + resolution: "yallist@npm:5.0.0" + checksum: 10c0/a499c81ce6d4a1d260d4ea0f6d49ab4da09681e32c3f0472dee16667ed69d01dae63a3b81745a24bd78476ec4fcf856114cb4896ace738e01da34b2c42235416 + languageName: node + linkType: hard + +"yauzl@npm:^2.10.0": + version: 2.10.0 + resolution: "yauzl@npm:2.10.0" + dependencies: + buffer-crc32: "npm:~0.2.3" + fd-slicer: "npm:~1.1.0" + checksum: 10c0/f265002af7541b9ec3589a27f5fb8f11cf348b53cc15e2751272e3c062cd73f3e715bc72d43257de71bbaecae446c3f1b14af7559e8ab0261625375541816422 + languageName: node + linkType: hard + +"yocto-queue@npm:^0.1.0": + version: 0.1.0 + resolution: "yocto-queue@npm:0.1.0" + checksum: 10c0/dceb44c28578b31641e13695d200d34ec4ab3966a5729814d5445b194933c096b7ced71494ce53a0e8820685d1d010df8b2422e5bf2cdea7e469d97ffbea306f + languageName: node + linkType: hard diff --git a/test/e2e/lib/framework/createTest.ts b/test/e2e/lib/framework/createTest.ts index 25b32dc831..9b4e11969e 100644 --- a/test/e2e/lib/framework/createTest.ts +++ b/test/e2e/lib/framework/createTest.ts @@ -2,6 +2,7 @@ import type { LogsInitConfiguration } from '@datadog/browser-logs' import type { RumInitConfiguration, RemoteConfiguration } from '@datadog/browser-rum-core' import type { BrowserContext, Page } from '@playwright/test' import { test, expect } from '@playwright/test' +import { _electron as electron } from 'playwright-core' import { addTag, addTestOptimizationTags } from '../helpers/tags' import { getRunId } from '../../../envUtils' import type { BrowserLog } from '../helpers/browser' @@ -10,7 +11,7 @@ import { DEFAULT_LOGS_CONFIGURATION, DEFAULT_RUM_CONFIGURATION } from '../helper import { validateRumFormat } from '../helpers/validation' import type { BrowserConfiguration } from '../../../browsers.conf' import { IntakeRegistry } from './intakeRegistry' -import { flushEvents } from './flushEvents' +import { flushEvents, flushElectronEvents } from './flushEvents' import type { Servers } from './httpServers' import { getTestServers, waitForServersIdle } from './httpServers' import type { SetupFactory, SetupOptions } from './pageSetups' @@ -50,6 +51,7 @@ type TestRunner = (testContext: TestContext) => Promise | void class TestBuilder { private rumConfiguration: RumInitConfiguration | undefined = undefined private alsoRunWithRumSlim = false + private isElectron = false private logsConfiguration: LogsInitConfiguration | undefined = undefined private remoteConfiguration?: RemoteConfiguration = undefined private head = '' @@ -87,6 +89,11 @@ class TestBuilder { return this } + withElectron() { + this.isElectron = true + return this + } + withLogs(logsInitConfiguration?: Partial) { this.logsConfiguration = { ...DEFAULT_LOGS_CONFIGURATION, ...logsInitConfiguration } return this @@ -194,6 +201,7 @@ class TestBuilder { testFixture: this.testFixture, extension: this.extension, hostName: this.hostName, + isElectron: this.isElectron, } if (this.alsoRunWithRumSlim) { @@ -268,20 +276,79 @@ function declareTest(title: string, setupOptions: SetupOptions, factory: SetupFa const testContext = createTestContext(servers, page, context, browserLogs, browserName, setupOptions) servers.intake.bindServerApp(createIntakeServerApp(testContext.intakeRegistry)) + bindServersToConfigurations(servers, setupOptions) const setup = factory(setupOptions, servers) servers.base.bindServerApp(createMockServerApp(servers, setup, setupOptions.remoteConfiguration)) servers.crossOrigin.bindServerApp(createMockServerApp(servers, setup)) - await setUpTest(browserLogs, testContext) + if (setupOptions.isElectron) { + await runElectronTest(runner, testContext, setupOptions) + } else { + await runBrowserTest(runner, testContext, browserLogs) + } + }) +} - try { - await runner(testContext) - tearDownPassedTest(testContext) - } finally { - await tearDownTest(testContext) +function bindServersToConfigurations(servers: Servers, setupOptions: SetupOptions) { + for (const config of [ + setupOptions.rum, + setupOptions.logs, + setupOptions.extension?.logsConfiguration, + setupOptions.extension?.rumConfiguration, + ]) { + if (config) { + config.proxy = servers.intake.origin + ;(config as any).remoteConfigurationProxy = `${servers.base.origin}/config` } + } +} + +async function runBrowserTest(runner: TestRunner, testContext: TestContext, browserLogs: BrowserLogsManager) { + await setUpTest(browserLogs, testContext) + try { + await runner(testContext) + tearDownPassedTest(testContext) + } finally { + await tearDownTest(testContext) + } +} + +async function runElectronTest(runner: TestRunner, testContext: TestContext, setupOptions: SetupOptions) { + const ELECTRON_APP_MAIN = 'test/apps/electron/dist/main.js' + const rumEnv = setupOptions.rum ? toEnvVariable(setupOptions.rum) : undefined + const electronApp = await electron.launch({ + args: [ELECTRON_APP_MAIN], + env: { + ...rumEnv, + ELECTRON_ENABLE_LOGGING: '1', + }, + }) + + const child = electronApp.process() + child.stdout?.on('data', (data) => console.log('[ELECTRON MAIN]', String(data))) + child.stderr?.on('data', (data) => console.error('[ELECTRON MAIN]', String(data))) + + const page = await electronApp.firstWindow() + testContext.page = page + await page.waitForLoadState('domcontentloaded') + await waitForServersIdle() + try { + await runner(testContext) + tearDownPassedTest(testContext) + } finally { + await flushElectronEvents(page) + await page.close() + } +} + +function toEnvVariable(rum: RumInitConfiguration) { + const namespace = 'RUM_' + const env: { [key: string]: any } = {} + Object.entries(rum).forEach(([key, value]) => { + env[`${namespace}${key}`] = value }) + return env } function createTestContext( diff --git a/test/e2e/lib/framework/flushEvents.ts b/test/e2e/lib/framework/flushEvents.ts index 7567d42116..47acf9b4f5 100644 --- a/test/e2e/lib/framework/flushEvents.ts +++ b/test/e2e/lib/framework/flushEvents.ts @@ -24,3 +24,9 @@ export async function flushEvents(page: Page) { await page.goto(`${servers.base.origin}/ok?duration=200`) await waitForServersIdle() } + +export async function flushElectronEvents(page: Page) { + // TODO improve electron sdk flush logic + await page.waitForTimeout(1000) + await waitForServersIdle() +} diff --git a/test/e2e/lib/framework/index.ts b/test/e2e/lib/framework/index.ts index 8baeb9662f..1d224d99e9 100644 --- a/test/e2e/lib/framework/index.ts +++ b/test/e2e/lib/framework/index.ts @@ -4,7 +4,7 @@ export { createExtension } from './createExtension' export { bundleSetup, html, npmSetup, reactSetup, formatConfiguration, createCrossOriginScriptUrls } from './pageSetups' export { IntakeRegistry } from './intakeRegistry' export { getTestServers, waitForServersIdle } from './httpServers' -export { flushEvents } from './flushEvents' +export { flushEvents, flushElectronEvents } from './flushEvents' export { waitForRequests } from './waitForRequests' export { LARGE_RESPONSE_MIN_BYTE_SIZE } from './serverApps/mock' export { getSdkBundlePath, getTestAppBundlePath } from './sdkBuilds' diff --git a/test/e2e/lib/framework/pageSetups.ts b/test/e2e/lib/framework/pageSetups.ts index 3a47a8ac51..3a5fe45970 100644 --- a/test/e2e/lib/framework/pageSetups.ts +++ b/test/e2e/lib/framework/pageSetups.ts @@ -8,6 +8,7 @@ import type { Servers } from './httpServers' export interface SetupOptions { rum?: RumInitConfiguration + isElectron: boolean useRumSlim: boolean logs?: LogsInitConfiguration logsInit: (initConfiguration: LogsInitConfiguration) => void @@ -75,7 +76,7 @@ n=o.getElementsByTagName(u)[0];n.parentNode.insertBefore(d,n) ${formatSnippet(logsScriptUrl, 'DD_LOGS')} DD_LOGS.onReady(function () { DD_LOGS.setGlobalContext(${JSON.stringify(options.context)}) - ;(${options.logsInit.toString()})(${formatConfiguration(options.logs, servers)}) + ;(${options.logsInit.toString()})(${formatConfiguration(options.logs)}) }) ` @@ -87,7 +88,7 @@ n=o.getElementsByTagName(u)[0];n.parentNode.insertBefore(d,n) ${formatSnippet(rumScriptUrl, 'DD_RUM')} DD_RUM.onReady(function () { DD_RUM.setGlobalContext(${JSON.stringify(options.context)}) - ;(${options.rumInit.toString()})(${formatConfiguration(options.rum, servers)}) + ;(${options.rumInit.toString()})(${formatConfiguration(options.rum)}) }) ` @@ -117,7 +118,7 @@ export function bundleSetup(options: SetupOptions, servers: Servers) { ` } @@ -127,7 +128,7 @@ export function bundleSetup(options: SetupOptions, servers: Servers) { ` } @@ -155,7 +156,7 @@ export function npmSetup(options: SetupOptions, servers: Servers) { ` @@ -166,7 +167,7 @@ export function npmSetup(options: SetupOptions, servers: Servers) { ` @@ -195,7 +196,7 @@ export function reactSetup(options: SetupOptions, servers: Servers, appName: str if (options.rum) { header += html` ` @@ -214,7 +215,7 @@ export function workerSetup(options: WorkerOptions, servers: Servers) { ${options.importScripts ? js`importScripts('/datadog-logs.js');` : js`import '/datadog-logs.js';`} // Initialize DD_LOGS in service worker - DD_LOGS.init(${formatConfiguration({ ...DEFAULT_LOGS_CONFIGURATION, forwardConsoleLogs: 'all', forwardErrorsToLogs: true }, servers)}) + DD_LOGS.init(${formatConfiguration({ ...DEFAULT_LOGS_CONFIGURATION, forwardConsoleLogs: 'all', forwardErrorsToLogs: true, proxy: servers.intake.origin })}) // Handle messages from main thread self.addEventListener('message', (event) => { @@ -292,7 +293,7 @@ function setupExtension(options: SetupOptions, servers: Servers) { ` } @@ -302,7 +303,7 @@ function setupExtension(options: SetupOptions, servers: Servers) { ` } @@ -310,27 +311,20 @@ function setupExtension(options: SetupOptions, servers: Servers) { return header } -export function formatConfiguration(initConfiguration: LogsInitConfiguration | RumInitConfiguration, servers: Servers) { +export function formatConfiguration(initConfiguration: LogsInitConfiguration | RumInitConfiguration) { const fns = new Map void>() - let result = JSON.stringify( - { - ...initConfiguration, - proxy: servers.intake.origin, - remoteConfigurationProxy: `${servers.base.origin}/config`, - }, - (_key, value) => { - if (typeof value === 'function') { - const id = generateUUID() - fns.set(id, value) - - return id - } + let result = JSON.stringify(initConfiguration, (_key, value) => { + if (typeof value === 'function') { + const id = generateUUID() + fns.set(id, value) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return value + return id } - ) + + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return value + }) result = result.replace('"LOCATION_ORIGIN"', 'location.origin') diff --git a/test/e2e/scenario/electron.scenario.ts b/test/e2e/scenario/electron.scenario.ts new file mode 100644 index 0000000000..acccd002b8 --- /dev/null +++ b/test/e2e/scenario/electron.scenario.ts @@ -0,0 +1,17 @@ +import { test, expect } from '@playwright/test' +import { createTest, flushElectronEvents } from '../lib/framework' + +test.describe('electron sdk', () => { + createTest('should track a view on the main process') + .withRum() + .withElectron() + .run(async ({ intakeRegistry, page }) => { + await flushElectronEvents(page) + + const viewEvent = intakeRegistry.rumViewEvents[0] + expect(viewEvent).toBeDefined() + expect(viewEvent.source).toBe('browser') + expect(viewEvent.view.name).toBe('ApplicationLaunch') + expect(viewEvent.view.url).toBe('com/datadog/application-launch/view') + }) +}) From 3ba365205dd6ca18e1a06cc829eb36b2091b3bf2 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Mon, 24 Nov 2025 17:12:10 +0100 Subject: [PATCH 42/58] Make e2e pass on ci --- .gitlab-ci.yml | 2 +- Dockerfile | 2 ++ package.json | 2 +- test/apps/electron/src/main.ts | 1 - test/e2e/lib/framework/createTest.ts | 1 + test/e2e/playwright.bs.config.ts | 2 +- test/e2e/scenario/electron.scenario.ts | 3 ++- 7 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 75b8762626..297a21491d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ variables: CURRENT_STAGING: staging-47 APP: 'browser-sdk' - CURRENT_CI_IMAGE: 93 + CURRENT_CI_IMAGE: 94 BUILD_STABLE_REGISTRY: 'registry.ddbuild.io' CI_IMAGE: '$BUILD_STABLE_REGISTRY/ci/$APP:$CURRENT_CI_IMAGE' GIT_REPOSITORY: 'git@github.com:DataDog/browser-sdk.git' diff --git a/Dockerfile b/Dockerfile index e3913da984..bad620c192 100644 --- a/Dockerfile +++ b/Dockerfile @@ -65,6 +65,8 @@ RUN apt-get -y install git RUN apt-get -y install procps +RUN apt-get -y install xvfb + # Woke RUN set -o pipefail \ && curl -sSfL https://git.io/getwoke | bash -s -- -b /usr/local/bin v0.17.1 diff --git a/package.json b/package.json index 25ec764423..f9c85ad41b 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "test:e2e:init": "yarn build && yarn build:apps && yarn playwright install chromium --with-deps", "test:e2e": "playwright test --config test/e2e/playwright.local.config.ts --project chromium", "test:e2e:bs": "node ./scripts/test/bs-wrapper.ts playwright test --config test/e2e/playwright.bs.config.ts", - "test:e2e:ci": "yarn test:e2e:init && yarn test:e2e", + "test:e2e:ci": "yarn test:e2e:init && xvfb-run -a yarn test:e2e", "test:e2e:ci:bs": "yarn build && yarn build:apps && yarn test:e2e:bs", "test:compat:tsc": "node scripts/check-typescript-compatibility.ts", "test:compat:ssr": "scripts/cli check_server_side_rendering_compatibility", diff --git a/test/apps/electron/src/main.ts b/test/apps/electron/src/main.ts index fcd82c3f1a..c16f5f6942 100644 --- a/test/apps/electron/src/main.ts +++ b/test/apps/electron/src/main.ts @@ -33,6 +33,5 @@ function retrieveRumConfiguration(): any { .forEach(([key, value]) => { rumConfiguration[key.replace(namespace, '')] = Number.isNaN(Number(value)) ? value : Number(value) }) - console.log(rumConfiguration) return rumConfiguration } diff --git a/test/e2e/lib/framework/createTest.ts b/test/e2e/lib/framework/createTest.ts index 9b4e11969e..963084a115 100644 --- a/test/e2e/lib/framework/createTest.ts +++ b/test/e2e/lib/framework/createTest.ts @@ -320,6 +320,7 @@ async function runElectronTest(runner: TestRunner, testContext: TestContext, set const electronApp = await electron.launch({ args: [ELECTRON_APP_MAIN], env: { + ...process.env, ...rumEnv, ELECTRON_ENABLE_LOGGING: '1', }, diff --git a/test/e2e/playwright.bs.config.ts b/test/e2e/playwright.bs.config.ts index 8066c1f683..af0d920ba0 100644 --- a/test/e2e/playwright.bs.config.ts +++ b/test/e2e/playwright.bs.config.ts @@ -7,7 +7,7 @@ import { browserConfigurations } from './browsers.conf' export default defineConfig({ ...baseConfig, workers: 5, // BrowserStack has a limit of 5 parallel sessions - testIgnore: ['**/developerExtension.scenario.ts', '**/s8sInject.scenario.ts'], // These test won't run in the BrowserStack + testIgnore: ['**/developerExtension.scenario.ts', '**/s8sInject.scenario.ts', '**/electron.scenario.ts'], // These test won't run in the BrowserStack projects: browserConfigurations.map((configuration) => ({ name: configuration.sessionName, metadata: configuration, diff --git a/test/e2e/scenario/electron.scenario.ts b/test/e2e/scenario/electron.scenario.ts index acccd002b8..320a10f2ad 100644 --- a/test/e2e/scenario/electron.scenario.ts +++ b/test/e2e/scenario/electron.scenario.ts @@ -1,8 +1,9 @@ import { test, expect } from '@playwright/test' -import { createTest, flushElectronEvents } from '../lib/framework' +import { createTest, flushElectronEvents, npmSetup } from '../lib/framework' test.describe('electron sdk', () => { createTest('should track a view on the main process') + .withSetup(npmSetup) .withRum() .withElectron() .run(async ({ intakeRegistry, page }) => { From a70e5095a683c2591330b97fcb7b51f8c68d9f39 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Tue, 25 Nov 2025 10:20:21 +0100 Subject: [PATCH 43/58] Use ApplicationLaunch for node view url --- packages/electron/src/domain/rum/mainProcessTracking.ts | 7 ++++--- test/e2e/scenario/electron.scenario.ts | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/electron/src/domain/rum/mainProcessTracking.ts b/packages/electron/src/domain/rum/mainProcessTracking.ts index 860c999fcc..1f42191d9f 100644 --- a/packages/electron/src/domain/rum/mainProcessTracking.ts +++ b/packages/electron/src/domain/rum/mainProcessTracking.ts @@ -6,6 +6,8 @@ import { HookNames, timeStampNow, combine, toServerDuration, elapsed } from '@da import type { Hooks } from '../../hooks' import type { CollectedRumEvent } from './events' +const NODE_VIEW_NAME = 'ApplicationLaunch' + export function startMainProcessTracking( hooks: Hooks, configuration: RumConfiguration, @@ -26,8 +28,7 @@ export function startMainProcessTracking( }, view: { id: mainProcessContext.viewId, - // TODO get customer package name - url: 'com/datadog/application-launch/view', + url: NODE_VIEW_NAME, }, service: configuration.service, env: configuration.env, @@ -49,7 +50,7 @@ export function startMainProcessTracking( view: { id: mainProcessContext.viewId, is_active: true, - name: 'ApplicationLaunch', + name: NODE_VIEW_NAME, time_spent: 0, // TODO update counters action: { diff --git a/test/e2e/scenario/electron.scenario.ts b/test/e2e/scenario/electron.scenario.ts index 320a10f2ad..517ad68acc 100644 --- a/test/e2e/scenario/electron.scenario.ts +++ b/test/e2e/scenario/electron.scenario.ts @@ -13,6 +13,6 @@ test.describe('electron sdk', () => { expect(viewEvent).toBeDefined() expect(viewEvent.source).toBe('browser') expect(viewEvent.view.name).toBe('ApplicationLaunch') - expect(viewEvent.view.url).toBe('com/datadog/application-launch/view') + expect(viewEvent.view.url).toBe('ApplicationLaunch') }) }) From 5ebdee848e48cf49bf88898b6b141044d105bf1e Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Tue, 25 Nov 2025 11:37:07 +0100 Subject: [PATCH 44/58] Add support for renderer telemetry / logs --- packages/electron/package.json | 10 +- packages/electron/src/domain/logs/assembly.ts | 27 ++++++ packages/electron/src/domain/main/bridge.ts | 31 +++--- packages/electron/src/entries/main.ts | 96 ++++++++++--------- yarn.lock | 9 +- 5 files changed, 99 insertions(+), 74 deletions(-) create mode 100644 packages/electron/src/domain/logs/assembly.ts diff --git a/packages/electron/package.json b/packages/electron/package.json index 4c9b9f819d..f755d53741 100644 --- a/packages/electron/package.json +++ b/packages/electron/package.json @@ -13,21 +13,13 @@ }, "dependencies": { "@datadog/browser-core": "6.24.0", + "@datadog/browser-logs": "6.24.0", "@datadog/browser-rum-core": "6.24.0", "@msgpack/msgpack": "3.1.2", "@openfeature/core": "1.9.1", "dd-trace": "^5.76.0", "graphql": "16.12.0" }, - "peerDependencies": { - "@datadog/browser-logs": "6.24.0", - "electron": "39" - }, - "peerDependenciesMeta": { - "@datadog/browser-logs": { - "optional": true - } - }, "repository": { "type": "git", "url": "https://github.com/DataDog/browser-sdk.git", diff --git a/packages/electron/src/domain/logs/assembly.ts b/packages/electron/src/domain/logs/assembly.ts new file mode 100644 index 0000000000..5edbb07843 --- /dev/null +++ b/packages/electron/src/domain/logs/assembly.ts @@ -0,0 +1,27 @@ +import type { Observable, Context, Batch } from '@datadog/browser-core' +import { HookNames, DISCARDED, combine } from '@datadog/browser-core' +import type { LogsEvent } from '@datadog/browser-logs' +import type { Hooks } from '../../hooks' + +export function startLogsEventAssembleAndSend( + onLogsEventObservable: Observable, + logsBatch: Batch, + hooks: Hooks +) { + onLogsEventObservable.subscribe((event) => { + const defaultLogsEventAttributes = hooks.triggerHook(HookNames.Assemble, { + eventType: 'log' as any, + })! + + if (defaultLogsEventAttributes === DISCARDED) { + return + } + + const serverLogEvent = combine(event as Context, { + session_id: defaultLogsEventAttributes.session!.id, + application_id: defaultLogsEventAttributes.application!.id, + }) + + logsBatch.add(serverLogEvent) + }) +} diff --git a/packages/electron/src/domain/main/bridge.ts b/packages/electron/src/domain/main/bridge.ts index 95d775c585..6fc85dc772 100644 --- a/packages/electron/src/domain/main/bridge.ts +++ b/packages/electron/src/domain/main/bridge.ts @@ -1,24 +1,31 @@ import type { Observable } from '@datadog/browser-core' -import type { RumEvent } from '@datadog/browser-rum-core' import { ipcMain } from 'electron' +import type { RumEvent } from '@datadog/browser-rum-core' +import type { LogsEvent } from '@datadog/browser-logs' import type { CollectedRumEvent } from '../rum/events' interface BridgeEvent { - eventType: 'rum' - event: RumEvent & { session: { id: string } } & { application: { id: string } } + eventType: 'rum' | 'internal_telemetry' | 'log' + event: unknown } -export function setupMainBridge(rumEventObservable: Observable) { +export function setupMainBridge( + rumEventObservable: Observable, + logsEventObservable: Observable +) { ipcMain.handle('datadog:send', (_event, msg: string) => { - const serverRumEvent = JSON.parse(msg) as BridgeEvent + const bridgeEvent = JSON.parse(msg) as BridgeEvent - if (serverRumEvent.eventType !== 'rum') { - // TODO: handle other types of events (telemetry, session replays, Logs, ....) - console.log('not a rum event', serverRumEvent) - - return + switch (bridgeEvent.eventType) { + case 'rum': + case 'internal_telemetry': + rumEventObservable.notify({ event: bridgeEvent.event as RumEvent, source: 'renderer' }) + break + case 'log': + logsEventObservable.notify(bridgeEvent.event as LogsEvent) + break + default: + console.log('Unhandled event type', bridgeEvent) } - - rumEventObservable.notify({ event: serverRumEvent.event, source: 'renderer' }) }) } diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index b399e26ef0..2c2651ff6b 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -1,32 +1,7 @@ /* eslint-disable jsdoc/check-indentation */ -/** - * TODO: - * - [ ] Basic session management - * - [x] Transport layer (for the bridge from webview, from dd-trace) - * - [x] handle rum events - * - [ ] handle routing for other type of events - * - [ ] telemetry - * - [ ] session replays - * - [ ] logs - * - [x] handle dd-trace events (forwards APM spans to trace intake) - * - [x] setup bridge client with ipc from webviews (renderer processes) - * - [x] use `exposeInMainWorld` to setup the bridge function that will setup the ipc to the main process - * - [ ] verify the IPCMain / IpcRenderer are generating correct spans (sync/async/callback/...) - * - [ ] check with APM for wraping IPCMain and net - * - [ ] crash reporting - * - [ ] Test bundling on Windows - * - [ ] Setup the build so we can measure the bundle sizes - * - [ ] check with APM how we can reduce the dd-trace-size - * - [ ] found a real world electron app to try and see how it looks - * - [ ] does the app uses IPC - * - [ ] look at all the TODOs around the electron SDK - * - [ ] add tests - * - [ ] source + user agent in the UI (electron app) - */ import type { RawError, PageMayExitEvent, Encoder, InitConfiguration, TrackType } from '@datadog/browser-core' import { Observable, - DeflateEncoderStreamId, createBatch, createHttpRequest, createFlushController, @@ -35,6 +10,7 @@ import { } from '@datadog/browser-core' import type { RumConfiguration, RumInitConfiguration } from '@datadog/browser-rum-core' import { createHooks, validateAndBuildRumConfiguration } from '@datadog/browser-rum-core' +import type { LogsEvent } from '@datadog/browser-logs' import tracer, { initTracer } from '../domain/trace/tracer' import { createIpcMain } from '../domain/main/ipcMain' import type { CollectedRumEvent } from '../domain/rum/events' @@ -45,6 +21,7 @@ import { startMainProcessTracking } from '../domain/rum/mainProcessTracking' import { startConvertSpanToRumEvent } from '../domain/rum/convertSpans' import type { Trace } from '../domain/trace/trace' import { createDdTraceAgent } from '../domain/trace/traceAgent' +import { startLogsEventAssembleAndSend } from '../domain/logs/assembly' function makeDatadogElectron() { return { @@ -60,38 +37,44 @@ function makeDatadogElectron() { const pageMayExitObservable = new Observable() const sessionExpireObservable = new Observable() const onRumEventObservable = new Observable() + const onLogsEventObservable = new Observable() const onTraceObservable = new Observable() const hooks = createHooks() - const createEncoder = () => createIdentityEncoder() const rumBatch = startElectronRumBatch( configuration, - () => { - console.error('Error reporting to Datadog') - }, + reportError, pageMayExitObservable, sessionExpireObservable, - createEncoder + createIdentityEncoder ) - startRumEventAssembleAndSend(onRumEventObservable, rumBatch, hooks) - const onActivityObservable = startActivityTracking(onRumEventObservable) - startMainProcessTracking(hooks, configuration, onRumEventObservable, onActivityObservable) - startConvertSpanToRumEvent(onTraceObservable, onRumEventObservable) + + const logsBatch = startElectronLogsBatch( + configuration, + reportError, + pageMayExitObservable, + sessionExpireObservable, + createIdentityEncoder + ) + startLogsEventAssembleAndSend(onLogsEventObservable, logsBatch, hooks) const spanBatch = startElectronSpanBatch( initConfiguration, - () => { - console.error('Error reporting to Datadog') - }, + reportError, pageMayExitObservable, sessionExpireObservable, - createEncoder + createIdentityEncoder ) onTraceObservable.subscribe((trace) => { spanBatch.add({ env: 'prod', spans: trace }) }) - setupMainBridge(onRumEventObservable) + + const onActivityObservable = startActivityTracking(onRumEventObservable) + startMainProcessTracking(hooks, configuration, onRumEventObservable, onActivityObservable) + startConvertSpanToRumEvent(onTraceObservable, onRumEventObservable) + setupMainBridge(onRumEventObservable, onLogsEventObservable) + initTracer(configuration.service!, configuration.env!, configuration.version!) createDdTraceAgent(onTraceObservable, hooks) @@ -112,10 +95,10 @@ export function startElectronRumBatch( reportError: (error: RawError) => void, pageMayExitObservable: Observable, sessionExpireObservable: Observable, - createEncoder: (streamId: DeflateEncoderStreamId) => Encoder + createEncoder: () => Encoder ) { const batch = createBatch({ - encoder: createEncoder(DeflateEncoderStreamId.RUM), + encoder: createEncoder(), request: createHttpRequest([configuration.rumEndpointBuilder], reportError), flushController: createFlushController({ pageMayExitObservable, @@ -126,19 +109,36 @@ export function startElectronRumBatch( return batch } +export function startElectronLogsBatch( + configuration: RumConfiguration, + reportError: (error: RawError) => void, + pageMayExitObservable: Observable, + sessionExpireObservable: Observable, + createEncoder: () => Encoder +) { + const batch = createBatch({ + encoder: createEncoder(), + request: createHttpRequest([configuration.logsEndpointBuilder], reportError), + flushController: createFlushController({ + pageMayExitObservable, + sessionExpireObservable, + }), + }) + + return batch +} + // TODO change it by a single event fetch export function startElectronSpanBatch( initConfiguration: InitConfiguration, reportError: (error: RawError) => void, pageMayExitObservable: Observable, sessionExpireObservable: Observable, - createEncoder: (streamId: DeflateEncoderStreamId) => Encoder + createEncoder: () => Encoder ) { - const endpoints = [createEndpointBuilder(initConfiguration, 'spans' as TrackType)] - const batch = createBatch({ - encoder: createEncoder(DeflateEncoderStreamId.RUM), - request: createHttpRequest(endpoints, reportError), + encoder: createEncoder(), + request: createHttpRequest([createEndpointBuilder(initConfiguration, 'spans' as TrackType)], reportError), flushController: createFlushController({ pageMayExitObservable, sessionExpireObservable, @@ -147,3 +147,7 @@ export function startElectronSpanBatch( return batch } + +function reportError() { + console.error('Error reporting to Datadog') +} diff --git a/yarn.lock b/yarn.lock index 307bc876b5..7d4dc729a6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -245,7 +245,7 @@ __metadata: languageName: unknown linkType: soft -"@datadog/browser-logs@workspace:*, @datadog/browser-logs@workspace:packages/logs": +"@datadog/browser-logs@npm:6.24.0, @datadog/browser-logs@workspace:*, @datadog/browser-logs@workspace:packages/logs": version: 0.0.0-use.local resolution: "@datadog/browser-logs@workspace:packages/logs" dependencies: @@ -374,6 +374,7 @@ __metadata: resolution: "@datadog/electron@workspace:packages/electron" dependencies: "@datadog/browser-core": "npm:6.24.0" + "@datadog/browser-logs": "npm:6.24.0" "@datadog/browser-rum-core": "npm:6.24.0" "@msgpack/msgpack": "npm:3.1.2" "@openfeature/core": "npm:1.9.1" @@ -382,12 +383,6 @@ __metadata: electron: "npm:39" graphql: "npm:16.12.0" pako: "npm:2.1.0" - peerDependencies: - "@datadog/browser-logs": 6.24.0 - electron: 39 - peerDependenciesMeta: - "@datadog/browser-logs": - optional: true languageName: unknown linkType: soft From 6edf098897793a18c12d03e6ab59dbbc5b7abf76 Mon Sep 17 00:00:00 2001 From: Adrian de la Rosa Date: Mon, 24 Nov 2025 11:58:39 +0100 Subject: [PATCH 45/58] crash report first iteration --- .gitignore | 3 + packages/electron/package.json | 7 +- .../electron/scripts/generate-wasm-base64.js | 39 ++ .../electron/src/domain/rum/crashReporter.ts | 223 ++++++++++ packages/electron/src/domain/rum/events.ts | 2 +- .../src/domain/rum/mainProcessTracking.ts | 7 +- packages/electron/src/entries/main.ts | 11 +- packages/electron/src/wasm/minidump.d.ts | 53 +++ packages/electron/src/wasm/minidump.js | 407 ++++++++++++++++++ packages/electron/src/wasm/minidump_bg.wasm | Bin 0 -> 1395196 bytes .../electron/src/wasm/minidump_bg.wasm.d.ts | 17 + scripts/build/build-package.ts | 25 ++ 12 files changed, 788 insertions(+), 6 deletions(-) create mode 100755 packages/electron/scripts/generate-wasm-base64.js create mode 100644 packages/electron/src/domain/rum/crashReporter.ts create mode 100644 packages/electron/src/wasm/minidump.d.ts create mode 100644 packages/electron/src/wasm/minidump.js create mode 100644 packages/electron/src/wasm/minidump_bg.wasm create mode 100644 packages/electron/src/wasm/minidump_bg.wasm.d.ts diff --git a/.gitignore b/.gitignore index f7c5dc265c..9cf5c4abb9 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,9 @@ package.tgz docs/ *.tsbuildinfo +# Generated WASM base64 files +**/*.wasm.base64.ts + # https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored .pnp.* .yarn/* diff --git a/packages/electron/package.json b/packages/electron/package.json index f755d53741..dd25080c10 100644 --- a/packages/electron/package.json +++ b/packages/electron/package.json @@ -35,5 +35,10 @@ }, "publishConfig": { "access": "public" - } + }, + "files": [ + "cjs/**/*", + "esm/**/*", + "bundle/**/*" + ] } diff --git a/packages/electron/scripts/generate-wasm-base64.js b/packages/electron/scripts/generate-wasm-base64.js new file mode 100755 index 0000000000..0e2fcd757f --- /dev/null +++ b/packages/electron/scripts/generate-wasm-base64.js @@ -0,0 +1,39 @@ +#!/usr/bin/env node + +/** + * This script converts the minidump_bg.wasm file to a base64-encoded string + * and generates a TypeScript file that exports it. + * This allows the WASM file to be embedded directly in the built code. + */ + +const fs = require('fs') +const path = require('path') + +const wasmPath = path.join(__dirname, '../src/wasm/minidump_bg.wasm') +const outputPath = path.join(__dirname, '../src/wasm/minidump_bg.wasm.base64.ts') + +console.log('Converting WASM to base64...') +console.log(` Input: ${wasmPath}`) +console.log(` Output: ${outputPath}`) + +// Read the WASM file +const wasmBuffer = fs.readFileSync(wasmPath) +const base64String = wasmBuffer.toString('base64') + +console.log(` WASM size: ${wasmBuffer.length} bytes`) +console.log(` Base64 size: ${base64String.length} bytes`) + +// Generate the TypeScript file +const tsContent = `// This file is automatically generated by scripts/generate-wasm-base64.js +// Do not edit manually + +/** + * Base64-encoded WebAssembly binary for the minidump parser + * Original size: ${wasmBuffer.length} bytes + * Encoded size: ${base64String.length} bytes + */ +export const MINIDUMP_WASM_BASE64 = '${base64String}' +` + +fs.writeFileSync(outputPath, tsContent, 'utf-8') +console.log('✓ Successfully generated base64 file') diff --git a/packages/electron/src/domain/rum/crashReporter.ts b/packages/electron/src/domain/rum/crashReporter.ts new file mode 100644 index 0000000000..ecf316d05f --- /dev/null +++ b/packages/electron/src/domain/rum/crashReporter.ts @@ -0,0 +1,223 @@ +import * as fs from 'node:fs' +import * as path from 'node:path' +import * as os from 'node:os' + +import type { Observable } from '@datadog/browser-core' +import { ErrorHandling, generateUUID } from '@datadog/browser-core' +import { RumEventType } from '@datadog/browser-rum-core' +import { app, crashReporter } from 'electron' + +import { process_minidump_with_stackwalk } from '../../wasm/minidump' +import type { CollectedRumEvent } from './events' + +/** + * Minidump parsed output structure + */ +interface MinidumpResult { + status: string + crash_info: { + type: string + address: string + crashing_thread: number + } + system_info: { + os: string + cpu: string + cpu_info: string + } + thread_count: number + threads: Array<{ + thread_index: number + frame_count: number + frames: Array<{ + module: string + function: string + instruction: string + module_offset: string + trust: string + }> + }> + crashing_thread?: { + thread_index: number + frames: Array<{ + module: string + function: string + instruction: string + module_offset: string + trust: string + }> + } + module_count: number + modules: Array<{ + base_address: string + code_file: string + code_identifier: string + debug_file: string + debug_identifier: string + version: string + }> +} + +/** + * Convert minidump parsed result to a RUM error event format + */ +function createCrashErrorEvent( + minidumpResult: MinidumpResult, + dumpFileName: string, + crashTime: number, + applicationId: string, + sessionId: string, + viewId: string +) { + // Transform threads + const threads = minidumpResult.threads.map((thread, threadId) => { + const isCrashed = thread.thread_index === minidumpResult.crash_info.crashing_thread + const stack = thread.frames + .map((frame) => { + const moduleName = frame.module ? path.basename(frame.module) : '???' + + // find module and read the base address + const address = minidumpResult.modules.find((module) => module.code_file === frame.module)?.base_address + // offset from hex do decimal + const offset = parseInt(frame.module_offset, 16) + + return `${threadId} ${moduleName} ${frame.instruction} ${address} + ${offset}` + }) + .join('\n') + + return { + name: `Thread ${thread.thread_index}`, + crashed: isCrashed, + stack, + } + }) + + // Transform modules to binary_images + const binaryImages = minidumpResult.modules.map((module) => { + // Extract base address value (remove 0x prefix if present) + const loadAddress = module.base_address + + // Determine if it's a system library based on path + const isSystem = + module.code_file.includes('/System/Library/') || + module.code_file.includes('/usr/lib/') || + module.code_file.includes('\\Windows\\') || + module.code_file.includes('\\System32\\') + + return { + uuid: module.debug_identifier, + name: path.basename(module.code_file), + is_system: isSystem, + load_address: loadAddress, + max_address: undefined, // Not provided by minidump parser + arch: minidumpResult.system_info.cpu, + } + }) + + // Get the crashed thread for the main stack trace + const crashedThread = threads.find((t) => t.crashed) + + return { + _dd: { + format_version: 2 as const, + }, + application: { id: applicationId }, + date: crashTime, + env: 'prod', + error: { + binary_images: binaryImages, + category: 'Exception' as const, + fingerprint: 'v10.B1602146B5E853D276447FE55B77482F', + handling: ErrorHandling.UNHANDLED, + id: generateUUID(), + is_crash: true, + message: `Application crashed (${dumpFileName})`, + meta: { + code_type: minidumpResult.system_info.cpu, + process: app.getName(), + exception_type: minidumpResult.crash_info.type, + path: undefined, // Could be extracted from modules + }, + source: 'source' as const, + source_type: 'electron' as 'browser', + threads, + type: minidumpResult.crash_info.type, + was_truncated: false, + }, + service: 'electron-adrian', + session: { id: sessionId, type: 'user' as const }, + source: 'electron' as 'browser', + type: RumEventType.ERROR, + view: { id: viewId, url: 'com/datadog/application-launch/view' }, + } +} + +/** + * Map OS to source_type + */ +function getSourceType(os: string): 'android' | 'ios' | 'browser' { + const osLower = os.toLowerCase() + if (osLower === 'mac' || osLower === 'ios') { + return 'ios' + } + if (osLower === 'android') { + return 'android' + } + return 'browser' +} + +/** + * Start monitoring for crash dumps and report them to RUM + */ +export function startCrashMonitoring( + onRumEventObservable: Observable, + applicationId: string, + sessionId: string, + viewId: string +) { + // Initialize crash reporter + crashReporter.start({ + uploadToServer: false, // We'll handle uploading via RUM + compress: true, + extra: { + sessionId, + }, + }) + + // Wait for app to be ready before accessing crash dumps directory + void app.whenReady().then(() => { + const crashesDirectory = app.getPath('crashDumps') + + // Check if there are any crash reports pending + const pendingCrashReports = fs.readdirSync(path.join(crashesDirectory, 'pending')) + + pendingCrashReports.forEach(async (crashReport) => { + const reportPath = path.join(crashesDirectory, 'pending', crashReport) + const reportMetadata = fs.statSync(reportPath) + const reportBytes = fs.readFileSync(reportPath) + + const resultJson = await process_minidump_with_stackwalk(reportBytes) + const minidumpResult: MinidumpResult = JSON.parse(resultJson) + + const crashTime = new Date(reportMetadata.ctime).getTime() + + const rumErrorEvent = createCrashErrorEvent( + minidumpResult, + crashReport, + crashTime, + applicationId, + sessionId, + viewId + ) + console.log(JSON.stringify(rumErrorEvent, null, 2)) + + onRumEventObservable.notify({ + event: rumErrorEvent, + source: 'main-process', + }) + + // delete the crash report + fs.unlinkSync(reportPath) + }) + }) +} diff --git a/packages/electron/src/domain/rum/events.ts b/packages/electron/src/domain/rum/events.ts index e5b2615d08..90779be74b 100644 --- a/packages/electron/src/domain/rum/events.ts +++ b/packages/electron/src/domain/rum/events.ts @@ -1,4 +1,4 @@ -import { RumEvent } from '@datadog/browser-rum-core' +import type { RumEvent } from '@datadog/browser-rum-core' export interface CollectedRumEvent { source: 'main-process' | 'renderer' diff --git a/packages/electron/src/domain/rum/mainProcessTracking.ts b/packages/electron/src/domain/rum/mainProcessTracking.ts index 1f42191d9f..9b3585cf3d 100644 --- a/packages/electron/src/domain/rum/mainProcessTracking.ts +++ b/packages/electron/src/domain/rum/mainProcessTracking.ts @@ -1,4 +1,3 @@ -import crypto from 'node:crypto' import type { RumConfiguration, RumViewEvent } from '@datadog/browser-rum-core' import { RumEventType } from '@datadog/browser-rum-core' import type { Observable } from '@datadog/browser-core' @@ -11,12 +10,14 @@ const NODE_VIEW_NAME = 'ApplicationLaunch' export function startMainProcessTracking( hooks: Hooks, configuration: RumConfiguration, + sessionId: string, + mainProcessViewId: string, onRumEventObservable: Observable, onActivityObservable: Observable ) { const mainProcessContext = { - sessionId: crypto.randomUUID(), - viewId: crypto.randomUUID(), + sessionId, + viewId: mainProcessViewId, } hooks.register(HookNames.Assemble, ({ eventType }) => ({ type: eventType, diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 2c2651ff6b..0eb074a228 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -1,4 +1,5 @@ /* eslint-disable jsdoc/check-indentation */ +import crypto from 'node:crypto' import type { RawError, PageMayExitEvent, Encoder, InitConfiguration, TrackType } from '@datadog/browser-core' import { Observable, @@ -19,6 +20,7 @@ import { startActivityTracking } from '../domain/rum/activity' import { startRumEventAssembleAndSend } from '../domain/rum/assembly' import { startMainProcessTracking } from '../domain/rum/mainProcessTracking' import { startConvertSpanToRumEvent } from '../domain/rum/convertSpans' +import { startCrashMonitoring } from '../domain/rum/crashReporter' import type { Trace } from '../domain/trace/trace' import { createDdTraceAgent } from '../domain/trace/traceAgent' import { startLogsEventAssembleAndSend } from '../domain/logs/assembly' @@ -40,6 +42,9 @@ function makeDatadogElectron() { const onLogsEventObservable = new Observable() const onTraceObservable = new Observable() const hooks = createHooks() + const sessionId = crypto.randomUUID() + const mainProcessViewId = crypto.randomUUID() + const createEncoder = () => createIdentityEncoder() const rumBatch = startElectronRumBatch( configuration, @@ -48,6 +53,7 @@ function makeDatadogElectron() { sessionExpireObservable, createIdentityEncoder ) + startRumEventAssembleAndSend(onRumEventObservable, rumBatch, hooks) const logsBatch = startElectronLogsBatch( @@ -71,9 +77,12 @@ function makeDatadogElectron() { }) const onActivityObservable = startActivityTracking(onRumEventObservable) - startMainProcessTracking(hooks, configuration, onRumEventObservable, onActivityObservable) + startMainProcessTracking(hooks, configuration, + sessionId, + mainProcessViewId, onRumEventObservable, onActivityObservable) startConvertSpanToRumEvent(onTraceObservable, onRumEventObservable) setupMainBridge(onRumEventObservable, onLogsEventObservable) + startCrashMonitoring(onRumEventObservable, initConfiguration.applicationId, sessionId, mainProcessViewId) initTracer(configuration.service!, configuration.env!, configuration.version!) createDdTraceAgent(onTraceObservable, hooks) diff --git a/packages/electron/src/wasm/minidump.d.ts b/packages/electron/src/wasm/minidump.d.ts new file mode 100644 index 0000000000..12b26fce8c --- /dev/null +++ b/packages/electron/src/wasm/minidump.d.ts @@ -0,0 +1,53 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Initialize panic hook for better error messages in WASM + */ +export function init(): void; +/** + * Parse a minidump from raw bytes and return basic information as JSON + * + * # Arguments + * * `dump_bytes` - The minidump file as a byte array + * + * # Returns + * A JSON string containing basic minidump information (system info, exception, threads, modules) + * + * # Example (JavaScript) + * ```js + * const fs = require('fs'); + * const { parse_minidump } = require('./minidump_wasm'); + * + * const dumpBytes = fs.readFileSync('crash.dmp'); + * const result = parse_minidump(dumpBytes); + * const json = JSON.parse(result); + * console.log('OS:', json.system_info.os); + * console.log('Crash reason:', json.exception.crash_reason); + * ``` + */ +export function parse_minidump(dump_bytes: Uint8Array): string; +/** + * Process a minidump with full stack walking (returns a Promise) + * + * # Arguments + * * `dump_bytes` - The minidump file as a byte array + * + * # Returns + * A Promise that resolves to a JSON string containing full crash analysis with stack traces + * + * # Example (JavaScript) + * ```js + * const fs = require('fs'); + * const { process_minidump_with_stackwalk } = require('./minidump_wasm'); + * + * const dumpBytes = fs.readFileSync('crash.dmp'); + * const result = await process_minidump_with_stackwalk(dumpBytes); + * const json = JSON.parse(result); + * + * // Access crashing thread's stack trace + * json.crashing_thread.frames.forEach((frame, i) => { + * console.log(`Frame ${i}: ${frame.module || '?'} + ${frame.offset}`); + * }); + * ``` + */ +export function process_minidump_with_stackwalk(dump_bytes: Uint8Array): Promise; diff --git a/packages/electron/src/wasm/minidump.js b/packages/electron/src/wasm/minidump.js new file mode 100644 index 0000000000..a05c33fff3 --- /dev/null +++ b/packages/electron/src/wasm/minidump.js @@ -0,0 +1,407 @@ +let imports = {} +imports['__wbindgen_placeholder__'] = module.exports + +let cachedUint8ArrayMemory0 = null + +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer) + } + return cachedUint8ArrayMemory0 +} + +let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) + +cachedTextDecoder.decode() + +function decodeText(ptr, len) { + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)) +} + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0 + return decodeText(ptr, len) +} + +function addToExternrefTable0(obj) { + const idx = wasm.__externref_table_alloc() + wasm.__wbindgen_externrefs.set(idx, obj) + return idx +} + +function handleError(f, args) { + try { + return f.apply(this, args) + } catch (e) { + const idx = addToExternrefTable0(e) + wasm.__wbindgen_exn_store(idx) + } +} + +let WASM_VECTOR_LEN = 0 + +const cachedTextEncoder = new TextEncoder() + +if (!('encodeInto' in cachedTextEncoder)) { + cachedTextEncoder.encodeInto = function (arg, view) { + const buf = cachedTextEncoder.encode(arg) + view.set(buf) + return { + read: arg.length, + written: buf.length, + } + } +} + +function passStringToWasm0(arg, malloc, realloc) { + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg) + const ptr = malloc(buf.length, 1) >>> 0 + getUint8ArrayMemory0() + .subarray(ptr, ptr + buf.length) + .set(buf) + WASM_VECTOR_LEN = buf.length + return ptr + } + + let len = arg.length + let ptr = malloc(len, 1) >>> 0 + + const mem = getUint8ArrayMemory0() + + let offset = 0 + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset) + if (code > 0x7f) { + break + } + mem[ptr + offset] = code + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset) + } + ptr = realloc(ptr, len, (len = offset + arg.length * 3), 1) >>> 0 + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len) + const ret = cachedTextEncoder.encodeInto(arg, view) + + offset += ret.written + ptr = realloc(ptr, len, offset, 1) >>> 0 + } + + WASM_VECTOR_LEN = offset + return ptr +} + +let cachedDataViewMemory0 = null + +function getDataViewMemory0() { + if ( + cachedDataViewMemory0 === null || + cachedDataViewMemory0.buffer.detached === true || + (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer) + ) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer) + } + return cachedDataViewMemory0 +} + +function isLikeNone(x) { + return x === undefined || x === null +} + +const CLOSURE_DTORS = + typeof FinalizationRegistry === 'undefined' + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry((state) => state.dtor(state.a, state.b)) + +function makeMutClosure(arg0, arg1, dtor, f) { + const state = { a: arg0, b: arg1, cnt: 1, dtor } + const real = (...args) => { + // First up with a closure we increment the internal reference + // count. This ensures that the Rust closure environment won't + // be deallocated while we're invoking it. + state.cnt++ + const a = state.a + state.a = 0 + try { + return f(a, state.b, ...args) + } finally { + state.a = a + real._wbg_cb_unref() + } + } + real._wbg_cb_unref = () => { + if (--state.cnt === 0) { + state.dtor(state.a, state.b) + state.a = 0 + CLOSURE_DTORS.unregister(state) + } + } + CLOSURE_DTORS.register(real, state, state) + return real +} +/** + * Initialize panic hook for better error messages in WASM + */ +exports.init = function () { + wasm.init() +} + +function passArray8ToWasm0(arg, malloc) { + const ptr = malloc(arg.length * 1, 1) >>> 0 + getUint8ArrayMemory0().set(arg, ptr / 1) + WASM_VECTOR_LEN = arg.length + return ptr +} + +function takeFromExternrefTable0(idx) { + const value = wasm.__wbindgen_externrefs.get(idx) + wasm.__externref_table_dealloc(idx) + return value +} +/** + * Parse a minidump from raw bytes and return basic information as JSON + * + * # Arguments + * * `dump_bytes` - The minidump file as a byte array + * + * # Returns + * A JSON string containing basic minidump information (system info, exception, threads, modules) + * + * # Example (JavaScript) + * ```js + * const fs = require('fs'); + * const { parse_minidump } = require('./minidump'); + * + * const dumpBytes = fs.readFileSync('crash.dmp'); + * const result = parse_minidump(dumpBytes); + * const json = JSON.parse(result); + * console.log('OS:', json.system_info.os); + * console.log('Crash reason:', json.exception.crash_reason); + * ``` + * + * @param {Uint8Array} dump_bytes + * @returns {string} + */ +exports.parse_minidump = function (dump_bytes) { + let deferred3_0 + let deferred3_1 + try { + const ptr0 = passArray8ToWasm0(dump_bytes, wasm.__wbindgen_malloc) + const len0 = WASM_VECTOR_LEN + const ret = wasm.parse_minidump(ptr0, len0) + var ptr2 = ret[0] + var len2 = ret[1] + if (ret[3]) { + ptr2 = 0 + len2 = 0 + throw takeFromExternrefTable0(ret[2]) + } + deferred3_0 = ptr2 + deferred3_1 = len2 + return getStringFromWasm0(ptr2, len2) + } finally { + wasm.__wbindgen_free(deferred3_0, deferred3_1, 1) + } +} + +/** + * Process a minidump with full stack walking (returns a Promise) + * + * # Arguments + * * `dump_bytes` - The minidump file as a byte array + * + * # Returns + * A Promise that resolves to a JSON string containing full crash analysis with stack traces + * + * # Example (JavaScript) + * ```js + * const fs = require('fs'); + * const { process_minidump_with_stackwalk } = require('./minidump'); + * + * const dumpBytes = fs.readFileSync('crash.dmp'); + * const result = await process_minidump_with_stackwalk(dumpBytes); + * const json = JSON.parse(result); + * + * // Access crashing thread's stack trace + * json.crashing_thread.frames.forEach((frame, i) => { + * console.log(`Frame ${i}: ${frame.module || '?'} + ${frame.offset}`); + * }); + * ``` + * + * @param {Uint8Array} dump_bytes + * @returns {Promise} + */ +exports.process_minidump_with_stackwalk = function (dump_bytes) { + const ptr0 = passArray8ToWasm0(dump_bytes, wasm.__wbindgen_malloc) + const len0 = WASM_VECTOR_LEN + const ret = wasm.process_minidump_with_stackwalk(ptr0, len0) + return ret +} + +function wasm_bindgen__convert__closures_____invoke__hbd2252a5ae7d61cd(arg0, arg1, arg2) { + wasm.wasm_bindgen__convert__closures_____invoke__hbd2252a5ae7d61cd(arg0, arg1, arg2) +} + +function wasm_bindgen__convert__closures_____invoke__h2fe7d57d144c8924(arg0, arg1, arg2, arg3) { + wasm.wasm_bindgen__convert__closures_____invoke__h2fe7d57d144c8924(arg0, arg1, arg2, arg3) +} + +exports.__wbg___wbindgen_is_function_ee8a6c5833c90377 = function (arg0) { + const ret = typeof arg0 === 'function' + return ret +} + +exports.__wbg___wbindgen_is_undefined_2d472862bd29a478 = function (arg0) { + const ret = arg0 === undefined + return ret +} + +exports.__wbg___wbindgen_throw_b855445ff6a94295 = function (arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)) +} + +exports.__wbg__wbg_cb_unref_2454a539ea5790d9 = function (arg0) { + arg0._wbg_cb_unref() +} + +exports.__wbg_call_525440f72fbfc0ea = function () { + return handleError(function (arg0, arg1, arg2) { + const ret = arg0.call(arg1, arg2) + return ret + }, arguments) +} + +exports.__wbg_call_e762c39fa8ea36bf = function () { + return handleError(function (arg0, arg1) { + const ret = arg0.call(arg1) + return ret + }, arguments) +} + +exports.__wbg_error_7534b8e9a36f1ab4 = function (arg0, arg1) { + let deferred0_0 + let deferred0_1 + try { + deferred0_0 = arg0 + deferred0_1 = arg1 + console.error(getStringFromWasm0(arg0, arg1)) + } finally { + wasm.__wbindgen_free(deferred0_0, deferred0_1, 1) + } +} + +exports.__wbg_new_3c3d849046688a66 = function (arg0, arg1) { + try { + var state0 = { a: arg0, b: arg1 } + var cb0 = (arg0, arg1) => { + const a = state0.a + state0.a = 0 + try { + return wasm_bindgen__convert__closures_____invoke__h2fe7d57d144c8924(a, state0.b, arg0, arg1) + } finally { + state0.a = a + } + } + const ret = new Promise(cb0) + return ret + } finally { + state0.a = state0.b = 0 + } +} + +exports.__wbg_new_8a6f238a6ece86ea = function () { + const ret = new Error() + return ret +} + +exports.__wbg_new_no_args_ee98eee5275000a4 = function (arg0, arg1) { + const ret = new Function(getStringFromWasm0(arg0, arg1)) + return ret +} + +exports.__wbg_queueMicrotask_34d692c25c47d05b = function (arg0) { + const ret = arg0.queueMicrotask + return ret +} + +exports.__wbg_queueMicrotask_9d76cacb20c84d58 = function (arg0) { + queueMicrotask(arg0) +} + +exports.__wbg_resolve_caf97c30b83f7053 = function (arg0) { + const ret = Promise.resolve(arg0) + return ret +} + +exports.__wbg_stack_0ed75d68575b0f3c = function (arg0, arg1) { + const ret = arg1.stack + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc) + const len1 = WASM_VECTOR_LEN + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true) + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true) +} + +exports.__wbg_static_accessor_GLOBAL_89e1d9ac6a1b250e = function () { + const ret = typeof global === 'undefined' ? null : global + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret) +} + +exports.__wbg_static_accessor_GLOBAL_THIS_8b530f326a9e48ac = function () { + const ret = typeof globalThis === 'undefined' ? null : globalThis + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret) +} + +exports.__wbg_static_accessor_SELF_6fdf4b64710cc91b = function () { + const ret = typeof self === 'undefined' ? null : self + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret) +} + +exports.__wbg_static_accessor_WINDOW_b45bfc5a37f6cfa2 = function () { + const ret = typeof window === 'undefined' ? null : window + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret) +} + +exports.__wbg_then_4f46f6544e6b4a28 = function (arg0, arg1) { + const ret = arg0.then(arg1) + return ret +} + +exports.__wbindgen_cast_2241b6af4c4b2941 = function (arg0, arg1) { + // Cast intrinsic for `Ref(String) -> Externref`. + const ret = getStringFromWasm0(arg0, arg1) + return ret +} + +exports.__wbindgen_cast_29d5b4f96fd1dba2 = function (arg0, arg1) { + // Cast intrinsic for `Closure(Closure { dtor_idx: 399, function: Function { arguments: [Externref], shim_idx: 400, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. + const ret = makeMutClosure( + arg0, + arg1, + wasm.wasm_bindgen__closure__destroy__h75e0120a17cf8b85, + wasm_bindgen__convert__closures_____invoke__hbd2252a5ae7d61cd + ) + return ret +} + +exports.__wbindgen_init_externref_table = function () { + const table = wasm.__wbindgen_externrefs + const offset = table.grow(4) + table.set(0, undefined) + table.set(offset + 0, undefined) + table.set(offset + 1, null) + table.set(offset + 2, true) + table.set(offset + 3, false) +} + +// Load WASM from base64-encoded string embedded in the code +const { MINIDUMP_WASM_BASE64 } = require('./minidump_bg.wasm.base64') +// Decode base64 to binary +const wasmBytes = Buffer.from(MINIDUMP_WASM_BASE64, 'base64') +const wasmModule = new WebAssembly.Module(wasmBytes) +const wasm = (exports.__wasm = new WebAssembly.Instance(wasmModule, imports).exports) + +wasm.__wbindgen_start() diff --git a/packages/electron/src/wasm/minidump_bg.wasm b/packages/electron/src/wasm/minidump_bg.wasm new file mode 100644 index 0000000000000000000000000000000000000000..23ea94b8adbd7a7b415bd805edbda84cd9f963f9 GIT binary patch literal 1395196 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%0DUcJ%2kxx@P+RJfi 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�f5!2K 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ð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 literal 0 HcmV?d00001 diff --git a/packages/electron/src/wasm/minidump_bg.wasm.d.ts b/packages/electron/src/wasm/minidump_bg.wasm.d.ts new file mode 100644 index 0000000000..8bcb6b97b4 --- /dev/null +++ b/packages/electron/src/wasm/minidump_bg.wasm.d.ts @@ -0,0 +1,17 @@ +/* tslint:disable */ +/* eslint-disable */ +export const memory: WebAssembly.Memory; +export const parse_minidump: (a: number, b: number) => [number, number, number, number]; +export const process_minidump_with_stackwalk: (a: number, b: number) => any; +export const init: () => void; +export const wasm_bindgen__convert__closures_____invoke__hbd2252a5ae7d61cd: (a: number, b: number, c: any) => void; +export const wasm_bindgen__closure__destroy__h75e0120a17cf8b85: (a: number, b: number) => void; +export const wasm_bindgen__convert__closures_____invoke__h2fe7d57d144c8924: (a: number, b: number, c: any, d: any) => void; +export const __wbindgen_exn_store: (a: number) => void; +export const __externref_table_alloc: () => number; +export const __wbindgen_externrefs: WebAssembly.Table; +export const __wbindgen_free: (a: number, b: number, c: number) => void; +export const __wbindgen_malloc: (a: number, b: number) => number; +export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; +export const __externref_table_dealloc: (a: number) => void; +export const __wbindgen_start: () => void; diff --git a/scripts/build/build-package.ts b/scripts/build/build-package.ts index 35de4985c5..7ad32a1940 100644 --- a/scripts/build/build-package.ts +++ b/scripts/build/build-package.ts @@ -2,6 +2,8 @@ import fs from 'node:fs/promises' import { parseArgs } from 'node:util' import path from 'node:path' import { globSync } from 'node:fs' +import { existsSync } from 'node:fs' +import { execSync } from 'node:child_process' import ts from 'typescript' import webpack from 'webpack' import webpackBase from '../../webpack.base.ts' @@ -26,6 +28,9 @@ runMain(async () => { }, }) + // Generate WASM base64 file if this is the electron package + await generateWasmBase64IfNeeded({ verbose: values.verbose }) + if (values.modules) { printLog('Building modules...') await buildModules({ @@ -51,6 +56,26 @@ runMain(async () => { printLog('Done.') }) +async function generateWasmBase64IfNeeded({ verbose }: { verbose: boolean }) { + // Check if this is the electron package by looking for the WASM generation script + const wasmGeneratorScript = './scripts/generate-wasm-base64.js' + + if (existsSync(wasmGeneratorScript)) { + printLog('Generating WASM base64...') + try { + execSync(`node ${wasmGeneratorScript}`, { + stdio: verbose ? 'inherit' : 'pipe', + encoding: 'utf-8' + }) + if (verbose) { + printLog('WASM base64 generation completed') + } + } catch (error) { + throw new Error(`Failed to generate WASM base64: ${error}`) + } + } +} + async function buildBundle({ filename, verbose }: { filename: string; verbose: boolean }) { await fs.rm('./bundle', { recursive: true, force: true }) return new Promise((resolve, reject) => { From 6ab2013ea090beeb38a2cd99963b3700c34ffebe Mon Sep 17 00:00:00 2001 From: Adrian de la Rosa Date: Tue, 25 Nov 2025 13:40:23 +0100 Subject: [PATCH 46/58] clean --- .../electron/src/domain/renderer/bridge.ts | 1 + .../electron/src/domain/rum/crashReporter.ts | 23 +++---------------- .../electron/src/domain/trace/traceAgent.ts | 2 ++ 3 files changed, 6 insertions(+), 20 deletions(-) diff --git a/packages/electron/src/domain/renderer/bridge.ts b/packages/electron/src/domain/renderer/bridge.ts index 17e780052b..3eeb8b42e7 100644 --- a/packages/electron/src/domain/renderer/bridge.ts +++ b/packages/electron/src/domain/renderer/bridge.ts @@ -16,6 +16,7 @@ export function setupRendererBridge() { void ipcRenderer.invoke('datadog:send', msg) }, } satisfies DatadogEventBridge + try { contextBridge.exposeInMainWorld('DatadogEventBridge', (window as any).DatadogEventBridge) } catch { diff --git a/packages/electron/src/domain/rum/crashReporter.ts b/packages/electron/src/domain/rum/crashReporter.ts index ecf316d05f..c9f043b41a 100644 --- a/packages/electron/src/domain/rum/crashReporter.ts +++ b/packages/electron/src/domain/rum/crashReporter.ts @@ -1,12 +1,12 @@ import * as fs from 'node:fs' import * as path from 'node:path' -import * as os from 'node:os' import type { Observable } from '@datadog/browser-core' import { ErrorHandling, generateUUID } from '@datadog/browser-core' import { RumEventType } from '@datadog/browser-rum-core' import { app, crashReporter } from 'electron' +// eslint-disable-next-line camelcase import { process_minidump_with_stackwalk } from '../../wasm/minidump' import type { CollectedRumEvent } from './events' @@ -127,7 +127,6 @@ function createCrashErrorEvent( error: { binary_images: binaryImages, category: 'Exception' as const, - fingerprint: 'v10.B1602146B5E853D276447FE55B77482F', handling: ErrorHandling.UNHANDLED, id: generateUUID(), is_crash: true, @@ -140,6 +139,7 @@ function createCrashErrorEvent( }, source: 'source' as const, source_type: 'electron' as 'browser', + stack: crashedThread?.stack, threads, type: minidumpResult.crash_info.type, was_truncated: false, @@ -152,23 +152,6 @@ function createCrashErrorEvent( } } -/** - * Map OS to source_type - */ -function getSourceType(os: string): 'android' | 'ios' | 'browser' { - const osLower = os.toLowerCase() - if (osLower === 'mac' || osLower === 'ios') { - return 'ios' - } - if (osLower === 'android') { - return 'android' - } - return 'browser' -} - -/** - * Start monitoring for crash dumps and report them to RUM - */ export function startCrashMonitoring( onRumEventObservable: Observable, applicationId: string, @@ -191,6 +174,7 @@ export function startCrashMonitoring( // Check if there are any crash reports pending const pendingCrashReports = fs.readdirSync(path.join(crashesDirectory, 'pending')) + // eslint-disable-next-line @typescript-eslint/no-misused-promises pendingCrashReports.forEach(async (crashReport) => { const reportPath = path.join(crashesDirectory, 'pending', crashReport) const reportMetadata = fs.statSync(reportPath) @@ -209,7 +193,6 @@ export function startCrashMonitoring( sessionId, viewId ) - console.log(JSON.stringify(rumErrorEvent, null, 2)) onRumEventObservable.notify({ event: rumErrorEvent, diff --git a/packages/electron/src/domain/trace/traceAgent.ts b/packages/electron/src/domain/trace/traceAgent.ts index 2a310f0798..0516b09bb7 100644 --- a/packages/electron/src/domain/trace/traceAgent.ts +++ b/packages/electron/src/domain/trace/traceAgent.ts @@ -13,9 +13,11 @@ export function createDdTraceAgent(onTraceObservable: Observable, hooks: server.on('request', (req, res) => { // Collect binary data chunks const chunks: Buffer[] = [] + req.on('data', (chunk: Buffer) => { chunks.push(chunk) }) + req.on('end', () => { const buffer = Buffer.concat(chunks) From ca0608f23ee716c853861741e31e0f01238ad5c3 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Tue, 25 Nov 2025 14:34:59 +0100 Subject: [PATCH 47/58] add global context APIs --- packages/electron/src/entries/main.ts | 44 +++++++++++++++++++++------ 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 0eb074a228..9de3f185a3 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -1,17 +1,25 @@ -/* eslint-disable jsdoc/check-indentation */ import crypto from 'node:crypto' -import type { RawError, PageMayExitEvent, Encoder, InitConfiguration, TrackType } from '@datadog/browser-core' +import type { RumConfiguration, RumInitConfiguration } from '@datadog/browser-rum-core' +import { createHooks, validateAndBuildRumConfiguration } from '@datadog/browser-rum-core' +import type { LogsEvent } from '@datadog/browser-logs' +import type { + PageMayExitEvent, + AbstractHooks, + RawError, + Encoder, + InitConfiguration, + TrackType, +} from '@datadog/browser-core' import { - Observable, createBatch, createHttpRequest, createFlushController, - createIdentityEncoder, createEndpointBuilder, + buildGlobalContextManager, + Observable, + createIdentityEncoder, + HookNames, } from '@datadog/browser-core' -import type { RumConfiguration, RumInitConfiguration } from '@datadog/browser-rum-core' -import { createHooks, validateAndBuildRumConfiguration } from '@datadog/browser-rum-core' -import type { LogsEvent } from '@datadog/browser-logs' import tracer, { initTracer } from '../domain/trace/tracer' import { createIpcMain } from '../domain/main/ipcMain' import type { CollectedRumEvent } from '../domain/rum/events' @@ -26,6 +34,8 @@ import { createDdTraceAgent } from '../domain/trace/traceAgent' import { startLogsEventAssembleAndSend } from '../domain/logs/assembly' function makeDatadogElectron() { + const globalContext = buildGlobalContextManager() + return { init(initConfiguration: RumInitConfiguration) { console.log('init from SDK Electron') @@ -44,7 +54,11 @@ function makeDatadogElectron() { const hooks = createHooks() const sessionId = crypto.randomUUID() const mainProcessViewId = crypto.randomUUID() - const createEncoder = () => createIdentityEncoder() + + ;(hooks as AbstractHooks).register(HookNames.Assemble, () => { + const context = globalContext.getContext() + return { context } + }) const rumBatch = startElectronRumBatch( configuration, @@ -77,9 +91,14 @@ function makeDatadogElectron() { }) const onActivityObservable = startActivityTracking(onRumEventObservable) - startMainProcessTracking(hooks, configuration, + startMainProcessTracking( + hooks, + configuration, sessionId, - mainProcessViewId, onRumEventObservable, onActivityObservable) + mainProcessViewId, + onRumEventObservable, + onActivityObservable + ) startConvertSpanToRumEvent(onTraceObservable, onRumEventObservable) setupMainBridge(onRumEventObservable, onLogsEventObservable) startCrashMonitoring(onRumEventObservable, initConfiguration.applicationId, sessionId, mainProcessViewId) @@ -92,6 +111,11 @@ function makeDatadogElectron() { pageMayExitObservable.notify({ reason: 'page_hide' }) }, 1000) }, + setGlobalContext: globalContext.setContext.bind(globalContext), + getGlobalContext: globalContext.getContext.bind(globalContext), + setGlobalContextProperty: globalContext.setContextProperty.bind(globalContext), + removeGlobalContextProperty: globalContext.removeContextProperty.bind(globalContext), + clearGlobalContext: globalContext.clearContext.bind(globalContext), } } From 5d554cc49795f2fbff5ff9cf51d22fcc7c7daebc Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Wed, 26 Nov 2025 11:53:21 +0100 Subject: [PATCH 48/58] setup node telemetry --- packages/core/src/domain/telemetry/index.ts | 1 + .../core/src/domain/telemetry/telemetry.ts | 1 + packages/core/src/index.ts | 1 + packages/electron/src/domain/main/bridge.ts | 32 +++-- .../electron/src/domain/rum/crashReporter.ts | 70 ++++----- .../src/domain/rum/mainProcessTracking.ts | 8 ++ .../src/domain/telemetry/telemetry.ts | 12 ++ .../electron/src/domain/trace/traceAgent.ts | 136 ++++++++++-------- packages/electron/src/entries/main.ts | 16 ++- 9 files changed, 160 insertions(+), 117 deletions(-) create mode 100644 packages/electron/src/domain/telemetry/telemetry.ts diff --git a/packages/core/src/domain/telemetry/index.ts b/packages/core/src/domain/telemetry/index.ts index c828c694a4..31736928b7 100644 --- a/packages/core/src/domain/telemetry/index.ts +++ b/packages/core/src/domain/telemetry/index.ts @@ -6,6 +6,7 @@ export { addTelemetryError, resetTelemetry, startTelemetry, + startTelemetryCollection, addTelemetryConfiguration, addTelemetryUsage, addTelemetryMetrics, diff --git a/packages/core/src/domain/telemetry/telemetry.ts b/packages/core/src/domain/telemetry/telemetry.ts index 82ec6d4cc1..c97a030b55 100644 --- a/packages/core/src/domain/telemetry/telemetry.ts +++ b/packages/core/src/domain/telemetry/telemetry.ts @@ -56,6 +56,7 @@ const ALLOWED_FRAME_URLS = [ export const enum TelemetryService { LOGS = 'browser-logs-sdk', RUM = 'browser-rum-sdk', + ELECTRON = 'electron-sdk', } export interface Telemetry { diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index f9abd115b9..e0eebbbe69 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -41,6 +41,7 @@ export type { } from './domain/telemetry' export { startTelemetry, + startTelemetryCollection, addTelemetryDebug, addTelemetryError, resetTelemetry, diff --git a/packages/electron/src/domain/main/bridge.ts b/packages/electron/src/domain/main/bridge.ts index 6fc85dc772..ec40c1bcb6 100644 --- a/packages/electron/src/domain/main/bridge.ts +++ b/packages/electron/src/domain/main/bridge.ts @@ -1,4 +1,5 @@ import type { Observable } from '@datadog/browser-core' +import { monitor } from '@datadog/browser-core' import { ipcMain } from 'electron' import type { RumEvent } from '@datadog/browser-rum-core' import type { LogsEvent } from '@datadog/browser-logs' @@ -13,19 +14,22 @@ export function setupMainBridge( rumEventObservable: Observable, logsEventObservable: Observable ) { - ipcMain.handle('datadog:send', (_event, msg: string) => { - const bridgeEvent = JSON.parse(msg) as BridgeEvent + ipcMain.handle( + 'datadog:send', + monitor((_event, msg: string) => { + const bridgeEvent = JSON.parse(msg) as BridgeEvent - switch (bridgeEvent.eventType) { - case 'rum': - case 'internal_telemetry': - rumEventObservable.notify({ event: bridgeEvent.event as RumEvent, source: 'renderer' }) - break - case 'log': - logsEventObservable.notify(bridgeEvent.event as LogsEvent) - break - default: - console.log('Unhandled event type', bridgeEvent) - } - }) + switch (bridgeEvent.eventType) { + case 'rum': + case 'internal_telemetry': + rumEventObservable.notify({ event: bridgeEvent.event as RumEvent, source: 'renderer' }) + break + case 'log': + logsEventObservable.notify(bridgeEvent.event as LogsEvent) + break + default: + console.log('Unhandled event type', bridgeEvent) + } + }) + ) } diff --git a/packages/electron/src/domain/rum/crashReporter.ts b/packages/electron/src/domain/rum/crashReporter.ts index c9f043b41a..d874587b4f 100644 --- a/packages/electron/src/domain/rum/crashReporter.ts +++ b/packages/electron/src/domain/rum/crashReporter.ts @@ -2,7 +2,7 @@ import * as fs from 'node:fs' import * as path from 'node:path' import type { Observable } from '@datadog/browser-core' -import { ErrorHandling, generateUUID } from '@datadog/browser-core' +import { monitor, ErrorHandling, generateUUID } from '@datadog/browser-core' import { RumEventType } from '@datadog/browser-rum-core' import { app, crashReporter } from 'electron' @@ -168,39 +168,41 @@ export function startCrashMonitoring( }) // Wait for app to be ready before accessing crash dumps directory - void app.whenReady().then(() => { - const crashesDirectory = app.getPath('crashDumps') - - // Check if there are any crash reports pending - const pendingCrashReports = fs.readdirSync(path.join(crashesDirectory, 'pending')) - - // eslint-disable-next-line @typescript-eslint/no-misused-promises - pendingCrashReports.forEach(async (crashReport) => { - const reportPath = path.join(crashesDirectory, 'pending', crashReport) - const reportMetadata = fs.statSync(reportPath) - const reportBytes = fs.readFileSync(reportPath) - - const resultJson = await process_minidump_with_stackwalk(reportBytes) - const minidumpResult: MinidumpResult = JSON.parse(resultJson) - - const crashTime = new Date(reportMetadata.ctime).getTime() - - const rumErrorEvent = createCrashErrorEvent( - minidumpResult, - crashReport, - crashTime, - applicationId, - sessionId, - viewId - ) - - onRumEventObservable.notify({ - event: rumErrorEvent, - source: 'main-process', + void app.whenReady().then( + monitor(() => { + const crashesDirectory = app.getPath('crashDumps') + + // Check if there are any crash reports pending + const pendingCrashReports = fs.readdirSync(path.join(crashesDirectory, 'pending')) + + // eslint-disable-next-line @typescript-eslint/no-misused-promises + pendingCrashReports.forEach(async (crashReport) => { + const reportPath = path.join(crashesDirectory, 'pending', crashReport) + const reportMetadata = fs.statSync(reportPath) + const reportBytes = fs.readFileSync(reportPath) + + const resultJson = await process_minidump_with_stackwalk(reportBytes) + const minidumpResult: MinidumpResult = JSON.parse(resultJson) + + const crashTime = new Date(reportMetadata.ctime).getTime() + + const rumErrorEvent = createCrashErrorEvent( + minidumpResult, + crashReport, + crashTime, + applicationId, + sessionId, + viewId + ) + + onRumEventObservable.notify({ + event: rumErrorEvent, + source: 'main-process', + }) + + // delete the crash report + fs.unlinkSync(reportPath) }) - - // delete the crash report - fs.unlinkSync(reportPath) }) - }) + ) } diff --git a/packages/electron/src/domain/rum/mainProcessTracking.ts b/packages/electron/src/domain/rum/mainProcessTracking.ts index 9b3585cf3d..9d35b744ed 100644 --- a/packages/electron/src/domain/rum/mainProcessTracking.ts +++ b/packages/electron/src/domain/rum/mainProcessTracking.ts @@ -35,6 +35,14 @@ export function startMainProcessTracking( env: configuration.env, version: configuration.version, })) + hooks.register(HookNames.AssembleTelemetry, () => ({ + application: { + id: configuration.applicationId, + }, + session: { + id: mainProcessContext.sessionId, + }, + })) console.log('sessionId', mainProcessContext.sessionId) console.log( '\x1b[34m%s\x1b[0m', diff --git a/packages/electron/src/domain/telemetry/telemetry.ts b/packages/electron/src/domain/telemetry/telemetry.ts new file mode 100644 index 0000000000..b898412422 --- /dev/null +++ b/packages/electron/src/domain/telemetry/telemetry.ts @@ -0,0 +1,12 @@ +import type { Batch, Configuration, AbstractHooks, TelemetryEvent, Context } from '@datadog/browser-core' +import { startTelemetryCollection, Observable, TelemetryService } from '@datadog/browser-core' + +export function startTelemetry(batch: Batch, configuration: Configuration, hooks: AbstractHooks) { + const observable = new Observable() + + observable.subscribe((event) => { + batch.add(event) + }) + + startTelemetryCollection(TelemetryService.ELECTRON, configuration, hooks, observable) +} diff --git a/packages/electron/src/domain/trace/traceAgent.ts b/packages/electron/src/domain/trace/traceAgent.ts index 0516b09bb7..337033a984 100644 --- a/packages/electron/src/domain/trace/traceAgent.ts +++ b/packages/electron/src/domain/trace/traceAgent.ts @@ -1,6 +1,6 @@ import { createServer } from 'node:http' import type { Observable } from '@datadog/browser-core' -import { HookNames, DISCARDED } from '@datadog/browser-core' +import { monitor, HookNames, DISCARDED } from '@datadog/browser-core' import { decode } from '@msgpack/msgpack' import type { Hooks } from '../../hooks' import type { Trace } from './trace' @@ -10,79 +10,91 @@ import { createIdentifier } from './id' export function createDdTraceAgent(onTraceObservable: Observable, hooks: Hooks) { const server = createServer() - server.on('request', (req, res) => { - // Collect binary data chunks - const chunks: Buffer[] = [] + server.on( + 'request', + monitor((req, res) => { + // Collect binary data chunks + const chunks: Buffer[] = [] - req.on('data', (chunk: Buffer) => { - chunks.push(chunk) - }) + req.on( + 'data', + monitor((chunk: Buffer) => { + chunks.push(chunk) + }) + ) - req.on('end', () => { - const buffer = Buffer.concat(chunks) + req.on( + 'end', + monitor(() => { + const buffer = Buffer.concat(chunks) - const decoded = decode(buffer) as Array< - Array<{ name: string; type: string; meta: { [key: string]: unknown }; [key: string]: unknown }> - > + const decoded = decode(buffer) as Array< + Array<{ name: string; type: string; meta: { [key: string]: unknown }; [key: string]: unknown }> + > - const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, { - eventType: 'span' as any, - })! + const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, { + eventType: 'span' as any, + })! - if (defaultRumEventAttributes === DISCARDED) { - return - } + if (defaultRumEventAttributes === DISCARDED) { + return + } - for (const trace of decoded) { - const filteredTrace = trace - .filter((span) => !isSdkRequest(span)) - .map((span) => ({ - // rewrite ids - ...span, - trace_id: createIdentifier(`${span.trace_id as number}`, 10).toString(16), - span_id: createIdentifier(`${span.span_id as number}`, 10).toString(16), - parent_id: createIdentifier(`${span.parent_id as number}`, 10).toString(16), - meta: { - ...span.meta, - '_dd.application.id': defaultRumEventAttributes.application!.id, - '_dd.session.id': defaultRumEventAttributes.session!.id, - '_dd.view.id': defaultRumEventAttributes.view!.id, - }, - })) + for (const trace of decoded) { + const filteredTrace = trace + .filter((span) => !isSdkRequest(span)) + .map((span) => ({ + // rewrite ids + ...span, + trace_id: createIdentifier(`${span.trace_id as number}`, 10).toString(16), + span_id: createIdentifier(`${span.span_id as number}`, 10).toString(16), + parent_id: createIdentifier(`${span.parent_id as number}`, 10).toString(16), + meta: { + ...span.meta, + '_dd.application.id': defaultRumEventAttributes.application!.id, + '_dd.session.id': defaultRumEventAttributes.session!.id, + '_dd.view.id': defaultRumEventAttributes.view!.id, + }, + })) - if (filteredTrace.length > 0) { - onTraceObservable.notify(filteredTrace) - } - } - }) + if (filteredTrace.length > 0) { + onTraceObservable.notify(filteredTrace) + } + } + }) + ) - // Respond with the agent API format that dd-trace expects - res.writeHead(200, { 'Content-Type': 'application/json' }) - res.end( - JSON.stringify({ - rate_by_service: { - 'service:dd-trace,env:prod': 1, - }, - }) - ) - }) + // Respond with the agent API format that dd-trace expects + res.writeHead(200, { 'Content-Type': 'application/json' }) + res.end( + JSON.stringify({ + rate_by_service: { + 'service:dd-trace,env:prod': 1, + }, + }) + ) + }) + ) - server.listen(0, () => { - const addressInfo = server.address() - if (!addressInfo) { - throw new Error('Failed to get server address') - } + server.listen( + 0, + monitor(() => { + const addressInfo = server.address() + if (!addressInfo) { + throw new Error('Failed to get server address') + } - if (typeof addressInfo === 'string') { - throw new Error(`Address is a string: ${addressInfo}`) - } + if (typeof addressInfo === 'string') { + throw new Error(`Address is a string: ${addressInfo}`) + } - const { port } = addressInfo - const url = `http://127.0.0.1:${port}` + const { port } = addressInfo + const url = `http://127.0.0.1:${port}` - // console.log('agents url', url) - tracer.setUrl(url) - }) + // console.log('agents url', url) + tracer.setUrl(url) + }) + ) } function isSdkRequest(span: any) { diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 9de3f185a3..c53d75af0c 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -11,6 +11,7 @@ import type { TrackType, } from '@datadog/browser-core' import { + monitor, createBatch, createHttpRequest, createFlushController, @@ -19,6 +20,7 @@ import { Observable, createIdentityEncoder, HookNames, + setInterval, } from '@datadog/browser-core' import tracer, { initTracer } from '../domain/trace/tracer' import { createIpcMain } from '../domain/main/ipcMain' @@ -32,6 +34,7 @@ import { startCrashMonitoring } from '../domain/rum/crashReporter' import type { Trace } from '../domain/trace/trace' import { createDdTraceAgent } from '../domain/trace/traceAgent' import { startLogsEventAssembleAndSend } from '../domain/logs/assembly' +import { startTelemetry } from '../domain/telemetry/telemetry' function makeDatadogElectron() { const globalContext = buildGlobalContextManager() @@ -67,8 +70,8 @@ function makeDatadogElectron() { sessionExpireObservable, createIdentityEncoder ) - startRumEventAssembleAndSend(onRumEventObservable, rumBatch, hooks) + startTelemetry(rumBatch, configuration, hooks) const logsBatch = startElectronLogsBatch( configuration, @@ -106,16 +109,15 @@ function makeDatadogElectron() { initTracer(configuration.service!, configuration.env!, configuration.version!) createDdTraceAgent(onTraceObservable, hooks) - // eslint-disable-next-line setInterval(() => { pageMayExitObservable.notify({ reason: 'page_hide' }) }, 1000) }, - setGlobalContext: globalContext.setContext.bind(globalContext), - getGlobalContext: globalContext.getContext.bind(globalContext), - setGlobalContextProperty: globalContext.setContextProperty.bind(globalContext), - removeGlobalContextProperty: globalContext.removeContextProperty.bind(globalContext), - clearGlobalContext: globalContext.clearContext.bind(globalContext), + setGlobalContext: monitor(globalContext.setContext.bind(globalContext)), + getGlobalContext: monitor(globalContext.getContext.bind(globalContext)), + setGlobalContextProperty: monitor(globalContext.setContextProperty.bind(globalContext)), + removeGlobalContextProperty: monitor(globalContext.removeContextProperty.bind(globalContext)), + clearGlobalContext: monitor(globalContext.clearContext.bind(globalContext)), } } From cc8cbff65def164b6206e55b5750c6d56e335898 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Wed, 26 Nov 2025 15:00:17 +0100 Subject: [PATCH 49/58] Capture uncaught exception and unhandled rejection --- .../electron/src/domain/rum/convertSpans.ts | 19 +------ .../src/domain/rum/errorCollection.ts | 57 +++++++++++++++++++ packages/electron/src/entries/main.ts | 2 + 3 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 packages/electron/src/domain/rum/errorCollection.ts diff --git a/packages/electron/src/domain/rum/convertSpans.ts b/packages/electron/src/domain/rum/convertSpans.ts index 41f2e8055d..9e985d9889 100644 --- a/packages/electron/src/domain/rum/convertSpans.ts +++ b/packages/electron/src/domain/rum/convertSpans.ts @@ -1,6 +1,6 @@ import type { Observable } from '@datadog/browser-core' -import { ResourceType, generateUUID, ErrorHandling } from '@datadog/browser-core' -import type { RumErrorEvent, RumResourceEvent } from '@datadog/browser-rum-core' +import { ResourceType, generateUUID } from '@datadog/browser-core' +import type { RumResourceEvent } from '@datadog/browser-rum-core' import { RumEventType } from '@datadog/browser-rum-core' import type { Trace } from '../trace/trace' import { createIdentifier } from '../trace/id' @@ -12,21 +12,6 @@ export function startConvertSpanToRumEvent( ) { onTraceObservable.subscribe((trace) => { trace.forEach((span) => { - if (span.error) { - const rumError: Partial = { - type: RumEventType.ERROR, - date: span.start / 1e6, - error: { - id: generateUUID(), - message: span.meta['error.message'], - stack: span.meta['error.stack'], - type: span.meta['error.type'], - source: 'source', - handling: ErrorHandling.UNHANDLED, - }, - } - onRumEventObservable.notify({ event: rumError as RumErrorEvent, source: 'main-process' }) - } if (span.name === 'http.request') { const rumResource: Partial = { type: RumEventType.RESOURCE, diff --git a/packages/electron/src/domain/rum/errorCollection.ts b/packages/electron/src/domain/rum/errorCollection.ts new file mode 100644 index 0000000000..5b9d27eaca --- /dev/null +++ b/packages/electron/src/domain/rum/errorCollection.ts @@ -0,0 +1,57 @@ +import type { Observable, RawError } from '@datadog/browser-core' +import { + computeRawError, + clocksNow, + NonErrorPrefix, + ErrorSource, + ErrorHandling, + computeStackTrace, + generateUUID, +} from '@datadog/browser-core' +import type { RumEvent } from '@datadog/browser-rum-core' +import { RumEventType } from '@datadog/browser-rum-core' +import type { CollectedRumEvent } from './events' + +export function startErrorCollection(onRumEventObservable: Observable) { + process.on('unhandledRejection', (reason) => { + const error = computeRawError({ + stackTrace: computeStackTrace(reason), + originalError: reason, + startClocks: clocksNow(), + nonErrorPrefix: NonErrorPrefix.UNCAUGHT, + source: ErrorSource.SOURCE, + handling: ErrorHandling.UNHANDLED, + }) + notifyRawError(error) + }) + + process.on('uncaughtException', (originalError) => { + const error = computeRawError({ + stackTrace: computeStackTrace(originalError), + originalError, + startClocks: clocksNow(), + nonErrorPrefix: NonErrorPrefix.UNCAUGHT, + source: ErrorSource.SOURCE, + handling: ErrorHandling.UNHANDLED, + }) + notifyRawError(error) + }) + + function notifyRawError(error: RawError) { + const rawRumEvent: Partial = { + date: error.startClocks.timeStamp, + error: { + id: generateUUID(), + message: error.message, + source: error.source, + stack: error.stack, + type: error.type, + handling: error.handling, + source_type: 'browser', + }, + type: RumEventType.ERROR, + context: error.context, + } + onRumEventObservable.notify({ event: rawRumEvent as RumEvent, source: 'main-process' }) + } +} diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index c53d75af0c..ba895a4d21 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -35,6 +35,7 @@ import type { Trace } from '../domain/trace/trace' import { createDdTraceAgent } from '../domain/trace/traceAgent' import { startLogsEventAssembleAndSend } from '../domain/logs/assembly' import { startTelemetry } from '../domain/telemetry/telemetry' +import { startErrorCollection } from '../domain/rum/errorCollection' function makeDatadogElectron() { const globalContext = buildGlobalContextManager() @@ -102,6 +103,7 @@ function makeDatadogElectron() { onRumEventObservable, onActivityObservable ) + startErrorCollection(onRumEventObservable) startConvertSpanToRumEvent(onTraceObservable, onRumEventObservable) setupMainBridge(onRumEventObservable, onLogsEventObservable) startCrashMonitoring(onRumEventObservable, initConfiguration.applicationId, sessionId, mainProcessViewId) From 2b26db915992aa0cba3541ed1cc9e34cec17c5a0 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Wed, 26 Nov 2025 17:18:34 +0100 Subject: [PATCH 50/58] pass env info through userAgent --- packages/core/src/index.ts | 1 + packages/core/src/transport/httpRequest.ts | 38 ++++++++++---- packages/core/src/transport/index.ts | 2 +- packages/electron/package.json | 3 ++ packages/electron/src/domain/trace/tracer.ts | 19 ------- packages/electron/src/entries/main.ts | 23 +++++++-- packages/electron/src/tools/userAgent.ts | 53 ++++++++++++++++++++ yarn.lock | 2 + 8 files changed, 107 insertions(+), 34 deletions(-) create mode 100644 packages/electron/src/tools/userAgent.ts diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index e0eebbbe69..17ab2b431b 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -74,6 +74,7 @@ export type { } from './transport' export { createHttpRequest, + RECOMMENDED_REQUEST_BYTES_LIMIT, canUseEventBridge, getEventBridge, bridgeSupports, diff --git a/packages/core/src/transport/httpRequest.ts b/packages/core/src/transport/httpRequest.ts index 04e6976ee7..58700e8f8a 100644 --- a/packages/core/src/transport/httpRequest.ts +++ b/packages/core/src/transport/httpRequest.ts @@ -73,7 +73,8 @@ export interface RetryInfo { export function createHttpRequest( endpointBuilders: EndpointBuilder[], reportError: (error: RawError) => void, - bytesLimit: number = RECOMMENDED_REQUEST_BYTES_LIMIT + bytesLimit: number = RECOMMENDED_REQUEST_BYTES_LIMIT, + userAgent?: string ): HttpRequest { const observable = new Observable>() const retryState = newRetryState() @@ -87,9 +88,9 @@ export function createHttpRequest( retryState, (payload, onResponse) => { if (isExperimentalFeatureEnabled(ExperimentalFeature.AVOID_FETCH_KEEPALIVE)) { - fetchStrategy(endpointBuilder, payload, onResponse) + fetchStrategy(endpointBuilder, payload, onResponse, userAgent) } else { - fetchKeepAliveStrategy(endpointBuilder, bytesLimit, payload, onResponse) + fetchKeepAliveStrategy(endpointBuilder, bytesLimit, payload, onResponse, userAgent) } }, endpointBuilder.trackType, @@ -104,13 +105,18 @@ export function createHttpRequest( */ sendOnExit: (payload: Body) => { for (const endpointBuilder of endpointBuilders) { - sendBeaconStrategy(endpointBuilder, bytesLimit, payload) + sendBeaconStrategy(endpointBuilder, bytesLimit, payload, userAgent) } }, } } -function sendBeaconStrategy(endpointBuilder: EndpointBuilder, bytesLimit: number, payload: Payload) { +function sendBeaconStrategy( + endpointBuilder: EndpointBuilder, + bytesLimit: number, + payload: Payload, + userAgent?: string +) { const canUseBeacon = !!navigator.sendBeacon && payload.bytesCount < bytesLimit if (canUseBeacon) { try { @@ -125,7 +131,7 @@ function sendBeaconStrategy(endpointBuilder: EndpointBuilder, bytesLimit: number } } - fetchStrategy(endpointBuilder, payload) + fetchStrategy(endpointBuilder, payload, undefined, userAgent) } let hasReportedBeaconError = false @@ -141,29 +147,39 @@ export function fetchKeepAliveStrategy( endpointBuilder: EndpointBuilder, bytesLimit: number, payload: Payload, - onResponse?: (r: HttpResponse) => void + onResponse?: (r: HttpResponse) => void, + userAgent?: string ) { const canUseKeepAlive = isKeepAliveSupported() && payload.bytesCount < bytesLimit if (canUseKeepAlive) { const fetchUrl = endpointBuilder.build('fetch-keepalive', payload) - fetch(fetchUrl, { method: 'POST', body: payload.data, keepalive: true, mode: 'cors' }) + const config: RequestInit = { method: 'POST', body: payload.data, keepalive: true, mode: 'cors' } + if (userAgent) { + config.headers = { 'User-Agent': userAgent } + } + fetch(fetchUrl, config) .then(monitor((response: Response) => onResponse?.({ status: response.status, type: response.type }))) .catch(monitor(() => fetchStrategy(endpointBuilder, payload, onResponse))) } else { - fetchStrategy(endpointBuilder, payload, onResponse) + fetchStrategy(endpointBuilder, payload, onResponse, userAgent) } } export function fetchStrategy( endpointBuilder: EndpointBuilder, payload: Payload, - onResponse?: (r: HttpResponse) => void + onResponse?: (r: HttpResponse) => void, + userAgent?: string ) { const fetchUrl = endpointBuilder.build('fetch', payload) - fetch(fetchUrl, { method: 'POST', body: payload.data, mode: 'cors' }) + const config: RequestInit = { method: 'POST', body: payload.data, mode: 'cors' } + if (userAgent) { + config.headers = { 'User-Agent': userAgent } + } + fetch(fetchUrl, config) .then(monitor((response: Response) => onResponse?.({ status: response.status, type: response.type }))) .catch(monitor(() => onResponse?.({ status: 0 }))) } diff --git a/packages/core/src/transport/index.ts b/packages/core/src/transport/index.ts index bf12615aa9..287b7338a6 100644 --- a/packages/core/src/transport/index.ts +++ b/packages/core/src/transport/index.ts @@ -1,5 +1,5 @@ export type { BandwidthStats, HttpRequest, HttpRequestEvent, Payload, RetryInfo } from './httpRequest' -export { createHttpRequest } from './httpRequest' +export { createHttpRequest, RECOMMENDED_REQUEST_BYTES_LIMIT } from './httpRequest' export type { BrowserWindowWithEventBridge, DatadogEventBridge } from './eventBridge' export { canUseEventBridge, bridgeSupports, getEventBridge, BridgeCapability } from './eventBridge' export type { Batch } from './batch' diff --git a/packages/electron/package.json b/packages/electron/package.json index dd25080c10..9198d381cf 100644 --- a/packages/electron/package.json +++ b/packages/electron/package.json @@ -20,6 +20,9 @@ "dd-trace": "^5.76.0", "graphql": "16.12.0" }, + "peerDependencies": { + "electron": "39" + }, "repository": { "type": "git", "url": "https://github.com/DataDog/browser-sdk.git", diff --git a/packages/electron/src/domain/trace/tracer.ts b/packages/electron/src/domain/trace/tracer.ts index d6991db208..ec3351a75d 100644 --- a/packages/electron/src/domain/trace/tracer.ts +++ b/packages/electron/src/domain/trace/tracer.ts @@ -1,29 +1,10 @@ import tracer from 'dd-trace' -import { app } from 'electron' export function initTracer(service: string, env: string, version: string) { tracer.init({ service, env, version, - tags: { - electron: { - appName: app.getName(), - appVersion: app.getVersion(), - version: process.versions.electron, - }, - node: { - version: process.versions.node, - }, - os: { - platform: process.platform, - release: process.release, - }, - chrome: { - version: process.versions.chrome, - }, - env: 'prod', - }, }) } // initialized in a different file to avoid hoisting. diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index ba895a4d21..7a187c3d40 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -11,6 +11,7 @@ import type { TrackType, } from '@datadog/browser-core' import { + RECOMMENDED_REQUEST_BYTES_LIMIT, monitor, createBatch, createHttpRequest, @@ -36,6 +37,7 @@ import { createDdTraceAgent } from '../domain/trace/traceAgent' import { startLogsEventAssembleAndSend } from '../domain/logs/assembly' import { startTelemetry } from '../domain/telemetry/telemetry' import { startErrorCollection } from '../domain/rum/errorCollection' +import { getUserAgent } from '../tools/userAgent' function makeDatadogElectron() { const globalContext = buildGlobalContextManager() @@ -136,7 +138,12 @@ export function startElectronRumBatch( ) { const batch = createBatch({ encoder: createEncoder(), - request: createHttpRequest([configuration.rumEndpointBuilder], reportError), + request: createHttpRequest( + [configuration.rumEndpointBuilder], + reportError, + RECOMMENDED_REQUEST_BYTES_LIMIT, + getUserAgent() + ), flushController: createFlushController({ pageMayExitObservable, sessionExpireObservable, @@ -155,7 +162,12 @@ export function startElectronLogsBatch( ) { const batch = createBatch({ encoder: createEncoder(), - request: createHttpRequest([configuration.logsEndpointBuilder], reportError), + request: createHttpRequest( + [configuration.logsEndpointBuilder], + reportError, + RECOMMENDED_REQUEST_BYTES_LIMIT, + getUserAgent() + ), flushController: createFlushController({ pageMayExitObservable, sessionExpireObservable, @@ -175,7 +187,12 @@ export function startElectronSpanBatch( ) { const batch = createBatch({ encoder: createEncoder(), - request: createHttpRequest([createEndpointBuilder(initConfiguration, 'spans' as TrackType)], reportError), + request: createHttpRequest( + [createEndpointBuilder(initConfiguration, 'spans' as TrackType)], + reportError, + RECOMMENDED_REQUEST_BYTES_LIMIT, + getUserAgent() + ), flushController: createFlushController({ pageMayExitObservable, sessionExpireObservable, diff --git a/packages/electron/src/tools/userAgent.ts b/packages/electron/src/tools/userAgent.ts new file mode 100644 index 0000000000..905b6fc257 --- /dev/null +++ b/packages/electron/src/tools/userAgent.ts @@ -0,0 +1,53 @@ +import os from 'os' +import { app } from 'electron' + +export function getUserAgent() { + return [ + `${app.getName()}/${app.getVersion()}`, + `(${getOSUserAgentPart()})`, + `Electron/${process.versions.electron}`, + `Chrome/${process.versions.chrome}`, + `Node/${process.versions.node}`, + ].join(' ') +} + +// totally vibe coded +function getOSUserAgentPart() { + const platform = os.platform() // 'darwin' | 'win32' | 'linux' + const arch = os.arch() // 'x64', 'arm64', etc. + + if (platform === 'darwin') { + // macOS version is kernel-style (e.g. '23.5.0') + // Convert to marketing version (e.g. macOS 14.x.x) + const version = os.release() // Darwin kernel version + const darwinMajor = parseInt(version.split('.')[0], 10) + + // Darwin→macOS mapping: Darwin 23 → macOS 14, 22 → 13, 21 → 12, 20 → 11 + const macOSMajor = darwinMajor - 9 + + // Browser uses underscore-separated + const macOSVersionUA = `${macOSMajor}_0_0` + + return `Macintosh; Intel Mac OS X ${macOSVersionUA}` + } + + if (platform === 'win32') { + // Map kernels to Windows versions + // Windows 10 → NT 10.0 + // Windows 11 → NT 10.0 (yes, same NT version!) + const ntVersion = '10.0' + + const archUA = arch === 'x64' || arch === 'arm64' ? 'Win64; x64' : arch + return `Windows NT ${ntVersion}; ${archUA}` + } + + // Generic Linux + if (platform === 'linux') { + const archUA = arch === 'x64' ? 'x86_64' : arch === 'arm64' ? 'aarch64' : arch + + return `X11; Linux ${archUA}` + } + + // fallback + return `${platform}; ${arch}` +} diff --git a/yarn.lock b/yarn.lock index 7d4dc729a6..063b413363 100644 --- a/yarn.lock +++ b/yarn.lock @@ -383,6 +383,8 @@ __metadata: electron: "npm:39" graphql: "npm:16.12.0" pako: "npm:2.1.0" + peerDependencies: + electron: 39 languageName: unknown linkType: soft From 654588064b41c6cad9f9c4cbca697781e39d155f Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Wed, 26 Nov 2025 18:06:34 +0100 Subject: [PATCH 51/58] rework entries --- packages/electron/main/package.json | 6 + packages/electron/package.json | 3 - packages/electron/plugin/package.json | 6 - packages/electron/preload/package.json | 6 + packages/electron/src/domain/main/ipcMain.ts | 2 +- .../domain/{renderer => preload}/bridge.ts | 0 .../{renderer => preload}/ipcRenderer.ts | 2 +- .../src/domain/{plugin => renderer}/plugin.ts | 0 packages/electron/src/entries/main.ts | 158 +++++++++--------- packages/electron/src/entries/plugin.ts | 2 - packages/electron/src/entries/preload.ts | 2 + packages/electron/src/entries/renderer.ts | 7 +- test/apps/electron/src/main.ts | 2 +- 13 files changed, 95 insertions(+), 101 deletions(-) create mode 100644 packages/electron/main/package.json delete mode 100644 packages/electron/plugin/package.json create mode 100644 packages/electron/preload/package.json rename packages/electron/src/domain/{renderer => preload}/bridge.ts (100%) rename packages/electron/src/domain/{renderer => preload}/ipcRenderer.ts (98%) rename packages/electron/src/domain/{plugin => renderer}/plugin.ts (100%) delete mode 100644 packages/electron/src/entries/plugin.ts create mode 100644 packages/electron/src/entries/preload.ts diff --git a/packages/electron/main/package.json b/packages/electron/main/package.json new file mode 100644 index 0000000000..842358f536 --- /dev/null +++ b/packages/electron/main/package.json @@ -0,0 +1,6 @@ +{ + "private": true, + "main": "../cjs/entries/main.js", + "module": "../esm/entries/main.js", + "types": "../cjs/entries/main.d.ts" +} diff --git a/packages/electron/package.json b/packages/electron/package.json index 9198d381cf..1825119b4a 100644 --- a/packages/electron/package.json +++ b/packages/electron/package.json @@ -2,9 +2,6 @@ "name": "@datadog/electron", "version": "6.23.0", "license": "Apache-2.0", - "main": "cjs/entries/main.js", - "module": "esm/entries/main.js", - "types": "cjs/entries/main.d.ts", "scripts": { "pack": "yarn pack", "build": "node ../../scripts/build/build-package.ts --modules --bundle datadog-electron.js", diff --git a/packages/electron/plugin/package.json b/packages/electron/plugin/package.json deleted file mode 100644 index 1033253946..0000000000 --- a/packages/electron/plugin/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "private": true, - "main": "../cjs/entries/plugin.js", - "module": "../esm/entries/plugin.js", - "types": "../cjs/entries/plugin.d.ts" -} diff --git a/packages/electron/preload/package.json b/packages/electron/preload/package.json new file mode 100644 index 0000000000..650beb32a7 --- /dev/null +++ b/packages/electron/preload/package.json @@ -0,0 +1,6 @@ +{ + "private": true, + "main": "../cjs/entries/preload.js", + "module": "../esm/entries/preload.js", + "types": "../cjs/entries/preload.d.ts" +} diff --git a/packages/electron/src/domain/main/ipcMain.ts b/packages/electron/src/domain/main/ipcMain.ts index 7341ad19e5..daf73ec35e 100644 --- a/packages/electron/src/domain/main/ipcMain.ts +++ b/packages/electron/src/domain/main/ipcMain.ts @@ -7,7 +7,7 @@ const SPAN_NAME_PREFIX = 'ipcMain' const isDatadogCarrier = (arg: any): arg is DatadogCarrier => typeof arg === 'object' && arg?.__dd_carrier === true -export function createIpcMain(): IpcMain { +export function monitorIpcMain(): IpcMain { const ddIpcMain = { ...ipcMain } ddIpcMain.on = withDatadogCarrier('on', ipcMain.on.bind(ipcMain)) diff --git a/packages/electron/src/domain/renderer/bridge.ts b/packages/electron/src/domain/preload/bridge.ts similarity index 100% rename from packages/electron/src/domain/renderer/bridge.ts rename to packages/electron/src/domain/preload/bridge.ts diff --git a/packages/electron/src/domain/renderer/ipcRenderer.ts b/packages/electron/src/domain/preload/ipcRenderer.ts similarity index 98% rename from packages/electron/src/domain/renderer/ipcRenderer.ts rename to packages/electron/src/domain/preload/ipcRenderer.ts index be18869cd0..a502efe62b 100644 --- a/packages/electron/src/domain/renderer/ipcRenderer.ts +++ b/packages/electron/src/domain/preload/ipcRenderer.ts @@ -60,7 +60,7 @@ function withDatadogCarrier R, R>( } } -export function createIpcRenderer(): IpcRenderer { +export function monitorIpcRenderer(): IpcRenderer { const ddIpcRenderer = { ...ipcRenderer } const observable = new BufferedObservable(100) diff --git a/packages/electron/src/domain/plugin/plugin.ts b/packages/electron/src/domain/renderer/plugin.ts similarity index 100% rename from packages/electron/src/domain/plugin/plugin.ts rename to packages/electron/src/domain/renderer/plugin.ts diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 7a187c3d40..a870036aa1 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -24,7 +24,7 @@ import { setInterval, } from '@datadog/browser-core' import tracer, { initTracer } from '../domain/trace/tracer' -import { createIpcMain } from '../domain/main/ipcMain' +import { monitorIpcMain } from '../domain/main/ipcMain' import type { CollectedRumEvent } from '../domain/rum/events' import { setupMainBridge } from '../domain/main/bridge' import { startActivityTracking } from '../domain/rum/activity' @@ -39,9 +39,84 @@ import { startTelemetry } from '../domain/telemetry/telemetry' import { startErrorCollection } from '../domain/rum/errorCollection' import { getUserAgent } from '../tools/userAgent' +export const ddElectron = makeDatadogElectron() +export { tracer } +export { monitorIpcMain } + function makeDatadogElectron() { const globalContext = buildGlobalContextManager() + function startElectronRumBatch( + configuration: RumConfiguration, + reportError: (error: RawError) => void, + pageMayExitObservable: Observable, + sessionExpireObservable: Observable, + createEncoder: () => Encoder + ) { + return createBatch({ + encoder: createEncoder(), + request: createHttpRequest( + [configuration.rumEndpointBuilder], + reportError, + RECOMMENDED_REQUEST_BYTES_LIMIT, + getUserAgent() + ), + flushController: createFlushController({ + pageMayExitObservable, + sessionExpireObservable, + }), + }) + } + + function startElectronLogsBatch( + configuration: RumConfiguration, + reportError: (error: RawError) => void, + pageMayExitObservable: Observable, + sessionExpireObservable: Observable, + createEncoder: () => Encoder + ) { + return createBatch({ + encoder: createEncoder(), + request: createHttpRequest( + [configuration.logsEndpointBuilder], + reportError, + RECOMMENDED_REQUEST_BYTES_LIMIT, + getUserAgent() + ), + flushController: createFlushController({ + pageMayExitObservable, + sessionExpireObservable, + }), + }) + } + + // TODO change it by a single event fetch + function startElectronSpanBatch( + initConfiguration: InitConfiguration, + reportError: (error: RawError) => void, + pageMayExitObservable: Observable, + sessionExpireObservable: Observable, + createEncoder: () => Encoder + ) { + return createBatch({ + encoder: createEncoder(), + request: createHttpRequest( + [createEndpointBuilder(initConfiguration, 'spans' as TrackType)], + reportError, + RECOMMENDED_REQUEST_BYTES_LIMIT, + getUserAgent() + ), + flushController: createFlushController({ + pageMayExitObservable, + sessionExpireObservable, + }), + }) + } + + function reportError() { + console.error('Error reporting to Datadog') + } + return { init(initConfiguration: RumInitConfiguration) { console.log('init from SDK Electron') @@ -124,84 +199,3 @@ function makeDatadogElectron() { clearGlobalContext: monitor(globalContext.clearContext.bind(globalContext)), } } - -export const ddElectron = makeDatadogElectron() -export { tracer } -export const ipcMain = createIpcMain() - -export function startElectronRumBatch( - configuration: RumConfiguration, - reportError: (error: RawError) => void, - pageMayExitObservable: Observable, - sessionExpireObservable: Observable, - createEncoder: () => Encoder -) { - const batch = createBatch({ - encoder: createEncoder(), - request: createHttpRequest( - [configuration.rumEndpointBuilder], - reportError, - RECOMMENDED_REQUEST_BYTES_LIMIT, - getUserAgent() - ), - flushController: createFlushController({ - pageMayExitObservable, - sessionExpireObservable, - }), - }) - - return batch -} - -export function startElectronLogsBatch( - configuration: RumConfiguration, - reportError: (error: RawError) => void, - pageMayExitObservable: Observable, - sessionExpireObservable: Observable, - createEncoder: () => Encoder -) { - const batch = createBatch({ - encoder: createEncoder(), - request: createHttpRequest( - [configuration.logsEndpointBuilder], - reportError, - RECOMMENDED_REQUEST_BYTES_LIMIT, - getUserAgent() - ), - flushController: createFlushController({ - pageMayExitObservable, - sessionExpireObservable, - }), - }) - - return batch -} - -// TODO change it by a single event fetch -export function startElectronSpanBatch( - initConfiguration: InitConfiguration, - reportError: (error: RawError) => void, - pageMayExitObservable: Observable, - sessionExpireObservable: Observable, - createEncoder: () => Encoder -) { - const batch = createBatch({ - encoder: createEncoder(), - request: createHttpRequest( - [createEndpointBuilder(initConfiguration, 'spans' as TrackType)], - reportError, - RECOMMENDED_REQUEST_BYTES_LIMIT, - getUserAgent() - ), - flushController: createFlushController({ - pageMayExitObservable, - sessionExpireObservable, - }), - }) - - return batch -} - -function reportError() { - console.error('Error reporting to Datadog') -} diff --git a/packages/electron/src/entries/plugin.ts b/packages/electron/src/entries/plugin.ts deleted file mode 100644 index 8df927b5d0..0000000000 --- a/packages/electron/src/entries/plugin.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type * from './plugin' -export { electronPlugin } from '../domain/plugin/plugin' diff --git a/packages/electron/src/entries/preload.ts b/packages/electron/src/entries/preload.ts new file mode 100644 index 0000000000..c511284e3e --- /dev/null +++ b/packages/electron/src/entries/preload.ts @@ -0,0 +1,2 @@ +export { monitorIpcRenderer } from '../domain/preload/ipcRenderer' +export { setupRendererBridge } from '../domain/preload/bridge' diff --git a/packages/electron/src/entries/renderer.ts b/packages/electron/src/entries/renderer.ts index 450bf90c56..ff9724bb1a 100644 --- a/packages/electron/src/entries/renderer.ts +++ b/packages/electron/src/entries/renderer.ts @@ -1,5 +1,2 @@ -import { createIpcRenderer } from '../domain/renderer/ipcRenderer' -import { setupRendererBridge } from '../domain/renderer/bridge' - -setupRendererBridge() -export const ipcRenderer = createIpcRenderer() +export type * from './renderer' +export { electronPlugin } from '../domain/renderer/plugin' diff --git a/test/apps/electron/src/main.ts b/test/apps/electron/src/main.ts index c16f5f6942..4a035cb6be 100644 --- a/test/apps/electron/src/main.ts +++ b/test/apps/electron/src/main.ts @@ -1,5 +1,5 @@ import { app, BrowserWindow } from 'electron' -import { ddElectron } from '@datadog/electron' +import { ddElectron } from '@datadog/electron/main' // Delay startup to not miss early logs in playwright setTimeout(startApp, 200) From 5490759dff2c115281906424c5a6a79f299da453 Mon Sep 17 00:00:00 2001 From: Adrian de la Rosa Date: Fri, 28 Nov 2025 16:28:50 +0100 Subject: [PATCH 52/58] =?UTF-8?q?=E2=9C=A8=20session=20manager=20&=20crash?= =?UTF-8?q?=20report?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/index.ts | 1 + .../electron/src/domain/rum/crashReporter.ts | 61 ++++++-- .../src/domain/rum/mainProcessTracking.ts | 63 ++++---- .../electron/src/domain/session/manager.ts | 147 ++++++++++++++++++ packages/electron/src/entries/main.ts | 21 ++- 5 files changed, 249 insertions(+), 44 deletions(-) create mode 100644 packages/electron/src/domain/session/manager.ts diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 17ab2b431b..a50202efb4 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -57,6 +57,7 @@ export { Observable, BufferedObservable } from './tools/observable' export type { SessionManager } from './domain/session/sessionManager' export { startSessionManager, stopSessionManager } from './domain/session/sessionManager' export { + SESSION_EXPIRATION_DELAY, SESSION_TIME_OUT_DELAY, // Exposed for tests SESSION_NOT_TRACKED, SessionPersistence, diff --git a/packages/electron/src/domain/rum/crashReporter.ts b/packages/electron/src/domain/rum/crashReporter.ts index d874587b4f..fb727af490 100644 --- a/packages/electron/src/domain/rum/crashReporter.ts +++ b/packages/electron/src/domain/rum/crashReporter.ts @@ -58,6 +58,16 @@ interface MinidumpResult { }> } +interface CrashContext { + sessionId: string + viewId: string +} + +const CRASH_CONTEXT_FILE_NAME = '.dd_context' + +let ready = false +const callbacks: Array<() => void> = [] + /** * Convert minidump parsed result to a RUM error event format */ @@ -152,19 +162,10 @@ function createCrashErrorEvent( } } -export function startCrashMonitoring( - onRumEventObservable: Observable, - applicationId: string, - sessionId: string, - viewId: string -) { +export function startCrashMonitoring(onRumEventObservable: Observable, applicationId: string) { // Initialize crash reporter crashReporter.start({ uploadToServer: false, // We'll handle uploading via RUM - compress: true, - extra: { - sessionId, - }, }) // Wait for app to be ready before accessing crash dumps directory @@ -172,9 +173,27 @@ export function startCrashMonitoring( monitor(() => { const crashesDirectory = app.getPath('crashDumps') + const crashContextPath = path.join(crashesDirectory, CRASH_CONTEXT_FILE_NAME) + + if (!fs.existsSync(crashContextPath)) { + console.warn('[Datadog] No crash context found') + // Stop reporting, we don't want to report incorrect data + ready = true + callbacks.forEach((callback) => callback()) + return + } + + // Read crash context from previous session + const crashContext = fs.readFileSync(crashContextPath, 'utf-8') + const crashContextData = JSON.parse(crashContext) as CrashContext + // Check if there are any crash reports pending const pendingCrashReports = fs.readdirSync(path.join(crashesDirectory, 'pending')) + if (pendingCrashReports.length === 0) { + console.log('[Datadog] No pending crash reports found') + } + // eslint-disable-next-line @typescript-eslint/no-misused-promises pendingCrashReports.forEach(async (crashReport) => { const reportPath = path.join(crashesDirectory, 'pending', crashReport) @@ -191,8 +210,8 @@ export function startCrashMonitoring( crashReport, crashTime, applicationId, - sessionId, - viewId + crashContextData.sessionId, + crashContextData.viewId ) onRumEventObservable.notify({ @@ -203,6 +222,24 @@ export function startCrashMonitoring( // delete the crash report fs.unlinkSync(reportPath) }) + + ready = true + callbacks.forEach((callback) => callback()) }) ) } + +export const storeCrashContext = monitor((context: { sessionId: string; viewId: string }) => { + if (!ready) { + callbacks.push(() => { + storeCrashContext(context) + }) + return + } + + console.debug('[Datadog] Storing crash context', context) + const crashesDirectory = app.getPath('crashDumps') + + const crashContextPath = path.join(crashesDirectory, CRASH_CONTEXT_FILE_NAME) + fs.writeFileSync(crashContextPath, JSON.stringify(context, null, 2), 'utf-8') +}) diff --git a/packages/electron/src/domain/rum/mainProcessTracking.ts b/packages/electron/src/domain/rum/mainProcessTracking.ts index 9d35b744ed..d0f6bbd69d 100644 --- a/packages/electron/src/domain/rum/mainProcessTracking.ts +++ b/packages/electron/src/domain/rum/mainProcessTracking.ts @@ -1,8 +1,9 @@ import type { RumConfiguration, RumViewEvent } from '@datadog/browser-rum-core' import { RumEventType } from '@datadog/browser-rum-core' import type { Observable } from '@datadog/browser-core' -import { HookNames, timeStampNow, combine, toServerDuration, elapsed } from '@datadog/browser-core' +import { SKIPPED, HookNames, timeStampNow, combine, toServerDuration, elapsed } from '@datadog/browser-core' import type { Hooks } from '../../hooks' +import type { SessionManager } from '../session/manager' import type { CollectedRumEvent } from './events' const NODE_VIEW_NAME = 'ApplicationLaunch' @@ -10,48 +11,58 @@ const NODE_VIEW_NAME = 'ApplicationLaunch' export function startMainProcessTracking( hooks: Hooks, configuration: RumConfiguration, - sessionId: string, + sessionManager: SessionManager, mainProcessViewId: string, onRumEventObservable: Observable, onActivityObservable: Observable ) { + let currentSessionId = sessionManager.getSession()?.id + + // Subscribe to session changes to update session ID + sessionManager.stateObservable.subscribe(({ id: sessionId }) => { + currentSessionId = sessionId + }) + const mainProcessContext = { - sessionId, viewId: mainProcessViewId, } - hooks.register(HookNames.Assemble, ({ eventType }) => ({ - type: eventType, - application: { - id: configuration.applicationId, - }, - session: { - id: mainProcessContext.sessionId, - }, - view: { - id: mainProcessContext.viewId, - url: NODE_VIEW_NAME, - }, - service: configuration.service, - env: configuration.env, - version: configuration.version, - })) + + hooks.register(HookNames.Assemble, ({ eventType, ...event }) => { + if ('session' in event) { + return SKIPPED + } + + return { + type: eventType, + application: { + id: configuration.applicationId, + }, + session: { + id: currentSessionId, + }, + view: { + id: mainProcessContext.viewId, + url: NODE_VIEW_NAME, + }, + service: configuration.service, + env: configuration.env, + version: configuration.version, + } + }) hooks.register(HookNames.AssembleTelemetry, () => ({ application: { id: configuration.applicationId, }, session: { - id: mainProcessContext.sessionId, + id: sessionManager.getSession()?.id, }, })) - console.log('sessionId', mainProcessContext.sessionId) - console.log( - '\x1b[34m%s\x1b[0m', - `https://app.datadoghq.com/rum/sessions?query=%40type%3Asession%20%40session.id%3A${mainProcessContext.sessionId}` - ) + console.log('sessionId', currentSessionId) console.log( '\x1b[34m%s\x1b[0m', - `https://app.datadoghq.com/apm/traces?query=%40_dd.session.id%3A${mainProcessContext.sessionId}` + `https://app.datadoghq.com/rum/sessions?query=%40type%3Asession%20%40session.id%3A${currentSessionId}` ) + console.log('\x1b[34m%s\x1b[0m', `https://app.datadoghq.com/apm/traces?query=%40_dd.session.id%3A${currentSessionId}`) const applicationStart = timeStampNow() let applicationLaunch = { type: RumEventType.VIEW, diff --git a/packages/electron/src/domain/session/manager.ts b/packages/electron/src/domain/session/manager.ts new file mode 100644 index 0000000000..0865ebcee8 --- /dev/null +++ b/packages/electron/src/domain/session/manager.ts @@ -0,0 +1,147 @@ +import * as fs from 'node:fs' +import * as path from 'node:path' +import { app } from 'electron' +import type { TimeStamp } from '@datadog/browser-core' +import { + Observable, + generateUUID, + timeStampNow, + SESSION_TIME_OUT_DELAY, + SESSION_EXPIRATION_DELAY, +} from '@datadog/browser-core' + +interface State { + id: string + createdAt: TimeStamp + lastActivityAt: TimeStamp +} + +interface PersistedState extends State { + anonymousId: string +} + +const SESSION_FILE_NAME = '.dd_s' + +// eslint-disable-next-line no-restricted-syntax +export class SessionManager { + public stateObservable = new Observable() + public expireObservable = new Observable() + + private readonly filePath: string + private readonly anonymousId: string + + private state: State + + constructor(onActivityObservable: Observable) { + // Set up file path for persistence + const userDataPath = app.getPath('userData') + this.filePath = path.join(userDataPath, SESSION_FILE_NAME) + + // Load persisted data or initialize new session + const fromState: PersistedState = this.loadPersistedData() ?? { + anonymousId: generateUUID(), + id: '', + lastActivityAt: 0 as TimeStamp, + createdAt: 0 as TimeStamp, + } + + this.anonymousId = fromState.anonymousId + this.state = { + id: fromState.id, + createdAt: fromState.createdAt, + lastActivityAt: fromState.lastActivityAt, + } + this.expandOrRenewSession() + + // Subscribe to activity events to extend session + onActivityObservable.subscribe(() => { + this.expandOrRenewSession() + }) + } + + public getSession(): PersistedState { + return { + anonymousId: this.anonymousId, + id: this.state.id, + createdAt: this.state.createdAt, + lastActivityAt: this.state.lastActivityAt, + } + } + + private expandOrRenewSession(): void { + const now = timeStampNow() + + const timeSinceLastActivity = now - this.state.lastActivityAt + const timeSinceCreation = now - this.state.createdAt + + const shouldRenew = timeSinceLastActivity >= 1 * 60 * 1000 || timeSinceCreation >= SESSION_TIME_OUT_DELAY + + if (shouldRenew) { + this.renewSession() + } else { + this.expandSession() + } + } + + /** + * Expand session by updating last activity time + */ + private expandSession(): void { + this.state.lastActivityAt = timeStampNow() + this.persistState() + console.debug('[Datadog] Expanded session', this.getSession()) + this.stateObservable.notify(this.getSession()) + } + + /** + * Renew session by generating a new session ID + */ + private renewSession(): void { + const now = timeStampNow() + + this.state = { + id: generateUUID(), + createdAt: now, + lastActivityAt: now, + } + + // Persist new state + this.persistState() + this.expireObservable.notify() + } + + /** + * Load persisted session data from disk + */ + private loadPersistedData(): PersistedState | undefined { + try { + if (!fs.existsSync(this.filePath)) { + return undefined + } + + const fileContent = fs.readFileSync(this.filePath, 'utf-8') + return JSON.parse(fileContent) as PersistedState + } catch { + return undefined + } + } + + /** + * Persist current session state to disk (async, non-blocking) + */ + private persistState(): void { + const data: PersistedState = { + anonymousId: this.anonymousId, + id: this.state.id, + createdAt: this.state.createdAt, + lastActivityAt: this.state.lastActivityAt, + } + + const fileContent = JSON.stringify(data, null, 2) + try { + fs.writeFileSync(this.filePath, fileContent, 'utf-8') + } catch { + // send telemetry + } + } +} diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index a870036aa1..2faa15f533 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -31,7 +31,7 @@ import { startActivityTracking } from '../domain/rum/activity' import { startRumEventAssembleAndSend } from '../domain/rum/assembly' import { startMainProcessTracking } from '../domain/rum/mainProcessTracking' import { startConvertSpanToRumEvent } from '../domain/rum/convertSpans' -import { startCrashMonitoring } from '../domain/rum/crashReporter' +import { startCrashMonitoring, storeCrashContext } from '../domain/rum/crashReporter' import type { Trace } from '../domain/trace/trace' import { createDdTraceAgent } from '../domain/trace/traceAgent' import { startLogsEventAssembleAndSend } from '../domain/logs/assembly' @@ -42,6 +42,7 @@ import { getUserAgent } from '../tools/userAgent' export const ddElectron = makeDatadogElectron() export { tracer } export { monitorIpcMain } +import { SessionManager } from '../domain/session/manager' function makeDatadogElectron() { const globalContext = buildGlobalContextManager() @@ -128,12 +129,10 @@ function makeDatadogElectron() { } const pageMayExitObservable = new Observable() - const sessionExpireObservable = new Observable() const onRumEventObservable = new Observable() const onLogsEventObservable = new Observable() const onTraceObservable = new Observable() const hooks = createHooks() - const sessionId = crypto.randomUUID() const mainProcessViewId = crypto.randomUUID() ;(hooks as AbstractHooks).register(HookNames.Assemble, () => { @@ -141,6 +140,17 @@ function makeDatadogElectron() { return { context } }) + // Initialize activity tracking first (needed by session manager) + const onActivityObservable = startActivityTracking(onRumEventObservable) + + // Initialize session manager + const sessionManager = new SessionManager(onActivityObservable) + const sessionExpireObservable = sessionManager.expireObservable + sessionManager.stateObservable.subscribe((state) => { + console.log('>>> subscribe', state) + storeCrashContext({ sessionId: state.id, viewId: mainProcessViewId }) + }) + const rumBatch = startElectronRumBatch( configuration, reportError, @@ -171,11 +181,10 @@ function makeDatadogElectron() { spanBatch.add({ env: 'prod', spans: trace }) }) - const onActivityObservable = startActivityTracking(onRumEventObservable) startMainProcessTracking( hooks, configuration, - sessionId, + sessionManager, mainProcessViewId, onRumEventObservable, onActivityObservable @@ -183,7 +192,7 @@ function makeDatadogElectron() { startErrorCollection(onRumEventObservable) startConvertSpanToRumEvent(onTraceObservable, onRumEventObservable) setupMainBridge(onRumEventObservable, onLogsEventObservable) - startCrashMonitoring(onRumEventObservable, initConfiguration.applicationId, sessionId, mainProcessViewId) + startCrashMonitoring(onRumEventObservable, initConfiguration.applicationId) initTracer(configuration.service!, configuration.env!, configuration.version!) createDdTraceAgent(onTraceObservable, hooks) From f147ce970162868b8813876ee5162a002d8c78a2 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Mon, 1 Dec 2025 11:16:51 +0100 Subject: [PATCH 53/58] Switch file accesses to async, remove some logs --- .../electron/src/domain/rum/crashReporter.ts | 79 ++++++++++--------- .../electron/src/domain/session/manager.ts | 9 +-- packages/electron/src/entries/main.ts | 5 +- 3 files changed, 46 insertions(+), 47 deletions(-) diff --git a/packages/electron/src/domain/rum/crashReporter.ts b/packages/electron/src/domain/rum/crashReporter.ts index fb727af490..7dd6e922e1 100644 --- a/packages/electron/src/domain/rum/crashReporter.ts +++ b/packages/electron/src/domain/rum/crashReporter.ts @@ -1,4 +1,4 @@ -import * as fs from 'node:fs' +import * as fs from 'node:fs/promises' import * as path from 'node:path' import type { Observable } from '@datadog/browser-core' @@ -170,12 +170,15 @@ export function startCrashMonitoring(onRumEventObservable: Observable { + monitor(async () => { const crashesDirectory = app.getPath('crashDumps') const crashContextPath = path.join(crashesDirectory, CRASH_CONTEXT_FILE_NAME) - if (!fs.existsSync(crashContextPath)) { + // Check if crash context file exists + try { + await fs.access(crashContextPath) + } catch { console.warn('[Datadog] No crash context found') // Stop reporting, we don't want to report incorrect data ready = true @@ -184,44 +187,49 @@ export function startCrashMonitoring(onRumEventObservable: Observable { - const reportPath = path.join(crashesDirectory, 'pending', crashReport) - const reportMetadata = fs.statSync(reportPath) - const reportBytes = fs.readFileSync(reportPath) - - const resultJson = await process_minidump_with_stackwalk(reportBytes) - const minidumpResult: MinidumpResult = JSON.parse(resultJson) - - const crashTime = new Date(reportMetadata.ctime).getTime() - - const rumErrorEvent = createCrashErrorEvent( - minidumpResult, - crashReport, - crashTime, - applicationId, - crashContextData.sessionId, - crashContextData.viewId - ) - - onRumEventObservable.notify({ - event: rumErrorEvent, - source: 'main-process', + // Process crash reports in parallel + await Promise.all( + pendingCrashReports.map(async (crashReport) => { + const reportPath = path.join(crashesDirectory, 'pending', crashReport) + const reportMetadata = await fs.stat(reportPath) + const reportBytes = await fs.readFile(reportPath) + + const resultJson = await process_minidump_with_stackwalk(reportBytes) + const minidumpResult: MinidumpResult = JSON.parse(resultJson) + + const crashTime = new Date(reportMetadata.ctime).getTime() + + const rumErrorEvent = createCrashErrorEvent( + minidumpResult, + crashReport, + crashTime, + applicationId, + crashContextData.sessionId, + crashContextData.viewId + ) + + onRumEventObservable.notify({ + event: rumErrorEvent, + source: 'main-process', + }) + + // delete the crash report + await fs.unlink(reportPath) + console.log(`[Datadog] crash processed: ${reportPath}`) }) - - // delete the crash report - fs.unlinkSync(reportPath) - }) + ) ready = true callbacks.forEach((callback) => callback()) @@ -229,17 +237,16 @@ export function startCrashMonitoring(onRumEventObservable: Observable { +export const storeCrashContext = monitor(async (context: { sessionId: string; viewId: string }) => { if (!ready) { callbacks.push(() => { - storeCrashContext(context) + void storeCrashContext(context) }) return } - console.debug('[Datadog] Storing crash context', context) const crashesDirectory = app.getPath('crashDumps') const crashContextPath = path.join(crashesDirectory, CRASH_CONTEXT_FILE_NAME) - fs.writeFileSync(crashContextPath, JSON.stringify(context, null, 2), 'utf-8') + await fs.writeFile(crashContextPath, JSON.stringify(context, null, 2), 'utf-8') }) diff --git a/packages/electron/src/domain/session/manager.ts b/packages/electron/src/domain/session/manager.ts index 0865ebcee8..c18e4b69cd 100644 --- a/packages/electron/src/domain/session/manager.ts +++ b/packages/electron/src/domain/session/manager.ts @@ -2,13 +2,7 @@ import * as fs from 'node:fs' import * as path from 'node:path' import { app } from 'electron' import type { TimeStamp } from '@datadog/browser-core' -import { - Observable, - generateUUID, - timeStampNow, - SESSION_TIME_OUT_DELAY, - SESSION_EXPIRATION_DELAY, -} from '@datadog/browser-core' +import { Observable, generateUUID, timeStampNow, SESSION_TIME_OUT_DELAY } from '@datadog/browser-core' interface State { id: string @@ -89,7 +83,6 @@ export class SessionManager { private expandSession(): void { this.state.lastActivityAt = timeStampNow() this.persistState() - console.debug('[Datadog] Expanded session', this.getSession()) this.stateObservable.notify(this.getSession()) } diff --git a/packages/electron/src/entries/main.ts b/packages/electron/src/entries/main.ts index 2faa15f533..046ade23f0 100644 --- a/packages/electron/src/entries/main.ts +++ b/packages/electron/src/entries/main.ts @@ -38,11 +38,11 @@ import { startLogsEventAssembleAndSend } from '../domain/logs/assembly' import { startTelemetry } from '../domain/telemetry/telemetry' import { startErrorCollection } from '../domain/rum/errorCollection' import { getUserAgent } from '../tools/userAgent' +import { SessionManager } from '../domain/session/manager' export const ddElectron = makeDatadogElectron() export { tracer } export { monitorIpcMain } -import { SessionManager } from '../domain/session/manager' function makeDatadogElectron() { const globalContext = buildGlobalContextManager() @@ -147,8 +147,7 @@ function makeDatadogElectron() { const sessionManager = new SessionManager(onActivityObservable) const sessionExpireObservable = sessionManager.expireObservable sessionManager.stateObservable.subscribe((state) => { - console.log('>>> subscribe', state) - storeCrashContext({ sessionId: state.id, viewId: mainProcessViewId }) + void storeCrashContext({ sessionId: state.id, viewId: mainProcessViewId }) }) const rumBatch = startElectronRumBatch( From ad456f6c91ed04da33ceb8e6f59ca95d1cfd3079 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Mon, 1 Dec 2025 15:35:36 +0100 Subject: [PATCH 54/58] look for dump in every directory (cross os compatibility) --- .../electron/src/domain/rum/crashReporter.ts | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/electron/src/domain/rum/crashReporter.ts b/packages/electron/src/domain/rum/crashReporter.ts index 7dd6e922e1..decde5ab14 100644 --- a/packages/electron/src/domain/rum/crashReporter.ts +++ b/packages/electron/src/domain/rum/crashReporter.ts @@ -191,7 +191,7 @@ export function startCrashMonitoring(onRumEventObservable: Observable { - const reportPath = path.join(crashesDirectory, 'pending', crashReport) + pendingCrashReports.map(async (reportPath) => { const reportMetadata = await fs.stat(reportPath) const reportBytes = await fs.readFile(reportPath) @@ -211,9 +210,10 @@ export function startCrashMonitoring(onRumEventObservable: Observable { if (!ready) { callbacks.push(() => { From ede97fd3391caf789c339b2bf8f711c3d549b8a8 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Mon, 1 Dec 2025 17:15:16 +0100 Subject: [PATCH 55/58] workaround for windows startup issue --- .../electron/src/domain/rum/crashReporter.ts | 131 +++++++++--------- 1 file changed, 68 insertions(+), 63 deletions(-) diff --git a/packages/electron/src/domain/rum/crashReporter.ts b/packages/electron/src/domain/rum/crashReporter.ts index decde5ab14..e93562b6c5 100644 --- a/packages/electron/src/domain/rum/crashReporter.ts +++ b/packages/electron/src/domain/rum/crashReporter.ts @@ -2,7 +2,7 @@ import * as fs from 'node:fs/promises' import * as path from 'node:path' import type { Observable } from '@datadog/browser-core' -import { monitor, ErrorHandling, generateUUID } from '@datadog/browser-core' +import { monitorError, monitor, ErrorHandling, generateUUID, setTimeout, ONE_SECOND } from '@datadog/browser-core' import { RumEventType } from '@datadog/browser-rum-core' import { app, crashReporter } from 'electron' @@ -169,72 +169,77 @@ export function startCrashMonitoring(onRumEventObservable: Observable { - const crashesDirectory = app.getPath('crashDumps') - - const crashContextPath = path.join(crashesDirectory, CRASH_CONTEXT_FILE_NAME) - - // Check if crash context file exists - try { - await fs.access(crashContextPath) - } catch { - console.warn('[Datadog] No crash context found') - // Stop reporting, we don't want to report incorrect data - ready = true - callbacks.forEach((callback) => callback()) - return - } - - // Read crash context from previous session - const crashContext = await fs.readFile(crashContextPath, 'utf-8') - const crashContextData = JSON.parse(crashContext) as CrashContext - - // Check if there are any crash reports pending - const pendingCrashReports = await getFilesRecursive(crashesDirectory, '.dmp') - - if (pendingCrashReports.length === 0) { - console.log('[Datadog] No pending crash reports found') - } else { - console.log(`[Datadog] ${pendingCrashReports.length} pending crash reports found`) - } - - // Process crash reports in parallel - await Promise.all( - pendingCrashReports.map(async (reportPath) => { - const reportMetadata = await fs.stat(reportPath) - const reportBytes = await fs.readFile(reportPath) - - const resultJson = await process_minidump_with_stackwalk(reportBytes) - const minidumpResult: MinidumpResult = JSON.parse(resultJson) - - const crashTime = new Date(reportMetadata.ctime).getTime() - - const reportName = path.basename(reportPath) - const rumErrorEvent = createCrashErrorEvent( - minidumpResult, - reportName, - crashTime, - applicationId, - crashContextData.sessionId, - crashContextData.viewId - ) - - onRumEventObservable.notify({ - event: rumErrorEvent, - source: 'main-process', - }) - - // delete the crash report - await fs.unlink(reportPath) - console.log(`[Datadog] crash processed: ${reportName}`) - }) + void app.whenReady().then(() => + // wait a bit more to prevent crash on windows ¯\_(ツ)_/¯ + setTimeout(() => { + processCrashesFiles(onRumEventObservable, applicationId).catch(monitorError) + }, ONE_SECOND) + ) +} + +async function processCrashesFiles(onRumEventObservable: Observable, applicationId: string) { + const crashesDirectory = app.getPath('crashDumps') + + const crashContextPath = path.join(crashesDirectory, CRASH_CONTEXT_FILE_NAME) + + // Check if crash context file exists + try { + await fs.access(crashContextPath) + } catch { + console.warn('[Datadog] No crash context found') + // Stop reporting, we don't want to report incorrect data + ready = true + callbacks.forEach((callback) => callback()) + return + } + + // Read crash context from previous session + const crashContext = await fs.readFile(crashContextPath, 'utf-8') + const crashContextData = JSON.parse(crashContext) as CrashContext + + // Check if there are any crash reports pending + const pendingCrashReports = await getFilesRecursive(crashesDirectory, '.dmp') + + if (pendingCrashReports.length === 0) { + console.log('[Datadog] No pending crash reports found') + } else { + console.log(`[Datadog] ${pendingCrashReports.length} pending crash reports found`) + } + + // Process crash reports in parallel + await Promise.all( + pendingCrashReports.map(async (reportPath) => { + const reportMetadata = await fs.stat(reportPath) + const reportBytes = await fs.readFile(reportPath) + + const resultJson = await process_minidump_with_stackwalk(reportBytes) + const minidumpResult: MinidumpResult = JSON.parse(resultJson) + + const crashTime = new Date(reportMetadata.ctime).getTime() + + const reportName = path.basename(reportPath) + const rumErrorEvent = createCrashErrorEvent( + minidumpResult, + reportName, + crashTime, + applicationId, + crashContextData.sessionId, + crashContextData.viewId ) - ready = true - callbacks.forEach((callback) => callback()) + onRumEventObservable.notify({ + event: rumErrorEvent, + source: 'main-process', + }) + + // delete the crash report + await fs.unlink(reportPath) + console.log(`[Datadog] crash processed: ${reportName}`) }) ) + + ready = true + callbacks.forEach((callback) => callback()) } async function getFilesRecursive(dir: string, ext: string) { From 11bcc815a187beb90fa78e5ddcc826cfdb15ce43 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Tue, 2 Dec 2025 11:43:08 +0100 Subject: [PATCH 56/58] add comment on setTimeout --- packages/electron/src/domain/rum/crashReporter.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/electron/src/domain/rum/crashReporter.ts b/packages/electron/src/domain/rum/crashReporter.ts index e93562b6c5..7712f49949 100644 --- a/packages/electron/src/domain/rum/crashReporter.ts +++ b/packages/electron/src/domain/rum/crashReporter.ts @@ -168,9 +168,15 @@ export function startCrashMonitoring(onRumEventObservable: Observable - // wait a bit more to prevent crash on windows ¯\_(ツ)_/¯ setTimeout(() => { processCrashesFiles(onRumEventObservable, applicationId).catch(monitorError) }, ONE_SECOND) From 9bb17058de620ecdf542ca6f7e871fa3b191d006 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Tue, 2 Dec 2025 15:03:38 +0100 Subject: [PATCH 57/58] fix build on windows --- developer-extension/package.json | 4 ++-- developer-extension/webpack.config.mts | 1 + scripts/lib/buildEnv.ts | 6 +++++- scripts/lib/command.ts | 7 +++++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/developer-extension/package.json b/developer-extension/package.json index 003c59bcc9..50686e4060 100644 --- a/developer-extension/package.json +++ b/developer-extension/package.json @@ -3,8 +3,8 @@ "version": "6.24.0", "private": true, "scripts": { - "build": "rm -rf dist && webpack --disable-interpret --mode production", - "dev": "rm -rf dist && webpack --disable-interpret --mode development && webpack serve --disable-interpret --mode development --config-name=panel --hot" + "build": "webpack --disable-interpret --mode production", + "dev": "webpack --disable-interpret --mode development && webpack serve --disable-interpret --mode development --config-name=panel --hot" }, "devDependencies": { "@pmmmwh/react-refresh-webpack-plugin": "^0.6.0", diff --git a/developer-extension/webpack.config.mts b/developer-extension/webpack.config.mts index 6b6bff398f..542d1844af 100644 --- a/developer-extension/webpack.config.mts +++ b/developer-extension/webpack.config.mts @@ -16,6 +16,7 @@ export default (_env: unknown, argv: { mode?: webpack.Configuration['mode'] }) = entry: './src/background', output: { filename: 'background.js', + clean: true, }, plugins: [ ...(isDevelopment diff --git a/scripts/lib/buildEnv.ts b/scripts/lib/buildEnv.ts index 4dfb5a15e5..d12600945d 100644 --- a/scripts/lib/buildEnv.ts +++ b/scripts/lib/buildEnv.ts @@ -51,7 +51,11 @@ const buildEnvFactories: BuildEnvFactories = { // Make sure the worker is built // TODO: Improve overall built time by rebuilding the worker only if its sources have changed? // TODO: Improve developer experience during tests by detecting worker source changes? - command`yarn build`.withCurrentWorkingDirectory(workerPath).run() + command`yarn build` + .withCurrentWorkingDirectory(workerPath) + // shell needed in windows to execute yarn in spawnSync + .withShell() + .run() return readFileSync(path.join(workerPath, 'bundle/worker.js'), { encoding: 'utf-8', }) diff --git a/scripts/lib/command.ts b/scripts/lib/command.ts index d6fc817d8b..86baf44b92 100644 --- a/scripts/lib/command.ts +++ b/scripts/lib/command.ts @@ -4,6 +4,7 @@ import { printError } from './executionUtils.ts' interface CommandOptions { cwd?: string stdio?: 'inherit' | 'pipe' + shell?: true } interface CommandBuilder { @@ -11,6 +12,7 @@ interface CommandBuilder { withEnvironment(newEnv: Record): CommandBuilder withCurrentWorkingDirectory(newCurrentWorkingDirectory: string): CommandBuilder withLogs(): CommandBuilder + withShell(): CommandBuilder run(): string } @@ -51,6 +53,11 @@ export function command(...templateArguments: [TemplateStringsArray, ...any[]]): return this }, + withShell() { + extraOptions.shell = true + return this + }, + withLogs() { extraOptions.stdio = 'inherit' return this From 6c83862af112f0846df0f0e239c8370e93ce7100 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Tue, 2 Dec 2025 17:48:27 +0100 Subject: [PATCH 58/58] increase timeout and wait for first renderer event --- .../electron/src/domain/rum/crashReporter.ts | 46 +++++++++++++++---- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/packages/electron/src/domain/rum/crashReporter.ts b/packages/electron/src/domain/rum/crashReporter.ts index 7712f49949..927fcb6c11 100644 --- a/packages/electron/src/domain/rum/crashReporter.ts +++ b/packages/electron/src/domain/rum/crashReporter.ts @@ -2,7 +2,15 @@ import * as fs from 'node:fs/promises' import * as path from 'node:path' import type { Observable } from '@datadog/browser-core' -import { monitorError, monitor, ErrorHandling, generateUUID, setTimeout, ONE_SECOND } from '@datadog/browser-core' +import { + monitorError, + monitor, + ErrorHandling, + generateUUID, + setTimeout, + clearTimeout, + ONE_SECOND, +} from '@datadog/browser-core' import { RumEventType } from '@datadog/browser-rum-core' import { app, crashReporter } from 'electron' @@ -65,7 +73,8 @@ interface CrashContext { const CRASH_CONTEXT_FILE_NAME = '.dd_context' -let ready = false +let pendingCrashReportsProcessed = false +let pendingCrashReportsProcessingStarted = false const callbacks: Array<() => void> = [] /** @@ -168,6 +177,8 @@ export function startCrashMonitoring(onRumEventObservable: Observable void processCrashesFiles(onRumEventObservable, applicationId).catch(monitorError) + // https://www.electronjs.org/docs/latest/tutorial/performance#2-loading-and-running-code-too-soon // As crashes files accesses and parsing can be I/O and CPU intensive, delay them to not impact the main thread during startup // Crashes at startup have been observed on windows VM without the setTimeout @@ -176,11 +187,26 @@ export function startCrashMonitoring(onRumEventObservable: Observable - setTimeout(() => { - processCrashesFiles(onRumEventObservable, applicationId).catch(monitorError) - }, ONE_SECOND) - ) + void app.whenReady().then(() => { + const subscription = onRumEventObservable.subscribe(({ source }) => { + if (source === 'renderer') { + tryProcessCrashesFiles(processing) + } + }) + + const timeout = setTimeout(() => { + tryProcessCrashesFiles(processing) + }, 5 * ONE_SECOND) + + function tryProcessCrashesFiles(callback: () => void) { + if (!pendingCrashReportsProcessingStarted) { + pendingCrashReportsProcessingStarted = true + subscription.unsubscribe() + clearTimeout(timeout) + callback() + } + } + }) } async function processCrashesFiles(onRumEventObservable: Observable, applicationId: string) { @@ -194,7 +220,7 @@ async function processCrashesFiles(onRumEventObservable: Observable callback()) return } @@ -244,7 +270,7 @@ async function processCrashesFiles(onRumEventObservable: Observable callback()) } @@ -269,7 +295,7 @@ async function getFilesRecursive(dir: string, ext: string) { } export const storeCrashContext = monitor(async (context: { sessionId: string; viewId: string }) => { - if (!ready) { + if (!pendingCrashReportsProcessed) { callbacks.push(() => { void storeCrashContext(context) })