diff --git a/frontend/obsidian-plugin/package.json b/frontend/obsidian-plugin/package.json index 12a52f28..0c09800b 100644 --- a/frontend/obsidian-plugin/package.json +++ b/frontend/obsidian-plugin/package.json @@ -13,8 +13,6 @@ "author": "", "license": "MIT", "devDependencies": { - "@plausible-analytics/tracker": "^0.4.3", - "@sentry/browser": "^10.8.0", "@types/node": "^24.8.1", "css-loader": "^7.1.2", "date-fns": "^4.1.0", @@ -22,7 +20,6 @@ "fs-extra": "^11.3.0", "mini-css-extract-plugin": "^2.9.2", "obsidian": "1.10.2", - "reconcile-text": "^0.5.0", "resolve-url-loader": "^5.0.0", "sass": "^1.91.0", "sass-loader": "^16.0.5", @@ -33,7 +30,6 @@ "tsx": "^4.20.5", "typescript": "5.8.3", "url": "^0.11.4", - "virtual-scroller": "^1.13.1", "webpack": "^5.99.9", "webpack-cli": "^6.0.1" } diff --git a/frontend/obsidian-plugin/src/vault-link-plugin.ts b/frontend/obsidian-plugin/src/vault-link-plugin.ts index 25a03ff6..fc16aae2 100644 --- a/frontend/obsidian-plugin/src/vault-link-plugin.ts +++ b/frontend/obsidian-plugin/src/vault-link-plugin.ts @@ -11,8 +11,6 @@ import { HistoryView } from "./views/history/history-view"; import { StatusBar } from "./views/status-bar/status-bar"; import { LogsView } from "./views/logs/logs-view"; import { StatusDescription } from "./views/status-description/status-description"; -import * as Sentry from "@sentry/browser"; -import { init as plausibleInit } from "@plausible-analytics/tracker"; import { SyncClient, rateLimit, @@ -50,45 +48,6 @@ export default class VaultLinkPlugin extends Plugin { ".trash/**" ); - plausibleInit({ - domain: "vault-link", - endpoint: "https://stats.schmelczer.dev/status", - autoCapturePageviews: true, - captureOnLocalhost: true, - logging: true - }); - - Sentry.init({ - dsn: "https://56accd39d92442e788a457a04623cf57@bugs.schmelczer.dev/1", - skipBrowserExtensionCheck: false - }); - - const onError = (event: ErrorEvent): void => { - Sentry.captureException(event.error, { - extra: { - message: event.message, - filename: event.filename, - lineno: event.lineno, - colno: event.colno - } - }); - }; - window.addEventListener("error", onError); - this.disposables.push(() => { - window.removeEventListener("error", onError); - }); - - const onUnhandledRejection = (event: PromiseRejectionEvent): void => { - Sentry.captureException(event.reason); - }; - window.addEventListener("unhandledrejection", onUnhandledRejection); - this.disposables.push(() => { - window.removeEventListener( - "unhandledrejection", - onUnhandledRejection - ); - }); - const isDebugBuild = process.env.NODE_ENV === "development"; const debugOptions = isDebugBuild ? { diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 2b52eb1d..e27a36f0 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -3487,23 +3487,11 @@ "node": ">= 10.13.0" } }, - "node_modules/reconcile-text": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/reconcile-text/-/reconcile-text-0.5.0.tgz", - "integrity": "sha512-zki3lqw9Oxdhm9ZvDN17VyYoL1Isc8BEL07ILVDE2yGfNEI7thrkczoNCUr+hkFU2rzZtfxECTG0b7p61AJ6wg==", - "dev": true, - "license": "MIT" - }, "node_modules/regex-parser": { "version": "2.3.1", "dev": true, "license": "MIT" }, - "node_modules/request-animation-frame-timeout": { - "version": "2.0.4", - "dev": true, - "license": "MIT" - }, "node_modules/require-directory": { "version": "2.1.1", "dev": true, @@ -4329,14 +4317,6 @@ "resolved": "obsidian-plugin", "link": true }, - "node_modules/virtual-scroller": { - "version": "1.13.1", - "dev": true, - "license": "MIT", - "dependencies": { - "request-animation-frame-timeout": "^2.0.3" - } - }, "node_modules/w3c-keyname": { "version": "2.2.8", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", @@ -4661,8 +4641,6 @@ "version": "0.10.0", "license": "MIT", "devDependencies": { - "@plausible-analytics/tracker": "^0.4.3", - "@sentry/browser": "^10.8.0", "@types/node": "^24.8.1", "css-loader": "^7.1.2", "date-fns": "^4.1.0", @@ -4670,7 +4648,6 @@ "fs-extra": "^11.3.0", "mini-css-extract-plugin": "^2.9.2", "obsidian": "1.10.2", - "reconcile-text": "^0.5.0", "resolve-url-loader": "^5.0.0", "sass": "^1.91.0", "sass-loader": "^16.0.5", @@ -4681,7 +4658,6 @@ "tsx": "^4.20.5", "typescript": "5.8.3", "url": "^0.11.4", - "virtual-scroller": "^1.13.1", "webpack": "^5.99.9", "webpack-cli": "^6.0.1" } @@ -4696,6 +4672,8 @@ "uuid": "^13.0.0" }, "devDependencies": { + "@plausible-analytics/tracker": "^0.4.3", + "@sentry/browser": "^10.8.0", "@types/node": "^24.8.1", "ts-loader": "^9.5.2", "tslib": "2.8.1", diff --git a/frontend/sync-client/package.json b/frontend/sync-client/package.json index d35e5a3d..b26cc67d 100644 --- a/frontend/sync-client/package.json +++ b/frontend/sync-client/package.json @@ -28,6 +28,8 @@ "webpack": "^5.99.9", "webpack-cli": "^6.0.1", "webpack-merge": "^6.0.1", + "@plausible-analytics/tracker": "^0.4.3", + "@sentry/browser": "^10.8.0", "ws": "^8.18.3" } } diff --git a/frontend/sync-client/src/persistence/settings.ts b/frontend/sync-client/src/persistence/settings.ts index bd895d15..87821728 100644 --- a/frontend/sync-client/src/persistence/settings.ts +++ b/frontend/sync-client/src/persistence/settings.ts @@ -10,6 +10,7 @@ export interface SyncSettings { ignorePatterns: string[]; webSocketRetryIntervalMs: number; diffCacheSizeMB: number; + enableTelemetry: boolean; } export const DEFAULT_SETTINGS: SyncSettings = { @@ -21,7 +22,8 @@ export const DEFAULT_SETTINGS: SyncSettings = { maxFileSizeMB: 10, ignorePatterns: [], webSocketRetryIntervalMs: 3500, - diffCacheSizeMB: 4 + diffCacheSizeMB: 4, + enableTelemetry: false }; export class Settings { diff --git a/frontend/sync-client/src/sync-client.ts b/frontend/sync-client/src/sync-client.ts index 2bfc2654..9547af65 100644 --- a/frontend/sync-client/src/sync-client.ts +++ b/frontend/sync-client/src/sync-client.ts @@ -22,11 +22,13 @@ import type { CursorSpan } from "./services/types/CursorSpan"; import type { MaybeOutdatedClientCursors } from "./types/maybe-outdated-client-cursors"; import { FileChangeNotifier } from "./sync-operations/file-change-notifier"; import { FixedSizeDocumentCache } from "./utils/fix-sized-cache"; +import { setUpTelemetry } from "./utils/set-up-telemetry"; export class SyncClient { private static readonly MINIMUM_SAVE_INTERVAL_MS = 1000; private hasStartedOfflineSync = false; private hasFinishedOfflineSync = false; + private unloadTelemetry?: () => void; private constructor( private readonly history: SyncHistory, @@ -41,6 +43,10 @@ export class SyncClient { private readonly fileChangeNotifier: FileChangeNotifier, private readonly contentCache: FixedSizeDocumentCache ) { + if (settings.getSettings().enableTelemetry) { + this.unloadTelemetry = setUpTelemetry(); + } + this.settings.addOnSettingsChangeListener( async (newSettings, oldSettings) => { if (newSettings.vaultName !== oldSettings.vaultName) { @@ -62,6 +68,16 @@ export class SyncClient { newSettings.diffCacheSizeMB * 1024 * 1024 ); } + + if ( + newSettings.enableTelemetry !== oldSettings.enableTelemetry + ) { + if (newSettings.enableTelemetry) { + this.unloadTelemetry = setUpTelemetry(); + } else { + this.unloadTelemetry?.(); + } + } } ); } diff --git a/frontend/sync-client/src/utils/set-up-telemetry.ts b/frontend/sync-client/src/utils/set-up-telemetry.ts new file mode 100644 index 00000000..cf065dd6 --- /dev/null +++ b/frontend/sync-client/src/utils/set-up-telemetry.ts @@ -0,0 +1,41 @@ +import * as Sentry from "@sentry/browser"; +import { init as plausibleInit } from "@plausible-analytics/tracker"; + +export const setUpTelemetry = (): (() => void) => { + plausibleInit({ + domain: "vault-link", + endpoint: "https://stats.schmelczer.dev/status", + autoCapturePageviews: true, + captureOnLocalhost: true, + logging: true + }); + + Sentry.init({ + dsn: "https://56accd39d92442e788a457a04623cf57@bugs.schmelczer.dev/1", + skipBrowserExtensionCheck: false + }); + + const onError = (event: ErrorEvent): void => { + Sentry.captureException(event.error, { + extra: { + message: event.message, + filename: event.filename, + lineno: event.lineno, + colno: event.colno + } + }); + }; + window.addEventListener("error", onError); + + const onUnhandledRejection = (event: PromiseRejectionEvent): void => { + Sentry.captureException(event.reason); + }; + window.addEventListener("unhandledrejection", onUnhandledRejection); + + return (): void => { + window.removeEventListener("error", onError); + window.removeEventListener("unhandledrejection", onUnhandledRejection); + Sentry.close(5000); + // unloading plausible requires reloading + }; +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..9e0474fd --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "vault-link", + "lockfileVersion": 3, + "requires": true, + "packages": {} +}