@chordcommerce/analytics 1.15.0 → 1.16.1

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.
@@ -16,6 +16,19 @@ export const addCdpSnippet = (options) => __awaiter(void 0, void 0, void 0, func
16
16
  if (!document || typeof document.createElement === 'undefined')
17
17
  return;
18
18
  const normalizedCDPDomain = normalizeCDPDomain(options.cdpDomain);
19
+ // Create a promise that resolves when CDP is ready
20
+ const cdpReadyPromise = new Promise((resolve) => {
21
+ const checkCdpReady = () => {
22
+ const cdp = window[`_${options.namespace}`];
23
+ if (cdp && typeof cdp.configure === 'function') {
24
+ resolve();
25
+ }
26
+ else {
27
+ setTimeout(checkCdpReady, 50);
28
+ }
29
+ };
30
+ checkCdpReady();
31
+ });
19
32
  const s = document.createElement('script');
20
33
  s.async = true;
21
34
  s.src = `${normalizedCDPDomain}/p.js`;
@@ -23,20 +36,11 @@ export const addCdpSnippet = (options) => __awaiter(void 0, void 0, void 0, func
23
36
  s.setAttribute('data-init-only', 'true');
24
37
  s.setAttribute('data-namespace', `_${options.namespace}`);
25
38
  s.setAttribute('data-write-key', options.cdpWriteKey);
39
+ document.head.appendChild(s);
40
+ // Wait for CDP to be ready before setting up consent
41
+ yield cdpReadyPromise;
26
42
  if (options.consent) {
27
- // If awaitConsent is true, wait for consent before loading CDP
28
- if (options.awaitConsent) {
29
- yield addCdpConsent(options).init();
30
- document.head.appendChild(s);
31
- }
32
- else {
33
- document.head.appendChild(s);
34
- // If not awaiting consent, initialize in the background
35
- addCdpConsent(options).init().catch(console.error);
36
- }
37
- }
38
- else {
39
- document.head.appendChild(s);
43
+ addCdpConsent(options).init();
40
44
  }
41
45
  });
42
46
  /*
@@ -15,7 +15,9 @@ export const addCdpConsent = (options) => {
15
15
  let adapter = null;
16
16
  let lastProcessedConsent = null;
17
17
  const POLLING_INTERVAL_MS = 50;
18
- const TIMEOUT_MS = 60000;
18
+ const TIMEOUT_MS = options.awaitConsentTimeout
19
+ ? options.awaitConsentTimeout
20
+ : 60000;
19
21
  /**
20
22
  * Returns the adapter for the specified consent management platform.
21
23
  */
@@ -66,7 +68,9 @@ export const addCdpConsent = (options) => {
66
68
  const cdp = window[`_${options.namespace}`];
67
69
  if (cdp && typeof cdp.configure === 'function') {
68
70
  try {
69
- cdp.configure({ privacy: updatedConsent });
71
+ if (Object.keys(updatedConsent).length > 0) {
72
+ cdp.configure({ privacy: updatedConsent });
73
+ }
70
74
  return true;
71
75
  }
72
76
  catch (error) {
@@ -21,7 +21,15 @@ export declare class ChordAnalytics<T extends ObjectTypes = ObjectTypes> {
21
21
  * Options for ChordAnalytics.
22
22
  */
23
23
  options: ChordAnalyticsOptions<T>;
24
+ /**
25
+ * Promise that resolves when CDP is ready
26
+ */
27
+ private cdpReadyPromise;
24
28
  constructor(options: ChordAnalyticsOptions<T>);
29
+ /**
30
+ * Initialize CDP snippet and wait for it to be ready
31
+ */
32
+ private initializeCdp;
25
33
  /**
26
34
  * Set debug mode for Chord Analytics
27
35
  * @param enabled - Whether debug mode should be enabled
@@ -22,6 +22,10 @@ export class ChordAnalytics {
22
22
  * Allows snippet.js to detect whether the snippet has started running yet.
23
23
  */
24
24
  this.invoked = true;
25
+ /**
26
+ * Promise that resolves when CDP is ready
27
+ */
28
+ this.cdpReadyPromise = null;
25
29
  /**
26
30
  * Set debug mode for Chord Analytics
27
31
  * @param enabled - Whether debug mode should be enabled
@@ -92,9 +96,13 @@ export class ChordAnalytics {
92
96
  /**
93
97
  * Send a `track` event to the CDP with any event name and properties.
94
98
  */
95
- this.track = (event, props, options) => {
99
+ this.track = (event, props, options) => __awaiter(this, void 0, void 0, function* () {
96
100
  if (!event)
97
101
  this.logger('No event name provided');
102
+ // Wait for CDP to be ready before sending track events
103
+ if (this.cdpReadyPromise) {
104
+ yield this.cdpReadyPromise;
105
+ }
98
106
  const formattedProps = this.options.stripNull && props ? pruneNullValues(props) : props;
99
107
  const finalEventProps = Object.assign(Object.assign({}, formattedProps), { meta: this.meta() });
100
108
  if (this.options.debug) {
@@ -136,11 +144,15 @@ export class ChordAnalytics {
136
144
  resolve();
137
145
  }
138
146
  });
139
- };
147
+ });
140
148
  /**
141
149
  * Send an `identify` event to the CDP with user id and traits.
142
150
  */
143
- this.identify = (...props) => {
151
+ this.identify = (...props) => __awaiter(this, void 0, void 0, function* () {
152
+ // Wait for CDP to be ready before sending identify events
153
+ if (this.cdpReadyPromise) {
154
+ yield this.cdpReadyPromise;
155
+ }
144
156
  try {
145
157
  const identifyPromises = [];
146
158
  const a = this.ccdp();
@@ -163,11 +175,15 @@ export class ChordAnalytics {
163
175
  catch (error) {
164
176
  this.logger(error);
165
177
  }
166
- };
178
+ });
167
179
  /**
168
180
  * Send a `page` event to the CDP.
169
181
  */
170
- this.page = (props = {}) => {
182
+ this.page = (props = {}) => __awaiter(this, void 0, void 0, function* () {
183
+ // Wait for CDP to be ready before sending page events
184
+ if (this.cdpReadyPromise) {
185
+ yield this.cdpReadyPromise;
186
+ }
171
187
  try {
172
188
  const pagePromises = [];
173
189
  const a = this.ccdp();
@@ -190,7 +206,7 @@ export class ChordAnalytics {
190
206
  catch (error) {
191
207
  this.logger(error);
192
208
  }
193
- };
209
+ });
194
210
  this.reset = () => {
195
211
  try {
196
212
  const resetPromises = [];
@@ -609,12 +625,25 @@ export class ChordAnalytics {
609
625
  enableLogging: debug,
610
626
  namespace: 'chord',
611
627
  stripNull: true,
612
- awaitConsent: true,
613
628
  };
614
629
  this.options = Object.assign(Object.assign({}, defaults), options);
615
630
  if (((_b = this.options) === null || _b === void 0 ? void 0 : _b.cdpDomain) && ((_c = this.options) === null || _c === void 0 ? void 0 : _c.cdpWriteKey) && window) {
616
631
  window[this.options.namespace] = (window === null || window === void 0 ? void 0 : window[this.options.namespace]) || this;
617
- addCdpSnippet(this.options);
632
+ this.initializeCdp();
618
633
  }
619
634
  }
635
+ /**
636
+ * Initialize CDP snippet and wait for it to be ready
637
+ */
638
+ initializeCdp() {
639
+ return __awaiter(this, void 0, void 0, function* () {
640
+ try {
641
+ this.cdpReadyPromise = addCdpSnippet(this.options);
642
+ yield this.cdpReadyPromise;
643
+ }
644
+ catch (error) {
645
+ console.error('CDP initialization failed:', error);
646
+ }
647
+ });
648
+ }
620
649
  }
@@ -38,6 +38,7 @@ export interface ChordAnalyticsOptions<T extends ObjectTypes = ObjectTypes> {
38
38
  namespace?: string;
39
39
  stripNull?: boolean;
40
40
  metadata: EventMetadata;
41
+ awaitConsentTimeout?: number;
41
42
  }
42
43
  export interface EventMetadata {
43
44
  i18n: i18nMetadata;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chordcommerce/analytics",
3
3
  "description": "Chord Commerce event tracking",
4
- "version": "1.15.0",
4
+ "version": "1.16.1",
5
5
  "author": "Chord Commerce <help@chord.co> (https://www.chord.co)",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",