using System.Text.Json; using DeepDrftModels.DTOs; using DeepDrftModels.Enums; using Microsoft.AspNetCore.Components; namespace DeepDrftPublic.Client.Services; /// /// Production (Phase 16 §2.2): serializes the play classification and fires /// it via navigator.sendBeacon to the proxied api/event/play route. Fire-and-forget by /// design — is synchronous (it is called from the player's close /// path and the unload handler, neither of which can await), so the beacon is dispatched without /// awaiting and its failure is irrelevant. No anonId is sent in wave 16.1. /// public sealed class BeaconPlayEventSink : IPlayEventSink { private readonly BeaconInterop _beacon; private readonly string _playUrl; public BeaconPlayEventSink(BeaconInterop beacon, NavigationManager navigation) { _beacon = beacon; // The WASM client posts to its own host, which proxies to DeepDrftAPI. BaseUri carries a // trailing slash; the route does not lead with one. _playUrl = $"{navigation.BaseUri}api/event/play"; } public void EmitPlay(string trackEntryKey, PlayBucket bucket) { var json = JsonSerializer.Serialize(new PlayEventDto { TrackEntryKey = trackEntryKey, Bucket = bucket, }); // Fire-and-forget: do not await. The beacon survives unload; the C# task may not, and we do not // act on the result either way. _ = _beacon.SendAsync(_playUrl, json); } }