Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/experiment-tag/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
},
"dependencies": {
"@amplitude/analytics-core": "^2.21.0",
"@amplitude/analytics-types": "^2.11.0",
"@amplitude/experiment-core": "^0.12.0",
"@amplitude/experiment-js-client": "^1.20.1",
"dom-mutator": "git+ssh://git@github.com:amplitude/dom-mutator#ef95c531a822bce55c197a6bf5e1d86d03bc086c",
Expand Down
40 changes: 40 additions & 0 deletions packages/experiment-tag/src/experiment.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AnalyticsConnector } from '@amplitude/analytics-connector';
import { Event, Plugin } from '@amplitude/analytics-types';
import {
EvaluationFlag,
getGlobalScope,
Expand Down Expand Up @@ -538,6 +539,45 @@ export class DefaultWebExperimentClient implements WebExperimentClient {
this.messageBus.publish('manual', { name });
}

/**
* Track an analytics event that can trigger page objects.
* @param event_type The event type/name
* @param event_properties Optional event properties
*/
public trackEvent(
event_type: string,
event_properties?: Record<string, unknown>,
) {
this.messageBus.publish('analytics_event', {
event_type,
event_properties: event_properties || {},
});
}

/**
* Returns an Amplitude plugin that forwards analytics events to trigger page objects.
* @returns An Amplitude Plugin that intercepts analytics events
*/
public plugin(): Plugin {
return {
name: '@amplitude/experiment-tag',
type: 'enrichment',

setup: async (): Promise<void> => {
// No setup required
},

execute: async (context: Event): Promise<Event> => {
this.trackEvent(
context.event_type,
context.event_properties as Record<string, unknown>,
);

return context;
},
};
}

private async fetchRemoteFlags() {
try {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
Expand Down
6 changes: 1 addition & 5 deletions packages/experiment-tag/src/message-bus.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
export interface EventProperties {
[k: string]: unknown;
}

export interface AnalyticsEvent {
event_type: string;
event_properties: EventProperties;
event_properties: Record<string, unknown>;
}

type Subscriber<T extends MessageType> = {
Expand Down
37 changes: 25 additions & 12 deletions packages/experiment-tag/src/subscriptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
MessagePayloads,
ElementAppearedPayload,
ManualTriggerPayload,
AnalyticsEventPayload,
MessageType,
} from './message-bus';
import { DebouncedMutationManager } from './mutation-manager';
Expand Down Expand Up @@ -417,11 +418,28 @@ export class SubscriptionManager {
page: PageObject,
message: MessagePayloads[T],
): boolean => {
// Check conditions
let evalContext: Record<string, unknown> = {
page: { url: this.globalScope.location.href },
};

if (page.trigger_type === 'analytics_event') {
const eventMessage = message as AnalyticsEventPayload;

evalContext = {
...evalContext,
type: 'analytics_event',
data: {
event: eventMessage.event_type,
properties: eventMessage.event_properties,
},
};
}

// Check conditions with enriched context
if (page.conditions && page.conditions.length > 0) {
const matchConditions = evaluationEngine.evaluateConditions(
{
context: { page: { url: this.globalScope.location.href } },
context: evalContext,
result: {},
},
page.conditions,
Expand All @@ -431,7 +449,7 @@ export class SubscriptionManager {
}
}

// Check if page is active
// Check if page is active based on trigger type
switch (page.trigger_type) {
case 'url_change':
return true;
Expand All @@ -441,15 +459,10 @@ export class SubscriptionManager {
return (message as ManualTriggerPayload).name === triggerValue.name;
}

// case 'analytics_event': {
// const eventMessage = message as AnalyticsEventPayload;
// return (
// eventMessage.event_type === page.trigger_value.event_type &&
// Object.entries(page.trigger_value.event_properties || {}).every(
// ([key, value]) => eventMessage.event_properties[key] === value,
// )
// );
// }
case 'analytics_event': {
// Event type already matched above, conditions evaluated
return true;
Comment on lines +463 to +464
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just want to double check: Shouldn't it check the trigger value?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the event-related + URL targeting conditions should be within conditions in PageObject.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate? My understanding of conditions is that it only refers to the URL page targeting rules and not events.

}

case 'element_appeared': {
const triggerValue = page.trigger_value as ElementAppearedTriggerValue;
Expand Down
93 changes: 8 additions & 85 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
"@amplitude/analytics-connector" "^1.6.4"
tslib "^2.4.1"

"@amplitude/analytics-types@^2.11.0":
version "2.11.0"
resolved "https://registry.yarnpkg.com/@amplitude/analytics-types/-/analytics-types-2.11.0.tgz#7aa83d82f49a5905628a676d44131f5e55ec9a82"
integrity sha512-L1niBXYSWmbyHUE/GNuf6YBljbafaxWI3X5jjEIZDFCjQvdWO3DKalY1VPFUbhgYQgWw7+bC6I/AlUaporyfig==

"@amplitude/types@^1.10.2":
version "1.10.2"
resolved "https://registry.yarnpkg.com/@amplitude/types/-/types-1.10.2.tgz#8f3c6c3c9ee24f401ee037b351c3c67eb945eefc"
Expand Down Expand Up @@ -43,7 +48,7 @@
dependencies:
"@babel/highlight" "^7.10.4"

"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.27.1":
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be"
integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==
Expand Down Expand Up @@ -923,14 +928,7 @@
"@babel/plugin-transform-modules-commonjs" "^7.27.1"
"@babel/plugin-transform-typescript" "^7.27.1"

"@babel/runtime-corejs3@^7.10.2":
version "7.27.6"
resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.27.6.tgz#97644153808a62898e7c05f3361501417db3c48b"
integrity sha512-vDVrlmRAY8z9Ul/HxT+8ceAru95LQgkSKiXkSYZvqtbkPSfhZJgpRp45Cldbh1GJ1kxzQkI70AqyrTI58KpaWQ==
dependencies:
core-js-pure "^3.30.2"

"@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.21.0":
"@babel/runtime@^7.11.2", "@babel/runtime@^7.21.0":
version "7.27.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.6.tgz#ec4070a04d76bae8ddbb10770ba55714a417b7c6"
integrity sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==
Expand Down Expand Up @@ -1443,17 +1441,6 @@
slash "^3.0.0"
write-file-atomic "^4.0.2"

"@jest/types@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e"
integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==
dependencies:
"@types/istanbul-lib-coverage" "^2.0.0"
"@types/istanbul-reports" "^3.0.0"
"@types/node" "*"
"@types/yargs" "^15.0.0"
chalk "^4.0.0"

"@jest/types@^29.6.3":
version "29.6.3"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59"
Expand Down Expand Up @@ -2286,20 +2273,6 @@
dependencies:
"@sinonjs/commons" "^3.0.0"

"@testing-library/dom@7.26.0":
version "7.26.0"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.26.0.tgz#da4d052dc426a4ccc916303369c6e7552126f680"
integrity sha512-fyKFrBbS1IigaE3FV21LyeC7kSGF84lqTlSYdKmGaHuK2eYQ/bXVPM5vAa2wx/AU1iPD6oQHsxy2QQ17q9AMCg==
dependencies:
"@babel/code-frame" "^7.10.4"
"@babel/runtime" "^7.10.3"
"@types/aria-query" "^4.2.0"
aria-query "^4.2.2"
chalk "^4.1.0"
dom-accessibility-api "^0.5.1"
lz-string "^1.4.4"
pretty-format "^26.4.2"

"@tootallnate/once@2":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
Expand Down Expand Up @@ -2330,11 +2303,6 @@
resolved "https://registry.yarnpkg.com/@types/amplitude-js/-/amplitude-js-8.16.5.tgz#ad8c2c0f2f8b436f014f8b72ddb5535dd00368e6"
integrity sha512-W73JfDpwDH4VijOGo+nVuQOqUCiqyEGGVdajU4ziWTLn27cn+QtFuFuBdlhCraIIrO52fDRO4NSOGkawtn77Jw==

"@types/aria-query@^4.2.0":
version "4.2.2"
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc"
integrity sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==

"@types/babel__core@^7.1.14":
version "7.20.5"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017"
Expand Down Expand Up @@ -2499,13 +2467,6 @@
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15"
integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==

"@types/yargs@^15.0.0":
version "15.0.19"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.19.tgz#328fb89e46109ecbdb70c295d96ff2f46dfd01b9"
integrity sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==
dependencies:
"@types/yargs-parser" "*"

"@types/yargs@^17.0.8":
version "17.0.33"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.33.tgz#8c32303da83eec050a84b3c7ae7b9f922d13e32d"
Expand Down Expand Up @@ -2739,7 +2700,7 @@ ansi-escapes@^4.2.1:
dependencies:
type-fest "^0.21.3"

ansi-regex@^5.0.0, ansi-regex@^5.0.1:
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
Expand Down Expand Up @@ -2798,14 +2759,6 @@ argparse@^2.0.1:
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==

aria-query@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b"
integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==
dependencies:
"@babel/runtime" "^7.10.2"
"@babel/runtime-corejs3" "^7.10.2"

array-buffer-byte-length@^1.0.1, array-buffer-byte-length@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz#384d12a37295aec3769ab022ad323a18a51ccf8b"
Expand Down Expand Up @@ -3533,11 +3486,6 @@ core-js-compat@^3.40.0:
dependencies:
browserslist "^4.25.0"

core-js-pure@^3.30.2:
version "3.43.0"
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.43.0.tgz#4df9c949c7abde839a8398d16a827a76856b1f0c"
integrity sha512-i/AgxU2+A+BbJdMxh3v7/vxi2SbFqxiFmg6VsDwYB4jkucrd1BZNA9a9gphC0fYMG5IBSgQcbQnk865VCLe7xA==

core-util-is@~1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
Expand Down Expand Up @@ -3783,11 +3731,6 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"

dom-accessibility-api@^0.5.1:
version "0.5.16"
resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453"
integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==

"dom-mutator@git+ssh://git@github.com:amplitude/dom-mutator#ef95c531a822bce55c197a6bf5e1d86d03bc086c":
version "0.7.1"
resolved "git+ssh://git@github.com:amplitude/dom-mutator#ef95c531a822bce55c197a6bf5e1d86d03bc086c"
Expand Down Expand Up @@ -6265,11 +6208,6 @@ lunr@^2.3.9:
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1"
integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==

lz-string@^1.4.4:
version "1.5.0"
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941"
integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==

magic-string@^0.25.7:
version "0.25.9"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c"
Expand Down Expand Up @@ -7413,16 +7351,6 @@ pretty-format@30.2.0:
ansi-styles "^5.2.0"
react-is "^18.3.1"

pretty-format@^26.4.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93"
integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==
dependencies:
"@jest/types" "^26.6.2"
ansi-regex "^5.0.0"
ansi-styles "^4.0.0"
react-is "^17.0.1"

pretty-format@^29.0.0, pretty-format@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812"
Expand Down Expand Up @@ -7553,11 +7481,6 @@ randombytes@^2.1.0:
dependencies:
safe-buffer "^5.1.0"

react-is@^17.0.1:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==

react-is@^18.0.0, react-is@^18.3.1:
version "18.3.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e"
Expand Down
Loading