Typescript client for Driftline analytics

Make track methods fire-and-forget (non-blocking)

Track methods now return void and don't await the HTTP request,
ensuring analytics never blocks app execution.

Changed files
+35 -24
+8
CHANGELOG.md
··· 1 1 # Changelog 2 2 3 + ## [0.1.3] - 2025-11-28 4 + 5 + ### Changed 6 + 7 + - Track methods are now fire-and-forget (non-blocking) 8 + - Methods return `void` instead of `Promise<void>` 9 + - Analytics calls no longer block app execution 10 + 3 11 ## [0.1.2] - 2025-11-28 4 12 5 13 ### Added
+1 -1
deno.json
··· 1 1 { 2 2 "name": "@tijs/driftline-client", 3 - "version": "0.1.2", 3 + "version": "0.1.3", 4 4 "license": "MIT", 5 5 "exports": "./mod.ts", 6 6 "compilerOptions": {
+26 -23
mod.ts
··· 18 18 * uid, 19 19 * }); 20 20 * 21 - * // Track events 22 - * await analytics.trackAccountCreated(); 23 - * await analytics.trackView("HomeScreen"); 24 - * await analytics.trackAction("checkin_created", "CheckinScreen", { placeType: "cafe" }); 21 + * // Track events (fire-and-forget, never blocks) 22 + * analytics.trackAccountCreated(); 23 + * analytics.trackView("HomeScreen"); 24 + * analytics.trackAction("checkin_created", "CheckinScreen", { placeType: "cafe" }); 25 25 * ``` 26 26 */ 27 27 ··· 107 107 * uid, 108 108 * }); 109 109 * 110 - * await analytics.trackView("HomeScreen"); 111 - * await analytics.trackAction("button_clicked", "HomeScreen", { buttonId: "submit" }); 110 + * analytics.trackView("HomeScreen"); 111 + * analytics.trackAction("button_clicked", "HomeScreen", { buttonId: "submit" }); 112 112 * ``` 113 113 */ 114 114 export class AnalyticsClient { ··· 174 174 * Track when an account is first created/registered for this app view. 175 175 * Should only be called once per user. 176 176 * 177 + * This method is fire-and-forget and returns immediately without blocking. 178 + * 177 179 * @param props - Optional additional properties 178 180 * 179 181 * @example 180 182 * ```ts 181 - * await analytics.trackAccountCreated(); 182 - * await analytics.trackAccountCreated({ referrer: "twitter" }); 183 + * analytics.trackAccountCreated(); 184 + * analytics.trackAccountCreated({ referrer: "twitter" }); 183 185 * ``` 184 186 */ 185 - async trackAccountCreated(props?: Record<string, unknown>): Promise<void> { 187 + trackAccountCreated(props?: Record<string, unknown>): void { 186 188 const event = this.createEvent( 187 189 "account", 188 190 "account_created", 189 191 undefined, 190 192 props, 191 193 ); 192 - await this.send(event); 194 + this.send(event); 193 195 } 194 196 195 197 /** 196 198 * Track a screen/view impression. 197 199 * 200 + * This method is fire-and-forget and returns immediately without blocking. 201 + * 198 202 * @param screen - Screen or page name 199 203 * @param props - Optional additional properties 200 204 * 201 205 * @example 202 206 * ```ts 203 - * await analytics.trackView("HomeScreen"); 204 - * await analytics.trackView("ProfileScreen", { userId: "123" }); 207 + * analytics.trackView("HomeScreen"); 208 + * analytics.trackView("ProfileScreen", { userId: "123" }); 205 209 * ``` 206 210 */ 207 - async trackView( 208 - screen: string, 209 - props?: Record<string, unknown>, 210 - ): Promise<void> { 211 + trackView(screen: string, props?: Record<string, unknown>): void { 211 212 const event = this.createEvent("view", "screen_impression", screen, props); 212 - await this.send(event); 213 + this.send(event); 213 214 } 214 215 215 216 /** 216 217 * Track a user action. 218 + * 219 + * This method is fire-and-forget and returns immediately without blocking. 217 220 * 218 221 * @param name - Action name (e.g., "checkin_created", "button_clicked") 219 222 * @param screen - Optional screen where the action occurred ··· 221 224 * 222 225 * @example 223 226 * ```ts 224 - * await analytics.trackAction("checkin_created"); 225 - * await analytics.trackAction("checkin_created", "CheckinScreen"); 226 - * await analytics.trackAction("checkin_created", "CheckinScreen", { placeType: "cafe" }); 227 + * analytics.trackAction("checkin_created"); 228 + * analytics.trackAction("checkin_created", "CheckinScreen"); 229 + * analytics.trackAction("checkin_created", "CheckinScreen", { placeType: "cafe" }); 227 230 * ``` 228 231 */ 229 - async trackAction( 232 + trackAction( 230 233 name: string, 231 234 screen?: string, 232 235 props?: Record<string, unknown>, 233 - ): Promise<void> { 236 + ): void { 234 237 const event = this.createEvent("action", name, screen, props); 235 - await this.send(event); 238 + this.send(event); 236 239 } 237 240 } 238 241