c084efa78e
Mint a first-party localStorage anonId, thread it onto play/share beacons, persist it via EventController, and add all-time distinct-listener counts (site/track/release). Storage columns + indexes already existed from 16.1.
42 lines
1.5 KiB
C#
42 lines
1.5 KiB
C#
using Microsoft.JSInterop;
|
|
|
|
namespace DeepDrftPublic.Client.Services;
|
|
|
|
/// <summary>
|
|
/// Production <see cref="IAnonIdProvider"/> over the <c>window.DeepDrftAnonId</c> TS interop. Reads the
|
|
/// first-party <c>localStorage</c> GUID once and caches it for the session, so the synchronous emit paths
|
|
/// read it with no JS hop. Scoped (per-session) like the other telemetry collaborators; the underlying
|
|
/// token itself outlives the session in <c>localStorage</c> — the cache just avoids repeated interop.
|
|
/// </summary>
|
|
public sealed class AnonIdProvider : IAnonIdProvider
|
|
{
|
|
private readonly IJSRuntime _js;
|
|
private bool _loaded;
|
|
|
|
public AnonIdProvider(IJSRuntime js)
|
|
{
|
|
_js = js;
|
|
}
|
|
|
|
public string? Current { get; private set; }
|
|
|
|
public async ValueTask EnsureLoadedAsync()
|
|
{
|
|
if (_loaded) return;
|
|
|
|
try
|
|
{
|
|
// The module returns null when localStorage is unavailable; we store that null and still
|
|
// mark loaded so we don't retry every emit. A genuine interop failure (module not yet
|
|
// imported, prerender) is caught below and leaves _loaded false so a later warm can succeed.
|
|
Current = await _js.InvokeAsync<string?>("DeepDrftAnonId.get");
|
|
_loaded = true;
|
|
}
|
|
catch
|
|
{
|
|
// Interop unavailable (prerender / module not loaded). Leave Current null and unloaded so a
|
|
// subsequent warm retries — telemetry simply omits the id until then.
|
|
}
|
|
}
|
|
}
|