Skip to content

Commit b611746

Browse files
authored
Add analytics.settings api (#1090)
1 parent 2299e9a commit b611746

File tree

7 files changed

+103
-44
lines changed

7 files changed

+103
-44
lines changed

.changeset/violet-actors-pump.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@segment/analytics-next': minor
3+
---
4+
5+
- Add public settings API
6+
- Do not expose loadLegacySettings / loadCDNSettings (private API)

packages/browser/src/browser/__tests__/integration.test.ts

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
/* eslint-disable @typescript-eslint/no-floating-promises */
2-
import { cdnSettingsKitchenSink } from '../../test-helpers/fixtures/cdn-settings'
2+
import {
3+
cdnSettingsKitchenSink,
4+
cdnSettingsMinimal,
5+
} from '../../test-helpers/fixtures/cdn-settings'
36
import { createMockFetchImplementation } from '../../test-helpers/fixtures/create-fetch-method'
47
import { Context } from '../../core/context'
58
import { Plugin } from '../../core/plugin'
69
import { JSDOM } from 'jsdom'
710
import { Analytics, InitOptions } from '../../core/analytics'
811
import { LegacyDestination } from '../../plugins/ajs-destination'
912
import { PersistedPriorityQueue } from '../../lib/priority-queue/persisted'
10-
// @ts-ignore loadLegacySettings mocked dependency is accused as unused
11-
import { AnalyticsBrowser, loadLegacySettings } from '..'
13+
// @ts-ignore loadCDNSettings mocked dependency is accused as unused
14+
import { AnalyticsBrowser, loadCDNSettings } from '..'
1215
// @ts-ignore isOffline mocked dependency is accused as unused
1316
import { isOffline } from '../../core/connection'
1417
import * as SegmentPlugin from '../../plugins/segmentio'
@@ -23,7 +26,8 @@ import {
2326
highEntropyTestData,
2427
lowEntropyTestData,
2528
} from '../../test-helpers/fixtures/client-hints'
26-
import { getGlobalAnalytics, NullAnalytics } from '../..'
29+
import { getGlobalAnalytics } from '../../lib/global-analytics-helper'
30+
import { NullAnalytics } from '../../core/analytics'
2731
import { recordIntegrationMetric } from '../../core/stats/metric-helpers'
2832

2933
let fetchCalls: ReturnType<typeof parseFetchCall>[] = []
@@ -1030,24 +1034,47 @@ describe('use', () => {
10301034
})
10311035
})
10321036

1033-
describe('timeout', () => {
1034-
it('has a default timeout value', async () => {
1037+
describe('public settings api', () => {
1038+
it('has expected settings', async () => {
10351039
const [analytics] = await AnalyticsBrowser.load({
10361040
writeKey,
1041+
cdnSettings: cdnSettingsMinimal,
1042+
})
1043+
1044+
expect(analytics.settings).toEqual({
1045+
writeKey,
1046+
cdnSettings: cdnSettingsMinimal,
1047+
timeout: 300,
10371048
})
1038-
//@ts-ignore
1039-
expect(analytics.settings.timeout).toEqual(300)
1049+
})
1050+
1051+
it('should have a writeKey', async () => {
1052+
const [analytics] = await AnalyticsBrowser.load({
1053+
writeKey,
1054+
})
1055+
1056+
expect(analytics.settings.writeKey).toBe(writeKey)
1057+
})
1058+
1059+
it('should have cdn settings', async () => {
1060+
const [analytics] = await AnalyticsBrowser.load({
1061+
writeKey,
1062+
cdnSettings: cdnSettingsMinimal,
1063+
})
1064+
1065+
expect(analytics.settings.cdnSettings).toEqual(cdnSettingsMinimal)
10401066
})
10411067

10421068
it('can set a timeout value', async () => {
10431069
const [analytics] = await AnalyticsBrowser.load({
10441070
writeKey,
10451071
})
1072+
expect(analytics.settings.timeout).toEqual(300)
10461073
analytics.timeout(50)
1047-
//@ts-ignore
10481074
expect(analytics.settings.timeout).toEqual(50)
10491075
})
10501076
})
1077+
10511078
describe('register', () => {
10521079
it('will not invoke any plugins that have initialization errors', async () => {
10531080
const analytics = AnalyticsBrowser.load({
@@ -1190,7 +1217,7 @@ describe('retries', () => {
11901217

11911218
beforeEach(async () => {
11921219
// @ts-ignore ignore reassining function
1193-
loadLegacySettings = jest.fn().mockReturnValue(
1220+
loadCDNSettings = jest.fn().mockReturnValue(
11941221
Promise.resolve({
11951222
integrations: { 'Segment.io': { retryQueue: false } },
11961223
})

packages/browser/src/browser/__tests__/query-string.integration.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { JSDOM } from 'jsdom'
22
import { Analytics } from '../../core/analytics'
3-
// @ts-ignore loadLegacySettings mocked dependency is accused as unused
3+
// @ts-ignore loadCDNSettings mocked dependency is accused as unused
44
import { AnalyticsBrowser } from '..'
55
import { setGlobalCDNUrl } from '../../lib/parse-cdn'
66
import { TEST_WRITEKEY } from '../../test-helpers/test-writekeys'

packages/browser/src/browser/__tests__/standalone-analytics.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import jsdom, { JSDOM } from 'jsdom'
22
import { InitOptions, getGlobalAnalytics } from '../../'
3-
import { AnalyticsBrowser, loadLegacySettings } from '../../browser'
3+
import { AnalyticsBrowser, loadCDNSettings } from '../../browser'
44
import { snippet } from '../../tester/__fixtures__/segment-snippet'
55
import { install } from '../standalone-analytics'
66
import unfetch from 'unfetch'
@@ -130,7 +130,7 @@ describe('standalone bundle', () => {
130130
// @ts-ignore ignore Response required fields
131131
.mockImplementation((): Promise<Response> => fetchSettings)
132132

133-
await loadLegacySettings(segmentDotCom)
133+
await loadCDNSettings(segmentDotCom)
134134

135135
expect(unfetch).toHaveBeenCalledWith(
136136
'https://cdn.foo.com/v1/projects/foo/settings'
@@ -145,7 +145,7 @@ describe('standalone bundle', () => {
145145
const mockCdn = 'http://my-overridden-cdn.com'
146146

147147
getGlobalAnalytics()!._cdn = mockCdn
148-
await loadLegacySettings(segmentDotCom)
148+
await loadCDNSettings(segmentDotCom)
149149

150150
expect(unfetch).toHaveBeenCalledWith(expect.stringContaining(mockCdn))
151151
})

packages/browser/src/browser/index.ts

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,7 @@ import { getProcessEnv } from '../lib/get-process-env'
22
import { getCDN, setGlobalCDNUrl } from '../lib/parse-cdn'
33

44
import { fetch } from '../lib/fetch'
5-
import {
6-
Analytics,
7-
AnalyticsSettings,
8-
NullAnalytics,
9-
InitOptions,
10-
} from '../core/analytics'
5+
import { Analytics, NullAnalytics, InitOptions } from '../core/analytics'
116
import { Context } from '../core/context'
127
import { Plan } from '../core/events'
138
import { Plugin } from '../core/plugin'
@@ -111,7 +106,8 @@ export interface CDNSettings {
111106
}
112107
}
113108

114-
export interface AnalyticsBrowserSettings extends AnalyticsSettings {
109+
export interface AnalyticsBrowserSettings {
110+
writeKey: string
115111
/**
116112
* The settings for the Segment Source.
117113
* If provided, `AnalyticsBrowser` will not fetch remote settings
@@ -122,9 +118,17 @@ export interface AnalyticsBrowserSettings extends AnalyticsSettings {
122118
* If provided, will override the default Segment CDN (https://cdn.segment.com) for this application.
123119
*/
124120
cdnURL?: string
121+
/**
122+
* Plugins or npm-installed action destinations
123+
*/
124+
plugins?: (Plugin | PluginFactory)[]
125+
/**
126+
* npm-installed classic destinations
127+
*/
128+
classicIntegrations?: ClassicIntegrationSource[]
125129
}
126130

127-
export function loadLegacySettings(
131+
export function loadCDNSettings(
128132
writeKey: string,
129133
cdnURL?: string
130134
): Promise<CDNSettings> {
@@ -330,31 +334,31 @@ async function loadAnalytics(
330334
preInitBuffer.push(new PreInitMethodCall('page', []))
331335
}
332336

333-
let legacySettings =
337+
let cdnSettings =
334338
settings.cdnSettings ??
335-
(await loadLegacySettings(settings.writeKey, settings.cdnURL))
339+
(await loadCDNSettings(settings.writeKey, settings.cdnURL))
336340

337341
if (options.updateCDNSettings) {
338-
legacySettings = options.updateCDNSettings(legacySettings)
342+
cdnSettings = options.updateCDNSettings(cdnSettings)
339343
}
340344

341345
// if options.disable is a function, we allow user to disable analytics based on CDN Settings
342346
if (typeof options.disable === 'function') {
343-
const disabled = await options.disable(legacySettings)
347+
const disabled = await options.disable(cdnSettings)
344348
if (disabled) {
345349
return [new NullAnalytics(), Context.system()]
346350
}
347351
}
348352

349353
const retryQueue: boolean =
350-
legacySettings.integrations['Segment.io']?.retryQueue ?? true
354+
cdnSettings.integrations['Segment.io']?.retryQueue ?? true
351355

352356
options = {
353357
retryQueue,
354358
...options,
355359
}
356360

357-
const analytics = new Analytics(settings, options)
361+
const analytics = new Analytics({ ...settings, cdnSettings }, options)
358362

359363
attachInspector(analytics)
360364

@@ -367,8 +371,8 @@ async function loadAnalytics(
367371
| undefined
368372

369373
Stats.initRemoteMetrics({
370-
...legacySettings.metrics,
371-
host: segmentLoadOptions?.apiHost ?? legacySettings.metrics?.host,
374+
...cdnSettings.metrics,
375+
host: segmentLoadOptions?.apiHost ?? cdnSettings.metrics?.host,
372376
protocol: segmentLoadOptions?.protocol,
373377
})
374378

@@ -377,7 +381,7 @@ async function loadAnalytics(
377381

378382
const ctx = await registerPlugins(
379383
settings.writeKey,
380-
legacySettings,
384+
cdnSettings,
381385
analytics,
382386
options,
383387
plugins,

packages/browser/src/core/analytics/index.ts

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,7 @@ import { EventQueue } from '../queue/event-queue'
2828
import { Group, ID, User, UserOptions } from '../user'
2929
import autoBind from '../../lib/bind-all'
3030
import { PersistedPriorityQueue } from '../../lib/priority-queue/persisted'
31-
import type {
32-
LegacyIntegration,
33-
ClassicIntegrationSource,
34-
} from '../../plugins/ajs-destination/types'
31+
import type { LegacyIntegration } from '../../plugins/ajs-destination/types'
3532
import type {
3633
DestinationMiddlewareFunction,
3734
MiddlewareFunction,
@@ -52,7 +49,6 @@ import {
5249
initializeStorages,
5350
isArrayOfStoreType,
5451
} from '../storage'
55-
import { PluginFactory } from '../../plugins/remote-loader'
5652
import { setGlobalAnalytics } from '../../lib/global-analytics-helper'
5753
import { popPageContext } from '../buffer'
5854

@@ -75,11 +71,33 @@ function createDefaultQueue(
7571
return new EventQueue(priorityQueue)
7672
}
7773

74+
/**
75+
* The public settings that are set on the analytics instance
76+
*/
77+
export class AnalyticsInstanceSettings {
78+
readonly writeKey: string
79+
/**
80+
* This is an unstable API, it may change in the future without warning.
81+
*/
82+
readonly cdnSettings: CDNSettings
83+
84+
/**
85+
* Auto-track specific timeout setting for legacy purposes.
86+
*/
87+
timeout = 300
88+
89+
constructor(settings: AnalyticsSettings) {
90+
this.writeKey = settings.writeKey
91+
this.cdnSettings = settings.cdnSettings ?? { integrations: {} }
92+
}
93+
}
94+
95+
/**
96+
* The settings that are used to configure the analytics instance
97+
*/
7898
export interface AnalyticsSettings {
7999
writeKey: string
80-
timeout?: number
81-
plugins?: (Plugin | PluginFactory)[]
82-
classicIntegrations?: ClassicIntegrationSource[]
100+
cdnSettings?: CDNSettings
83101
}
84102

85103
export interface InitOptions {
@@ -155,7 +173,7 @@ export class Analytics
155173
extends Emitter
156174
implements AnalyticsCore, AnalyticsClassic
157175
{
158-
protected settings: AnalyticsSettings
176+
settings: AnalyticsInstanceSettings
159177
private _user: User
160178
private _group: Group
161179
private eventFactory: EventFactory
@@ -177,8 +195,7 @@ export class Analytics
177195
super()
178196
const cookieOptions = options?.cookie
179197
const disablePersistance = options?.disableClientPersistence ?? false
180-
this.settings = settings
181-
this.settings.timeout = this.settings.timeout ?? 300
198+
this.settings = new AnalyticsInstanceSettings(settings)
182199
this.queue =
183200
queue ??
184201
createDefaultQueue(

packages/browser/src/index.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
export * from './core/analytics'
2-
export * from './browser'
1+
export { Analytics, AnalyticsSettings, InitOptions } from './core/analytics'
2+
export {
3+
AnalyticsBrowser,
4+
AnalyticsBrowserSettings,
5+
CDNSettings,
6+
RemoteIntegrationSettings,
7+
} from './browser'
38
export * from './node'
49

510
export * from './core/context'

0 commit comments

Comments
 (0)