Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
silesky committed May 21, 2024
1 parent 2299e9a commit 3be7b87
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 35 deletions.
5 changes: 5 additions & 0 deletions .changeset/violet-actors-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@segment/analytics-next': minor
---

Add public settings API
41 changes: 34 additions & 7 deletions packages/browser/src/browser/__tests__/integration.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
/* eslint-disable @typescript-eslint/no-floating-promises */
import { cdnSettingsKitchenSink } from '../../test-helpers/fixtures/cdn-settings'
import {
cdnSettingsKitchenSink,
cdnSettingsMinimal,
} from '../../test-helpers/fixtures/cdn-settings'
import { createMockFetchImplementation } from '../../test-helpers/fixtures/create-fetch-method'
import { Context } from '../../core/context'
import { Plugin } from '../../core/plugin'
Expand All @@ -23,7 +26,8 @@ import {
highEntropyTestData,
lowEntropyTestData,
} from '../../test-helpers/fixtures/client-hints'
import { getGlobalAnalytics, NullAnalytics } from '../..'
import { getGlobalAnalytics } from '../../lib/global-analytics-helper'
import { NullAnalytics } from '../../core/analytics'
import { recordIntegrationMetric } from '../../core/stats/metric-helpers'

let fetchCalls: ReturnType<typeof parseFetchCall>[] = []
Expand Down Expand Up @@ -1030,24 +1034,47 @@ describe('use', () => {
})
})

describe('timeout', () => {
it('has a default timeout value', async () => {
describe('public settings api', () => {
it('has expected settings', async () => {
const [analytics] = await AnalyticsBrowser.load({
writeKey,
cdnSettings: cdnSettingsMinimal,
})

expect(analytics.settings).toEqual({
writeKey,
cdnSettings: cdnSettingsMinimal,
timeout: 300,
})
//@ts-ignore
expect(analytics.settings.timeout).toEqual(300)
})

it('should have a writeKey', async () => {
const [analytics] = await AnalyticsBrowser.load({
writeKey,
})

expect(analytics.settings.writeKey).toBe(writeKey)
})

it('should have cdn settings', async () => {
const [analytics] = await AnalyticsBrowser.load({
writeKey,
cdnSettings: cdnSettingsMinimal,
})

expect(analytics.settings.cdnSettings).toEqual(cdnSettingsMinimal)
})

it('can set a timeout value', async () => {
const [analytics] = await AnalyticsBrowser.load({
writeKey,
})
expect(analytics.settings.timeout).toEqual(300)
analytics.timeout(50)
//@ts-ignore
expect(analytics.settings.timeout).toEqual(50)
})
})

describe('register', () => {
it('will not invoke any plugins that have initialization errors', async () => {
const analytics = AnalyticsBrowser.load({
Expand Down
34 changes: 19 additions & 15 deletions packages/browser/src/browser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@ import { getProcessEnv } from '../lib/get-process-env'
import { getCDN, setGlobalCDNUrl } from '../lib/parse-cdn'

import { fetch } from '../lib/fetch'
import {
Analytics,
AnalyticsSettings,
NullAnalytics,
InitOptions,
} from '../core/analytics'
import { Analytics, NullAnalytics, InitOptions } from '../core/analytics'
import { Context } from '../core/context'
import { Plan } from '../core/events'
import { Plugin } from '../core/plugin'
Expand Down Expand Up @@ -111,7 +106,8 @@ export interface CDNSettings {
}
}

export interface AnalyticsBrowserSettings extends AnalyticsSettings {
export interface AnalyticsBrowserSettings {
writeKey: string
/**
* The settings for the Segment Source.
* If provided, `AnalyticsBrowser` will not fetch remote settings
Expand All @@ -122,6 +118,14 @@ export interface AnalyticsBrowserSettings extends AnalyticsSettings {
* If provided, will override the default Segment CDN (https://cdn.segment.com) for this application.
*/
cdnURL?: string
/**
* Plugins or npm-installed action destinations
*/
plugins?: (Plugin | PluginFactory)[]
/**
* npm-installed classic destinations
*/
classicIntegrations?: ClassicIntegrationSource[]
}

export function loadLegacySettings(
Expand Down Expand Up @@ -330,31 +334,31 @@ async function loadAnalytics(
preInitBuffer.push(new PreInitMethodCall('page', []))
}

let legacySettings =
let cdnSettings =
settings.cdnSettings ??
(await loadLegacySettings(settings.writeKey, settings.cdnURL))

if (options.updateCDNSettings) {
legacySettings = options.updateCDNSettings(legacySettings)
cdnSettings = options.updateCDNSettings(cdnSettings)
}

// if options.disable is a function, we allow user to disable analytics based on CDN Settings
if (typeof options.disable === 'function') {
const disabled = await options.disable(legacySettings)
const disabled = await options.disable(cdnSettings)
if (disabled) {
return [new NullAnalytics(), Context.system()]
}
}

const retryQueue: boolean =
legacySettings.integrations['Segment.io']?.retryQueue ?? true
cdnSettings.integrations['Segment.io']?.retryQueue ?? true

options = {
retryQueue,
...options,
}

const analytics = new Analytics(settings, options)
const analytics = new Analytics({ ...settings, cdnSettings }, options)

attachInspector(analytics)

Expand All @@ -367,8 +371,8 @@ async function loadAnalytics(
| undefined

Stats.initRemoteMetrics({
...legacySettings.metrics,
host: segmentLoadOptions?.apiHost ?? legacySettings.metrics?.host,
...cdnSettings.metrics,
host: segmentLoadOptions?.apiHost ?? cdnSettings.metrics?.host,
protocol: segmentLoadOptions?.protocol,
})

Expand All @@ -377,7 +381,7 @@ async function loadAnalytics(

const ctx = await registerPlugins(
settings.writeKey,
legacySettings,
cdnSettings,
analytics,
options,
plugins,
Expand Down
40 changes: 29 additions & 11 deletions packages/browser/src/core/analytics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ import { EventQueue } from '../queue/event-queue'
import { Group, ID, User, UserOptions } from '../user'
import autoBind from '../../lib/bind-all'
import { PersistedPriorityQueue } from '../../lib/priority-queue/persisted'
import type {
LegacyIntegration,
ClassicIntegrationSource,
} from '../../plugins/ajs-destination/types'
import type { LegacyIntegration } from '../../plugins/ajs-destination/types'
import type {
DestinationMiddlewareFunction,
MiddlewareFunction,
Expand All @@ -52,7 +49,6 @@ import {
initializeStorages,
isArrayOfStoreType,
} from '../storage'
import { PluginFactory } from '../../plugins/remote-loader'
import { setGlobalAnalytics } from '../../lib/global-analytics-helper'
import { popPageContext } from '../buffer'

Expand All @@ -75,11 +71,34 @@ function createDefaultQueue(
return new EventQueue(priorityQueue)
}

/**
* The public settings that are set on the analytics instance
*/
export class AnalyticsInstanceSettings {
readonly writeKey: string
/**
* This is an unstable API, it may change in the future without warning.
*/
readonly cdnSettings: CDNSettings
/**
* The timeout for the analytics request in milliseconds
*/
// this is an odd setting --
// it's only used in autotrack? Not sure what the history is, or why it's publicly exposed.
readonly timeout = 300

constructor(settings: AnalyticsSettings) {
this.writeKey = settings.writeKey
this.cdnSettings = settings.cdnSettings ?? { integrations: {} }
}
}

/**
* The settings that are used to configure the analytics instance
*/
export interface AnalyticsSettings {
writeKey: string
timeout?: number
plugins?: (Plugin | PluginFactory)[]
classicIntegrations?: ClassicIntegrationSource[]
cdnSettings?: CDNSettings
}

export interface InitOptions {
Expand Down Expand Up @@ -155,7 +174,7 @@ export class Analytics
extends Emitter
implements AnalyticsCore, AnalyticsClassic
{
protected settings: AnalyticsSettings
settings: AnalyticsInstanceSettings
private _user: User
private _group: Group
private eventFactory: EventFactory
Expand All @@ -177,8 +196,7 @@ export class Analytics
super()
const cookieOptions = options?.cookie
const disablePersistance = options?.disableClientPersistence ?? false
this.settings = settings
this.settings.timeout = this.settings.timeout ?? 300
this.settings = new AnalyticsInstanceSettings(settings)
this.queue =
queue ??
createDefaultQueue(
Expand Down
11 changes: 9 additions & 2 deletions packages/browser/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
export * from './core/analytics'
export * from './browser'
export { Analytics, AnalyticsSettings, InitOptions } from './core/analytics'
export {
AnalyticsBrowser,
AnalyticsBrowserSettings,
CDNSettings,
RemoteIntegrationSettings,
// Unclear why this is in the public API, but @cradek said that he saw a customer using this
loadLegacySettings,
} from './browser'
export * from './node'

export * from './core/context'
Expand Down
11 changes: 11 additions & 0 deletions packages/browser/src/test-helpers/test-analytics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Analytics, AnalyticsSettings } from '../core/analytics'
import { cdnSettingsMinimal } from './fixtures'

export class TestAnalytics extends Analytics {
constructor(settings: Partial<AnalyticsSettings> = {}, ...args: any[]) {
super(
{ writeKey: 'test', cdnSettings: cdnSettingsMinimal, ...settings },
...args
)
}
}

0 comments on commit 3be7b87

Please sign in to comment.