@chordcommerce/analytics 1.22.1-beta.1 → 1.22.2
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/dist/cjs/client/index.d.ts +3 -1
- package/dist/cjs/client/index.js +46 -19
- package/dist/client/index.d.ts +3 -1
- package/dist/client/index.js +37 -25
- package/package.json +1 -1
|
@@ -31,7 +31,7 @@ export declare class ChordAnalytics<T extends ObjectTypes = ObjectTypes> {
|
|
|
31
31
|
*/
|
|
32
32
|
private cdpReadyPromise;
|
|
33
33
|
private consentConfig;
|
|
34
|
-
private
|
|
34
|
+
private resetCompletePromise;
|
|
35
35
|
/**
|
|
36
36
|
* Queue for events waiting for consent to be ready
|
|
37
37
|
*/
|
|
@@ -73,6 +73,7 @@ export declare class ChordAnalytics<T extends ObjectTypes = ObjectTypes> {
|
|
|
73
73
|
ccdp: () => AnyAnalytics;
|
|
74
74
|
logger: (message?: any, ...optionalParams: any[]) => void;
|
|
75
75
|
isResetting: () => boolean;
|
|
76
|
+
private waitForReadyState;
|
|
76
77
|
/**
|
|
77
78
|
* Wait for consent manager to be ready (no timeout - queues indefinitely).
|
|
78
79
|
* Uses a shared promise so multiple events share the same watcher.
|
|
@@ -151,6 +152,7 @@ export declare class ChordAnalytics<T extends ObjectTypes = ObjectTypes> {
|
|
|
151
152
|
*/
|
|
152
153
|
private sendPageEvent;
|
|
153
154
|
reset: () => Promise<void>;
|
|
155
|
+
private performReset;
|
|
154
156
|
/**
|
|
155
157
|
* Handler for postMessage events from the Shopify Web Pixel sandbox.
|
|
156
158
|
* Bound to the instance for proper `this` context and cleanup.
|
package/dist/cjs/client/index.js
CHANGED
|
@@ -87,7 +87,9 @@ var ChordAnalytics = /** @class */ (function () {
|
|
|
87
87
|
*/
|
|
88
88
|
this.cdpReadyPromise = null;
|
|
89
89
|
this.consentConfig = null;
|
|
90
|
-
|
|
90
|
+
// Non-null while reset() is in flight. Acts as both the coalescing handle and
|
|
91
|
+
// the gate that track/identify/page await before executing.
|
|
92
|
+
this.resetCompletePromise = null;
|
|
91
93
|
/**
|
|
92
94
|
* Queue for events waiting for consent to be ready
|
|
93
95
|
*/
|
|
@@ -260,7 +262,21 @@ var ChordAnalytics = /** @class */ (function () {
|
|
|
260
262
|
console.log.apply(console, __spreadArray([message], optionalParams, false));
|
|
261
263
|
};
|
|
262
264
|
this.isResetting = function () {
|
|
263
|
-
return _this.
|
|
265
|
+
return _this.resetCompletePromise !== null;
|
|
266
|
+
};
|
|
267
|
+
// Single gate for all outgoing operations. Returns a Promise only when there
|
|
268
|
+
// is actually something to wait for, preserving synchronous execution in the
|
|
269
|
+
// common case where CDP is ready and no reset is in flight.
|
|
270
|
+
this.waitForReadyState = function () {
|
|
271
|
+
var cdp = _this.cdpReadyPromise;
|
|
272
|
+
var reset = _this.resetCompletePromise;
|
|
273
|
+
if (!cdp && !reset)
|
|
274
|
+
return undefined;
|
|
275
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
276
|
+
if (cdp && reset)
|
|
277
|
+
return Promise.all([cdp, reset]).then(function () { });
|
|
278
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
279
|
+
return cdp !== null && cdp !== void 0 ? cdp : reset;
|
|
264
280
|
};
|
|
265
281
|
/**
|
|
266
282
|
* Wait for consent manager to be ready (no timeout - queues indefinitely).
|
|
@@ -453,6 +469,7 @@ var ChordAnalytics = /** @class */ (function () {
|
|
|
453
469
|
* If consent is not ready, the event is queued until consent is available.
|
|
454
470
|
*/
|
|
455
471
|
this.track = function (event, props, options) { return __awaiter(_this, void 0, void 0, function () {
|
|
472
|
+
var gate;
|
|
456
473
|
return __generator(this, function (_a) {
|
|
457
474
|
switch (_a.label) {
|
|
458
475
|
case 0:
|
|
@@ -462,18 +479,13 @@ var ChordAnalytics = /** @class */ (function () {
|
|
|
462
479
|
}
|
|
463
480
|
if (!event)
|
|
464
481
|
this.logger('No event name provided');
|
|
465
|
-
|
|
466
|
-
if (
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
return [4 /*yield*/, this.cdpReadyPromise];
|
|
482
|
+
gate = this.waitForReadyState();
|
|
483
|
+
if (!gate) return [3 /*break*/, 2];
|
|
484
|
+
return [4 /*yield*/, gate
|
|
485
|
+
// If consent is configured but not ready, queue the event
|
|
486
|
+
];
|
|
471
487
|
case 1:
|
|
472
488
|
_a.sent();
|
|
473
|
-
if (this.options.enableLogging && this.options.debug) {
|
|
474
|
-
// eslint-disable-next-line no-console
|
|
475
|
-
console.log("[Chord Analytics DEBUG]: track(\"".concat(event, "\") cdpReadyPromise resolved"));
|
|
476
|
-
}
|
|
477
489
|
_a.label = 2;
|
|
478
490
|
case 2:
|
|
479
491
|
// If consent is configured but not ready, queue the event
|
|
@@ -583,11 +595,15 @@ var ChordAnalytics = /** @class */ (function () {
|
|
|
583
595
|
* If consent is not ready, the event is queued until consent is available.
|
|
584
596
|
*/
|
|
585
597
|
this.identify = function (userIdOrTraits, traitsOrOptions, options) { return __awaiter(_this, void 0, void 0, function () {
|
|
598
|
+
var gate;
|
|
586
599
|
return __generator(this, function (_a) {
|
|
587
600
|
switch (_a.label) {
|
|
588
601
|
case 0:
|
|
589
|
-
|
|
590
|
-
return [
|
|
602
|
+
gate = this.waitForReadyState();
|
|
603
|
+
if (!gate) return [3 /*break*/, 2];
|
|
604
|
+
return [4 /*yield*/, gate
|
|
605
|
+
// If consent is configured but not ready, queue the event
|
|
606
|
+
];
|
|
591
607
|
case 1:
|
|
592
608
|
_a.sent();
|
|
593
609
|
_a.label = 2;
|
|
@@ -670,11 +686,15 @@ var ChordAnalytics = /** @class */ (function () {
|
|
|
670
686
|
this.page = function (options, props) {
|
|
671
687
|
if (props === void 0) { props = {}; }
|
|
672
688
|
return __awaiter(_this, void 0, void 0, function () {
|
|
689
|
+
var gate;
|
|
673
690
|
return __generator(this, function (_a) {
|
|
674
691
|
switch (_a.label) {
|
|
675
692
|
case 0:
|
|
676
|
-
|
|
677
|
-
return [
|
|
693
|
+
gate = this.waitForReadyState();
|
|
694
|
+
if (!gate) return [3 /*break*/, 2];
|
|
695
|
+
return [4 /*yield*/, gate
|
|
696
|
+
// If consent is configured but not ready, queue the event
|
|
697
|
+
];
|
|
678
698
|
case 1:
|
|
679
699
|
_a.sent();
|
|
680
700
|
_a.label = 2;
|
|
@@ -742,14 +762,21 @@ var ChordAnalytics = /** @class */ (function () {
|
|
|
742
762
|
});
|
|
743
763
|
});
|
|
744
764
|
};
|
|
745
|
-
|
|
765
|
+
// Coalesces concurrent reset() calls — a second caller gets the same in-flight
|
|
766
|
+
// Promise rather than triggering a duplicate reset.
|
|
767
|
+
this.reset = function () {
|
|
768
|
+
if (!_this.resetCompletePromise) {
|
|
769
|
+
_this.resetCompletePromise = _this.performReset();
|
|
770
|
+
}
|
|
771
|
+
return _this.resetCompletePromise;
|
|
772
|
+
};
|
|
773
|
+
this.performReset = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
746
774
|
var a, b, maxAttempts, attempts, userState, error_3;
|
|
747
775
|
var _a;
|
|
748
776
|
return __generator(this, function (_b) {
|
|
749
777
|
switch (_b.label) {
|
|
750
778
|
case 0:
|
|
751
779
|
_b.trys.push([0, 4, 5, 6]);
|
|
752
|
-
this.resetInProgress = true;
|
|
753
780
|
a = this.ccdp();
|
|
754
781
|
if (a && typeof a.reset === 'function') {
|
|
755
782
|
a.reset();
|
|
@@ -785,7 +812,7 @@ var ChordAnalytics = /** @class */ (function () {
|
|
|
785
812
|
this.logger(error_3);
|
|
786
813
|
return [3 /*break*/, 6];
|
|
787
814
|
case 5:
|
|
788
|
-
this.
|
|
815
|
+
this.resetCompletePromise = null;
|
|
789
816
|
return [7 /*endfinally*/];
|
|
790
817
|
case 6: return [2 /*return*/];
|
|
791
818
|
}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export declare class ChordAnalytics<T extends ObjectTypes = ObjectTypes> {
|
|
|
31
31
|
*/
|
|
32
32
|
private cdpReadyPromise;
|
|
33
33
|
private consentConfig;
|
|
34
|
-
private
|
|
34
|
+
private resetCompletePromise;
|
|
35
35
|
/**
|
|
36
36
|
* Queue for events waiting for consent to be ready
|
|
37
37
|
*/
|
|
@@ -73,6 +73,7 @@ export declare class ChordAnalytics<T extends ObjectTypes = ObjectTypes> {
|
|
|
73
73
|
ccdp: () => AnyAnalytics;
|
|
74
74
|
logger: (message?: any, ...optionalParams: any[]) => void;
|
|
75
75
|
isResetting: () => boolean;
|
|
76
|
+
private waitForReadyState;
|
|
76
77
|
/**
|
|
77
78
|
* Wait for consent manager to be ready (no timeout - queues indefinitely).
|
|
78
79
|
* Uses a shared promise so multiple events share the same watcher.
|
|
@@ -151,6 +152,7 @@ export declare class ChordAnalytics<T extends ObjectTypes = ObjectTypes> {
|
|
|
151
152
|
*/
|
|
152
153
|
private sendPageEvent;
|
|
153
154
|
reset: () => Promise<void>;
|
|
155
|
+
private performReset;
|
|
154
156
|
/**
|
|
155
157
|
* Handler for postMessage events from the Shopify Web Pixel sandbox.
|
|
156
158
|
* Bound to the instance for proper `this` context and cleanup.
|
package/dist/client/index.js
CHANGED
|
@@ -36,7 +36,9 @@ export class ChordAnalytics {
|
|
|
36
36
|
*/
|
|
37
37
|
this.cdpReadyPromise = null;
|
|
38
38
|
this.consentConfig = null;
|
|
39
|
-
|
|
39
|
+
// Non-null while reset() is in flight. Acts as both the coalescing handle and
|
|
40
|
+
// the gate that track/identify/page await before executing.
|
|
41
|
+
this.resetCompletePromise = null;
|
|
40
42
|
/**
|
|
41
43
|
* Queue for events waiting for consent to be ready
|
|
42
44
|
*/
|
|
@@ -205,7 +207,21 @@ export class ChordAnalytics {
|
|
|
205
207
|
console.log(message, ...optionalParams);
|
|
206
208
|
};
|
|
207
209
|
this.isResetting = () => {
|
|
208
|
-
return this.
|
|
210
|
+
return this.resetCompletePromise !== null;
|
|
211
|
+
};
|
|
212
|
+
// Single gate for all outgoing operations. Returns a Promise only when there
|
|
213
|
+
// is actually something to wait for, preserving synchronous execution in the
|
|
214
|
+
// common case where CDP is ready and no reset is in flight.
|
|
215
|
+
this.waitForReadyState = () => {
|
|
216
|
+
const cdp = this.cdpReadyPromise;
|
|
217
|
+
const reset = this.resetCompletePromise;
|
|
218
|
+
if (!cdp && !reset)
|
|
219
|
+
return undefined;
|
|
220
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
221
|
+
if (cdp && reset)
|
|
222
|
+
return Promise.all([cdp, reset]).then(() => { });
|
|
223
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
224
|
+
return cdp !== null && cdp !== void 0 ? cdp : reset;
|
|
209
225
|
};
|
|
210
226
|
/**
|
|
211
227
|
* Wait for consent manager to be ready (no timeout - queues indefinitely).
|
|
@@ -359,18 +375,9 @@ export class ChordAnalytics {
|
|
|
359
375
|
}
|
|
360
376
|
if (!event)
|
|
361
377
|
this.logger('No event name provided');
|
|
362
|
-
|
|
363
|
-
if (
|
|
364
|
-
|
|
365
|
-
// eslint-disable-next-line no-console
|
|
366
|
-
console.log(`[Chord Analytics DEBUG]: track("${event}") waiting for cdpReadyPromise`);
|
|
367
|
-
}
|
|
368
|
-
yield this.cdpReadyPromise;
|
|
369
|
-
if (this.options.enableLogging && this.options.debug) {
|
|
370
|
-
// eslint-disable-next-line no-console
|
|
371
|
-
console.log(`[Chord Analytics DEBUG]: track("${event}") cdpReadyPromise resolved`);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
378
|
+
const gate = this.waitForReadyState();
|
|
379
|
+
if (gate)
|
|
380
|
+
yield gate;
|
|
374
381
|
// If consent is configured but not ready, queue the event
|
|
375
382
|
if (this.consentConfig && !this.consentConfig.isConsentReady()) {
|
|
376
383
|
if (this.options.enableLogging && this.options.debug) {
|
|
@@ -466,10 +473,9 @@ export class ChordAnalytics {
|
|
|
466
473
|
* If consent is not ready, the event is queued until consent is available.
|
|
467
474
|
*/
|
|
468
475
|
this.identify = (userIdOrTraits, traitsOrOptions, options) => __awaiter(this, void 0, void 0, function* () {
|
|
469
|
-
|
|
470
|
-
if (
|
|
471
|
-
yield
|
|
472
|
-
}
|
|
476
|
+
const gate = this.waitForReadyState();
|
|
477
|
+
if (gate)
|
|
478
|
+
yield gate;
|
|
473
479
|
// If consent is configured but not ready, queue the event
|
|
474
480
|
if (this.consentConfig && !this.consentConfig.isConsentReady()) {
|
|
475
481
|
return this.queueEventForConsent('identify', [
|
|
@@ -536,10 +542,9 @@ export class ChordAnalytics {
|
|
|
536
542
|
* If consent is not ready, the event is queued until consent is available.
|
|
537
543
|
*/
|
|
538
544
|
this.page = (options, props = {}) => __awaiter(this, void 0, void 0, function* () {
|
|
539
|
-
|
|
540
|
-
if (
|
|
541
|
-
yield
|
|
542
|
-
}
|
|
545
|
+
const gate = this.waitForReadyState();
|
|
546
|
+
if (gate)
|
|
547
|
+
yield gate;
|
|
543
548
|
// If consent is configured but not ready, queue the event
|
|
544
549
|
if (this.consentConfig && !this.consentConfig.isConsentReady()) {
|
|
545
550
|
return this.queueEventForConsent('page', [options, props]);
|
|
@@ -584,10 +589,17 @@ export class ChordAnalytics {
|
|
|
584
589
|
}
|
|
585
590
|
});
|
|
586
591
|
});
|
|
587
|
-
|
|
592
|
+
// Coalesces concurrent reset() calls — a second caller gets the same in-flight
|
|
593
|
+
// Promise rather than triggering a duplicate reset.
|
|
594
|
+
this.reset = () => {
|
|
595
|
+
if (!this.resetCompletePromise) {
|
|
596
|
+
this.resetCompletePromise = this.performReset();
|
|
597
|
+
}
|
|
598
|
+
return this.resetCompletePromise;
|
|
599
|
+
};
|
|
600
|
+
this.performReset = () => __awaiter(this, void 0, void 0, function* () {
|
|
588
601
|
var _e;
|
|
589
602
|
try {
|
|
590
|
-
this.resetInProgress = true;
|
|
591
603
|
const a = this.ccdp();
|
|
592
604
|
if (a && typeof a.reset === 'function') {
|
|
593
605
|
a.reset();
|
|
@@ -617,7 +629,7 @@ export class ChordAnalytics {
|
|
|
617
629
|
this.logger(error);
|
|
618
630
|
}
|
|
619
631
|
finally {
|
|
620
|
-
this.
|
|
632
|
+
this.resetCompletePromise = null;
|
|
621
633
|
}
|
|
622
634
|
});
|
|
623
635
|
/**
|
package/package.json
CHANGED