@amplitude/analytics-core 2.50.1-featelement-selector-v1.0 → 2.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/heartbeat.d.ts +42 -0
- package/lib/cjs/heartbeat.d.ts.map +1 -0
- package/lib/cjs/heartbeat.js +189 -0
- package/lib/cjs/heartbeat.js.map +1 -0
- package/lib/cjs/index.d.ts +2 -1
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +4 -2
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/remote-config/remote-config.d.ts +20 -1
- package/lib/cjs/remote-config/remote-config.d.ts.map +1 -1
- package/lib/cjs/remote-config/remote-config.js +67 -32
- package/lib/cjs/remote-config/remote-config.js.map +1 -1
- package/lib/cjs/types/config/react-native-config.d.ts +1 -1
- package/lib/cjs/types/config/react-native-config.d.ts.map +1 -1
- package/lib/cjs/types/config/react-native-config.js.map +1 -1
- package/lib/cjs/types/event/base-event.d.ts +5 -0
- package/lib/cjs/types/event/base-event.d.ts.map +1 -1
- package/lib/cjs/types/event/base-event.js.map +1 -1
- package/lib/esm/heartbeat.d.ts +42 -0
- package/lib/esm/heartbeat.d.ts.map +1 -0
- package/lib/esm/heartbeat.js +185 -0
- package/lib/esm/heartbeat.js.map +1 -0
- package/lib/esm/index.d.ts +2 -1
- package/lib/esm/index.d.ts.map +1 -1
- package/lib/esm/index.js +2 -1
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/remote-config/remote-config.d.ts +20 -1
- package/lib/esm/remote-config/remote-config.d.ts.map +1 -1
- package/lib/esm/remote-config/remote-config.js +67 -32
- package/lib/esm/remote-config/remote-config.js.map +1 -1
- package/lib/esm/types/config/react-native-config.d.ts +1 -1
- package/lib/esm/types/config/react-native-config.d.ts.map +1 -1
- package/lib/esm/types/config/react-native-config.js.map +1 -1
- package/lib/esm/types/event/base-event.d.ts +5 -0
- package/lib/esm/types/event/base-event.d.ts.map +1 -1
- package/lib/esm/types/event/base-event.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-config.js","sourceRoot":"","sources":["../../../src/remote-config/remote-config.ts"],"names":[],"mappings":";;;;AAEA,2EAAwE;AACxE,sCAAqC;AAqBxB,QAAA,aAAa,GAAG,4CAA4C,CAAC;AAC7D,QAAA,aAAa,GAAG,+CAA+C,CAAC;AAChE,QAAA,mBAAmB,GAAG,CAAC,CAAC;AACrC,IAAM,WAAW,GAAG;IAClB,eAAe,EAAE,GAAG;IACpB,SAAS,EAAE,GAAG;IACd,UAAU,EAAE,GAAG;CACP,CAAC;AAEX;;;GAGG;AACH,IAAM,eAAe,GAAG,IAAI,CAAC;AAE7B;;;GAGG;AACH,IAAM,gCAAgC,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;AAwEpE;IAgBE,4BAAY,MAAc,EAAE,MAAe,EAAE,UAAiC,EAAE,SAAkB;QAArD,2BAAA,EAAA,iBAAiC;QAT9E,2CAA2C;QAC3C,kBAAa,GAAmB,EAAE,CAAC;QACnC,mFAAmF;QACnF,wBAAmB,GAAkB,IAAI,CAAC;QAC1C,uDAAuD;QACvD,iBAAY,GAAqC,IAAI,CAAC;QACtD,qEAAqE;QACrE,6BAAwB,GAAG,KAAK,CAAC;QAG/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,SAAS,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,qBAAa,CAAC,CAAC,CAAC,qBAAa,CAAC,CAAC;QACpF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,IAAI,qDAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9D,CAAC;IAED,sCAAS,GAAT,UAAU,GAAuB,EAAE,YAA0B,EAAE,QAA8B;QAC3F,IAAM,EAAE,GAAG,IAAA,WAAI,GAAE,CAAC;QAClB,IAAM,YAAY,GAAG;YACnB,EAAE,EAAE,EAAE;YACN,GAAG,EAAE,GAAG;YACR,YAAY,EAAE,YAAY;YAC1B,QAAQ,EAAE,QAAQ;SACnB,CAAC;QACF,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAEtC,IAAI,YAAY,KAAK,KAAK,EAAE;YAC1B,KAAK,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;SACtC;aAAM;YACL,KAAK,IAAI,CAAC,sBAAsB,CAAC,YAAY,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;SACtE;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,wCAAW,GAAX,UAAY,EAAU;QACpB,IAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,UAAC,YAAY,IAAK,OAAA,YAAY,CAAC,EAAE,KAAK,EAAE,EAAtB,CAAsB,CAAC,CAAC;QACrF,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2EAAoE,EAAE,oBAAiB,CAAC,CAAC;YAC3G,OAAO,KAAK,CAAC;SACd;QAED,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,+EAAwE,EAAE,MAAG,CAAC,CAAC;QACjG,OAAO,IAAI,CAAC;IACd,CAAC;IAEK,0CAAa,GAAnB;;;;;;;wBACE,mEAAmE;wBACnE,IAAI,IAAI,CAAC,mBAAmB,EAAE;4BACtB,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,mBAAmB,CAAC;4BACjE,IAAI,kBAAkB,GAAG,gCAAgC,EAAE;gCACzD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;gCAC7E,sBAAO;6BACR;yBACF;wBAEc,qBAAM,IAAI,CAAC,uBAAuB,EAAE,EAAA;;wBAA7C,MAAM,GAAG,SAAoC;wBACnD,KAAK,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;wBACpC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,UAAC,YAAY;4BACtC,KAAI,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;wBACpD,CAAC,CAAC,CAAC;;;;;KACJ;IAED;;;OAGG;IACH,oDAAuB,GAAvB;QAAA,iBA8BC;QA7BC,IAAI,IAAI,CAAC,YAAY,EAAE;YACrB,OAAO,IAAI,CAAC,YAAY,CAAC;SAC1B;QAED,IAAI,IAAI,CAAC,wBAAwB,EAAE;YACjC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;YAC1E,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;gBAClC,YAAY,EAAE,IAAI;gBAClB,SAAS,EAAE,IAAI,IAAI,EAAE;aACtB,CAAC,CAAC,OAAO,CAAC;gBACT,KAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YAC3B,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,YAAY,CAAC;SAC1B;QAED,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,EAAE;aAC7B,IAAI,CAAC,UAAC,MAAM;YACX,6DAA6D;YAC7D,IAAI,MAAM,CAAC,YAAY,KAAK,IAAI,EAAE;gBAChC,KAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;aACvC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;aACD,OAAO,CAAC;YACP,0DAA0D;YAC1D,KAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEL,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACG,yCAAY,GAAlB,UAAmB,YAA0B;;;;;;;wBACrC,aAAa,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC,IAAI,CAAC,UAAC,MAAM;4BAC/D,KAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0EAAmE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAE,CAAC,CAAC;4BAC/G,KAAI,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;4BAClD,KAAK,KAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;wBACtC,CAAC,CAAC,CAAC;wBAEG,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,UAAC,MAAM;4BAC1D,OAAO,MAAM,CAAC;wBAChB,CAAC,CAAC,CAAC;wBAGY,qBAAM,OAAO,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC,EAAA;;wBAA1D,MAAM,GAAG,SAAiD;wBAEhE,8CAA8C;wBAC9C,IAAI,MAAM,KAAK,SAAS,EAAE;4BACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yEAAkE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAE,CAAC,CAAC;4BAC9G,6DAA6D;4BAC7D,IAAI,MAAM,CAAC,YAAY,KAAK,IAAI,EAAE;gCAChC,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;6BAClD;iCAAM;gCACL,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uFAAuF,CAAC,CAAC;6BAC5G;yBACF;wBACD,qBAAM,aAAa,EAAA;;wBAAnB,SAAmB,CAAC;;;;;KACrB;IAED;;OAEG;IACG,mDAAsB,GAA5B,UAA6B,YAA0B,EAAE,OAAe;;;;;;wBAChE,cAAc,GAAG,IAAI,OAAO,CAAC,UAAC,CAAC,EAAE,MAAM;4BAC3C,UAAU,CAAC;gCACT,MAAM,CAAC,kBAAkB,CAAC,CAAC;4BAC7B,CAAC,EAAE,OAAO,CAAC,CAAC;wBACd,CAAC,CAAC,CAAC;;;;wBAGiC,qBAAM,OAAO,CAAC,IAAI,CAAC;gCACnD,IAAI,CAAC,uBAAuB,EAAE;gCAC9B,cAAc;6BACf,CAAC,EAAA;;wBAHI,MAAM,GAAqB,CAAC,SAGhC,CAAqB;wBAEvB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,6EAA6E,CAAC,CAAC;wBACjG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;wBAClD,KAAK,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;;;;wBAEpC,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,mGAAmG,CACpG,CAAC;wBACa,qBAAM,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAA;;wBAAzC,MAAM,GAAG,SAAgC;wBAC/C,IAAI,MAAM,CAAC,YAAY,KAAK,IAAI,EAAE;4BAChC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,+EAA+E,CAAC,CAAC;4BACnG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;yBAClD;6BAAM;4BACL,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,+EAA+E,CAAC,CAAC;4BACnG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;yBACnD;;;;;;KAEJ;IAED;;;OAGG;IACH,yCAAY,GAAZ,UAAa,YAA0B,EAAE,gBAAkC,EAAE,MAAc;QACzF,YAAY,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC;QAEvC,IAAI,cAAmC,CAAC;QACxC,IAAI,YAAY,CAAC,GAAG,EAAE;YACpB,+BAA+B;YAC/B,qDAAqD;YACrD,8CAA8C;YAC9C,0CAA0C;YAC1C,cAAc,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,UAAC,MAAM,EAAE,GAAG;gBAC9D,IAAI,MAAM,KAAK,IAAI,EAAE;oBACnB,OAAO,MAAM,CAAC;iBACf;gBAED,OAAO,GAAG,IAAI,MAAM,CAAC,CAAC,CAAE,MAAM,CAAC,GAAG,CAAkB,CAAC,CAAC,CAAC,IAAI,CAAC;YAC9D,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;SACnC;aAAM;YACL,cAAc,GAAG,gBAAgB,CAAC,YAAY,CAAC;SAChD;QAED,YAAY,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC5E,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACG,kCAAK,GAAX,UAAY,OAAqC,EAAE,OAAiC;QAAxE,wBAAA,EAAA,UAAkB,2BAAmB;QAAE,wBAAA,EAAA,yBAAiC;;;;;;;wBAC5E,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;wBAC7B,sBAAsB,GAAqB;4BAC/C,YAAY,EAAE,IAAI;4BAClB,SAAS,EAAE,IAAI,IAAI,EAAE;yBACtB,CAAC;4CAEO,OAAO;;;;;wCACV,WAAW,GAAG,IAAI,CAAC;wCAEjB,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;wCACxC,SAAS,GAAG,UAAU,CAAC,cAAM,OAAA,eAAe,CAAC,KAAK,EAAE,EAAvB,CAAuB,EAAE,OAAO,CAAC,CAAC;;;;wCAGvD,qBAAM,KAAK,CAAC,OAAK,YAAY,EAAE,EAAE;gDAC3C,MAAM,EAAE,KAAK;gDACb,OAAO,EAAE;oDACP,MAAM,EAAE,KAAK;iDACd;gDACD,MAAM,EAAE,eAAe,CAAC,MAAM;6CAC/B,CAAC,EAAA;;wCANI,GAAG,GAAG,SAMV;6CAGE,CAAC,GAAG,CAAC,EAAE,EAAP,wBAAO;wCACI,qBAAM,GAAG,CAAC,IAAI,EAAE,EAAA;;wCAAvB,IAAI,GAAG,SAAgB;wCAC7B,OAAK,MAAM,CAAC,KAAK,CAAC,qDAA8C,OAAO,0BAAgB,GAAG,CAAC,MAAM,eAAK,IAAI,CAAE,CAAC,CAAC;wCAE9G,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW,CAAC,eAAe,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW,CAAC,SAAS,EAAE;4CACtF,OAAK,MAAM,CAAC,KAAK,CACf,iDAA0C,GAAG,CAAC,MAAM,uDAAoD,CACzG,CAAC;4CACF,OAAK,wBAAwB,GAAG,IAAI,CAAC;4CACrC,WAAW,GAAG,KAAK,CAAC;yCACrB;6CAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW,CAAC,UAAU,EAAE;4CACzF,WAAW,GAAG,KAAK,CAAC;yCACrB;;4CAGmC,qBAAM,GAAG,CAAC,IAAI,EAAE,EAAA;;wCAA9C,YAAY,GAAiB,CAAC,SAAgB,CAAiB;uEAC9D;oDACL,YAAY,EAAE,YAAY;oDAC1B,SAAS,EAAE,IAAI,IAAI,EAAE;iDACtB;;;;wCAGH,iFAAiF;wCACjF,IAAI,OAAK,YAAY,KAAK,IAAI,OAAK,CAAC,IAAI,KAAK,YAAY,EAAE;4CACzD,OAAK,MAAM,CAAC,KAAK,CAAC,qDAA8C,OAAO,8BAAoB,OAAO,OAAI,CAAC,CAAC;yCACzG;6CAAM;4CACL,OAAK,MAAM,CAAC,KAAK,CAAC,qDAA8C,OAAO,2BAAwB,EAAE,OAAK,CAAC,CAAC;yCACzG;;;wCAED,sDAAsD;wCACtD,YAAY,CAAC,SAAS,CAAC,CAAC;;;wCAG1B,IAAI,CAAC,WAAW,EAAE;;yCAEjB;6CAKG,CAAA,OAAO,GAAG,OAAO,GAAG,CAAC,CAAA,EAArB,yBAAqB;wCACvB,qBAAM,IAAI,OAAO,CAAC,UAAC,OAAO,IAAK,OAAA,UAAU,CAAC,OAAO,EAAE,KAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,EAAlD,CAAkD,CAAC,EAAA;;wCAAlF,SAAkF,CAAC;;;;;;;wBAzD9E,OAAO,GAAG,CAAC;;;6BAAE,CAAA,OAAO,GAAG,OAAO,CAAA;sDAA9B,OAAO;;;;;;;;;wBAAyB,OAAO,EAAE,CAAA;;4BA6DlD,sBAAO,sBAAsB,EAAC;;;;KAC/B;IAED;;OAEG;IACH,2CAAc,GAAd,UAAe,SAAiB;QAC9B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IAC/C,CAAC;IAED,yCAAY,GAAZ;QACE,sDAAsD;QACtD,IAAM,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEtD,IAAM,SAAS,GAAG,IAAI,eAAe,EAAE,CAAC;QACxC,SAAS,CAAC,MAAM,CAAC,cAAc,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAElE,OAAO,UAAG,IAAI,CAAC,SAAS,cAAI,aAAa,cAAI,SAAS,CAAC,QAAQ,EAAE,CAAE,CAAC;IACtE,CAAC;IA9Se,+BAAY,GAAG,SAAS,CAAC;IA+S3C,yBAAC;CAAA,AAhTD,IAgTC;AAhTY,gDAAkB","sourcesContent":["import { ServerZoneType } from '../types/server-zone';\nimport { ILogger } from '../logger';\nimport { RemoteConfigLocalStorage } from './remote-config-localstorage';\nimport { UUID } from '../utils/uuid';\n\n/**\n * Modes for receiving remote config updates:\n * - `'all'` – Optimized for both speed and freshness. Returns the fastest response first\n * (cache or remote), then always waits for and returns the remote response to ensure\n * the most up-to-date config. Callback may be called once (if remote wins) or twice\n * (cache first, then remote).\n * - `{ timeout: number }` – Prefers remote data but with a fallback strategy. Waits for\n * a remote response until the specified timeout (in milliseconds), then falls back to\n * cached data if available. Callback is called exactly once.\n */\nexport type DeliveryMode = 'all' | { timeout: number };\n\n/**\n * Sources of returned remote config:\n * - `cache` - Fetched from local storage.\n * - `remote` - Fetched from remote.\n */\nexport type Source = 'cache' | 'remote';\n\nexport const US_SERVER_URL = 'https://sr-client-cfg.amplitude.com/config';\nexport const EU_SERVER_URL = 'https://sr-client-cfg.eu.amplitude.com/config';\nexport const DEFAULT_MAX_RETRIES = 3;\nconst CODE_STATUS = {\n INVALID_API_KEY: 401,\n FORBIDDEN: 403,\n RATE_LIMIT: 429,\n} as const;\n\n/**\n * The default timeout for fetch in milliseconds.\n * Linear backoff policy: timeout / retry times is the interval between fetch retry.\n */\nconst DEFAULT_TIMEOUT = 1000;\n\n/**\n * The minimum time between fetches in milliseconds.\n * This prevents too many requests from being sent in a short period of time.\n */\nconst DEFAULT_MIN_TIME_BETWEEN_FETCHES = 5 * 60 * 1000; // 5 minutes\n\nexport interface RemoteConfig {\n [key: string]: any;\n}\n\nexport interface RemoteConfigInfo {\n remoteConfig: RemoteConfig | null;\n // Timestamp of when the remote config was fetched.\n lastFetch: Date;\n}\n\nexport interface RemoteConfigStorage {\n /**\n * Fetch remote config from storage asynchronously.\n */\n fetchConfig(): Promise<RemoteConfigInfo>;\n\n /**\n * Set remote config to storage asynchronously.\n */\n setConfig(config: RemoteConfigInfo): Promise<boolean>;\n}\n\n/**\n * Information about each callback registered by `RemoteConfigClient.subscribe()`,\n * managed internally by `RemoteConfigClient`.\n */\nexport interface CallbackInfo {\n id: string;\n key?: string;\n deliveryMode: DeliveryMode;\n callback: RemoteConfigCallback;\n lastCallback?: Date;\n}\n\n/**\n * Callback used in `RemoteConfigClient.subscribe()`.\n * This function is called when the remote config is fetched.\n */\ntype RemoteConfigCallback = (remoteConfig: RemoteConfig | null, source: Source, lastFetch: Date) => void;\n\nexport interface IRemoteConfigClient {\n /**\n * Subscribe for updates to remote config.\n * Callback is guaranteed to be called at least once,\n * Whether we are able to fetch a config or not.\n *\n * @param key - a string containing a series of period delimited keys to filter the returned config.\n * Ie, {a: {b: {c: ...}}} would return {b: {c: ...}} for \"a\" or {c: ...} for \"a.b\".\n * Set to `undefined` to subscribe all keys.\n * @param deliveryMode - how the initial callback is sent.\n * @param callback - a block that will be called when remote config is fetched.\n * @return id - identification of the subscribe and can be used to unsubscribe from updates.\n */\n subscribe(key: string | undefined, deliveryMode: DeliveryMode, callback: RemoteConfigCallback): string;\n\n /**\n * Unsubscribe a callback from receiving future updates.\n *\n * @param id - identification of the callback that you want to unsubscribe.\n * It's the return value of subscribe().\n * @return boolean - whether the callback is removed.\n */\n unsubscribe(id: string): boolean;\n\n /**\n * Request the remote config client to fetch from remote, update cache, and callback.\n */\n updateConfigs(): void;\n}\n\nexport class RemoteConfigClient implements IRemoteConfigClient {\n static readonly CONFIG_GROUP = 'browser';\n\n readonly apiKey: string;\n readonly serverUrl: string;\n readonly logger: ILogger;\n readonly storage: RemoteConfigStorage;\n // Registered callbackInfos by subscribe().\n callbackInfos: CallbackInfo[] = [];\n // Track the last successful fetch time for throttling (timestamp in milliseconds).\n lastSuccessfulFetch: number | null = null;\n // Store the in-flight fetch promise for deduplication.\n fetchPromise: Promise<RemoteConfigInfo> | null = null;\n // Used to skip periodic updateConfigs calls when API key is invalid.\n isLastFetchInvalidApiKey = false;\n\n constructor(apiKey: string, logger: ILogger, serverZone: ServerZoneType = 'US', serverUrl?: string) {\n this.apiKey = apiKey;\n this.serverUrl = serverUrl || (serverZone === 'US' ? US_SERVER_URL : EU_SERVER_URL);\n this.logger = logger;\n this.storage = new RemoteConfigLocalStorage(apiKey, logger);\n }\n\n subscribe(key: string | undefined, deliveryMode: DeliveryMode, callback: RemoteConfigCallback): string {\n const id = UUID();\n const callbackInfo = {\n id: id,\n key: key,\n deliveryMode: deliveryMode,\n callback: callback,\n };\n this.callbackInfos.push(callbackInfo);\n\n if (deliveryMode === 'all') {\n void this.subscribeAll(callbackInfo);\n } else {\n void this.subscribeWaitForRemote(callbackInfo, deliveryMode.timeout);\n }\n\n return id;\n }\n\n unsubscribe(id: string): boolean {\n const index = this.callbackInfos.findIndex((callbackInfo) => callbackInfo.id === id);\n if (index === -1) {\n this.logger.debug(`Remote config client unsubscribe failed because callback with id ${id} doesn't exist.`);\n return false;\n }\n\n this.callbackInfos.splice(index, 1);\n this.logger.debug(`Remote config client unsubscribe succeeded removing callback with id ${id}.`);\n return true;\n }\n\n async updateConfigs() {\n // Check if we need to throttle based on last successful fetch time\n if (this.lastSuccessfulFetch) {\n const timeSinceLastFetch = Date.now() - this.lastSuccessfulFetch;\n if (timeSinceLastFetch < DEFAULT_MIN_TIME_BETWEEN_FETCHES) {\n this.logger.debug('Remote config client skipping updateConfigs: Too recent');\n return;\n }\n }\n\n const result = await this.getOrCreateFetchPromise();\n void this.storage.setConfig(result);\n this.callbackInfos.forEach((callbackInfo) => {\n this.sendCallback(callbackInfo, result, 'remote');\n });\n }\n\n /**\n * Get the in-flight fetch promise or create a new one.\n * This ensures multiple subscribe calls share the same network request.\n */\n getOrCreateFetchPromise(): Promise<RemoteConfigInfo> {\n if (this.fetchPromise) {\n return this.fetchPromise;\n }\n\n if (this.isLastFetchInvalidApiKey) {\n this.logger.debug('Remote config client skipping fetch: Invalid API key');\n this.fetchPromise = Promise.resolve({\n remoteConfig: null,\n lastFetch: new Date(),\n }).finally(() => {\n this.fetchPromise = null;\n });\n return this.fetchPromise;\n }\n\n this.fetchPromise = this.fetch()\n .then((result) => {\n // Update last successful fetch time if we got a valid config\n if (result.remoteConfig !== null) {\n this.lastSuccessfulFetch = Date.now();\n }\n return result;\n })\n .finally(() => {\n // Clear the promise after it settles (success or failure)\n this.fetchPromise = null;\n });\n\n return this.fetchPromise;\n }\n\n /**\n * Send remote first. If it's already complete, we can skip the cached response.\n * - if remote is fetched first, no cache fetch.\n * - if cache is fetched first, still fetching remote.\n */\n async subscribeAll(callbackInfo: CallbackInfo) {\n const remotePromise = this.getOrCreateFetchPromise().then((result) => {\n this.logger.debug(`Remote config client subscription all mode fetched from remote: ${JSON.stringify(result)}`);\n this.sendCallback(callbackInfo, result, 'remote');\n void this.storage.setConfig(result);\n });\n\n const cachePromise = this.storage.fetchConfig().then((result) => {\n return result;\n });\n\n // Wait for the first result to resolve\n const result = await Promise.race([remotePromise, cachePromise]);\n\n // If cache is fetched first, wait for remote.\n if (result !== undefined) {\n this.logger.debug(`Remote config client subscription all mode fetched from cache: ${JSON.stringify(result)}`);\n // Skip sending callback if cache is empty (first time user).\n if (result.remoteConfig !== null) {\n this.sendCallback(callbackInfo, result, 'cache');\n } else {\n this.logger.debug('Remote config client skips sending callback because cache is empty (first time user).');\n }\n }\n await remotePromise;\n }\n\n /**\n * Waits for a remote response until the given timeout, then return a cached copy, if available.\n */\n async subscribeWaitForRemote(callbackInfo: CallbackInfo, timeout: number) {\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => {\n reject('Timeout exceeded');\n }, timeout);\n });\n\n try {\n const result: RemoteConfigInfo = (await Promise.race([\n this.getOrCreateFetchPromise(),\n timeoutPromise,\n ])) as RemoteConfigInfo;\n\n this.logger.debug('Remote config client subscription wait for remote mode returns from remote.');\n this.sendCallback(callbackInfo, result, 'remote');\n void this.storage.setConfig(result);\n } catch (error) {\n this.logger.debug(\n 'Remote config client subscription wait for remote mode exceeded timeout. Try to fetch from cache.',\n );\n const result = await this.storage.fetchConfig();\n if (result.remoteConfig !== null) {\n this.logger.debug('Remote config client subscription wait for remote mode returns a cached copy.');\n this.sendCallback(callbackInfo, result, 'cache');\n } else {\n this.logger.debug('Remote config client subscription wait for remote mode failed to fetch cache.');\n this.sendCallback(callbackInfo, result, 'remote');\n }\n }\n }\n\n /**\n * Call the callback with filtered remote config based on key.\n * @param remoteConfigInfo - the whole remote config object without filtering by key.\n */\n sendCallback(callbackInfo: CallbackInfo, remoteConfigInfo: RemoteConfigInfo, source: Source) {\n callbackInfo.lastCallback = new Date();\n\n let filteredConfig: RemoteConfig | null;\n if (callbackInfo.key) {\n // Filter remote config by key.\n // For example, if remote config is {a: {b: {c: 1}}},\n // if key = 'a', filter result is {b: {c: 1}};\n // if key = 'a.b', filter result is {c: 1}\n filteredConfig = callbackInfo.key.split('.').reduce((config, key) => {\n if (config === null) {\n return config;\n }\n\n return key in config ? (config[key] as RemoteConfig) : null;\n }, remoteConfigInfo.remoteConfig);\n } else {\n filteredConfig = remoteConfigInfo.remoteConfig;\n }\n\n callbackInfo.callback(filteredConfig, source, remoteConfigInfo.lastFetch);\n }\n\n /**\n * Fetch remote config from remote.\n * @param retries - the number of retries. default is 3.\n * @param timeout - the timeout in milliseconds. Default is 1000.\n * This timeout serves two purposes:\n * 1. It determines how long to wait for each remote config fetch request before aborting it.\n * If the fetch does not complete within the specified timeout, the request is cancelled using AbortController,\n * and the attempt is considered failed (and may be retried if retries remain).\n * 2. It is also used to calculate the interval between retries. The total timeout is divided by the number of retries,\n * so each retry waits for (timeout / retries) milliseconds before the next attempt (linear backoff).\n * Retry behavior by status code:\n * - 401: invalid API key (stop retries and disable future updateConfigs calls).\n * - 429: retry up to max retries.\n * - other 4xx: no retry.\n * - 5xx and network failures: retry up to max retries.\n * @returns the remote config info. null if failed to fetch or the response is not valid JSON.\n */\n async fetch(retries: number = DEFAULT_MAX_RETRIES, timeout: number = DEFAULT_TIMEOUT): Promise<RemoteConfigInfo> {\n const interval = timeout / retries;\n const failedRemoteConfigInfo: RemoteConfigInfo = {\n remoteConfig: null,\n lastFetch: new Date(),\n };\n\n for (let attempt = 0; attempt < retries; attempt++) {\n let shouldRetry = true;\n // Create AbortController for request timeout\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => abortController.abort(), timeout);\n\n try {\n const res = await fetch(this.getUrlParams(), {\n method: 'GET',\n headers: {\n Accept: '*/*',\n },\n signal: abortController.signal,\n });\n\n // Handle unsuccessful fetch\n if (!res.ok) {\n const body = await res.text();\n this.logger.debug(`Remote config client fetch with retry time ${retries} failed with ${res.status}: ${body}`);\n\n if (res.status === CODE_STATUS.INVALID_API_KEY || res.status === CODE_STATUS.FORBIDDEN) {\n this.logger.error(\n `Remote config client fetch failed with ${res.status}. Invalid API key; future fetches will be skipped.`,\n );\n this.isLastFetchInvalidApiKey = true;\n shouldRetry = false;\n } else if (res.status >= 400 && res.status < 500 && res.status !== CODE_STATUS.RATE_LIMIT) {\n shouldRetry = false;\n }\n } else {\n // Handle successful fetch\n const remoteConfig: RemoteConfig = (await res.json()) as RemoteConfig;\n return {\n remoteConfig: remoteConfig,\n lastFetch: new Date(),\n };\n }\n } catch (error) {\n // Handle rejects when the request fails, for example, a network error or timeout\n if (error instanceof Error && error.name === 'AbortError') {\n this.logger.debug(`Remote config client fetch with retry time ${retries} timed out after ${timeout}ms`);\n } else {\n this.logger.debug(`Remote config client fetch with retry time ${retries} is rejected because: `, error);\n }\n } finally {\n // Clear the timeout since request completed or failed\n clearTimeout(timeoutId);\n }\n\n if (!shouldRetry) {\n break;\n }\n\n // Linear backoff:\n // wait for the specified interval before the next attempt\n // except after the last attempt.\n if (attempt < retries - 1) {\n await new Promise((resolve) => setTimeout(resolve, this.getJitterDelay(interval)));\n }\n }\n\n return failedRemoteConfigInfo;\n }\n\n /**\n * Return jitter in the bound of [0,baseDelay) and then floor round.\n */\n getJitterDelay(baseDelay: number): number {\n return Math.floor(Math.random() * baseDelay);\n }\n\n getUrlParams(): string {\n // URL encode the API key to handle special characters\n const encodedApiKey = encodeURIComponent(this.apiKey);\n\n const urlParams = new URLSearchParams();\n urlParams.append('config_group', RemoteConfigClient.CONFIG_GROUP);\n\n return `${this.serverUrl}/${encodedApiKey}?${urlParams.toString()}`;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"remote-config.js","sourceRoot":"","sources":["../../../src/remote-config/remote-config.ts"],"names":[],"mappings":"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","sourcesContent":["import { ServerZoneType } from '../types/server-zone';\nimport { ILogger } from '../logger';\nimport { RemoteConfigLocalStorage } from './remote-config-localstorage';\nimport { UUID } from '../utils/uuid';\n\n/**\n * Modes for receiving remote config updates:\n * - `'all'` – Optimized for both speed and freshness. Returns the fastest response first\n * (cache or remote), then always waits for and returns the remote response to ensure\n * the most up-to-date config. Callback may be called once (if remote wins) or twice\n * (cache first, then remote).\n * - `{ timeout: number }` – Prefers remote data but with a fallback strategy. Waits for\n * a remote response until the specified timeout (in milliseconds), then falls back to\n * cached data if available. Callback is called exactly once.\n */\nexport type DeliveryMode = 'all' | { timeout: number };\n\n/**\n * Sources of returned remote config:\n * - `cache` - Fetched from local storage.\n * - `remote` - Fetched from remote.\n */\nexport type Source = 'cache' | 'remote';\n\n/**\n * The fully-formed remote-config request handed to a custom transport. Consumers that need to\n * own the network call (e.g. to attach auth headers and route through a proxy) supply a\n * {@link RemoteConfigCustomFetch} via the client constructor; the client builds this request\n * (resolved URL, headers, abort signal) and the callback executes it.\n */\nexport interface RemoteConfigFetchRequest {\n url: string;\n method: 'GET';\n headers: Record<string, string>;\n /** Abort signal the client uses to enforce the fetch timeout; honor it in your fetch call. */\n signal?: AbortSignal;\n}\n\n/**\n * Custom transport for the remote-config fetch. Must return a `Response`. Retry/backoff stays\n * in the client around this callback, so it is invoked once per attempt.\n */\nexport type RemoteConfigCustomFetch = (request: RemoteConfigFetchRequest) => Promise<Response>;\n\n/**\n * Settles with `promise`, but rejects with an AbortError when `signal` fires. The request-timeout\n * signal is handed to customFetch, but a transport that ignores it would block the await (and the\n * retry loop) indefinitely; racing the abort guarantees the client-side timeout always applies.\n * The transport's own promise keeps running — we can't cancel it — we just stop awaiting it.\n */\nfunction abortableFetch(promise: Promise<Response>, signal: AbortSignal): Promise<Response> {\n return new Promise<Response>((resolve, reject) => {\n const onAbort = () => {\n // Match how a native aborted fetch rejects (name 'AbortError') so fetch()'s catch logs it\n // as a timeout; either way the loop retries since the abort doesn't clear shouldRetry.\n const err = new Error('Remote config custom fetch aborted by timeout');\n err.name = 'AbortError';\n reject(err);\n };\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n (value) => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n (err) => {\n signal.removeEventListener('abort', onAbort);\n reject(err);\n },\n );\n });\n}\n\nexport const US_SERVER_URL = 'https://sr-client-cfg.amplitude.com/config';\nexport const EU_SERVER_URL = 'https://sr-client-cfg.eu.amplitude.com/config';\nexport const DEFAULT_MAX_RETRIES = 3;\nconst CODE_STATUS = {\n INVALID_API_KEY: 401,\n FORBIDDEN: 403,\n RATE_LIMIT: 429,\n} as const;\n\n/**\n * The default timeout for fetch in milliseconds.\n * Linear backoff policy: timeout / retry times is the interval between fetch retry.\n */\nconst DEFAULT_TIMEOUT = 1000;\n\n/**\n * The minimum time between fetches in milliseconds.\n * This prevents too many requests from being sent in a short period of time.\n */\nconst DEFAULT_MIN_TIME_BETWEEN_FETCHES = 5 * 60 * 1000; // 5 minutes\n\nexport interface RemoteConfig {\n [key: string]: any;\n}\n\nexport interface RemoteConfigInfo {\n remoteConfig: RemoteConfig | null;\n // Timestamp of when the remote config was fetched.\n lastFetch: Date;\n}\n\nexport interface RemoteConfigStorage {\n /**\n * Fetch remote config from storage asynchronously.\n */\n fetchConfig(): Promise<RemoteConfigInfo>;\n\n /**\n * Set remote config to storage asynchronously.\n */\n setConfig(config: RemoteConfigInfo): Promise<boolean>;\n}\n\n/**\n * Information about each callback registered by `RemoteConfigClient.subscribe()`,\n * managed internally by `RemoteConfigClient`.\n */\nexport interface CallbackInfo {\n id: string;\n key?: string;\n deliveryMode: DeliveryMode;\n callback: RemoteConfigCallback;\n lastCallback?: Date;\n}\n\n/**\n * Callback used in `RemoteConfigClient.subscribe()`.\n * This function is called when the remote config is fetched.\n */\ntype RemoteConfigCallback = (remoteConfig: RemoteConfig | null, source: Source, lastFetch: Date) => void;\n\nexport interface IRemoteConfigClient {\n /**\n * Subscribe for updates to remote config.\n * Callback is guaranteed to be called at least once,\n * Whether we are able to fetch a config or not.\n *\n * @param key - a string containing a series of period delimited keys to filter the returned config.\n * Ie, {a: {b: {c: ...}}} would return {b: {c: ...}} for \"a\" or {c: ...} for \"a.b\".\n * Set to `undefined` to subscribe all keys.\n * @param deliveryMode - how the initial callback is sent.\n * @param callback - a block that will be called when remote config is fetched.\n * @return id - identification of the subscribe and can be used to unsubscribe from updates.\n */\n subscribe(key: string | undefined, deliveryMode: DeliveryMode, callback: RemoteConfigCallback): string;\n\n /**\n * Unsubscribe a callback from receiving future updates.\n *\n * @param id - identification of the callback that you want to unsubscribe.\n * It's the return value of subscribe().\n * @return boolean - whether the callback is removed.\n */\n unsubscribe(id: string): boolean;\n\n /**\n * Request the remote config client to fetch from remote, update cache, and callback.\n */\n updateConfigs(): void;\n}\n\nexport class RemoteConfigClient implements IRemoteConfigClient {\n static readonly CONFIG_GROUP = 'browser';\n\n readonly apiKey: string;\n readonly serverUrl: string;\n readonly logger: ILogger;\n readonly storage: RemoteConfigStorage;\n // Registered callbackInfos by subscribe().\n callbackInfos: CallbackInfo[] = [];\n // Track the last successful fetch time for throttling (timestamp in milliseconds).\n lastSuccessfulFetch: number | null = null;\n // Store the in-flight fetch promise for deduplication.\n fetchPromise: Promise<RemoteConfigInfo> | null = null;\n // Used to skip periodic updateConfigs calls when API key is invalid.\n isLastFetchInvalidApiKey = false;\n // Optional custom transport. When provided, it replaces the internal fetch for the config GET\n // (e.g. to attach auth and route through a proxy). Retry stays in the client around it.\n readonly customFetch?: RemoteConfigCustomFetch;\n\n constructor(\n apiKey: string,\n logger: ILogger,\n serverZone: ServerZoneType = 'US',\n serverUrl?: string,\n customFetch?: RemoteConfigCustomFetch,\n ) {\n this.apiKey = apiKey;\n this.serverUrl = serverUrl || (serverZone === 'US' ? US_SERVER_URL : EU_SERVER_URL);\n this.logger = logger;\n this.storage = new RemoteConfigLocalStorage(apiKey, logger);\n this.customFetch = customFetch;\n }\n\n subscribe(key: string | undefined, deliveryMode: DeliveryMode, callback: RemoteConfigCallback): string {\n const id = UUID();\n const callbackInfo = {\n id: id,\n key: key,\n deliveryMode: deliveryMode,\n callback: callback,\n };\n this.callbackInfos.push(callbackInfo);\n\n if (deliveryMode === 'all') {\n void this.subscribeAll(callbackInfo);\n } else {\n void this.subscribeWaitForRemote(callbackInfo, deliveryMode.timeout);\n }\n\n return id;\n }\n\n unsubscribe(id: string): boolean {\n const index = this.callbackInfos.findIndex((callbackInfo) => callbackInfo.id === id);\n if (index === -1) {\n this.logger.debug(`Remote config client unsubscribe failed because callback with id ${id} doesn't exist.`);\n return false;\n }\n\n this.callbackInfos.splice(index, 1);\n this.logger.debug(`Remote config client unsubscribe succeeded removing callback with id ${id}.`);\n return true;\n }\n\n async updateConfigs() {\n // Check if we need to throttle based on last successful fetch time\n if (this.lastSuccessfulFetch) {\n const timeSinceLastFetch = Date.now() - this.lastSuccessfulFetch;\n if (timeSinceLastFetch < DEFAULT_MIN_TIME_BETWEEN_FETCHES) {\n this.logger.debug('Remote config client skipping updateConfigs: Too recent');\n return;\n }\n }\n\n const result = await this.getOrCreateFetchPromise();\n void this.storage.setConfig(result);\n this.callbackInfos.forEach((callbackInfo) => {\n this.sendCallback(callbackInfo, result, 'remote');\n });\n }\n\n /**\n * Get the in-flight fetch promise or create a new one.\n * This ensures multiple subscribe calls share the same network request.\n */\n getOrCreateFetchPromise(): Promise<RemoteConfigInfo> {\n if (this.fetchPromise) {\n return this.fetchPromise;\n }\n\n if (this.isLastFetchInvalidApiKey) {\n this.logger.debug('Remote config client skipping fetch: Invalid API key');\n this.fetchPromise = Promise.resolve({\n remoteConfig: null,\n lastFetch: new Date(),\n }).finally(() => {\n this.fetchPromise = null;\n });\n return this.fetchPromise;\n }\n\n this.fetchPromise = this.fetch()\n .then((result) => {\n // Update last successful fetch time if we got a valid config\n if (result.remoteConfig !== null) {\n this.lastSuccessfulFetch = Date.now();\n }\n return result;\n })\n .finally(() => {\n // Clear the promise after it settles (success or failure)\n this.fetchPromise = null;\n });\n\n return this.fetchPromise;\n }\n\n /**\n * Send remote first. If it's already complete, we can skip the cached response.\n * - if remote is fetched first, no cache fetch.\n * - if cache is fetched first, still fetching remote.\n */\n async subscribeAll(callbackInfo: CallbackInfo) {\n const remotePromise = this.getOrCreateFetchPromise().then((result) => {\n this.logger.debug(`Remote config client subscription all mode fetched from remote: ${JSON.stringify(result)}`);\n this.sendCallback(callbackInfo, result, 'remote');\n void this.storage.setConfig(result);\n });\n\n const cachePromise = this.storage.fetchConfig().then((result) => {\n return result;\n });\n\n // Wait for the first result to resolve\n const result = await Promise.race([remotePromise, cachePromise]);\n\n // If cache is fetched first, wait for remote.\n if (result !== undefined) {\n this.logger.debug(`Remote config client subscription all mode fetched from cache: ${JSON.stringify(result)}`);\n // Skip sending callback if cache is empty (first time user).\n if (result.remoteConfig !== null) {\n this.sendCallback(callbackInfo, result, 'cache');\n } else {\n this.logger.debug('Remote config client skips sending callback because cache is empty (first time user).');\n }\n }\n await remotePromise;\n }\n\n /**\n * Waits for a remote response until the given timeout, then return a cached copy, if available.\n */\n async subscribeWaitForRemote(callbackInfo: CallbackInfo, timeout: number) {\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => {\n reject('Timeout exceeded');\n }, timeout);\n });\n\n try {\n const result: RemoteConfigInfo = (await Promise.race([\n this.getOrCreateFetchPromise(),\n timeoutPromise,\n ])) as RemoteConfigInfo;\n\n this.logger.debug('Remote config client subscription wait for remote mode returns from remote.');\n this.sendCallback(callbackInfo, result, 'remote');\n void this.storage.setConfig(result);\n } catch (error) {\n this.logger.debug(\n 'Remote config client subscription wait for remote mode exceeded timeout. Try to fetch from cache.',\n );\n const result = await this.storage.fetchConfig();\n if (result.remoteConfig !== null) {\n this.logger.debug('Remote config client subscription wait for remote mode returns a cached copy.');\n this.sendCallback(callbackInfo, result, 'cache');\n } else {\n this.logger.debug('Remote config client subscription wait for remote mode failed to fetch cache.');\n this.sendCallback(callbackInfo, result, 'remote');\n }\n }\n }\n\n /**\n * Call the callback with filtered remote config based on key.\n * @param remoteConfigInfo - the whole remote config object without filtering by key.\n */\n sendCallback(callbackInfo: CallbackInfo, remoteConfigInfo: RemoteConfigInfo, source: Source) {\n callbackInfo.lastCallback = new Date();\n\n let filteredConfig: RemoteConfig | null;\n if (callbackInfo.key) {\n // Filter remote config by key.\n // For example, if remote config is {a: {b: {c: 1}}},\n // if key = 'a', filter result is {b: {c: 1}};\n // if key = 'a.b', filter result is {c: 1}\n filteredConfig = callbackInfo.key.split('.').reduce((config, key) => {\n if (config === null) {\n return config;\n }\n\n return key in config ? (config[key] as RemoteConfig) : null;\n }, remoteConfigInfo.remoteConfig);\n } else {\n filteredConfig = remoteConfigInfo.remoteConfig;\n }\n\n callbackInfo.callback(filteredConfig, source, remoteConfigInfo.lastFetch);\n }\n\n /**\n * Fetch remote config from remote.\n * @param retries - the number of retries. default is 3.\n * @param timeout - the timeout in milliseconds. Default is 1000.\n * This timeout serves two purposes:\n * 1. It determines how long to wait for each remote config fetch request before aborting it.\n * If the fetch does not complete within the specified timeout, the request is cancelled using AbortController,\n * and the attempt is considered failed (and may be retried if retries remain).\n * 2. It is also used to calculate the interval between retries. The total timeout is divided by the number of retries,\n * so each retry waits for (timeout / retries) milliseconds before the next attempt (linear backoff).\n * Retry behavior by status code:\n * - 401: invalid API key (stop retries and disable future updateConfigs calls).\n * - 429: retry up to max retries.\n * - other 4xx: no retry.\n * - 5xx and network failures: retry up to max retries.\n * @returns the remote config info. null if failed to fetch or the response is not valid JSON.\n */\n async fetch(retries: number = DEFAULT_MAX_RETRIES, timeout: number = DEFAULT_TIMEOUT): Promise<RemoteConfigInfo> {\n const interval = timeout / retries;\n const failedRemoteConfigInfo: RemoteConfigInfo = {\n remoteConfig: null,\n lastFetch: new Date(),\n };\n\n for (let attempt = 0; attempt < retries; attempt++) {\n let shouldRetry = true;\n // Create AbortController for request timeout\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => abortController.abort(), timeout);\n\n try {\n const url = this.getUrlParams();\n const headers: Record<string, string> = { Accept: '*/*' };\n // When a custom transport is configured, hand it the fully-formed request and let it own\n // the network call; otherwise use the built-in fetch. Retry/response handling is identical.\n // The built-in fetch cancels directly on the signal; the custom transport can't be\n // cancelled, so race it against the abort (abortableFetch) to enforce the timeout even if\n // the transport ignores the signal — otherwise a hung transport would block every retry.\n const res = this.customFetch\n ? await abortableFetch(\n this.customFetch({ url, method: 'GET', headers, signal: abortController.signal }),\n abortController.signal,\n )\n : await fetch(url, {\n method: 'GET',\n headers,\n signal: abortController.signal,\n });\n\n // Treat a 2xx status as success even when `res.ok` is absent. A custom transport may return\n // a Response-like object that sets `status`/`text()`/`json()` but not `ok` (e.g. an axios\n // adapter); falling back to the status range keeps the config path consistent with the\n // event-upload path while still honoring native fetch's `ok`.\n const isSuccess = res.ok || (res.status >= 200 && res.status < 300);\n // Handle unsuccessful fetch\n if (!isSuccess) {\n const body = await res.text();\n this.logger.debug(`Remote config client fetch with retry time ${retries} failed with ${res.status}: ${body}`);\n\n if (res.status === CODE_STATUS.INVALID_API_KEY || res.status === CODE_STATUS.FORBIDDEN) {\n this.logger.error(\n `Remote config client fetch failed with ${res.status}. Invalid API key; future fetches will be skipped.`,\n );\n this.isLastFetchInvalidApiKey = true;\n shouldRetry = false;\n } else if (res.status >= 400 && res.status < 500 && res.status !== CODE_STATUS.RATE_LIMIT) {\n shouldRetry = false;\n }\n } else {\n // Handle successful fetch\n const remoteConfig: RemoteConfig = (await res.json()) as RemoteConfig;\n return {\n remoteConfig: remoteConfig,\n lastFetch: new Date(),\n };\n }\n } catch (error) {\n // Handle rejects when the request fails, for example, a network error or timeout\n if (error instanceof Error && error.name === 'AbortError') {\n this.logger.debug(`Remote config client fetch with retry time ${retries} timed out after ${timeout}ms`);\n } else {\n this.logger.debug(`Remote config client fetch with retry time ${retries} is rejected because: `, error);\n }\n } finally {\n // Clear the timeout since request completed or failed\n clearTimeout(timeoutId);\n }\n\n if (!shouldRetry) {\n break;\n }\n\n // Linear backoff:\n // wait for the specified interval before the next attempt\n // except after the last attempt.\n if (attempt < retries - 1) {\n await new Promise((resolve) => setTimeout(resolve, this.getJitterDelay(interval)));\n }\n }\n\n return failedRemoteConfigInfo;\n }\n\n /**\n * Return jitter in the bound of [0,baseDelay) and then floor round.\n */\n getJitterDelay(baseDelay: number): number {\n return Math.floor(Math.random() * baseDelay);\n }\n\n getUrlParams(): string {\n // URL encode the API key to handle special characters\n const encodedApiKey = encodeURIComponent(this.apiKey);\n\n const urlParams = new URLSearchParams();\n urlParams.append('config_group', RemoteConfigClient.CONFIG_GROUP);\n\n return `${this.serverUrl}/${encodedApiKey}?${urlParams.toString()}`;\n }\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import { Storage } from '../storage';
|
|
|
3
3
|
import { UserSession } from '../user-session';
|
|
4
4
|
type HiddenOptions = 'apiKey' | 'lastEventId';
|
|
5
5
|
export type ReactNativeOptions = Omit<Partial<ReactNativeConfig>, HiddenOptions>;
|
|
6
|
-
export interface ReactNativeConfig extends Omit<IConfig, '
|
|
6
|
+
export interface ReactNativeConfig extends Omit<IConfig, 'requestMetadata'> {
|
|
7
7
|
trackingOptions: ReactNativeTrackingOptions;
|
|
8
8
|
trackingSessionEvents?: boolean;
|
|
9
9
|
migrateLegacyData?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-native-config.d.ts","sourceRoot":"","sources":["../../../../src/types/config/react-native-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,KAAK,aAAa,GAAG,QAAQ,GAAG,aAAa,CAAC;AAE9C,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,aAAa,CAAC,CAAC;AAEjF,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"react-native-config.d.ts","sourceRoot":"","sources":["../../../../src/types/config/react-native-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,KAAK,aAAa,GAAG,QAAQ,GAAG,aAAa,CAAC;AAE9C,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,aAAa,CAAC,CAAC;AAEjF,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACzE,eAAe,EAAE,0BAA0B,CAAC;IAC5C,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,6BAA6B,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACpC,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CACpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-native-config.js","sourceRoot":"","sources":["../../../../src/types/config/react-native-config.ts"],"names":[],"mappings":"","sourcesContent":["import { IConfig } from './core-config';\nimport { Storage } from '../storage';\nimport { UserSession } from '../user-session';\n\ntype HiddenOptions = 'apiKey' | 'lastEventId';\n\nexport type ReactNativeOptions = Omit<Partial<ReactNativeConfig>, HiddenOptions>;\n\nexport interface ReactNativeConfig extends Omit<IConfig, '
|
|
1
|
+
{"version":3,"file":"react-native-config.js","sourceRoot":"","sources":["../../../../src/types/config/react-native-config.ts"],"names":[],"mappings":"","sourcesContent":["import { IConfig } from './core-config';\nimport { Storage } from '../storage';\nimport { UserSession } from '../user-session';\n\ntype HiddenOptions = 'apiKey' | 'lastEventId';\n\nexport type ReactNativeOptions = Omit<Partial<ReactNativeConfig>, HiddenOptions>;\n\nexport interface ReactNativeConfig extends Omit<IConfig, 'requestMetadata'> {\n trackingOptions: ReactNativeTrackingOptions;\n trackingSessionEvents?: boolean;\n migrateLegacyData?: boolean;\n appVersion?: string;\n attribution?: ReactNativeAttributionOptions;\n deviceId?: string;\n cookieExpiration: number;\n cookieSameSite: string;\n cookieSecure: boolean;\n cookieStorage: Storage<UserSession>;\n cookieUpgrade: boolean;\n disableCookies: boolean;\n domain: string;\n lastEventTime?: number;\n lastEventId?: number;\n partnerId?: string;\n sessionId?: number;\n sessionTimeout: number;\n userId?: string;\n}\n\nexport interface ReactNativeAttributionOptions {\n disabled?: boolean;\n excludeReferrers?: string[];\n initialEmptyValue?: string;\n trackNewCampaigns?: boolean;\n trackPageViews?: boolean;\n resetSessionOnNewCampaign?: boolean;\n}\n\nexport interface ReactNativeTrackingOptions {\n adid?: boolean;\n carrier?: boolean;\n appSetId?: boolean;\n idfv?: boolean;\n country?: boolean;\n\n deviceManufacturer?: boolean;\n deviceModel?: boolean;\n ipAddress?: boolean;\n language?: boolean;\n osName?: boolean;\n osVersion?: boolean;\n platform?: boolean;\n [key: string]: boolean | undefined;\n}\n"]}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { Plan } from './plan';
|
|
2
2
|
import { IngestionMetadataEventProperty } from './ingestion-metadata';
|
|
3
|
+
export interface Delay {
|
|
4
|
+
id: string;
|
|
5
|
+
timeout?: number;
|
|
6
|
+
}
|
|
3
7
|
export interface BaseEvent extends EventOptions {
|
|
4
8
|
event_type: string;
|
|
5
9
|
event_properties?: {
|
|
@@ -60,5 +64,6 @@ export interface EventOptions {
|
|
|
60
64
|
groups?: {
|
|
61
65
|
[key: string]: any;
|
|
62
66
|
} | undefined;
|
|
67
|
+
delay?: Delay;
|
|
63
68
|
}
|
|
64
69
|
//# sourceMappingURL=base-event.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-event.d.ts","sourceRoot":"","sources":["../../../../src/types/event/base-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,8BAA8B,EAAE,MAAM,sBAAsB,CAAC;AAEtE,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,GAAG,SAAS,CAAC;IACtD,eAAe,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,GAAG,SAAS,CAAC;IACrD,gBAAgB,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,GAAG,SAAS,CAAC;CACvD;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,kBAAkB,CAAC,EAAE,8BAA8B,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IAC/B,MAAM,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"base-event.d.ts","sourceRoot":"","sources":["../../../../src/types/event/base-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,8BAA8B,EAAE,MAAM,sBAAsB,CAAC;AAEtE,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,GAAG,SAAS,CAAC;IACtD,eAAe,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,GAAG,SAAS,CAAC;IACrD,gBAAgB,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,GAAG,SAAS,CAAC;CACvD;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,kBAAkB,CAAC,EAAE,8BAA8B,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IAC/B,MAAM,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,GAAG,SAAS,CAAC;IAC5C,KAAK,CAAC,EAAE,KAAK,CAAC;CACf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-event.js","sourceRoot":"","sources":["../../../../src/types/event/base-event.ts"],"names":[],"mappings":"","sourcesContent":["import { Plan } from './plan';\nimport { IngestionMetadataEventProperty } from './ingestion-metadata';\n\nexport interface BaseEvent extends EventOptions {\n event_type: string;\n event_properties?: { [key: string]: any } | undefined;\n user_properties?: { [key: string]: any } | undefined;\n group_properties?: { [key: string]: any } | undefined;\n}\n\nexport interface EventOptions {\n user_id?: string;\n device_id?: string;\n time?: number;\n location_lat?: number;\n location_lng?: number;\n app_version?: string;\n version_name?: string;\n library?: string;\n platform?: string;\n os_name?: string;\n os_version?: string;\n device_brand?: string;\n device_manufacturer?: string;\n device_model?: string;\n carrier?: string;\n country?: string;\n region?: string;\n city?: string;\n dma?: string;\n idfa?: string;\n idfv?: string;\n adid?: string;\n android_id?: string;\n language?: string;\n ip?: string;\n price?: number;\n quantity?: number;\n revenue?: number;\n receipt?: string;\n receiptSig?: string;\n productId?: string;\n revenueType?: string;\n currency?: string;\n event_id?: number;\n session_id?: number;\n insert_id?: string;\n plan?: Plan;\n ingestion_metadata?: IngestionMetadataEventProperty;\n partner_id?: string;\n user_agent?: string;\n android_app_set_id?: string;\n extra?: { [key: string]: any };\n groups?: { [key: string]: any } | undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"base-event.js","sourceRoot":"","sources":["../../../../src/types/event/base-event.ts"],"names":[],"mappings":"","sourcesContent":["import { Plan } from './plan';\nimport { IngestionMetadataEventProperty } from './ingestion-metadata';\n\nexport interface Delay {\n id: string;\n timeout?: number;\n}\n\nexport interface BaseEvent extends EventOptions {\n event_type: string;\n event_properties?: { [key: string]: any } | undefined;\n user_properties?: { [key: string]: any } | undefined;\n group_properties?: { [key: string]: any } | undefined;\n}\n\nexport interface EventOptions {\n user_id?: string;\n device_id?: string;\n time?: number;\n location_lat?: number;\n location_lng?: number;\n app_version?: string;\n version_name?: string;\n library?: string;\n platform?: string;\n os_name?: string;\n os_version?: string;\n device_brand?: string;\n device_manufacturer?: string;\n device_model?: string;\n carrier?: string;\n country?: string;\n region?: string;\n city?: string;\n dma?: string;\n idfa?: string;\n idfv?: string;\n adid?: string;\n android_id?: string;\n language?: string;\n ip?: string;\n price?: number;\n quantity?: number;\n revenue?: number;\n receipt?: string;\n receiptSig?: string;\n productId?: string;\n revenueType?: string;\n currency?: string;\n event_id?: number;\n session_id?: number;\n insert_id?: string;\n plan?: Plan;\n ingestion_metadata?: IngestionMetadataEventProperty;\n partner_id?: string;\n user_agent?: string;\n android_app_set_id?: string;\n extra?: { [key: string]: any };\n groups?: { [key: string]: any } | undefined;\n delay?: Delay;\n}\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ILogger } from './logger';
|
|
2
|
+
import { CoreClient } from './types/client/core-client';
|
|
3
|
+
import { BaseEvent } from './types/event/base-event';
|
|
4
|
+
import { Result } from './types/result';
|
|
5
|
+
export declare class Heartbeat {
|
|
6
|
+
private client;
|
|
7
|
+
private pulse;
|
|
8
|
+
private delayTimeout;
|
|
9
|
+
private logger?;
|
|
10
|
+
private events;
|
|
11
|
+
private delayId;
|
|
12
|
+
private interval;
|
|
13
|
+
private resetPromise;
|
|
14
|
+
constructor(client: CoreClient, pulse: number, delayTimeout: number, logger?: ILogger | undefined);
|
|
15
|
+
private heartbeat;
|
|
16
|
+
private resetHeartbeat;
|
|
17
|
+
/**
|
|
18
|
+
* An instant event is one that has no delay and gets ingested immediately
|
|
19
|
+
* @param event
|
|
20
|
+
* @returns
|
|
21
|
+
*/
|
|
22
|
+
private isInstantEvent;
|
|
23
|
+
private checkEventSizeLimit;
|
|
24
|
+
track(event: BaseEvent): Promise<Result | Error | undefined>;
|
|
25
|
+
/**
|
|
26
|
+
* Ingest an event with no delay
|
|
27
|
+
*
|
|
28
|
+
* (This is different from normal "track". It sends the events to the "/delayed" endpoint
|
|
29
|
+
* so that it can be tracked in the same payload as other events, for atomicity)
|
|
30
|
+
* @param event
|
|
31
|
+
* @returns
|
|
32
|
+
*/
|
|
33
|
+
trackNoDelay(event: BaseEvent): Promise<Error | Result | undefined>;
|
|
34
|
+
/**
|
|
35
|
+
* Update an existing event
|
|
36
|
+
* @param event
|
|
37
|
+
*/
|
|
38
|
+
update(event: BaseEvent): Promise<void>;
|
|
39
|
+
stop(): void;
|
|
40
|
+
}
|
|
41
|
+
export declare function getHeartbeatInstance(client: CoreClient, logger?: ILogger): Heartbeat;
|
|
42
|
+
//# sourceMappingURL=heartbeat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../src/heartbeat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAS,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AASxC,qBAAa,SAAS;IAOlB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,MAAM,CAAC;IATjB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,YAAY,CAAkC;gBAG5C,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,MAAM,CAAC,qBAAS;YAMZ,SAAS;YAwBT,cAAc;IAmB5B;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,mBAAmB;IAYrB,KAAK,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;IAiBlE;;;;;;;OAOG;IACG,YAAY,CAAC,KAAK,EAAE,SAAS;IAKnC;;;OAGG;IACG,MAAM,CAAC,KAAK,EAAE,SAAS;IAc7B,IAAI;CAKL;AAUD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAQpF"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { __assign, __awaiter, __generator, __read, __rest, __spreadArray, __values } from "tslib";
|
|
2
|
+
import { UUID } from './utils/uuid';
|
|
3
|
+
var EVENTS_SIZE_LIMIT = 4 * 10000; // 4KB
|
|
4
|
+
var Heartbeat = /** @class */ (function () {
|
|
5
|
+
function Heartbeat(client, pulse, delayTimeout, logger) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
this.pulse = pulse;
|
|
8
|
+
this.delayTimeout = delayTimeout;
|
|
9
|
+
this.logger = logger;
|
|
10
|
+
this.interval = null;
|
|
11
|
+
this.resetPromise = null;
|
|
12
|
+
this.events = new Map();
|
|
13
|
+
this.delayId = UUID();
|
|
14
|
+
}
|
|
15
|
+
Heartbeat.prototype.heartbeat = function () {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
17
|
+
var trackedEvents, _loop_1, this_1, _a, _b, event_1;
|
|
18
|
+
var e_1, _c;
|
|
19
|
+
var _this = this;
|
|
20
|
+
return __generator(this, function (_d) {
|
|
21
|
+
switch (_d.label) {
|
|
22
|
+
case 0:
|
|
23
|
+
// stop sending heartbeats if no events are queued
|
|
24
|
+
if (this.events.size === 0) {
|
|
25
|
+
this.stop();
|
|
26
|
+
return [2 /*return*/, []];
|
|
27
|
+
}
|
|
28
|
+
trackedEvents = [];
|
|
29
|
+
_loop_1 = function (event_1) {
|
|
30
|
+
var event_type = event_1.event_type, event_properties = event_1.event_properties, eventOptions = __rest(event_1, ["event_type", "event_properties"]);
|
|
31
|
+
var eventPromise = this_1.client.track(event_type, event_properties, eventOptions).promise;
|
|
32
|
+
// if the event has no timeout, then it's instant ingested and we can
|
|
33
|
+
// delete it after it was ingested
|
|
34
|
+
if (this_1.isInstantEvent(event_1)) {
|
|
35
|
+
var insertId_1 = event_1.insert_id;
|
|
36
|
+
void eventPromise.finally(function () { return _this.events.delete(insertId_1); });
|
|
37
|
+
}
|
|
38
|
+
trackedEvents.push(eventPromise);
|
|
39
|
+
};
|
|
40
|
+
this_1 = this;
|
|
41
|
+
try {
|
|
42
|
+
for (_a = __values(this.events.values()), _b = _a.next(); !_b.done; _b = _a.next()) {
|
|
43
|
+
event_1 = _b.value;
|
|
44
|
+
_loop_1(event_1);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
48
|
+
finally {
|
|
49
|
+
try {
|
|
50
|
+
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
51
|
+
}
|
|
52
|
+
finally { if (e_1) throw e_1.error; }
|
|
53
|
+
}
|
|
54
|
+
return [4 /*yield*/, Promise.all(trackedEvents)];
|
|
55
|
+
case 1: return [2 /*return*/, _d.sent()];
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
Heartbeat.prototype.resetHeartbeat = function () {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
62
|
+
var _this = this;
|
|
63
|
+
return __generator(this, function (_a) {
|
|
64
|
+
switch (_a.label) {
|
|
65
|
+
case 0:
|
|
66
|
+
if (!this.resetPromise) return [3 /*break*/, 2];
|
|
67
|
+
return [4 /*yield*/, this.resetPromise];
|
|
68
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
69
|
+
case 2:
|
|
70
|
+
// reset the heartbeat interval
|
|
71
|
+
if (this.interval)
|
|
72
|
+
clearInterval(this.interval);
|
|
73
|
+
this.interval = setInterval(function () { return void _this.heartbeat(); }, this.pulse);
|
|
74
|
+
// invoke heartbeat on the next macrotask tick
|
|
75
|
+
this.resetPromise = new Promise(function (resolve) {
|
|
76
|
+
setTimeout(function () {
|
|
77
|
+
resolve(_this.heartbeat());
|
|
78
|
+
}, 0);
|
|
79
|
+
});
|
|
80
|
+
this.resetPromise.finally(function () { return (_this.resetPromise = null); });
|
|
81
|
+
return [4 /*yield*/, this.resetPromise];
|
|
82
|
+
case 3: return [2 /*return*/, _a.sent()];
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* An instant event is one that has no delay and gets ingested immediately
|
|
89
|
+
* @param event
|
|
90
|
+
* @returns
|
|
91
|
+
*/
|
|
92
|
+
Heartbeat.prototype.isInstantEvent = function (event) {
|
|
93
|
+
return Boolean(event.insert_id && !event.delay.timeout);
|
|
94
|
+
};
|
|
95
|
+
Heartbeat.prototype.checkEventSizeLimit = function (event) {
|
|
96
|
+
var _a;
|
|
97
|
+
if (JSON.stringify(__spreadArray([], __read(this.events.values()), false)).length > EVENTS_SIZE_LIMIT) {
|
|
98
|
+
/* istanbul ignore next */
|
|
99
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn("Heartbeat: events size limit reached, rejecting event with id=".concat(event.insert_id));
|
|
100
|
+
if (event.insert_id) {
|
|
101
|
+
this.events.delete(event.insert_id);
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
return true;
|
|
106
|
+
};
|
|
107
|
+
Heartbeat.prototype.track = function (event) {
|
|
108
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
109
|
+
var heartbeatResult;
|
|
110
|
+
return __generator(this, function (_a) {
|
|
111
|
+
switch (_a.label) {
|
|
112
|
+
case 0:
|
|
113
|
+
if (!event.insert_id) {
|
|
114
|
+
return [2 /*return*/, new Error('insert_id is required on events tracked with heartbeat')];
|
|
115
|
+
}
|
|
116
|
+
this.events.set(event.insert_id, __assign(__assign({}, event), { delay: event.delay || { id: this.delayId, timeout: this.delayTimeout } }));
|
|
117
|
+
if (!this.checkEventSizeLimit(event)) {
|
|
118
|
+
return [2 /*return*/];
|
|
119
|
+
}
|
|
120
|
+
return [4 /*yield*/, this.resetHeartbeat()];
|
|
121
|
+
case 1:
|
|
122
|
+
heartbeatResult = _a.sent();
|
|
123
|
+
return [2 /*return*/, heartbeatResult.find(function (result) { return result.event.insert_id === event.insert_id; })];
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Ingest an event with no delay
|
|
130
|
+
*
|
|
131
|
+
* (This is different from normal "track". It sends the events to the "/delayed" endpoint
|
|
132
|
+
* so that it can be tracked in the same payload as other events, for atomicity)
|
|
133
|
+
* @param event
|
|
134
|
+
* @returns
|
|
135
|
+
*/
|
|
136
|
+
Heartbeat.prototype.trackNoDelay = function (event) {
|
|
137
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
138
|
+
return __generator(this, function (_a) {
|
|
139
|
+
event.delay = { id: this.delayId };
|
|
140
|
+
return [2 /*return*/, this.track(event)];
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Update an existing event
|
|
146
|
+
* @param event
|
|
147
|
+
*/
|
|
148
|
+
Heartbeat.prototype.update = function (event) {
|
|
149
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
150
|
+
var backupEvent;
|
|
151
|
+
return __generator(this, function (_a) {
|
|
152
|
+
if (event.insert_id && this.events.has(event.insert_id)) {
|
|
153
|
+
backupEvent = this.events.get(event.insert_id);
|
|
154
|
+
this.events.set(event.insert_id, __assign(__assign({}, event), { delay: { id: this.delayId, timeout: this.delayTimeout } }));
|
|
155
|
+
if (!this.checkEventSizeLimit(event) && backupEvent) {
|
|
156
|
+
this.events.set(event.insert_id, backupEvent);
|
|
157
|
+
return [2 /*return*/];
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return [2 /*return*/];
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
Heartbeat.prototype.stop = function () {
|
|
165
|
+
this.interval && clearInterval(this.interval);
|
|
166
|
+
this.interval = null;
|
|
167
|
+
this.events.clear();
|
|
168
|
+
};
|
|
169
|
+
return Heartbeat;
|
|
170
|
+
}());
|
|
171
|
+
export { Heartbeat };
|
|
172
|
+
var DEFAULT_HEARTBEAT_INTERVAL = 60000;
|
|
173
|
+
// const DEFAULT_HEARTBEAT_INTERVAL = 2_000; // TODO: DO NOT MERGE THIS
|
|
174
|
+
var DEFAULT_HEARTBEAT_DELAY_TIMEOUT = 3600000;
|
|
175
|
+
var heartbeatMap = new Map();
|
|
176
|
+
export function getHeartbeatInstance(client, logger) {
|
|
177
|
+
var existing = heartbeatMap.get(client);
|
|
178
|
+
if (existing) {
|
|
179
|
+
return existing;
|
|
180
|
+
}
|
|
181
|
+
var heartbeat = new Heartbeat(client, DEFAULT_HEARTBEAT_INTERVAL, DEFAULT_HEARTBEAT_DELAY_TIMEOUT, logger);
|
|
182
|
+
heartbeatMap.set(client, heartbeat);
|
|
183
|
+
return heartbeat;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=heartbeat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../src/heartbeat.ts"],"names":[],"mappings":"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","sourcesContent":["import { ILogger } from './logger';\nimport { CoreClient } from './types/client/core-client';\nimport { BaseEvent, Delay } from './types/event/base-event';\nimport { Result } from './types/result';\nimport { UUID } from './utils/uuid';\n\ntype DelayedEvent = BaseEvent & {\n delay: Delay;\n};\n\nconst EVENTS_SIZE_LIMIT = 4 * 10_000; // 4KB\n\nexport class Heartbeat {\n private events: Map<string, DelayedEvent>;\n private delayId: string;\n private interval: NodeJS.Timeout | null = null;\n private resetPromise: Promise<Result[]> | null = null;\n\n constructor(\n private client: CoreClient,\n private pulse: number,\n private delayTimeout: number,\n private logger?: ILogger,\n ) {\n this.events = new Map<string, DelayedEvent>();\n this.delayId = UUID();\n }\n\n private async heartbeat(): Promise<Result[]> {\n // stop sending heartbeats if no events are queued\n if (this.events.size === 0) {\n this.stop();\n return [];\n }\n\n // track all of the delayed events\n const trackedEvents = [];\n for (const event of this.events.values()) {\n const { event_type, event_properties, ...eventOptions } = event;\n const eventPromise = this.client.track(event_type, event_properties, eventOptions).promise;\n\n // if the event has no timeout, then it's instant ingested and we can\n // delete it after it was ingested\n if (this.isInstantEvent(event)) {\n const insertId = event.insert_id;\n void eventPromise.finally(() => this.events.delete(insertId));\n }\n trackedEvents.push(eventPromise);\n }\n return await Promise.all(trackedEvents);\n }\n\n private async resetHeartbeat() {\n // if a reset is already in progress, return the existing promise\n if (this.resetPromise) return await this.resetPromise;\n\n // reset the heartbeat interval\n if (this.interval) clearInterval(this.interval);\n this.interval = setInterval(() => void this.heartbeat(), this.pulse);\n\n // invoke heartbeat on the next macrotask tick\n this.resetPromise = new Promise((resolve) => {\n setTimeout(() => {\n resolve(this.heartbeat());\n }, 0);\n });\n this.resetPromise.finally(() => (this.resetPromise = null));\n\n return await this.resetPromise;\n }\n\n /**\n * An instant event is one that has no delay and gets ingested immediately\n * @param event\n * @returns\n */\n private isInstantEvent(event: DelayedEvent): event is DelayedEvent & { insert_id: string } {\n return Boolean(event.insert_id && !event.delay.timeout);\n }\n\n private checkEventSizeLimit(event: BaseEvent) {\n if (JSON.stringify([...this.events.values()]).length > EVENTS_SIZE_LIMIT) {\n /* istanbul ignore next */\n this.logger?.warn(`Heartbeat: events size limit reached, rejecting event with id=${event.insert_id!}`);\n if (event.insert_id) {\n this.events.delete(event.insert_id);\n }\n return false;\n }\n return true;\n }\n\n async track(event: BaseEvent): Promise<Result | Error | undefined> {\n if (!event.insert_id) {\n return new Error('insert_id is required on events tracked with heartbeat');\n }\n this.events.set(event.insert_id, {\n ...event,\n delay: event.delay || { id: this.delayId, timeout: this.delayTimeout },\n });\n if (!this.checkEventSizeLimit(event)) {\n return;\n }\n\n // emit a heartbeat, restart interval and return the result\n const heartbeatResult = await this.resetHeartbeat();\n return heartbeatResult.find((result) => result.event.insert_id === event.insert_id);\n }\n\n /**\n * Ingest an event with no delay\n *\n * (This is different from normal \"track\". It sends the events to the \"/delayed\" endpoint\n * so that it can be tracked in the same payload as other events, for atomicity)\n * @param event\n * @returns\n */\n async trackNoDelay(event: BaseEvent) {\n event.delay = { id: this.delayId };\n return this.track(event);\n }\n\n /**\n * Update an existing event\n * @param event\n */\n async update(event: BaseEvent) {\n if (event.insert_id && this.events.has(event.insert_id)) {\n const backupEvent = this.events.get(event.insert_id);\n this.events.set(event.insert_id, {\n ...event,\n delay: { id: this.delayId, timeout: this.delayTimeout },\n });\n if (!this.checkEventSizeLimit(event) && backupEvent) {\n this.events.set(event.insert_id, backupEvent);\n return;\n }\n }\n }\n\n stop() {\n this.interval && clearInterval(this.interval);\n this.interval = null;\n this.events.clear();\n }\n}\n\nconst DEFAULT_HEARTBEAT_INTERVAL = 60_000;\n// const DEFAULT_HEARTBEAT_INTERVAL = 2_000; // TODO: DO NOT MERGE THIS\nconst DEFAULT_HEARTBEAT_DELAY_TIMEOUT = 3_600_000;\n\ntype HeartbeatMap = Map<CoreClient, Heartbeat>;\n\nconst heartbeatMap: HeartbeatMap = new Map<CoreClient, Heartbeat>();\n\nexport function getHeartbeatInstance(client: CoreClient, logger?: ILogger): Heartbeat {\n const existing = heartbeatMap.get(client);\n if (existing) {\n return existing;\n }\n const heartbeat = new Heartbeat(client, DEFAULT_HEARTBEAT_INTERVAL, DEFAULT_HEARTBEAT_DELAY_TIMEOUT, logger);\n heartbeatMap.set(client, heartbeat);\n return heartbeat;\n}\n"]}
|
package/lib/esm/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { AmplitudeContext } from './types/amplitude-context';
|
|
|
5
5
|
export { Identify, IIdentify, ValidPropertyType } from './identify';
|
|
6
6
|
export { Revenue, IRevenue, RevenueProperty } from './revenue';
|
|
7
7
|
export { Destination } from './plugins/destination';
|
|
8
|
+
export { getHeartbeatInstance } from './heartbeat';
|
|
8
9
|
export { IdentityEventSender } from './plugins/identity';
|
|
9
10
|
export { Config, RequestMetadata } from './config';
|
|
10
11
|
export { IConfig } from './types/config/core-config';
|
|
@@ -31,7 +32,7 @@ export { registerSdkLoaderMetadata } from './diagnostics/uncaught-sdk-errors';
|
|
|
31
32
|
export { BaseTransport } from './transports/base';
|
|
32
33
|
export { FetchTransport } from './transports/fetch';
|
|
33
34
|
export { compressToGzipArrayBuffer, isCompressionStreamAvailable, MIN_GZIP_UPLOAD_BODY_SIZE_BYTES, } from './transports/gzip';
|
|
34
|
-
export { RemoteConfigClient, IRemoteConfigClient, RemoteConfig, Source } from './remote-config/remote-config';
|
|
35
|
+
export { RemoteConfigClient, IRemoteConfigClient, RemoteConfig, Source, RemoteConfigFetchRequest, RemoteConfigCustomFetch, } from './remote-config/remote-config';
|
|
35
36
|
export { LogLevel } from './types/loglevel';
|
|
36
37
|
export { AMPLITUDE_PREFIX, STORAGE_PREFIX } from './types/constants';
|
|
37
38
|
export { Storage, IdentityStorageType, CookieStorageConfig } from './types/storage';
|
package/lib/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACzF,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAE9E,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EACL,yBAAyB,EACzB,4BAA4B,EAC5B,+BAA+B,GAChC,MAAM,mBAAmB,CAAC;AAE3B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/esm/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export { AmplitudeCore } from './core-client';
|
|
|
2
2
|
export { Identify } from './identify';
|
|
3
3
|
export { Revenue, RevenueProperty } from './revenue';
|
|
4
4
|
export { Destination } from './plugins/destination';
|
|
5
|
+
export { getHeartbeatInstance } from './heartbeat';
|
|
5
6
|
export { IdentityEventSender } from './plugins/identity';
|
|
6
7
|
export { Config, RequestMetadata } from './config';
|
|
7
8
|
export { Logger } from './logger';
|
|
@@ -27,7 +28,7 @@ export { registerSdkLoaderMetadata } from './diagnostics/uncaught-sdk-errors';
|
|
|
27
28
|
export { BaseTransport } from './transports/base';
|
|
28
29
|
export { FetchTransport } from './transports/fetch';
|
|
29
30
|
export { compressToGzipArrayBuffer, isCompressionStreamAvailable, MIN_GZIP_UPLOAD_BODY_SIZE_BYTES, } from './transports/gzip';
|
|
30
|
-
export { RemoteConfigClient } from './remote-config/remote-config';
|
|
31
|
+
export { RemoteConfigClient, } from './remote-config/remote-config';
|
|
31
32
|
export { LogLevel } from './types/loglevel';
|
|
32
33
|
export { AMPLITUDE_PREFIX, STORAGE_PREFIX } from './types/constants';
|
|
33
34
|
export { consoleObserver } from './observers/console';
|
package/lib/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export { AmplitudeCore } from './core-client';\nexport { CoreClient, PluginHost } from './types/client/core-client';\nexport { AnalyticsClient } from './types/client/analytics-client';\nexport { AmplitudeContext } from './types/amplitude-context';\nexport { Identify, IIdentify, ValidPropertyType } from './identify';\nexport { Revenue, IRevenue, RevenueProperty } from './revenue';\nexport { Destination } from './plugins/destination';\nexport { IdentityEventSender } from './plugins/identity';\nexport { Config, RequestMetadata } from './config';\nexport { IConfig } from './types/config/core-config';\nexport { Logger, ILogger, LogConfig } from './logger';\nexport { getGlobalScope } from './global-scope';\nexport { getAnalyticsConnector, setConnectorDeviceId, setConnectorUserId } from './analytics-connector';\nexport { isNewSession } from './session';\nexport { getCookieName, getOldCookieName } from './cookie-name';\nexport { getLanguage } from './language';\nexport { getQueryParams } from './query-params';\n\nexport { returnWrapper, AmplitudeReturn } from './utils/return-wrapper';\nexport { debugWrapper, getClientLogConfig, getClientStates } from './utils/debug';\nexport { UUID } from './utils/uuid';\nexport { createIdentifyEvent } from './utils/event-builder';\nexport { isUrlMatchAllowlist, getDecodeURI } from './utils/url-utils';\nexport { generateHashCode, isTimestampInSample } from './utils/sampling';\nexport { omitUndefined } from './utils/omit-undefined';\n\nexport { MemoryStorage } from './storage/memory';\nexport { CookieStorage, isDomainEqual, decodeCookieValue } from './storage/cookie';\nexport { getStorageKey } from './storage/helpers';\n\nexport { BrowserStorage } from './storage/browser-storage';\n\nexport { DiagnosticsClient, IDiagnosticsClient } from './diagnostics/diagnostics-client';\nexport { registerSdkLoaderMetadata } from './diagnostics/uncaught-sdk-errors';\n\nexport { BaseTransport } from './transports/base';\nexport { FetchTransport } from './transports/fetch';\nexport {\n compressToGzipArrayBuffer,\n isCompressionStreamAvailable,\n MIN_GZIP_UPLOAD_BODY_SIZE_BYTES,\n} from './transports/gzip';\n\nexport { RemoteConfigClient, IRemoteConfigClient, RemoteConfig, Source } from './remote-config/remote-config';\n\nexport { LogLevel } from './types/loglevel';\nexport { AMPLITUDE_PREFIX, STORAGE_PREFIX } from './types/constants';\nexport { Storage, IdentityStorageType, CookieStorageConfig } from './types/storage';\nexport { consoleObserver } from './observers/console';\nexport {\n Event,\n IdentifyOperation,\n SpecialEventType,\n IdentifyEvent,\n GroupIdentifyEvent,\n IdentifyUserProperties,\n} from './types/event/event';\nexport { EventOptions, BaseEvent } from './types/event/base-event';\nexport { IngestionMetadata } from './types/event/ingestion-metadata';\nexport { ServerZoneType, ServerZone } from './types/server-zone';\nexport { OfflineDisabled } from './types/offline';\nexport { Plan } from './types/event/plan';\nexport { TransportType, Transport, TransportOptions, TransportTypeOrOptions } from './types/transport';\nexport { Payload } from './types/payload';\nexport { Response } from './types/response';\nexport { UserSession } from './types/user-session';\nexport {\n Plugin,\n BeforePlugin,\n DestinationPlugin,\n EnrichmentPlugin,\n PluginType,\n AnalyticsIdentity,\n} from './types/plugin';\nexport { Result } from './types/result';\nexport {\n ElementInteractionsOptions,\n Messenger,\n ActionType,\n DEFAULT_CSS_SELECTOR_ALLOWLIST,\n DEFAULT_DATA_ATTRIBUTE_PREFIX,\n DEFAULT_ACTION_CLICK_ALLOWLIST,\n DEFAULT_EXPOSURE_DURATION,\n LabeledEvent,\n Trigger,\n DataSource,\n} from './types/element-interactions';\n\nexport {\n FrustrationInteractionsOptions,\n DEFAULT_DEAD_CLICK_ALLOWLIST,\n DEFAULT_RAGE_CLICK_ALLOWLIST,\n DEFAULT_ERROR_CLICK_ALLOWLIST,\n DEFAULT_RAGE_CLICK_THRESHOLD,\n DEFAULT_RAGE_CLICK_WINDOW_MS,\n DEFAULT_RAGE_CLICK_OUT_OF_BOUNDS_THRESHOLD,\n DEFAULT_DEAD_CLICK_WINDOW_MS,\n} from './types/frustration-interactions';\nexport { PageTrackingOptions, PageTrackingTrackOn, PageTrackingHistoryChanges } from './types/page-view-tracking';\nexport { FormInteractionsOptions } from './types/form-interactions';\nexport { Status } from './types/status';\n\nexport { NetworkEventCallback, networkObserver } from './observers/network';\nexport { NetworkRequestEvent, IRequestWrapper, JsonObject, JsonValue, JsonArray } from './network-request-event';\nexport { NetworkTrackingOptions, NetworkCaptureRule } from './types/network-tracking';\nexport { SAFE_HEADERS, FORBIDDEN_HEADERS } from './types/constants';\n\nexport { PageUrlEnrichmentOptions } from './types/page-url-enrichment';\nexport { CustomEnrichmentOptions } from './types/custom-enrichment';\nexport { PerformanceTrackingOptions, MainThreadBlockOptions } from './types/performance-tracking';\n\n// Campaign\nexport { Campaign, UTMParameters, ReferrerParameters, ClickIdParameters, ICampaignParser } from './types/campaign';\nexport { EMPTY_VALUE, BASE_CAMPAIGN, MKTG } from './types/constants';\nexport { CampaignParser } from './campaign/campaign-parser';\nexport {\n getPageTitle,\n TEXT_MASK_ATTRIBUTE,\n MASKED_TEXT_VALUE,\n replaceSensitiveString,\n CC_REGEX,\n SSN_REGEX,\n EMAIL_REGEX,\n} from './plugins/helpers';\n\n// Browser\nexport {\n BrowserConfig,\n BrowserOptions,\n DefaultTrackingOptions,\n TrackingOptions,\n TrackingMethod,\n AutocaptureOptions,\n CookieOptions,\n AttributionOptions,\n RemoteConfigOptions,\n} from './types/config/browser-config';\nexport { BrowserClient } from './types/client/browser-client';\n\n// Node\nexport { NodeClient } from './types/client/node-client';\nexport { NodeConfig, NodeOptions } from './types/config/node-config';\n\n// React Native\nexport {\n ReactNativeConfig,\n ReactNativeTrackingOptions,\n ReactNativeOptions,\n ReactNativeAttributionOptions,\n} from './types/config/react-native-config';\nexport { ReactNativeClient } from './types/client/react-native-client';\n\nexport { Observable, asyncMap, merge, multicast, Unsubscribable } from './utils/observable';\n\nexport { InstanceProxy } from './types/proxy';\nexport { safeJsonStringify } from './utils/safe-stringify';\n\n// Messenger (cross-window communication)\nexport type { BaseWindowMessenger, ActionHandler } from './messenger/base-window-messenger';\nexport { getOrCreateWindowMessenger } from './messenger/base-window-messenger';\nexport { enableBackgroundCapture } from './messenger/background-capture';\nexport {\n AMPLITUDE_ORIGIN,\n AMPLITUDE_ORIGIN_EU,\n AMPLITUDE_ORIGIN_STAGING,\n AMPLITUDE_ORIGINS_MAP,\n AMPLITUDE_BACKGROUND_CAPTURE_SCRIPT_URL,\n} from './messenger/constants';\n\nexport { ExcludeInternalReferrersOptions, EXCLUDE_INTERNAL_REFERRERS_CONDITIONS } from './types/config/browser-config';\n\nexport { VideoObserver, State as VideoState, type VideoObserverParams } from './observers/video';\nexport { EmbeddedVideoPlayer, type Vendor as VideoVendor } from './video-analytics/types';\nexport { isChromeExtension } from './utils/environment';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export { AmplitudeCore } from './core-client';\nexport { CoreClient, PluginHost } from './types/client/core-client';\nexport { AnalyticsClient } from './types/client/analytics-client';\nexport { AmplitudeContext } from './types/amplitude-context';\nexport { Identify, IIdentify, ValidPropertyType } from './identify';\nexport { Revenue, IRevenue, RevenueProperty } from './revenue';\nexport { Destination } from './plugins/destination';\nexport { getHeartbeatInstance } from './heartbeat';\nexport { IdentityEventSender } from './plugins/identity';\nexport { Config, RequestMetadata } from './config';\nexport { IConfig } from './types/config/core-config';\nexport { Logger, ILogger, LogConfig } from './logger';\nexport { getGlobalScope } from './global-scope';\nexport { getAnalyticsConnector, setConnectorDeviceId, setConnectorUserId } from './analytics-connector';\nexport { isNewSession } from './session';\nexport { getCookieName, getOldCookieName } from './cookie-name';\nexport { getLanguage } from './language';\nexport { getQueryParams } from './query-params';\n\nexport { returnWrapper, AmplitudeReturn } from './utils/return-wrapper';\nexport { debugWrapper, getClientLogConfig, getClientStates } from './utils/debug';\nexport { UUID } from './utils/uuid';\nexport { createIdentifyEvent } from './utils/event-builder';\nexport { isUrlMatchAllowlist, getDecodeURI } from './utils/url-utils';\nexport { generateHashCode, isTimestampInSample } from './utils/sampling';\nexport { omitUndefined } from './utils/omit-undefined';\n\nexport { MemoryStorage } from './storage/memory';\nexport { CookieStorage, isDomainEqual, decodeCookieValue } from './storage/cookie';\nexport { getStorageKey } from './storage/helpers';\n\nexport { BrowserStorage } from './storage/browser-storage';\n\nexport { DiagnosticsClient, IDiagnosticsClient } from './diagnostics/diagnostics-client';\nexport { registerSdkLoaderMetadata } from './diagnostics/uncaught-sdk-errors';\n\nexport { BaseTransport } from './transports/base';\nexport { FetchTransport } from './transports/fetch';\nexport {\n compressToGzipArrayBuffer,\n isCompressionStreamAvailable,\n MIN_GZIP_UPLOAD_BODY_SIZE_BYTES,\n} from './transports/gzip';\n\nexport {\n RemoteConfigClient,\n IRemoteConfigClient,\n RemoteConfig,\n Source,\n RemoteConfigFetchRequest,\n RemoteConfigCustomFetch,\n} from './remote-config/remote-config';\n\nexport { LogLevel } from './types/loglevel';\nexport { AMPLITUDE_PREFIX, STORAGE_PREFIX } from './types/constants';\nexport { Storage, IdentityStorageType, CookieStorageConfig } from './types/storage';\nexport { consoleObserver } from './observers/console';\nexport {\n Event,\n IdentifyOperation,\n SpecialEventType,\n IdentifyEvent,\n GroupIdentifyEvent,\n IdentifyUserProperties,\n} from './types/event/event';\nexport { EventOptions, BaseEvent } from './types/event/base-event';\nexport { IngestionMetadata } from './types/event/ingestion-metadata';\nexport { ServerZoneType, ServerZone } from './types/server-zone';\nexport { OfflineDisabled } from './types/offline';\nexport { Plan } from './types/event/plan';\nexport { TransportType, Transport, TransportOptions, TransportTypeOrOptions } from './types/transport';\nexport { Payload } from './types/payload';\nexport { Response } from './types/response';\nexport { UserSession } from './types/user-session';\nexport {\n Plugin,\n BeforePlugin,\n DestinationPlugin,\n EnrichmentPlugin,\n PluginType,\n AnalyticsIdentity,\n} from './types/plugin';\nexport { Result } from './types/result';\nexport {\n ElementInteractionsOptions,\n Messenger,\n ActionType,\n DEFAULT_CSS_SELECTOR_ALLOWLIST,\n DEFAULT_DATA_ATTRIBUTE_PREFIX,\n DEFAULT_ACTION_CLICK_ALLOWLIST,\n DEFAULT_EXPOSURE_DURATION,\n LabeledEvent,\n Trigger,\n DataSource,\n} from './types/element-interactions';\n\nexport {\n FrustrationInteractionsOptions,\n DEFAULT_DEAD_CLICK_ALLOWLIST,\n DEFAULT_RAGE_CLICK_ALLOWLIST,\n DEFAULT_ERROR_CLICK_ALLOWLIST,\n DEFAULT_RAGE_CLICK_THRESHOLD,\n DEFAULT_RAGE_CLICK_WINDOW_MS,\n DEFAULT_RAGE_CLICK_OUT_OF_BOUNDS_THRESHOLD,\n DEFAULT_DEAD_CLICK_WINDOW_MS,\n} from './types/frustration-interactions';\nexport { PageTrackingOptions, PageTrackingTrackOn, PageTrackingHistoryChanges } from './types/page-view-tracking';\nexport { FormInteractionsOptions } from './types/form-interactions';\nexport { Status } from './types/status';\n\nexport { NetworkEventCallback, networkObserver } from './observers/network';\nexport { NetworkRequestEvent, IRequestWrapper, JsonObject, JsonValue, JsonArray } from './network-request-event';\nexport { NetworkTrackingOptions, NetworkCaptureRule } from './types/network-tracking';\nexport { SAFE_HEADERS, FORBIDDEN_HEADERS } from './types/constants';\n\nexport { PageUrlEnrichmentOptions } from './types/page-url-enrichment';\nexport { CustomEnrichmentOptions } from './types/custom-enrichment';\nexport { PerformanceTrackingOptions, MainThreadBlockOptions } from './types/performance-tracking';\n\n// Campaign\nexport { Campaign, UTMParameters, ReferrerParameters, ClickIdParameters, ICampaignParser } from './types/campaign';\nexport { EMPTY_VALUE, BASE_CAMPAIGN, MKTG } from './types/constants';\nexport { CampaignParser } from './campaign/campaign-parser';\nexport {\n getPageTitle,\n TEXT_MASK_ATTRIBUTE,\n MASKED_TEXT_VALUE,\n replaceSensitiveString,\n CC_REGEX,\n SSN_REGEX,\n EMAIL_REGEX,\n} from './plugins/helpers';\n\n// Browser\nexport {\n BrowserConfig,\n BrowserOptions,\n DefaultTrackingOptions,\n TrackingOptions,\n TrackingMethod,\n AutocaptureOptions,\n CookieOptions,\n AttributionOptions,\n RemoteConfigOptions,\n} from './types/config/browser-config';\nexport { BrowserClient } from './types/client/browser-client';\n\n// Node\nexport { NodeClient } from './types/client/node-client';\nexport { NodeConfig, NodeOptions } from './types/config/node-config';\n\n// React Native\nexport {\n ReactNativeConfig,\n ReactNativeTrackingOptions,\n ReactNativeOptions,\n ReactNativeAttributionOptions,\n} from './types/config/react-native-config';\nexport { ReactNativeClient } from './types/client/react-native-client';\n\nexport { Observable, asyncMap, merge, multicast, Unsubscribable } from './utils/observable';\n\nexport { InstanceProxy } from './types/proxy';\nexport { safeJsonStringify } from './utils/safe-stringify';\n\n// Messenger (cross-window communication)\nexport type { BaseWindowMessenger, ActionHandler } from './messenger/base-window-messenger';\nexport { getOrCreateWindowMessenger } from './messenger/base-window-messenger';\nexport { enableBackgroundCapture } from './messenger/background-capture';\nexport {\n AMPLITUDE_ORIGIN,\n AMPLITUDE_ORIGIN_EU,\n AMPLITUDE_ORIGIN_STAGING,\n AMPLITUDE_ORIGINS_MAP,\n AMPLITUDE_BACKGROUND_CAPTURE_SCRIPT_URL,\n} from './messenger/constants';\n\nexport { ExcludeInternalReferrersOptions, EXCLUDE_INTERNAL_REFERRERS_CONDITIONS } from './types/config/browser-config';\n\nexport { VideoObserver, State as VideoState, type VideoObserverParams } from './observers/video';\nexport { EmbeddedVideoPlayer, type Vendor as VideoVendor } from './video-analytics/types';\nexport { isChromeExtension } from './utils/environment';\n"]}
|
|
@@ -19,6 +19,24 @@ export type DeliveryMode = 'all' | {
|
|
|
19
19
|
* - `remote` - Fetched from remote.
|
|
20
20
|
*/
|
|
21
21
|
export type Source = 'cache' | 'remote';
|
|
22
|
+
/**
|
|
23
|
+
* The fully-formed remote-config request handed to a custom transport. Consumers that need to
|
|
24
|
+
* own the network call (e.g. to attach auth headers and route through a proxy) supply a
|
|
25
|
+
* {@link RemoteConfigCustomFetch} via the client constructor; the client builds this request
|
|
26
|
+
* (resolved URL, headers, abort signal) and the callback executes it.
|
|
27
|
+
*/
|
|
28
|
+
export interface RemoteConfigFetchRequest {
|
|
29
|
+
url: string;
|
|
30
|
+
method: 'GET';
|
|
31
|
+
headers: Record<string, string>;
|
|
32
|
+
/** Abort signal the client uses to enforce the fetch timeout; honor it in your fetch call. */
|
|
33
|
+
signal?: AbortSignal;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Custom transport for the remote-config fetch. Must return a `Response`. Retry/backoff stays
|
|
37
|
+
* in the client around this callback, so it is invoked once per attempt.
|
|
38
|
+
*/
|
|
39
|
+
export type RemoteConfigCustomFetch = (request: RemoteConfigFetchRequest) => Promise<Response>;
|
|
22
40
|
export declare const US_SERVER_URL = "https://sr-client-cfg.amplitude.com/config";
|
|
23
41
|
export declare const EU_SERVER_URL = "https://sr-client-cfg.eu.amplitude.com/config";
|
|
24
42
|
export declare const DEFAULT_MAX_RETRIES = 3;
|
|
@@ -92,7 +110,8 @@ export declare class RemoteConfigClient implements IRemoteConfigClient {
|
|
|
92
110
|
lastSuccessfulFetch: number | null;
|
|
93
111
|
fetchPromise: Promise<RemoteConfigInfo> | null;
|
|
94
112
|
isLastFetchInvalidApiKey: boolean;
|
|
95
|
-
|
|
113
|
+
readonly customFetch?: RemoteConfigCustomFetch;
|
|
114
|
+
constructor(apiKey: string, logger: ILogger, serverZone?: ServerZoneType, serverUrl?: string, customFetch?: RemoteConfigCustomFetch);
|
|
96
115
|
subscribe(key: string | undefined, deliveryMode: DeliveryMode, callback: RemoteConfigCallback): string;
|
|
97
116
|
unsubscribe(id: string): boolean;
|
|
98
117
|
updateConfigs(): Promise<void>;
|