diff --git a/.changeset/plenty-peaches-roll.md b/.changeset/plenty-peaches-roll.md new file mode 100644 index 000000000..c20ac51d7 --- /dev/null +++ b/.changeset/plenty-peaches-roll.md @@ -0,0 +1,6 @@ +--- +'@segment/analytics-next': major +--- + +Remove experimental/undocumented AnalyticsNode library from browser. @segment/analytics-node should be used. +Should also fix https://github.com/segmentio/analytics-next/issues/837. diff --git a/packages/browser/package.json b/packages/browser/package.json index f9f468ce9..703c41d32 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -10,12 +10,6 @@ "main": "./dist/cjs/index.js", "module": "./dist/pkg/index.js", "types": "./dist/types/index.d.ts", - "browser": { - "./dist/cjs/node": "./dist/cjs/node/node.browser.js", - "./dist/cjs/node.js": "./dist/cjs/node/node.browser.js", - "./dist/pkg/node": "./dist/pkg/node/node.browser.js", - "./dist/pkg/node.js": "./dist/pkg/node/node.browser.js" - }, "files": [ "dist/", "src/", @@ -54,13 +48,13 @@ "@segment/tsub": "1.0.1", "dset": "^3.1.2", "js-cookie": "3.0.1", - "node-fetch": "^2.6.7", "spark-md5": "^3.0.1", "tslib": "^2.4.1", "unfetch": "^4.1.0" }, "devDependencies": { "@internal/config": "0.0.0", + "@segment/analytics-node": "*", "@segment/analytics.js-integration": "^3.3.3", "@segment/analytics.js-integration-amplitude": "^3.3.3", "@size-limit/preset-big-lib": "^7.0.8", @@ -88,6 +82,7 @@ "log-update": "^4.0.0", "micro-memoize": "^4.0.9", "mime": "^2.4.6", + "node-fetch": "^2.6.7", "node-gyp": "^9.0.0", "playwright": "^1.28.1", "serve-handler": "^6.1.3", diff --git a/packages/browser/qa/lib/stats.ts b/packages/browser/qa/lib/stats.ts index 00a39da67..2f8cc68e6 100644 --- a/packages/browser/qa/lib/stats.ts +++ b/packages/browser/qa/lib/stats.ts @@ -1,29 +1,19 @@ -import { Analytics } from '../../src/index' -import { Context } from '../../src/core/context' -import { AnalyticsNode } from '../../src/node' +import { Analytics, Context } from '@segment/analytics-node' import ex from 'execa' -let analytics!: Analytics - - const getBranch = async () => (await ex('git', ['branch', '--show-current'])).stdout -async function client(): Promise { - +function client(): Analytics { if (!process.env.STATS_WRITEKEY) { throw new Error('no process.env.STATS_WRITEKEY') } - if (analytics) { - return analytics - } - - const [nodeAnalytics] = await AnalyticsNode.load({ + const analytics = new Analytics({ writeKey: process.env.STATS_WRITEKEY, + maxEventsInBatch: 1, }) - analytics = nodeAnalytics return analytics } @@ -31,21 +21,24 @@ export async function gauge( metric: string, value: number = 0, tags: string[] = [] -): Promise { - const ajs = await client() +) { + const ajs = client() const branch = process.env.BUILDKITE_BRANCH || (await getBranch()) - const ctx = await ajs.track( - metric, - { - value, - tags: [...tags, `branch:${branch}`], - type: 'gauge', - }, - { - userId: 'system', - } + const ctx = await new Promise((resolve, reject) => + ajs.track( + { + event: metric, + properties: { + value, + tags: [...tags, `branch:${branch}`], + type: 'gauge', + }, + userId: 'system', + }, + (err, res) => (err ? reject(err) : resolve(res!)) + ) ) return ctx diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts index a3006eee2..0b0207e23 100644 --- a/packages/browser/src/index.ts +++ b/packages/browser/src/index.ts @@ -1,6 +1,5 @@ export * from './core/analytics' export * from './browser' -export * from './node' export * from './core/context' export * from './core/events' diff --git a/packages/browser/src/node/__tests__/node-integration.test.ts b/packages/browser/src/node/__tests__/node-integration.test.ts deleted file mode 100644 index d67a59183..000000000 --- a/packages/browser/src/node/__tests__/node-integration.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { AnalyticsNode } from '../..' - -const writeKey = 'foo' - -describe('Initialization', () => { - it('loads analytics-node-next plugin', async () => { - const [analytics] = await AnalyticsNode.load({ - writeKey, - }) - - expect(analytics.queue.plugins.length).toBe(2) - - const ajsNodeXt = analytics.queue.plugins.find( - (xt) => xt.name === 'analytics-node-next' - ) - expect(ajsNodeXt).toBeDefined() - expect(ajsNodeXt?.isLoaded()).toBeTruthy() - }) -}) diff --git a/packages/browser/src/node/index.ts b/packages/browser/src/node/index.ts deleted file mode 100644 index f2a89084c..000000000 --- a/packages/browser/src/node/index.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Analytics } from '../core/analytics' -import { Context } from '../core/context' -import { validation } from '../plugins/validation' -import { analyticsNode } from '../plugins/analytics-node' -import { Plugin } from '../core/plugin' -import { EventQueue } from '../core/queue/event-queue' -import { PriorityQueue } from '../lib/priority-queue' - -export class AnalyticsNode { - static async load(settings: { - writeKey: string - }): Promise<[Analytics, Context]> { - const cookieOptions = { - persist: false, - } - - const queue = new EventQueue(new PriorityQueue(3, [])) - const options = { user: cookieOptions, group: cookieOptions } - const analytics = new Analytics(settings, options, queue) - - const nodeSettings = { - writeKey: settings.writeKey, - name: 'analytics-node-next', - type: 'after' as Plugin['type'], - version: 'latest', - } - - const ctx = await analytics.register( - validation, - analyticsNode(nodeSettings) - ) - analytics.emit('initialize', settings, cookieOptions ?? {}) - - return [analytics, ctx] - } -} diff --git a/packages/browser/src/node/node.browser.ts b/packages/browser/src/node/node.browser.ts deleted file mode 100644 index fb8d85826..000000000 --- a/packages/browser/src/node/node.browser.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class AnalyticsNode { - static load(): Promise { - return Promise.reject( - new Error('AnalyticsNode is not available in browsers.') - ) - } -} diff --git a/packages/browser/src/plugins/analytics-node/__tests__/index.test.ts b/packages/browser/src/plugins/analytics-node/__tests__/index.test.ts deleted file mode 100644 index b34bd64ed..000000000 --- a/packages/browser/src/plugins/analytics-node/__tests__/index.test.ts +++ /dev/null @@ -1,69 +0,0 @@ -const fetcher = jest.fn() -jest.mock('node-fetch', () => fetcher) - -import { Analytics } from '../../../core/analytics' -import { AnalyticsNode } from '../../..' - -const myDate = new Date('2016') -const _Date = Date - -describe('Analytics Node', () => { - let ajs: Analytics - - beforeEach(async () => { - jest.resetAllMocks() - - const [analytics] = await AnalyticsNode.load({ - writeKey: 'abc123', - }) - - ajs = analytics - - // @ts-ignore - global.Date = jest.fn(() => myDate) - /* eslint-disable @typescript-eslint/unbound-method */ - global.Date.UTC = _Date.UTC - global.Date.parse = _Date.parse - global.Date.now = _Date.now - }) - - describe('AJS', () => { - test('fireEvent instantiates the right event types', async () => { - await ajs.track('track') - expect(fetcher).toHaveBeenCalledWith( - 'https://api.segment.io/v1/track', - expect.anything() - ) - - await ajs.identify('identify') - expect(fetcher).toHaveBeenCalledWith( - 'https://api.segment.io/v1/identify', - expect.anything() - ) - - await ajs.page('page') - expect(fetcher).toHaveBeenCalledWith( - 'https://api.segment.io/v1/page', - expect.anything() - ) - - await ajs.group('group') - expect(fetcher).toHaveBeenCalledWith( - 'https://api.segment.io/v1/group', - expect.anything() - ) - - await ajs.alias('alias') - expect(fetcher).toHaveBeenCalledWith( - 'https://api.segment.io/v1/alias', - expect.anything() - ) - - await ajs.screen('screen') - expect(fetcher).toHaveBeenCalledWith( - 'https://api.segment.io/v1/screen', - expect.anything() - ) - }) - }) -}) diff --git a/packages/browser/src/plugins/analytics-node/index.ts b/packages/browser/src/plugins/analytics-node/index.ts deleted file mode 100644 index 955d80f44..000000000 --- a/packages/browser/src/plugins/analytics-node/index.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Plugin } from '../../core/plugin' -import { Context } from '../../core/context' -import { SegmentEvent } from '../../core/events' -import fetch from 'node-fetch' -import { version } from '../../generated/version' - -interface AnalyticsNodeSettings { - writeKey: string - name: string - type: Plugin['type'] - version: string -} - -const btoa = (val: string): string => Buffer.from(val).toString('base64') - -export async function post( - event: SegmentEvent, - writeKey: string -): Promise { - const res = await fetch(`https://api.segment.io/v1/${event.type}`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'User-Agent': 'analytics-node-next/latest', - Authorization: `Basic ${btoa(writeKey)}`, - }, - body: JSON.stringify(event), - }) - - if (!res.ok) { - throw new Error('Message Rejected') - } - - return event -} - -export function analyticsNode(settings: AnalyticsNodeSettings): Plugin { - const send = async (ctx: Context): Promise => { - ctx.updateEvent('context.library.name', 'analytics-node-next') - ctx.updateEvent('context.library.version', version) - ctx.updateEvent('_metadata.nodeVersion', process.versions.node) - - await post(ctx.event, settings.writeKey) - return ctx - } - - const plugin: Plugin = { - name: settings.name, - type: settings.type, - version: settings.version, - - load: (ctx) => Promise.resolve(ctx), - isLoaded: () => true, - - track: send, - identify: send, - page: send, - alias: send, - group: send, - screen: send, - } - - return plugin -} diff --git a/yarn.lock b/yarn.lock index daf2766f8..9b831c2db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1733,6 +1733,7 @@ __metadata: "@internal/config": 0.0.0 "@lukeed/uuid": ^2.0.0 "@segment/analytics-core": 1.2.4 + "@segment/analytics-node": "*" "@segment/analytics.js-integration": ^3.3.3 "@segment/analytics.js-integration-amplitude": ^3.3.3 "@segment/analytics.js-video-plugins": ^0.2.1