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