From 4b25e36cf68febe6f67a533aa0e938f7db6966d9 Mon Sep 17 00:00:00 2001 From: Jono Date: Sat, 19 Sep 2026 07:25:44 -0700 Subject: [PATCH] Telemetry: count each sync backend once per app load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RemoteStorage re-emits "connected" for an already-connected backend during startup (Dropbox emits it twice), so sync-connect events over-counted app loads by connected users. Track providers already reported for the page load and fire once per provider, so the events read as "app loads using " — a different provider connecting later in the session still counts. Also list sync-connect-remotestorage in the documented event table, which previously only covered Dropbox and Google Drive. --- docs/TELEMETRY.md | 1 + src/utils/sync/storage.ts | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/TELEMETRY.md b/docs/TELEMETRY.md index e871b24..8ccb6d8 100644 --- a/docs/TELEMETRY.md +++ b/docs/TELEMETRY.md @@ -26,6 +26,7 @@ This is everything Savr ever sends: | `pwa-install-dismissed` | The user dismisses the PWA install prompt (Chromium only) | | `sync-connect-dropbox` | Cloud sync is connected to Dropbox | | `sync-connect-googledrive` | Cloud sync is connected to Google Drive | +| `sync-connect-remotestorage` | Cloud sync is connected to a remoteStorage provider (user@host account) | ## What is never collected diff --git a/src/utils/sync/storage.ts b/src/utils/sync/storage.ts index 18d0b2b..e097092 100644 --- a/src/utils/sync/storage.ts +++ b/src/utils/sync/storage.ts @@ -209,6 +209,13 @@ function initRemote() { // articles (e.g. from the bookmarklet flow) whose uploads haven't reached the server yet. let hasTriggeredInitialReconcile = false; + // Providers already reported to telemetry this app load. RS re-emits + // "connected" for an already-connected backend during startup (and can emit + // it more than once), so without this a single app load would log several + // sync-connect events and inflate the backend totals. One event per + // provider per page load; a different provider connecting later still counts. + const trackedSyncProviders = new Set(); + // Apply a single reconciler Op (progress is tracked by the caller). async function applyOp(op: Op): Promise { if (op.type === "fetch") { @@ -335,7 +342,11 @@ function initRemote() { console.info(`🟢 remoteStorage connected to "${remoteStorage.remote.userAddress}"`); // Anonymous telemetry: record which provider type connected, never the // account address. `backend` is "dropbox" | "googledrive" | "remotestorage". - trackSyncConnect((remoteStorage as unknown as { backend?: string }).backend || "unknown"); + const provider = (remoteStorage as unknown as { backend?: string }).backend || "unknown"; + if (!trackedSyncProviders.has(provider)) { + trackedSyncProviders.add(provider); + trackSyncConnect(provider); + } hasTriggeredInitialReconcile = false; // Reconcile is intentionally NOT triggered here. Running it immediately on "connected" // is unsafe: RS's local listing cache hasn't been refreshed from the server yet, so