@@ -2,10 +2,12 @@ import fs from "fs";
22import os from "os" ;
33import path from "path" ;
44import { apiClient } from "./apiClient.js" ;
5+ import config from "../config.js" ;
56
67const CACHE_DIR = path . join ( os . homedir ( ) , ".browserstack" , "combined_cache" ) ;
78const CACHE_FILE = path . join ( CACHE_DIR , "data.json" ) ;
89const TTL_MS = 24 * 60 * 60 * 1000 ; // 1 day
10+ const TTL_STARTED_MS = 3 * 60 * 60 * 1000 ; // 3 Hours
911
1012export enum BrowserStackProducts {
1113 LIVE = "live" ,
@@ -64,3 +66,29 @@ export async function getDevicesAndBrowsers(
6466
6567 return cache [ type ] ;
6668}
69+
70+ // Rate limiter for started event (3H)
71+ export function shouldSendStartedEvent ( ) : boolean {
72+ try {
73+ if ( config && config . REMOTE_MCP ) {
74+ return false ;
75+ }
76+ if ( ! fs . existsSync ( CACHE_DIR ) ) {
77+ fs . mkdirSync ( CACHE_DIR , { recursive : true } ) ;
78+ }
79+ let cache : Record < string , any > = { } ;
80+ if ( fs . existsSync ( CACHE_FILE ) ) {
81+ const raw = fs . readFileSync ( CACHE_FILE , "utf8" ) ;
82+ cache = JSON . parse ( raw || "{}" ) ;
83+ const last = parseInt ( cache . lastStartedEvent , 10 ) ;
84+ if ( ! isNaN ( last ) && Date . now ( ) - last < TTL_STARTED_MS ) {
85+ return false ;
86+ }
87+ }
88+ cache . lastStartedEvent = Date . now ( ) ;
89+ fs . writeFileSync ( CACHE_FILE , JSON . stringify ( cache , null , 2 ) , "utf8" ) ;
90+ return true ;
91+ } catch {
92+ return true ;
93+ }
94+ }
0 commit comments