@avsbhq/node 1.7.0 → 1.7.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.
- package/dist/index.cjs +33 -3
- package/dist/index.d.cts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +33 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -701,7 +701,7 @@ function createServerTracker(options) {
|
|
|
701
701
|
var import_streaming = require("@avsbhq/utils/streaming");
|
|
702
702
|
|
|
703
703
|
// src/version.ts
|
|
704
|
-
var SDK_VERSION = "1.7.
|
|
704
|
+
var SDK_VERSION = "1.7.1";
|
|
705
705
|
|
|
706
706
|
// src/UserBoundClient.ts
|
|
707
707
|
var import_core6 = require("@avsbhq/core");
|
|
@@ -844,6 +844,12 @@ var AvsbServer = class {
|
|
|
844
844
|
readyPromise = null;
|
|
845
845
|
pendingEvents = [];
|
|
846
846
|
pendingPurchases = [];
|
|
847
|
+
/**
|
|
848
|
+
* Exposures produced before the tracker existed. Third member of the
|
|
849
|
+
* pre-ready family alongside `pendingEvents` and `pendingPurchases`; it used
|
|
850
|
+
* to be missing, and exposures were dropped on the floor instead.
|
|
851
|
+
*/
|
|
852
|
+
pendingExposures = [];
|
|
847
853
|
/** ms-epoch of the last liveness heartbeat, for the throttle. */
|
|
848
854
|
lastHeartbeatAt = 0;
|
|
849
855
|
/** Keys of one-time warnings, so a request loop cannot flood a log. */
|
|
@@ -920,6 +926,7 @@ var AvsbServer = class {
|
|
|
920
926
|
if (!keyShape.valid && keyShape.message) {
|
|
921
927
|
this.logger.error(keyShape.message);
|
|
922
928
|
}
|
|
929
|
+
if (this.datafile) this.initTracker();
|
|
923
930
|
}
|
|
924
931
|
// ---------------------------------------------------------------------------
|
|
925
932
|
// Readiness
|
|
@@ -1029,7 +1036,9 @@ var AvsbServer = class {
|
|
|
1029
1036
|
this.logger.warn(
|
|
1030
1037
|
"AvsB datafile refresh did not apply a new datafile; the SDK keeps serving the one it already has. The request error is logged above."
|
|
1031
1038
|
);
|
|
1039
|
+
return;
|
|
1032
1040
|
}
|
|
1041
|
+
if (result === "applied" && !this.ready) this.onDatafileReadable();
|
|
1033
1042
|
}
|
|
1034
1043
|
/**
|
|
1035
1044
|
* Adopt a datafile received out of band: a bootstrap blob from
|
|
@@ -1049,6 +1058,7 @@ var AvsbServer = class {
|
|
|
1049
1058
|
this.onDatafileReadable();
|
|
1050
1059
|
return;
|
|
1051
1060
|
}
|
|
1061
|
+
this.initTracker();
|
|
1052
1062
|
if (changed) {
|
|
1053
1063
|
this.emit("configUpdate", {
|
|
1054
1064
|
publishedAt: datafile.publishedAt,
|
|
@@ -1456,7 +1466,11 @@ var AvsbServer = class {
|
|
|
1456
1466
|
*/
|
|
1457
1467
|
deliverExposure(event) {
|
|
1458
1468
|
const stamped = event.eventId ? event : { ...event, eventId: (0, import_node_crypto2.randomUUID)() };
|
|
1459
|
-
this.tracker
|
|
1469
|
+
if (this.tracker) {
|
|
1470
|
+
this.tracker.queue(stamped);
|
|
1471
|
+
} else {
|
|
1472
|
+
this.enqueuePendingExposure(stamped);
|
|
1473
|
+
}
|
|
1460
1474
|
this.emit("exposure", stamped);
|
|
1461
1475
|
}
|
|
1462
1476
|
toFlag(result, defaultValue) {
|
|
@@ -1579,7 +1593,7 @@ var AvsbServer = class {
|
|
|
1579
1593
|
// ---------------------------------------------------------------------------
|
|
1580
1594
|
initTracker() {
|
|
1581
1595
|
if (!this.datafile || this.tracker) return;
|
|
1582
|
-
|
|
1596
|
+
const tracker = createServerTracker({
|
|
1583
1597
|
sdkKey: this.sdkKey,
|
|
1584
1598
|
collectEndpoint: this.datafile.collectEndpoint,
|
|
1585
1599
|
flushInterval: this.eventOptions.flushInterval,
|
|
@@ -1588,6 +1602,12 @@ var AvsbServer = class {
|
|
|
1588
1602
|
retryAttempts: this.eventOptions.retryAttempts,
|
|
1589
1603
|
logger: this.logger
|
|
1590
1604
|
});
|
|
1605
|
+
this.tracker = tracker;
|
|
1606
|
+
if (this.pendingExposures.length > 0) {
|
|
1607
|
+
const queued = this.pendingExposures;
|
|
1608
|
+
this.pendingExposures = [];
|
|
1609
|
+
for (const event of queued) tracker.queue(event);
|
|
1610
|
+
}
|
|
1591
1611
|
if (this.pendingEvents.length > 0) {
|
|
1592
1612
|
const queued = this.pendingEvents;
|
|
1593
1613
|
this.pendingEvents = [];
|
|
@@ -1599,6 +1619,16 @@ var AvsbServer = class {
|
|
|
1599
1619
|
for (const item of queued) void this.trackPurchase(item.visitorId, item.order);
|
|
1600
1620
|
}
|
|
1601
1621
|
}
|
|
1622
|
+
enqueuePendingExposure(event) {
|
|
1623
|
+
if (this.pendingExposures.length >= this.eventOptions.maxQueueSize) {
|
|
1624
|
+
this.pendingExposures.shift();
|
|
1625
|
+
this.warnOnce(
|
|
1626
|
+
"pending-exposures-full",
|
|
1627
|
+
`Pre-ready exposure queue reached ${this.eventOptions.maxQueueSize} events; the oldest are being dropped. This means the datafile never loaded, so nothing has been delivered yet: check the datafile error logged above.`
|
|
1628
|
+
);
|
|
1629
|
+
}
|
|
1630
|
+
this.pendingExposures.push(event);
|
|
1631
|
+
}
|
|
1602
1632
|
enqueuePending(eventKey, payload) {
|
|
1603
1633
|
if (this.pendingEvents.length >= this.eventOptions.maxQueueSize) {
|
|
1604
1634
|
this.pendingEvents.shift();
|
package/dist/index.d.cts
CHANGED
|
@@ -375,6 +375,12 @@ declare class AvsbServer {
|
|
|
375
375
|
private readyPromise;
|
|
376
376
|
private pendingEvents;
|
|
377
377
|
private pendingPurchases;
|
|
378
|
+
/**
|
|
379
|
+
* Exposures produced before the tracker existed. Third member of the
|
|
380
|
+
* pre-ready family alongside `pendingEvents` and `pendingPurchases`; it used
|
|
381
|
+
* to be missing, and exposures were dropped on the floor instead.
|
|
382
|
+
*/
|
|
383
|
+
private pendingExposures;
|
|
378
384
|
/** ms-epoch of the last liveness heartbeat, for the throttle. */
|
|
379
385
|
private lastHeartbeatAt;
|
|
380
386
|
/** Keys of one-time warnings, so a request loop cannot flood a log. */
|
|
@@ -535,6 +541,7 @@ declare class AvsbServer {
|
|
|
535
541
|
private findVariation;
|
|
536
542
|
private fireExposureForStickyAssignment;
|
|
537
543
|
private initTracker;
|
|
544
|
+
private enqueuePendingExposure;
|
|
538
545
|
private enqueuePending;
|
|
539
546
|
/**
|
|
540
547
|
* Fetch and apply the datafile.
|
|
@@ -669,6 +676,6 @@ type WebhookVerifyResult = {
|
|
|
669
676
|
*/
|
|
670
677
|
declare function verifyWebhookSignature(payload: string | Buffer, headers: WebhookHeaders, secret: string, options?: VerifyWebhookOptions): WebhookVerifyResult;
|
|
671
678
|
|
|
672
|
-
declare const SDK_VERSION = "1.7.
|
|
679
|
+
declare const SDK_VERSION = "1.7.1";
|
|
673
680
|
|
|
674
681
|
export { AvsbServer, type AvsbServerOptions, DEFAULT_TOLERANCE_SECONDS, type DatafileRecipe, type DatasetGetResult, type DatasetsClient, type EventOptions, type GetAllFlagsOptions, InMemoryStickyBucketService, type PurchaseOrder, type RecProduct, type RecsAttribution, type RecsClient, type RecsGetRequest, type RecsResult, type RedisLike, type RedisStickyBucketOptions, RedisStickyBucketService, SDK_VERSION, type ServerEventMap, type ServerEventName, type ServerGetFlagOptions, type ServerLogLevel, type UserBoundClient, type VerifyWebhookOptions, type WebhookHeaders, type WebhookVerifyFailure, type WebhookVerifyResult, createDecisionLog, defaultLogger, isDevEnvironment, resolveServerLogger, verifyWebhookSignature };
|
package/dist/index.d.ts
CHANGED
|
@@ -375,6 +375,12 @@ declare class AvsbServer {
|
|
|
375
375
|
private readyPromise;
|
|
376
376
|
private pendingEvents;
|
|
377
377
|
private pendingPurchases;
|
|
378
|
+
/**
|
|
379
|
+
* Exposures produced before the tracker existed. Third member of the
|
|
380
|
+
* pre-ready family alongside `pendingEvents` and `pendingPurchases`; it used
|
|
381
|
+
* to be missing, and exposures were dropped on the floor instead.
|
|
382
|
+
*/
|
|
383
|
+
private pendingExposures;
|
|
378
384
|
/** ms-epoch of the last liveness heartbeat, for the throttle. */
|
|
379
385
|
private lastHeartbeatAt;
|
|
380
386
|
/** Keys of one-time warnings, so a request loop cannot flood a log. */
|
|
@@ -535,6 +541,7 @@ declare class AvsbServer {
|
|
|
535
541
|
private findVariation;
|
|
536
542
|
private fireExposureForStickyAssignment;
|
|
537
543
|
private initTracker;
|
|
544
|
+
private enqueuePendingExposure;
|
|
538
545
|
private enqueuePending;
|
|
539
546
|
/**
|
|
540
547
|
* Fetch and apply the datafile.
|
|
@@ -669,6 +676,6 @@ type WebhookVerifyResult = {
|
|
|
669
676
|
*/
|
|
670
677
|
declare function verifyWebhookSignature(payload: string | Buffer, headers: WebhookHeaders, secret: string, options?: VerifyWebhookOptions): WebhookVerifyResult;
|
|
671
678
|
|
|
672
|
-
declare const SDK_VERSION = "1.7.
|
|
679
|
+
declare const SDK_VERSION = "1.7.1";
|
|
673
680
|
|
|
674
681
|
export { AvsbServer, type AvsbServerOptions, DEFAULT_TOLERANCE_SECONDS, type DatafileRecipe, type DatasetGetResult, type DatasetsClient, type EventOptions, type GetAllFlagsOptions, InMemoryStickyBucketService, type PurchaseOrder, type RecProduct, type RecsAttribution, type RecsClient, type RecsGetRequest, type RecsResult, type RedisLike, type RedisStickyBucketOptions, RedisStickyBucketService, SDK_VERSION, type ServerEventMap, type ServerEventName, type ServerGetFlagOptions, type ServerLogLevel, type UserBoundClient, type VerifyWebhookOptions, type WebhookHeaders, type WebhookVerifyFailure, type WebhookVerifyResult, createDecisionLog, defaultLogger, isDevEnvironment, resolveServerLogger, verifyWebhookSignature };
|
package/dist/index.js
CHANGED
|
@@ -667,7 +667,7 @@ import {
|
|
|
667
667
|
} from "@avsbhq/utils/streaming";
|
|
668
668
|
|
|
669
669
|
// src/version.ts
|
|
670
|
-
var SDK_VERSION = "1.7.
|
|
670
|
+
var SDK_VERSION = "1.7.1";
|
|
671
671
|
|
|
672
672
|
// src/UserBoundClient.ts
|
|
673
673
|
import { bucketingKey } from "@avsbhq/core";
|
|
@@ -810,6 +810,12 @@ var AvsbServer = class {
|
|
|
810
810
|
readyPromise = null;
|
|
811
811
|
pendingEvents = [];
|
|
812
812
|
pendingPurchases = [];
|
|
813
|
+
/**
|
|
814
|
+
* Exposures produced before the tracker existed. Third member of the
|
|
815
|
+
* pre-ready family alongside `pendingEvents` and `pendingPurchases`; it used
|
|
816
|
+
* to be missing, and exposures were dropped on the floor instead.
|
|
817
|
+
*/
|
|
818
|
+
pendingExposures = [];
|
|
813
819
|
/** ms-epoch of the last liveness heartbeat, for the throttle. */
|
|
814
820
|
lastHeartbeatAt = 0;
|
|
815
821
|
/** Keys of one-time warnings, so a request loop cannot flood a log. */
|
|
@@ -886,6 +892,7 @@ var AvsbServer = class {
|
|
|
886
892
|
if (!keyShape.valid && keyShape.message) {
|
|
887
893
|
this.logger.error(keyShape.message);
|
|
888
894
|
}
|
|
895
|
+
if (this.datafile) this.initTracker();
|
|
889
896
|
}
|
|
890
897
|
// ---------------------------------------------------------------------------
|
|
891
898
|
// Readiness
|
|
@@ -995,7 +1002,9 @@ var AvsbServer = class {
|
|
|
995
1002
|
this.logger.warn(
|
|
996
1003
|
"AvsB datafile refresh did not apply a new datafile; the SDK keeps serving the one it already has. The request error is logged above."
|
|
997
1004
|
);
|
|
1005
|
+
return;
|
|
998
1006
|
}
|
|
1007
|
+
if (result === "applied" && !this.ready) this.onDatafileReadable();
|
|
999
1008
|
}
|
|
1000
1009
|
/**
|
|
1001
1010
|
* Adopt a datafile received out of band: a bootstrap blob from
|
|
@@ -1015,6 +1024,7 @@ var AvsbServer = class {
|
|
|
1015
1024
|
this.onDatafileReadable();
|
|
1016
1025
|
return;
|
|
1017
1026
|
}
|
|
1027
|
+
this.initTracker();
|
|
1018
1028
|
if (changed) {
|
|
1019
1029
|
this.emit("configUpdate", {
|
|
1020
1030
|
publishedAt: datafile.publishedAt,
|
|
@@ -1422,7 +1432,11 @@ var AvsbServer = class {
|
|
|
1422
1432
|
*/
|
|
1423
1433
|
deliverExposure(event) {
|
|
1424
1434
|
const stamped = event.eventId ? event : { ...event, eventId: randomUUID2() };
|
|
1425
|
-
this.tracker
|
|
1435
|
+
if (this.tracker) {
|
|
1436
|
+
this.tracker.queue(stamped);
|
|
1437
|
+
} else {
|
|
1438
|
+
this.enqueuePendingExposure(stamped);
|
|
1439
|
+
}
|
|
1426
1440
|
this.emit("exposure", stamped);
|
|
1427
1441
|
}
|
|
1428
1442
|
toFlag(result, defaultValue) {
|
|
@@ -1545,7 +1559,7 @@ var AvsbServer = class {
|
|
|
1545
1559
|
// ---------------------------------------------------------------------------
|
|
1546
1560
|
initTracker() {
|
|
1547
1561
|
if (!this.datafile || this.tracker) return;
|
|
1548
|
-
|
|
1562
|
+
const tracker = createServerTracker({
|
|
1549
1563
|
sdkKey: this.sdkKey,
|
|
1550
1564
|
collectEndpoint: this.datafile.collectEndpoint,
|
|
1551
1565
|
flushInterval: this.eventOptions.flushInterval,
|
|
@@ -1554,6 +1568,12 @@ var AvsbServer = class {
|
|
|
1554
1568
|
retryAttempts: this.eventOptions.retryAttempts,
|
|
1555
1569
|
logger: this.logger
|
|
1556
1570
|
});
|
|
1571
|
+
this.tracker = tracker;
|
|
1572
|
+
if (this.pendingExposures.length > 0) {
|
|
1573
|
+
const queued = this.pendingExposures;
|
|
1574
|
+
this.pendingExposures = [];
|
|
1575
|
+
for (const event of queued) tracker.queue(event);
|
|
1576
|
+
}
|
|
1557
1577
|
if (this.pendingEvents.length > 0) {
|
|
1558
1578
|
const queued = this.pendingEvents;
|
|
1559
1579
|
this.pendingEvents = [];
|
|
@@ -1565,6 +1585,16 @@ var AvsbServer = class {
|
|
|
1565
1585
|
for (const item of queued) void this.trackPurchase(item.visitorId, item.order);
|
|
1566
1586
|
}
|
|
1567
1587
|
}
|
|
1588
|
+
enqueuePendingExposure(event) {
|
|
1589
|
+
if (this.pendingExposures.length >= this.eventOptions.maxQueueSize) {
|
|
1590
|
+
this.pendingExposures.shift();
|
|
1591
|
+
this.warnOnce(
|
|
1592
|
+
"pending-exposures-full",
|
|
1593
|
+
`Pre-ready exposure queue reached ${this.eventOptions.maxQueueSize} events; the oldest are being dropped. This means the datafile never loaded, so nothing has been delivered yet: check the datafile error logged above.`
|
|
1594
|
+
);
|
|
1595
|
+
}
|
|
1596
|
+
this.pendingExposures.push(event);
|
|
1597
|
+
}
|
|
1568
1598
|
enqueuePending(eventKey, payload) {
|
|
1569
1599
|
if (this.pendingEvents.length >= this.eventOptions.maxQueueSize) {
|
|
1570
1600
|
this.pendingEvents.shift();
|
package/package.json
CHANGED