@salesforcedevs/dx-components 1.38.0 → 1.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforcedevs/dx-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.39.0",
|
|
4
4
|
"description": "DX Lightning web components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"engines": {
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"luxon": "3.4.4",
|
|
45
45
|
"msw": "^2.12.4"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "055e2a716cf3e946add92e953e136835730bc5fc"
|
|
48
48
|
}
|
|
@@ -38,6 +38,47 @@ function archTrack(
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
interface NamespaceConfig {
|
|
42
|
+
eventName: string;
|
|
43
|
+
queue: string;
|
|
44
|
+
indicator: string;
|
|
45
|
+
replay: (
|
|
46
|
+
element: EventTarget,
|
|
47
|
+
event: string,
|
|
48
|
+
payload: Record<string, unknown>
|
|
49
|
+
) => void;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// The two tracking-event namespaces dx-instrumentation can bridge. Keyed by the
|
|
53
|
+
// values accepted by the `namespaces` attribute.
|
|
54
|
+
const NAMESPACE_CONFIGS: Record<"developer" | "architect", NamespaceConfig> = {
|
|
55
|
+
developer: {
|
|
56
|
+
eventName: DX_TRACKING_EVENT_NAME,
|
|
57
|
+
queue: DX_LISTENER_QUEUE,
|
|
58
|
+
indicator: DX_LISTENER_INDICATOR,
|
|
59
|
+
replay: dxTrack
|
|
60
|
+
},
|
|
61
|
+
architect: {
|
|
62
|
+
eventName: ARCH_TRACKING_EVENT_NAME,
|
|
63
|
+
queue: ARCH_LISTENER_QUEUE,
|
|
64
|
+
indicator: ARCH_LISTENER_INDICATOR,
|
|
65
|
+
replay: archTrack
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Maps the `namespaces` attribute to the configs it activates.
|
|
70
|
+
function resolveNamespaceConfigs(namespaces: string): NamespaceConfig[] {
|
|
71
|
+
switch (namespaces) {
|
|
72
|
+
case "developer":
|
|
73
|
+
return [NAMESPACE_CONFIGS.developer];
|
|
74
|
+
case "architect":
|
|
75
|
+
return [NAMESPACE_CONFIGS.architect];
|
|
76
|
+
case "both":
|
|
77
|
+
default:
|
|
78
|
+
return [NAMESPACE_CONFIGS.developer, NAMESPACE_CONFIGS.architect];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
41
82
|
const googleTagManager = {
|
|
42
83
|
track: function (e: Event) {
|
|
43
84
|
if ((window as any).dataLayer === undefined) {
|
|
@@ -54,13 +95,14 @@ interface TrackEventListener {
|
|
|
54
95
|
}
|
|
55
96
|
|
|
56
97
|
/**
|
|
57
|
-
* Attaches a listener for
|
|
58
|
-
*
|
|
59
|
-
* event to every tracker function. A single component can therefore
|
|
60
|
-
* event namespaces into the dataLayer.
|
|
98
|
+
* Attaches a listener for each of the given tracking event names (e.g.
|
|
99
|
+
* `developerwebsite_track` and/or `architectssite_track`), forwarding every
|
|
100
|
+
* caught event to every tracker function. A single component can therefore
|
|
101
|
+
* bridge one or both event namespaces into the dataLayer.
|
|
61
102
|
*/
|
|
62
103
|
export function instrumentationTrackEventListener(
|
|
63
|
-
trackerFns: { track: (e: Event) => void }[] = []
|
|
104
|
+
trackerFns: { track: (e: Event) => void }[] = [],
|
|
105
|
+
eventNames: string[] = [DX_TRACKING_EVENT_NAME, ARCH_TRACKING_EVENT_NAME]
|
|
64
106
|
): TrackEventListener {
|
|
65
107
|
if (trackerFns.length === 0) {
|
|
66
108
|
throw new Error("No tracker functions passed");
|
|
@@ -73,16 +115,15 @@ export function instrumentationTrackEventListener(
|
|
|
73
115
|
};
|
|
74
116
|
|
|
75
117
|
const attachEventListener = () => {
|
|
76
|
-
|
|
77
|
-
|
|
118
|
+
eventNames.forEach((eventName) => {
|
|
119
|
+
document.addEventListener(eventName, handleTrackEvent);
|
|
120
|
+
});
|
|
78
121
|
};
|
|
79
122
|
|
|
80
123
|
const removeEventListener = () => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
handleTrackEvent
|
|
85
|
-
);
|
|
124
|
+
eventNames.forEach((eventName) => {
|
|
125
|
+
document.removeEventListener(eventName, handleTrackEvent);
|
|
126
|
+
});
|
|
86
127
|
};
|
|
87
128
|
|
|
88
129
|
return {
|
|
@@ -93,49 +134,54 @@ export function instrumentationTrackEventListener(
|
|
|
93
134
|
|
|
94
135
|
/**
|
|
95
136
|
* Unified instrumentation bridge. Mount a single <dx-instrumentation> to forward
|
|
96
|
-
*
|
|
97
|
-
* dataLayer
|
|
98
|
-
*
|
|
137
|
+
* developer-website and/or architect-website tracking events into the GTM
|
|
138
|
+
* dataLayer. Renders nothing.
|
|
139
|
+
*
|
|
140
|
+
* By default (`namespaces="both"`) it bridges both the developer
|
|
141
|
+
* (`developerwebsite_track`) and architect (`architectssite_track`) namespaces,
|
|
142
|
+
* replacing the need to mount <dw-instrumentation> and <arch-instrumentation>
|
|
143
|
+
* separately. Set `namespaces="developer"` (or `"architect"`) to bridge only one
|
|
144
|
+
* — e.g. on a site whose header analytics already reach the dataLayer through
|
|
145
|
+
* another path, so draining the architect queue here would double-count.
|
|
99
146
|
*/
|
|
100
147
|
export default class Instrumentation extends LightningElement {
|
|
101
148
|
@api useGoogleTagManager = false;
|
|
102
149
|
|
|
150
|
+
// "both" (default) | "developer" | "architect"
|
|
151
|
+
@api namespaces = "both";
|
|
152
|
+
|
|
103
153
|
private tracker: TrackEventListener | null = null;
|
|
104
154
|
|
|
105
155
|
private setupTracker() {
|
|
156
|
+
const configs = resolveNamespaceConfigs(this.namespaces);
|
|
106
157
|
const trackerFunctions = this.useGoogleTagManager
|
|
107
158
|
? [googleTagManager]
|
|
108
159
|
: [];
|
|
109
|
-
this.tracker = instrumentationTrackEventListener(
|
|
160
|
+
this.tracker = instrumentationTrackEventListener(
|
|
161
|
+
trackerFunctions,
|
|
162
|
+
configs.map((c) => c.eventName)
|
|
163
|
+
);
|
|
110
164
|
this.tracker.add();
|
|
111
|
-
// Mark
|
|
112
|
-
//
|
|
113
|
-
(
|
|
114
|
-
|
|
165
|
+
// Mark each active namespace initialized so track() calls from that
|
|
166
|
+
// stack dispatch live events instead of queueing.
|
|
167
|
+
configs.forEach((c) => {
|
|
168
|
+
(window as any)[c.indicator] = true;
|
|
169
|
+
});
|
|
115
170
|
}
|
|
116
171
|
|
|
117
172
|
private dispatchQueuedEvents() {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
event
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
173
|
+
resolveNamespaceConfigs(this.namespaces).forEach((config) => {
|
|
174
|
+
const queue = (window as any)[config.queue];
|
|
175
|
+
if (Array.isArray(queue)) {
|
|
176
|
+
while (queue.length > 0) {
|
|
177
|
+
const event = queue.pop() as {
|
|
178
|
+
event: string;
|
|
179
|
+
payload: Record<string, unknown>;
|
|
180
|
+
};
|
|
181
|
+
config.replay(this, event.event, event.payload);
|
|
182
|
+
}
|
|
126
183
|
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const archQueue = (window as any)[ARCH_LISTENER_QUEUE];
|
|
130
|
-
if (Array.isArray(archQueue)) {
|
|
131
|
-
while (archQueue.length > 0) {
|
|
132
|
-
const event = archQueue.pop() as {
|
|
133
|
-
event: string;
|
|
134
|
-
payload: Record<string, unknown>;
|
|
135
|
-
};
|
|
136
|
-
archTrack(this, event.event, event.payload);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
184
|
+
});
|
|
139
185
|
}
|
|
140
186
|
|
|
141
187
|
renderedCallback() {
|