Skip to content

Commit 44cc464

Browse files
authored
Add support for segment inspector (#413)
This patch adds event reporting to Segment Inspector. The reporting happens through the interface injected by the extension itself.
1 parent 9b032ee commit 44cc464

File tree

7 files changed

+121
-1
lines changed

7 files changed

+121
-1
lines changed

.changeset/khaki-frogs-look.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@segment/analytics-next': minor
3+
---
4+
5+
Add support for Segment Inspector Chrome extension

packages/browser/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
"size-limit": [
4444
{
4545
"path": "dist/umd/index.js",
46-
"limit": "25.6 KB"
46+
"limit": "25.8 KB"
4747
}
4848
],
4949
"dependencies": {
@@ -59,6 +59,7 @@
5959
"unfetch": "^4.1.0"
6060
},
6161
"devDependencies": {
62+
"@segment/inspector-core": "^1.0.0",
6263
"@size-limit/preset-big-lib": "^7.0.8",
6364
"@types/flat": "^5.0.1",
6465
"@types/fs-extra": "^9.0.2",

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import type {
2929
import { version } from '../../generated/version'
3030
import { PriorityQueue } from '../../lib/priority-queue'
3131
import { getGlobal } from '../../lib/get-global'
32+
import { inspectorHost } from '../inspector'
3233

3334
const deprecationWarning =
3435
'This is being deprecated and will be not be available in future releases of Analytics JS'
@@ -114,6 +115,13 @@ export class Analytics extends Emitter {
114115
this.integrations = options?.integrations ?? {}
115116
this.options = options ?? {}
116117

118+
inspectorHost.start({
119+
user: {
120+
id: this.user().id() || null,
121+
traits: this.user().traits(),
122+
},
123+
})
124+
117125
autoBind(this)
118126
}
119127

@@ -321,6 +329,13 @@ export class Analytics extends Emitter {
321329
): Promise<DispatchedEvent> {
322330
const ctx = new Context(event)
323331

332+
inspectorHost.trace({
333+
stage: 'triggered',
334+
id: ctx.id,
335+
event: event as any,
336+
timestamp: new Date().toISOString(),
337+
})
338+
324339
if (isOffline() && !this.options.retryQueue) {
325340
return ctx
326341
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { Analytics } from '../../analytics'
2+
3+
let analytics: Analytics
4+
5+
describe('Inspector interface', () => {
6+
beforeEach(() => {
7+
window.__SEGMENT_INSPECTOR__ = {
8+
start: jest.fn(),
9+
trace: jest.fn(),
10+
}
11+
12+
analytics = new Analytics({
13+
writeKey: 'abc',
14+
})
15+
})
16+
17+
it('accepts and starts up an inspector client trying to connect', () => {
18+
expect(window.__SEGMENT_INSPECTOR__?.start).toHaveBeenCalledTimes(1)
19+
})
20+
21+
it('notifies the connected inspector client about each event API call and delivery', async () => {
22+
expect(window.__SEGMENT_INSPECTOR__?.trace).not.toHaveBeenCalled()
23+
24+
const timestampMatcher = expect.stringMatching(
25+
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/
26+
)
27+
const deliveryPromise = analytics.track('Test event').catch(() => {})
28+
29+
// expect 2 calls, triggered report, followed enriched report
30+
expect(window.__SEGMENT_INSPECTOR__?.trace).toHaveBeenCalledTimes(2)
31+
32+
expect(window.__SEGMENT_INSPECTOR__?.trace).toHaveBeenCalledWith(
33+
expect.objectContaining({
34+
stage: 'triggered',
35+
timestamp: timestampMatcher,
36+
event: expect.objectContaining({
37+
event: 'Test event',
38+
type: 'track',
39+
}),
40+
})
41+
)
42+
43+
await deliveryPromise
44+
45+
// triggered -> enriched -> delivered
46+
expect(window.__SEGMENT_INSPECTOR__?.trace).toHaveBeenCalledTimes(3)
47+
48+
expect(window.__SEGMENT_INSPECTOR__?.trace).toHaveBeenCalledWith(
49+
expect.objectContaining({
50+
stage: 'delivered',
51+
timestamp: timestampMatcher,
52+
event: expect.objectContaining({
53+
event: 'Test event',
54+
type: 'track',
55+
}),
56+
})
57+
)
58+
})
59+
})
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { Inspector } from '@segment/inspector-core'
2+
import { getGlobal } from '../../lib/get-global'
3+
4+
declare global {
5+
interface Window {
6+
__SEGMENT_INSPECTOR__?: Inspector
7+
}
8+
}
9+
10+
const env = getGlobal()
11+
12+
export const inspectorHost: Inspector = {
13+
start: (...args) => (env as any)?.['__SEGMENT_INSPECTOR__']?.start(...args),
14+
trace: (...args) => (env as any)?.['__SEGMENT_INSPECTOR__']?.trace(...args),
15+
}

packages/browser/src/core/queue/event-queue.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Emitter } from '../emitter'
88
import { Integrations } from '../events'
99
import { Plugin } from '../plugin'
1010
import { attempt, ensure } from './delivery'
11+
import { inspectorHost } from '../inspector'
1112

1213
type PluginsByType = {
1314
before: Plugin[]
@@ -265,6 +266,13 @@ export class EventQueue extends Emitter {
265266
}
266267
}
267268

269+
inspectorHost.trace({
270+
stage: 'enriched',
271+
id: ctx.id,
272+
event: ctx.event as any,
273+
timestamp: new Date().toISOString(),
274+
})
275+
268276
// Enrichment and before plugins can re-arrange the deny list dynamically
269277
// so we need to pluck them at the end
270278
const { destinations, after } = this.availableExtensions(
@@ -282,6 +290,15 @@ export class EventQueue extends Emitter {
282290

283291
ctx.stats.increment('message_delivered')
284292

293+
inspectorHost.trace({
294+
stage: 'delivered',
295+
id: ctx.id,
296+
event: ctx.event as any,
297+
timestamp: new Date().toISOString(),
298+
// FIXME: Resolve browsers destinations that the event was sent to
299+
destinations: ['segment.io'],
300+
})
301+
285302
const afterCalls = after.map((after) => attempt(ctx, after))
286303
await Promise.all(afterCalls)
287304

yarn.lock

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,6 +1491,7 @@ __metadata:
14911491
"@lukeed/uuid": ^2.0.0
14921492
"@segment/analytics.js-video-plugins": ^0.2.1
14931493
"@segment/facade": ^3.4.9
1494+
"@segment/inspector-core": ^1.0.0
14941495
"@segment/tsub": ^0.1.12
14951496
"@size-limit/preset-big-lib": ^7.0.8
14961497
"@types/flat": ^5.0.1
@@ -1570,6 +1571,13 @@ __metadata:
15701571
languageName: node
15711572
linkType: hard
15721573

1574+
"@segment/inspector-core@npm:^1.0.0":
1575+
version: 1.0.0
1576+
resolution: "@segment/inspector-core@npm:1.0.0"
1577+
checksum: 4c04303301f54cab9fe8d0502fe0a755ad21206b8917ebbfb5edb8be5888cd7ed4dc948cf34e52b957863de44f9152551d78571ba12c00106f573fdb2136f4ef
1578+
languageName: node
1579+
linkType: hard
1580+
15731581
"@segment/isodate-traverse@npm:^1.1.1":
15741582
version: 1.1.1
15751583
resolution: "@segment/isodate-traverse@npm:1.1.1"

0 commit comments

Comments
 (0)