Skip to content

Commit d6ef98c

Browse files
committed
update signals runtime package
1 parent 5190f92 commit d6ef98c

File tree

6 files changed

+84
-12
lines changed

6 files changed

+84
-12
lines changed

packages/signals/signals-integration-tests/src/helpers/base-page-object.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
SignalAPIRequestBuffer,
88
TrackingAPIRequestBuffer,
99
} from './network-utils'
10+
import { SegmentEvent } from '@segment/analytics-next'
1011

1112
export class BasePage {
1213
protected page!: Page
@@ -82,6 +83,17 @@ export class BasePage {
8283
enableSignalsIngestion: true,
8384
...signalSettings,
8485
})
86+
87+
window.signalsEmitted = []
88+
window.signalsPlugin.onSignal((signal) => {
89+
window.signalsEmitted.push(signal)
90+
})
91+
window.segmentEvents = []
92+
window.analytics.on('track', (event) => {
93+
if (event !== 'Segment Signal Generated') {
94+
window.segmentEvents.push(event)
95+
}
96+
})
8597
window.analytics.load({
8698
writeKey: '<SOME_WRITE_KEY>',
8799
plugins: [window.signalsPlugin],
@@ -92,6 +104,14 @@ export class BasePage {
92104
return this
93105
}
94106

107+
getEmittedSignals(): Promise<Signal[]> {
108+
return this.page.evaluate(() => window.signalsEmitted)
109+
}
110+
111+
getSegmentEvents(): Promise<SegmentEvent[]> {
112+
return this.page.evaluate(() => window.segmentEvents)
113+
}
114+
95115
private async setupMockedRoutes() {
96116
// clear any existing saved requests
97117
this.trackingAPI.clear()
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import type { AnalyticsBrowser } from '@segment/analytics-next'
2-
import type { SignalsPlugin } from '@segment/analytics-signals'
1+
import type { AnalyticsBrowser, SegmentEvent } from '@segment/analytics-next'
2+
import type { Signal, SignalsPlugin } from '@segment/analytics-signals'
33

44
declare global {
55
interface Window {
66
analytics: AnalyticsBrowser
77
signalsPlugin: SignalsPlugin
8+
signalsEmitted: Signal[]
9+
segmentEvents: SegmentEvent[]
810
}
911
}

packages/signals/signals-integration-tests/src/tests/signals-vanilla/signals-find.test.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,29 @@ test('should find the most recent signal', async ({ page }) => {
1414
}`
1515

1616
await indexPage.loadAndWait(page, basicEdgeFn)
17-
const tapiFlush = indexPage.waitForTrackingApiFlush()
1817
await indexPage.addUserDefinedSignal({ num: 1 })
1918
await indexPage.addUserDefinedSignal({ num: 2 })
2019
await indexPage.clickComplexButton()
21-
await tapiFlush
22-
const lastEvent = indexPage.trackingAPI.lastEvent()
23-
expect(lastEvent.event).toEqual('correct signal found')
20+
await page.waitForFunction(() => window.segmentEvents.length === 1)
21+
const events = await page.evaluate(() => window.segmentEvents)
22+
expect(events[0]).toEqual('correct signal found')
23+
})
24+
25+
test('should work with other signals', async ({ page }) => {
26+
const basicEdgeFn = `const processSignal = (signal) => {
27+
if (signal.type === 'interaction' && signal.data.eventType === 'click') {
28+
const oldSignal = signals.find(signal, 'userDefined', (s) => s.data.order === 'old')
29+
const oldestSignal = signals.find(oldSignal, 'userDefined')
30+
analytics.track('order: ' + oldestSignal.data.order)
31+
}
32+
}`
33+
34+
await indexPage.loadAndWait(page, basicEdgeFn)
35+
await indexPage.addUserDefinedSignal({ order: 'oldest' })
36+
await indexPage.addUserDefinedSignal({ order: 'old' })
37+
await indexPage.addUserDefinedSignal({ order: 'young' })
38+
await indexPage.clickButton()
39+
await page.waitForFunction(() => window.segmentEvents.length === 1)
40+
const events = await page.evaluate(() => window.segmentEvents)
41+
expect(events[0]).toEqual('order: oldest')
2442
})
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/* eslint-disable */
22
// GENERATED, DO NOT EDIT
3-
// @segment/analytics-signals-runtime@0.0.0
3+
// @segment/analytics-signals-runtime@1.0.0
44
// Entry point: src/mobile/index.signals-runtime.ts
55
export const getRuntimeCode = (): string => `
6-
"use strict";(()=>{var g=Object.defineProperty;var f=(r,n)=>{for(var e in n)g(r,e,{get:n[e],enumerable:!0})};var l={};f(l,{EventType:()=>d,LocalDataAction:()=>c,NavigationAction:()=>S,NetworkAction:()=>u,SignalType:()=>p});var p=Object.freeze({Interaction:"interaction",Navigation:"navigation",Network:"network",LocalData:"localData",Instrumentation:"instrumentation",UserDefined:"userDefined"}),d=Object.freeze({Track:"track",Page:"page",Screen:"screen",Identify:"identify",Group:"group",Alias:"alias"}),S=Object.freeze({Forward:"forward",Backward:"backward",Modal:"modal",Entering:"entering",Leaving:"leaving",Page:"page",Popup:"popup"}),u=Object.freeze({Request:"request",Response:"response"}),c=Object.freeze({Loaded:"loaded",Updated:"updated",Saved:"saved",Deleted:"deleted",Undefined:"undefined"});var a=class{constructor(n=[]){this.find=(n,e,i)=>this.filter(n,e,i)[0];this.filter=(n,e,i)=>{let o=s=>s.type===e;return this.signalBuffer.slice(this.signalBuffer.indexOf(n)+1).filter(o).filter(s=>i?i(s):()=>!0)};this.signalBuffer=n}};var t=class extends a{constructor(e=[]){super(e);this.add=e=>{this.signalCounter<0&&(this.signalCounter=0),"index"in e&&e.index==-1&&(e.index=this.getNextIndex()),this.signalBuffer.unshift(e),this.signalBuffer.length>this.maxBufferSize&&this.signalBuffer.pop()};this.getNextIndex=()=>{let e=this.signalCounter;return this.signalCounter+=1,e};this.signalCounter=0,this.maxBufferSize=1e3}};Object.assign(globalThis,{signals:new t},l);})();
6+
"use strict";(()=>{var o=Object.defineProperty;var f=(l,n)=>{for(var e in n)o(l,e,{get:n[e],enumerable:!0})};var g={};f(g,{EventType:()=>d,LocalDataAction:()=>c,NavigationAction:()=>S,NetworkAction:()=>u,SignalType:()=>p});var p=Object.freeze({Interaction:"interaction",Navigation:"navigation",Network:"network",LocalData:"localData",Instrumentation:"instrumentation",UserDefined:"userDefined"}),d=Object.freeze({Track:"track",Page:"page",Screen:"screen",Identify:"identify",Group:"group",Alias:"alias"}),S=Object.freeze({Forward:"forward",Backward:"backward",Modal:"modal",Entering:"entering",Leaving:"leaving",Page:"page",Popup:"popup"}),u=Object.freeze({Request:"request",Response:"response"}),c=Object.freeze({Loaded:"loaded",Updated:"updated",Saved:"saved",Deleted:"deleted",Undefined:"undefined"});var r=class{constructor(n=[]){this.find=(n,e,t)=>this.filter(n,e,t)[0];this.filter=(n,e,t)=>{let a=this.signalBuffer.findIndex(i=>i===n?!0:"id"in i&&"id"in n?i.id===n.id:"index"in i&&"index"in n?i.index===n.index:JSON.stringify(i)===JSON.stringify(n));return a===-1&&console.warn("Invariant: the fromSignal was not found in the signalBuffer"),this.filterBuffer(this.signalBuffer.slice(a+1),e,t)};this.filterBuffer=(n,e,t)=>{let a=i=>i.type===e;return n.filter(a).filter(i=>t?t(i):()=>!0)};this.signalBuffer=n}};var s=class extends r{constructor(e=[]){super(e);this.add=e=>{this.signalCounter<0&&(this.signalCounter=0),"index"in e&&e.index==-1&&(e.index=this.getNextIndex()),this.signalBuffer.unshift(e),this.signalBuffer.length>this.maxBufferSize&&this.signalBuffer.pop()};this.getNextIndex=()=>{let e=this.signalCounter;return this.signalCounter+=1,e};this.signalCounter=0,this.maxBufferSize=1e3}};Object.assign(globalThis,{signals:new s},g);})();
77
`
88

packages/signals/signals-runtime/src/shared/signals-runtime.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,44 @@ export abstract class SignalsRuntime<Signal extends BaseSignal = BaseSignal> {
4040
fromSignal: Signal,
4141
signalType: SignalType,
4242
predicate?: (signal: SignalOfType<Signal, SignalType>) => boolean
43+
): SignalOfType<Signal, SignalType>[] => {
44+
const foundIndex = this.signalBuffer.findIndex((el) => {
45+
// if can use referential comparison, use that. Or if has ID, use that to compare
46+
// or else, use JSON.stringify to do a deep comparison
47+
if (el === fromSignal) {
48+
return true
49+
} else if ('id' in el && 'id' in fromSignal) {
50+
return el.id === fromSignal.id
51+
} else if ('index' in el && 'index' in fromSignal) {
52+
return el.index === fromSignal.index
53+
} else {
54+
return JSON.stringify(el) === JSON.stringify(fromSignal)
55+
}
56+
})
57+
58+
if (foundIndex === -1) {
59+
console.warn(
60+
'Invariant: the fromSignal was not found in the signalBuffer'
61+
)
62+
}
63+
64+
return this.filterBuffer(
65+
this.signalBuffer.slice(foundIndex + 1),
66+
signalType,
67+
predicate
68+
)
69+
}
70+
71+
private filterBuffer = <SignalType extends Signal['type']>(
72+
buffer: Signal[],
73+
signalType: SignalType,
74+
predicate?: (signal: SignalOfType<Signal, SignalType>) => boolean
4375
): SignalOfType<Signal, SignalType>[] => {
4476
const _isSignalOfType = (
4577
signal: Signal
4678
): signal is SignalOfType<Signal, SignalType> => signal.type === signalType
47-
return this.signalBuffer
48-
.slice(this.signalBuffer.indexOf(fromSignal) + 1)
79+
80+
return buffer
4981
.filter(_isSignalOfType)
5082
.filter((signal) => (predicate ? predicate(signal) : () => true))
5183
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/* eslint-disable */
22
// GENERATED, DO NOT EDIT
3-
// @segment/analytics-signals-runtime@0.0.0
3+
// @segment/analytics-signals-runtime@1.0.0
44
// Entry point: src/web/index.signals-runtime.ts
55
export const getRuntimeCode = (): string => `
6-
"use strict";(()=>{var o=Object.defineProperty;var S=(l,e)=>{for(var n in e)o(l,n,{get:e[n],enumerable:!0})};var i=class{constructor(e=[]){this.find=(e,n,a)=>this.filter(e,n,a)[0];this.filter=(e,n,a)=>{let s=g=>g.type===n;return this.signalBuffer.slice(this.signalBuffer.indexOf(e)+1).filter(s).filter(g=>a?a(g):()=>!0)};this.signalBuffer=e}};var t=class extends i{};var r={};S(r,{EventType:()=>f,NavigationAction:()=>p,SignalType:()=>y});var f=Object.freeze({Track:"track",Page:"page",Screen:"screen",Identify:"identify",Group:"group",Alias:"alias"}),p=Object.freeze({URLChange:"urlChange",PageLoad:"pageLoad"}),y=Object.freeze({Interaction:"interaction",Navigation:"navigation",Network:"network",LocalData:"localData",Instrumentation:"instrumentation",UserDefined:"userDefined"});Object.assign(globalThis,{signals:new t},r);})();
6+
"use strict";(()=>{var f=Object.defineProperty;var o=(r,n)=>{for(var i in n)f(r,i,{get:n[i],enumerable:!0})};var l=class{constructor(n=[]){this.find=(n,i,a)=>this.filter(n,i,a)[0];this.filter=(n,i,a)=>{let t=this.signalBuffer.findIndex(e=>e===n?!0:"id"in e&&"id"in n?e.id===n.id:"index"in e&&"index"in n?e.index===n.index:JSON.stringify(e)===JSON.stringify(n));return t===-1&&console.warn("Invariant: the fromSignal was not found in the signalBuffer"),this.filterBuffer(this.signalBuffer.slice(t+1),i,a)};this.filterBuffer=(n,i,a)=>{let t=e=>e.type===i;return n.filter(t).filter(e=>a?a(e):()=>!0)};this.signalBuffer=n}};var g=class extends l{};var s={};o(s,{EventType:()=>S,NavigationAction:()=>p,SignalType:()=>y});var S=Object.freeze({Track:"track",Page:"page",Screen:"screen",Identify:"identify",Group:"group",Alias:"alias"}),p=Object.freeze({URLChange:"urlChange",PageLoad:"pageLoad"}),y=Object.freeze({Interaction:"interaction",Navigation:"navigation",Network:"network",LocalData:"localData",Instrumentation:"instrumentation",UserDefined:"userDefined"});Object.assign(globalThis,{signals:new g},s);})();
77
`
88

0 commit comments

Comments
 (0)