@pixels-online/pixels-client-js-sdk 1.17.0 → 1.19.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/dist/core/OfferStore.d.ts +20 -14
- package/dist/core/OfferwallClient.d.ts +6 -4
- package/dist/index.esm.js +265 -78
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +266 -77
- package/dist/index.js.map +1 -1
- package/dist/offerwall-sdk.umd.js +266 -77
- package/dist/offerwall-sdk.umd.js.map +1 -1
- package/dist/utils/conditions.d.ts +13 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -628,25 +628,33 @@ class SSEConnection {
|
|
|
628
628
|
}
|
|
629
629
|
|
|
630
630
|
class OfferStore {
|
|
631
|
-
constructor(config) {
|
|
631
|
+
constructor(config, client) {
|
|
632
|
+
this.client = client;
|
|
632
633
|
this.offers = new Map();
|
|
633
|
-
this.
|
|
634
|
+
this.players = new Map();
|
|
634
635
|
this.logger = createLogger(config, 'OfferStore');
|
|
635
636
|
}
|
|
636
|
-
getPlayer() {
|
|
637
|
-
|
|
637
|
+
getPlayer(targetId = this.client.getSelfId()) {
|
|
638
|
+
if (!targetId)
|
|
639
|
+
return null;
|
|
640
|
+
return this.players.get(targetId) || null;
|
|
638
641
|
}
|
|
639
642
|
setPlayer(player) {
|
|
640
|
-
this.player
|
|
643
|
+
this.players.set(player.snapshot.playerId, player);
|
|
641
644
|
this.logger.log('Updated player:', player);
|
|
642
645
|
}
|
|
643
646
|
/**
|
|
644
647
|
* Set all offers (replaces existing)
|
|
645
648
|
*/
|
|
646
|
-
setOffers(offers) {
|
|
647
|
-
this.
|
|
649
|
+
setOffers(offers, target) {
|
|
650
|
+
const targetPlayer = target || this.getPlayer();
|
|
651
|
+
if (!targetPlayer) {
|
|
652
|
+
this.logger.warn('No target player to set offers for');
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
this.offers.set(targetPlayer.snapshot.playerId, new Map());
|
|
648
656
|
offers.forEach((offer) => {
|
|
649
|
-
this.offers.set(offer.instanceId, offer);
|
|
657
|
+
this.offers.get(targetPlayer.snapshot.playerId).set(offer.instanceId, offer);
|
|
650
658
|
});
|
|
651
659
|
this.logger.log(`Set ${offers.length} offers`);
|
|
652
660
|
}
|
|
@@ -654,16 +662,23 @@ class OfferStore {
|
|
|
654
662
|
* Add or update a single offer
|
|
655
663
|
*/
|
|
656
664
|
upsertOffer(offer) {
|
|
657
|
-
|
|
658
|
-
|
|
665
|
+
let playerOffers = this.offers.get(offer.playerId);
|
|
666
|
+
if (!playerOffers) {
|
|
667
|
+
playerOffers = new Map();
|
|
668
|
+
this.offers.set(offer.playerId, playerOffers);
|
|
669
|
+
}
|
|
670
|
+
const previousOffer = playerOffers.get(offer.instanceId);
|
|
671
|
+
playerOffers.set(offer.instanceId, offer);
|
|
659
672
|
this.logger.log(`${previousOffer ? 'Updated' : 'Added'} offer:`, offer.instanceId);
|
|
660
673
|
return previousOffer;
|
|
661
674
|
}
|
|
662
675
|
/**
|
|
663
676
|
* Remove an offer
|
|
664
677
|
*/
|
|
665
|
-
removeOffer(offerId) {
|
|
666
|
-
|
|
678
|
+
removeOffer(offerId, targetId = this.client.getSelfId()) {
|
|
679
|
+
if (!targetId)
|
|
680
|
+
return false;
|
|
681
|
+
const removed = this.offers.get(targetId)?.delete(offerId) || false;
|
|
667
682
|
if (removed) {
|
|
668
683
|
this.logger.log(`Removed offer:`, offerId);
|
|
669
684
|
}
|
|
@@ -672,26 +687,30 @@ class OfferStore {
|
|
|
672
687
|
/**
|
|
673
688
|
* Get a single offer
|
|
674
689
|
*/
|
|
675
|
-
getOffer(offerId) {
|
|
676
|
-
|
|
690
|
+
getOffer(offerId, targetId = this.client.getSelfId()) {
|
|
691
|
+
if (!targetId)
|
|
692
|
+
return undefined;
|
|
693
|
+
return this.offers.get(targetId)?.get(offerId);
|
|
677
694
|
}
|
|
678
695
|
/**
|
|
679
696
|
* Get all offers
|
|
680
697
|
*/
|
|
681
|
-
getAllOffers() {
|
|
682
|
-
|
|
698
|
+
getAllOffers(targetId = this.client.getSelfId()) {
|
|
699
|
+
if (!targetId)
|
|
700
|
+
return [];
|
|
701
|
+
return Array.from(this.offers.get(targetId)?.values() || []);
|
|
683
702
|
}
|
|
684
703
|
/**
|
|
685
704
|
* Get offers filtered by status
|
|
686
705
|
*/
|
|
687
|
-
getOffersByStatus(status) {
|
|
688
|
-
return this.getAllOffers().filter((offer) => offer.status === status);
|
|
706
|
+
getOffersByStatus(status, targetId = this.client.getSelfId()) {
|
|
707
|
+
return this.getAllOffers(targetId).filter((offer) => offer.status === status);
|
|
689
708
|
}
|
|
690
709
|
/**
|
|
691
710
|
* Get active offers (not expired, not claimed)
|
|
692
711
|
*/
|
|
693
|
-
getActiveOffers() {
|
|
694
|
-
return this.getAllOffers().filter((offer) => {
|
|
712
|
+
getActiveOffers(targetId = this.client.getSelfId()) {
|
|
713
|
+
return this.getAllOffers(targetId).filter((offer) => {
|
|
695
714
|
if (!offer.status)
|
|
696
715
|
return false; // Must have a status
|
|
697
716
|
return (offer.status === 'surfaced' ||
|
|
@@ -702,14 +721,14 @@ class OfferStore {
|
|
|
702
721
|
/**
|
|
703
722
|
* Get claimable offers
|
|
704
723
|
*/
|
|
705
|
-
getClaimableOffers() {
|
|
706
|
-
return this.getOffersByStatus('claimable');
|
|
724
|
+
getClaimableOffers(targetId = this.client.getSelfId()) {
|
|
725
|
+
return this.getOffersByStatus('claimable', targetId);
|
|
707
726
|
}
|
|
708
727
|
/**
|
|
709
728
|
* Check if an offer has expired
|
|
710
729
|
*/
|
|
711
|
-
isOfferExpired(offerId) {
|
|
712
|
-
const offer = this.getOffer(offerId);
|
|
730
|
+
isOfferExpired(offerId, targetId = this.client.getSelfId()) {
|
|
731
|
+
const offer = this.getOffer(offerId, targetId);
|
|
713
732
|
if (!offer)
|
|
714
733
|
return true;
|
|
715
734
|
// Check status
|
|
@@ -722,17 +741,29 @@ class OfferStore {
|
|
|
722
741
|
return false;
|
|
723
742
|
}
|
|
724
743
|
/**
|
|
725
|
-
* Clear all offers
|
|
744
|
+
* Clear all offers for a specific player
|
|
726
745
|
*/
|
|
727
|
-
clear() {
|
|
746
|
+
clear(targetId = this.client.getSelfId()) {
|
|
747
|
+
if (!targetId)
|
|
748
|
+
return;
|
|
749
|
+
this.offers.set(targetId, new Map());
|
|
750
|
+
this.logger.log('Cleared all offers for player:', targetId);
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
* Clear all offers for all players
|
|
754
|
+
*/
|
|
755
|
+
clearAll() {
|
|
728
756
|
this.offers.clear();
|
|
729
|
-
this.logger.log('Cleared all offers');
|
|
757
|
+
this.logger.log('Cleared all offers for all players');
|
|
730
758
|
}
|
|
731
759
|
/**
|
|
732
|
-
* Get offer count
|
|
760
|
+
* Get offer count (for self player)
|
|
733
761
|
*/
|
|
734
762
|
get size() {
|
|
735
|
-
|
|
763
|
+
const selfId = this.client.getSelfId();
|
|
764
|
+
if (!selfId)
|
|
765
|
+
return 0;
|
|
766
|
+
return this.offers.get(selfId)?.size || 0;
|
|
736
767
|
}
|
|
737
768
|
}
|
|
738
769
|
|
|
@@ -835,7 +866,9 @@ class AssetHelper {
|
|
|
835
866
|
return null;
|
|
836
867
|
}
|
|
837
868
|
setCurrencyAssetContents(currencies) {
|
|
838
|
-
|
|
869
|
+
Object.keys(currencies).forEach((key) => {
|
|
870
|
+
this.currencies[key] = currencies[key];
|
|
871
|
+
});
|
|
839
872
|
}
|
|
840
873
|
resolveReward(reward) {
|
|
841
874
|
if (reward.kind === 'loyalty_currency' && reward.rewardId) {
|
|
@@ -891,6 +924,7 @@ class OfferwallClient {
|
|
|
891
924
|
constructor(config) {
|
|
892
925
|
this.isInitializing = false;
|
|
893
926
|
this.pendingStackedToken = null;
|
|
927
|
+
this.selfId = null;
|
|
894
928
|
this.config = {
|
|
895
929
|
autoConnect: config.autoConnect ?? false,
|
|
896
930
|
reconnect: config.reconnect ?? true,
|
|
@@ -903,7 +937,7 @@ class OfferwallClient {
|
|
|
903
937
|
this.hooks = this.config.hooks || {};
|
|
904
938
|
this.logger = createLogger(this.config, 'OfferwallClient');
|
|
905
939
|
this.eventEmitter = new EventEmitter(this.config);
|
|
906
|
-
this.offerStore = new OfferStore(this.config);
|
|
940
|
+
this.offerStore = new OfferStore(this.config, this);
|
|
907
941
|
this.tokenManager = new TokenManager(this.config);
|
|
908
942
|
this.assetHelper = new AssetHelper(this.config);
|
|
909
943
|
this.sseConnection = new SSEConnection(this.config, this.eventEmitter, this.tokenManager);
|
|
@@ -944,6 +978,9 @@ class OfferwallClient {
|
|
|
944
978
|
get assets() {
|
|
945
979
|
return this.assetHelper;
|
|
946
980
|
}
|
|
981
|
+
getSelfId() {
|
|
982
|
+
return this.selfId;
|
|
983
|
+
}
|
|
947
984
|
/**
|
|
948
985
|
* Initialize the offerwall client and connect
|
|
949
986
|
*/
|
|
@@ -1006,8 +1043,9 @@ class OfferwallClient {
|
|
|
1006
1043
|
if (this.sseConnection) {
|
|
1007
1044
|
this.sseConnection.disconnect();
|
|
1008
1045
|
}
|
|
1009
|
-
this.offerStore.
|
|
1046
|
+
this.offerStore.clearAll();
|
|
1010
1047
|
this.tokenManager.clearToken();
|
|
1048
|
+
this.selfId = null;
|
|
1011
1049
|
if (this.hooks.afterDisconnect) {
|
|
1012
1050
|
await this.hooks.afterDisconnect();
|
|
1013
1051
|
}
|
|
@@ -1015,8 +1053,8 @@ class OfferwallClient {
|
|
|
1015
1053
|
/**
|
|
1016
1054
|
* Claim rewards for an offer
|
|
1017
1055
|
*/
|
|
1018
|
-
async claimReward(instanceId) {
|
|
1019
|
-
const offer = this.offerStore.getOffer(instanceId);
|
|
1056
|
+
async claimReward(instanceId, targetId = this.getSelfId()) {
|
|
1057
|
+
const offer = this.offerStore.getOffer(instanceId, targetId);
|
|
1020
1058
|
if (!offer) {
|
|
1021
1059
|
throw new Error(`Offer ${instanceId} not found`);
|
|
1022
1060
|
}
|
|
@@ -1031,7 +1069,7 @@ class OfferwallClient {
|
|
|
1031
1069
|
}
|
|
1032
1070
|
}
|
|
1033
1071
|
try {
|
|
1034
|
-
const response = await this.claimOfferAPI(instanceId);
|
|
1072
|
+
const response = await this.claimOfferAPI(instanceId, targetId);
|
|
1035
1073
|
const updatedOffer = { ...offer, status: 'claimed' };
|
|
1036
1074
|
this.offerStore.upsertOffer(updatedOffer);
|
|
1037
1075
|
this.eventEmitter.emit(OfferEvent.OFFER_CLAIMED, {
|
|
@@ -1087,7 +1125,7 @@ class OfferwallClient {
|
|
|
1087
1125
|
});
|
|
1088
1126
|
*/
|
|
1089
1127
|
this.eventEmitter.on(OfferEvent.OFFER_SURFACED, ({ offer }) => {
|
|
1090
|
-
this.offerStore.upsertOffer(offer);
|
|
1128
|
+
this.offerStore.upsertOffer(offer); // should always be selfId
|
|
1091
1129
|
this.logger.log(`Surfaced offer: ${offer.instanceId}`);
|
|
1092
1130
|
});
|
|
1093
1131
|
}
|
|
@@ -1117,23 +1155,27 @@ class OfferwallClient {
|
|
|
1117
1155
|
}
|
|
1118
1156
|
return response.json();
|
|
1119
1157
|
}
|
|
1120
|
-
async claimOfferAPI(instanceId) {
|
|
1158
|
+
async claimOfferAPI(instanceId, targetId = null) {
|
|
1121
1159
|
return this.postWithAuth('/v1/client/reward/claim', {
|
|
1122
1160
|
instanceId,
|
|
1123
1161
|
kind: 'offer',
|
|
1162
|
+
targetId: targetId || undefined,
|
|
1124
1163
|
});
|
|
1125
1164
|
}
|
|
1126
|
-
getPlayer() {
|
|
1127
|
-
return this.offerStore.getPlayer();
|
|
1165
|
+
getPlayer(targetId = this.getSelfId()) {
|
|
1166
|
+
return this.offerStore.getPlayer(targetId);
|
|
1128
1167
|
}
|
|
1129
|
-
getOffers() {
|
|
1130
|
-
return this.offerStore.getAllOffers();
|
|
1168
|
+
getOffers(targetId = this.getSelfId()) {
|
|
1169
|
+
return this.offerStore.getAllOffers(targetId);
|
|
1131
1170
|
}
|
|
1132
|
-
async refreshOffersAndPlayer() {
|
|
1171
|
+
async refreshOffersAndPlayer(targetId = null) {
|
|
1133
1172
|
try {
|
|
1134
|
-
const { offers, player } = await this.getOffersAndPlayer();
|
|
1135
|
-
|
|
1173
|
+
const { offers, player } = await this.getOffersAndPlayer(targetId);
|
|
1174
|
+
if (targetId == null) {
|
|
1175
|
+
this.selfId = player.snapshot.playerId;
|
|
1176
|
+
}
|
|
1136
1177
|
this.offerStore.setPlayer(player);
|
|
1178
|
+
this.offerStore.setOffers(offers, player);
|
|
1137
1179
|
this.eventEmitter.emit(OfferEvent.REFRESH, { offers, player: player });
|
|
1138
1180
|
this.logger.log('Refreshed offers and player snapshot');
|
|
1139
1181
|
}
|
|
@@ -1142,9 +1184,10 @@ class OfferwallClient {
|
|
|
1142
1184
|
throw error;
|
|
1143
1185
|
}
|
|
1144
1186
|
}
|
|
1145
|
-
async getOffersAndPlayer() {
|
|
1187
|
+
async getOffersAndPlayer(targetId = null) {
|
|
1146
1188
|
const data = await this.postWithAuth('/v1/client/player/campaigns', {
|
|
1147
1189
|
viewingCampaigns: true,
|
|
1190
|
+
targetId: targetId || undefined,
|
|
1148
1191
|
});
|
|
1149
1192
|
if (!data.offers || !Array.isArray(data.offers)) {
|
|
1150
1193
|
throw new Error('No offers returned from offers endpoint');
|
|
@@ -1919,6 +1962,8 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
|
|
|
1919
1962
|
const claimMultiplier = shouldScale ? (playerOffer.claimedCount || 0) + 1 : 1;
|
|
1920
1963
|
const conditionData = [];
|
|
1921
1964
|
let isValid = true;
|
|
1965
|
+
let maxTotalClaimsFromScaling = Infinity;
|
|
1966
|
+
const updateMax = (limit) => (maxTotalClaimsFromScaling = Math.min(maxTotalClaimsFromScaling, limit));
|
|
1922
1967
|
if (completionConditions?.context?.id) {
|
|
1923
1968
|
const hasTrackedContext = completionTrackers?.context &&
|
|
1924
1969
|
completionConditions.context.id === completionTrackers.context;
|
|
@@ -1935,17 +1980,22 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
|
|
|
1935
1980
|
}
|
|
1936
1981
|
else {
|
|
1937
1982
|
if (isDisqualify)
|
|
1938
|
-
return { isValid: false };
|
|
1983
|
+
return { isValid: false, availableClaimsNow: 0 };
|
|
1939
1984
|
}
|
|
1940
1985
|
}
|
|
1941
1986
|
if (conditions?.buyItem) {
|
|
1942
|
-
const
|
|
1943
|
-
const
|
|
1987
|
+
const baseAmount = conditions.buyItem.amount || 1;
|
|
1988
|
+
const scaledAmount = baseAmount * claimMultiplier;
|
|
1989
|
+
const trackerValue = completionTrackers?.buyItem || 0;
|
|
1990
|
+
const isDisqualify = trackerValue < scaledAmount;
|
|
1991
|
+
if (shouldScale && baseAmount > 0) {
|
|
1992
|
+
updateMax(Math.floor(trackerValue / baseAmount));
|
|
1993
|
+
}
|
|
1944
1994
|
if (addDetails) {
|
|
1945
1995
|
conditionData.push({
|
|
1946
1996
|
isMet: !isDisqualify,
|
|
1947
1997
|
kind: 'buyItem',
|
|
1948
|
-
trackerAmount:
|
|
1998
|
+
trackerAmount: trackerValue,
|
|
1949
1999
|
text: `Buy ${scaledAmount} ${conditions.buyItem.name}`,
|
|
1950
2000
|
});
|
|
1951
2001
|
if (isDisqualify)
|
|
@@ -1953,17 +2003,22 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
|
|
|
1953
2003
|
}
|
|
1954
2004
|
else {
|
|
1955
2005
|
if (isDisqualify)
|
|
1956
|
-
return { isValid: false };
|
|
2006
|
+
return { isValid: false, availableClaimsNow: 0 };
|
|
1957
2007
|
}
|
|
1958
2008
|
}
|
|
1959
2009
|
if (conditions?.spendCurrency) {
|
|
1960
|
-
const
|
|
1961
|
-
const
|
|
2010
|
+
const baseAmount = conditions.spendCurrency.amount || 1;
|
|
2011
|
+
const scaledAmount = baseAmount * claimMultiplier;
|
|
2012
|
+
const trackerValue = completionTrackers?.spendCurrency || 0;
|
|
2013
|
+
const isDisqualify = trackerValue < scaledAmount;
|
|
2014
|
+
if (shouldScale && baseAmount > 0) {
|
|
2015
|
+
updateMax(Math.floor(trackerValue / baseAmount));
|
|
2016
|
+
}
|
|
1962
2017
|
if (addDetails) {
|
|
1963
2018
|
conditionData.push({
|
|
1964
2019
|
isMet: !isDisqualify,
|
|
1965
2020
|
kind: 'spendCurrency',
|
|
1966
|
-
trackerAmount:
|
|
2021
|
+
trackerAmount: trackerValue,
|
|
1967
2022
|
text: `Spend ${scaledAmount} ${conditions.spendCurrency.name}`,
|
|
1968
2023
|
});
|
|
1969
2024
|
if (isDisqualify)
|
|
@@ -1971,17 +2026,22 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
|
|
|
1971
2026
|
}
|
|
1972
2027
|
else {
|
|
1973
2028
|
if (isDisqualify)
|
|
1974
|
-
return { isValid: false };
|
|
2029
|
+
return { isValid: false, availableClaimsNow: 0 };
|
|
1975
2030
|
}
|
|
1976
2031
|
}
|
|
1977
2032
|
if (conditions?.depositCurrency) {
|
|
1978
|
-
const
|
|
1979
|
-
const
|
|
2033
|
+
const baseAmount = conditions.depositCurrency.amount || 1;
|
|
2034
|
+
const scaledAmount = baseAmount * claimMultiplier;
|
|
2035
|
+
const trackerValue = completionTrackers?.depositCurrency || 0;
|
|
2036
|
+
const isDisqualify = trackerValue < scaledAmount;
|
|
2037
|
+
if (shouldScale && baseAmount > 0) {
|
|
2038
|
+
updateMax(Math.floor(trackerValue / baseAmount));
|
|
2039
|
+
}
|
|
1980
2040
|
if (addDetails) {
|
|
1981
2041
|
conditionData.push({
|
|
1982
2042
|
isMet: !isDisqualify,
|
|
1983
2043
|
kind: 'depositCurrency',
|
|
1984
|
-
trackerAmount:
|
|
2044
|
+
trackerAmount: trackerValue,
|
|
1985
2045
|
text: `Deposit ${scaledAmount} ${conditions.depositCurrency.name}`,
|
|
1986
2046
|
});
|
|
1987
2047
|
if (isDisqualify)
|
|
@@ -1989,7 +2049,7 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
|
|
|
1989
2049
|
}
|
|
1990
2050
|
else {
|
|
1991
2051
|
if (isDisqualify)
|
|
1992
|
-
return { isValid: false };
|
|
2052
|
+
return { isValid: false, availableClaimsNow: 0 };
|
|
1993
2053
|
}
|
|
1994
2054
|
}
|
|
1995
2055
|
if (conditions?.login) {
|
|
@@ -2006,7 +2066,7 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
|
|
|
2006
2066
|
}
|
|
2007
2067
|
else {
|
|
2008
2068
|
if (!isMet)
|
|
2009
|
-
return { isValid: false };
|
|
2069
|
+
return { isValid: false, availableClaimsNow: 0 };
|
|
2010
2070
|
}
|
|
2011
2071
|
}
|
|
2012
2072
|
if (conditions?.loginStreak) {
|
|
@@ -2026,7 +2086,7 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
|
|
|
2026
2086
|
}
|
|
2027
2087
|
else {
|
|
2028
2088
|
if (isDisqualify)
|
|
2029
|
-
return { isValid: false };
|
|
2089
|
+
return { isValid: false, availableClaimsNow: 0 };
|
|
2030
2090
|
}
|
|
2031
2091
|
}
|
|
2032
2092
|
if (conditions?.social) {
|
|
@@ -2048,6 +2108,17 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
|
|
|
2048
2108
|
if (likes < minLikes || views < minViews || comments < minComments) {
|
|
2049
2109
|
isDisqualify = true;
|
|
2050
2110
|
}
|
|
2111
|
+
if (shouldScale && mode === 'accumulate' && hasContent) {
|
|
2112
|
+
const baseLikes = cSocial?.minLikes || 0;
|
|
2113
|
+
const baseViews = cSocial?.minViews || 0;
|
|
2114
|
+
const baseComments = cSocial?.minComments || 0;
|
|
2115
|
+
if (baseLikes > 0)
|
|
2116
|
+
updateMax(Math.floor(likes / baseLikes));
|
|
2117
|
+
if (baseViews > 0)
|
|
2118
|
+
updateMax(Math.floor(views / baseViews));
|
|
2119
|
+
if (baseComments > 0)
|
|
2120
|
+
updateMax(Math.floor(comments / baseComments));
|
|
2121
|
+
}
|
|
2051
2122
|
if (addDetails) {
|
|
2052
2123
|
const platformMap = {
|
|
2053
2124
|
tiktok: 'TikTok',
|
|
@@ -2119,14 +2190,18 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
|
|
|
2119
2190
|
}
|
|
2120
2191
|
else {
|
|
2121
2192
|
if (isDisqualify)
|
|
2122
|
-
return { isValid: false };
|
|
2193
|
+
return { isValid: false, availableClaimsNow: 0 };
|
|
2123
2194
|
}
|
|
2124
2195
|
}
|
|
2125
2196
|
// Linked completions - wait for N linked entities to complete
|
|
2126
2197
|
if (conditions?.linkedCompletions?.min) {
|
|
2198
|
+
const baseMin = conditions.linkedCompletions.min;
|
|
2127
2199
|
const currentCount = completionTrackers?.linkedCompletions || 0;
|
|
2128
|
-
const scaledMin =
|
|
2200
|
+
const scaledMin = baseMin * claimMultiplier;
|
|
2129
2201
|
const isDisqualify = currentCount < scaledMin;
|
|
2202
|
+
if (shouldScale && baseMin > 0) {
|
|
2203
|
+
updateMax(Math.floor(currentCount / baseMin));
|
|
2204
|
+
}
|
|
2130
2205
|
if (addDetails) {
|
|
2131
2206
|
conditionData.push({
|
|
2132
2207
|
isMet: !isDisqualify,
|
|
@@ -2139,7 +2214,7 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
|
|
|
2139
2214
|
}
|
|
2140
2215
|
else {
|
|
2141
2216
|
if (isDisqualify)
|
|
2142
|
-
return { isValid: false };
|
|
2217
|
+
return { isValid: false, availableClaimsNow: 0 };
|
|
2143
2218
|
}
|
|
2144
2219
|
}
|
|
2145
2220
|
if (conditions?.dynamicTracker?.conditions?.length) {
|
|
@@ -2149,6 +2224,13 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
|
|
|
2149
2224
|
...conditions.dynamicTracker,
|
|
2150
2225
|
conditions: resolvedConditions,
|
|
2151
2226
|
}, claimMultiplier);
|
|
2227
|
+
if (shouldScale) {
|
|
2228
|
+
const dynamicMax = getMaxClaimsForDynamicGroup(completionTrackers?.dynamicTracker || {}, {
|
|
2229
|
+
...conditions.dynamicTracker,
|
|
2230
|
+
conditions: resolvedConditions,
|
|
2231
|
+
}, playerOffer.claimedCount || 0);
|
|
2232
|
+
updateMax(dynamicMax);
|
|
2233
|
+
}
|
|
2152
2234
|
if (addDetails) {
|
|
2153
2235
|
conditionData.push({
|
|
2154
2236
|
isMet: dynamicResult,
|
|
@@ -2160,7 +2242,7 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
|
|
|
2160
2242
|
}
|
|
2161
2243
|
else {
|
|
2162
2244
|
if (!dynamicResult)
|
|
2163
|
-
return { isValid: false };
|
|
2245
|
+
return { isValid: false, availableClaimsNow: 0 };
|
|
2164
2246
|
}
|
|
2165
2247
|
}
|
|
2166
2248
|
const r = meetsBaseConditions({
|
|
@@ -2171,9 +2253,18 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
|
|
|
2171
2253
|
});
|
|
2172
2254
|
isValid = isValid && r.isValid;
|
|
2173
2255
|
conditionData.push(...(r.conditionData || []));
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2256
|
+
if (maxClaimCount && maxClaimCount > 0) {
|
|
2257
|
+
updateMax(maxClaimCount);
|
|
2258
|
+
}
|
|
2259
|
+
const claimedCount = playerOffer.claimedCount || 0;
|
|
2260
|
+
let availableClaimsNow = !isValid
|
|
2261
|
+
? 0
|
|
2262
|
+
: maxTotalClaimsFromScaling === Infinity
|
|
2263
|
+
? -1
|
|
2264
|
+
: Math.max(0, maxTotalClaimsFromScaling - claimedCount);
|
|
2265
|
+
return { isValid, conditionData, availableClaimsNow };
|
|
2266
|
+
}
|
|
2267
|
+
return { isValid: true, conditionData: [], availableClaimsNow: -1 };
|
|
2177
2268
|
};
|
|
2178
2269
|
/**
|
|
2179
2270
|
* Checks if completion conditions were met before a specific expiry time.
|
|
@@ -2338,26 +2429,30 @@ function evaluateDynamicCondition(dynamicObj, cond, claimMultiplier = 1) {
|
|
|
2338
2429
|
}
|
|
2339
2430
|
}
|
|
2340
2431
|
const compareTo = isNumber ? Number(cond.compareTo) : String(cond.compareTo);
|
|
2341
|
-
switch (cond.operator) {
|
|
2342
|
-
case '==':
|
|
2343
|
-
return val === compareTo;
|
|
2344
|
-
case '!=':
|
|
2345
|
-
return val !== compareTo;
|
|
2346
|
-
}
|
|
2347
2432
|
if (isNumber && typeof compareTo === 'number') {
|
|
2433
|
+
const skipMultiplier = cond.operator === '==' || cond.operator === '!=';
|
|
2434
|
+
const scaledCompareTo = skipMultiplier ? compareTo : compareTo * claimMultiplier;
|
|
2348
2435
|
switch (cond.operator) {
|
|
2436
|
+
case '==':
|
|
2437
|
+
return val === scaledCompareTo;
|
|
2438
|
+
case '!=':
|
|
2439
|
+
return val !== scaledCompareTo;
|
|
2349
2440
|
case '>':
|
|
2350
|
-
return val >
|
|
2441
|
+
return val > scaledCompareTo;
|
|
2351
2442
|
case '>=':
|
|
2352
|
-
return val >=
|
|
2443
|
+
return val >= scaledCompareTo;
|
|
2353
2444
|
case '<':
|
|
2354
|
-
return val <
|
|
2445
|
+
return val < scaledCompareTo;
|
|
2355
2446
|
case '<=':
|
|
2356
|
-
return val <=
|
|
2447
|
+
return val <= scaledCompareTo;
|
|
2357
2448
|
}
|
|
2358
2449
|
}
|
|
2359
2450
|
else if (!isNumber && typeof compareTo === 'string') {
|
|
2360
2451
|
switch (cond.operator) {
|
|
2452
|
+
case '==':
|
|
2453
|
+
return val === compareTo;
|
|
2454
|
+
case '!=':
|
|
2455
|
+
return val !== compareTo;
|
|
2361
2456
|
case 'has':
|
|
2362
2457
|
return val.includes(compareTo);
|
|
2363
2458
|
case 'not_has':
|
|
@@ -2366,6 +2461,98 @@ function evaluateDynamicCondition(dynamicObj, cond, claimMultiplier = 1) {
|
|
|
2366
2461
|
}
|
|
2367
2462
|
return false;
|
|
2368
2463
|
}
|
|
2464
|
+
/**
|
|
2465
|
+
* Calculates the maximum number of claims supported by a single dynamic condition.
|
|
2466
|
+
*/
|
|
2467
|
+
function getMaxClaimsForDynamicCondition(dynamicObj, cond) {
|
|
2468
|
+
if (!dynamicObj)
|
|
2469
|
+
return 0;
|
|
2470
|
+
const val = dynamicObj[cond.key];
|
|
2471
|
+
if (val === undefined)
|
|
2472
|
+
return 0;
|
|
2473
|
+
if (typeof val === 'number') {
|
|
2474
|
+
const base = Number(cond.compareTo);
|
|
2475
|
+
if (isNaN(base)) {
|
|
2476
|
+
return evaluateDynamicCondition(dynamicObj, cond, 1) ? Infinity : 0;
|
|
2477
|
+
}
|
|
2478
|
+
switch (cond.operator) {
|
|
2479
|
+
case '>=':
|
|
2480
|
+
if (base === 0)
|
|
2481
|
+
return val >= 0 ? Infinity : 0;
|
|
2482
|
+
if (base < 0)
|
|
2483
|
+
return val >= base ? Infinity : 0;
|
|
2484
|
+
return Math.max(0, Math.floor(val / base));
|
|
2485
|
+
case '>':
|
|
2486
|
+
if (base === 0)
|
|
2487
|
+
return val > 0 ? Infinity : 0;
|
|
2488
|
+
if (base < 0)
|
|
2489
|
+
return val > base ? Infinity : 0;
|
|
2490
|
+
if (val <= 0)
|
|
2491
|
+
return 0;
|
|
2492
|
+
return Math.max(0, Math.ceil(val / base) - 1);
|
|
2493
|
+
case '==':
|
|
2494
|
+
return val === base ? Infinity : 0;
|
|
2495
|
+
case '!=':
|
|
2496
|
+
return val !== base ? Infinity : 0;
|
|
2497
|
+
case '<=':
|
|
2498
|
+
if (base === 0)
|
|
2499
|
+
return val <= 0 ? Infinity : 0;
|
|
2500
|
+
if (base > 0)
|
|
2501
|
+
return evaluateDynamicCondition(dynamicObj, cond, 1) ? Infinity : 0;
|
|
2502
|
+
if (val >= 0)
|
|
2503
|
+
return 0;
|
|
2504
|
+
return Math.max(0, Math.floor(val / base));
|
|
2505
|
+
case '<':
|
|
2506
|
+
if (base === 0)
|
|
2507
|
+
return val < 0 ? Infinity : 0;
|
|
2508
|
+
if (base > 0)
|
|
2509
|
+
return evaluateDynamicCondition(dynamicObj, cond, 1) ? Infinity : 0;
|
|
2510
|
+
if (val >= 0)
|
|
2511
|
+
return 0;
|
|
2512
|
+
return Math.max(0, Math.ceil(val / base) - 1);
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
// we don't scale the rest, they are always true or always false
|
|
2516
|
+
return evaluateDynamicCondition(dynamicObj, cond, 1) ? Infinity : 0;
|
|
2517
|
+
}
|
|
2518
|
+
/**
|
|
2519
|
+
* Calculates the maximum number of claims supported by a group of dynamic conditions.
|
|
2520
|
+
*/
|
|
2521
|
+
function getMaxClaimsForDynamicGroup(dynamicObj, dynamicGroup, currentClaimCount = 0) {
|
|
2522
|
+
const { conditions, links } = dynamicGroup;
|
|
2523
|
+
if (!conditions || conditions.length === 0)
|
|
2524
|
+
return Infinity;
|
|
2525
|
+
// AND only
|
|
2526
|
+
if (!links || links.length === 0 || links.every((l) => l === 'AND')) {
|
|
2527
|
+
let minClaims = Infinity;
|
|
2528
|
+
for (const cond of conditions) {
|
|
2529
|
+
const max = getMaxClaimsForDynamicCondition(dynamicObj, cond);
|
|
2530
|
+
if (max === 0)
|
|
2531
|
+
return 0;
|
|
2532
|
+
minClaims = Math.min(minClaims, max);
|
|
2533
|
+
}
|
|
2534
|
+
return minClaims;
|
|
2535
|
+
}
|
|
2536
|
+
// OR only
|
|
2537
|
+
if (links.every((l) => l === 'OR')) {
|
|
2538
|
+
let maxClaims = 0;
|
|
2539
|
+
for (const cond of conditions) {
|
|
2540
|
+
const max = getMaxClaimsForDynamicCondition(dynamicObj, cond);
|
|
2541
|
+
if (max === Infinity)
|
|
2542
|
+
return Infinity;
|
|
2543
|
+
maxClaims = Math.max(maxClaims, max);
|
|
2544
|
+
}
|
|
2545
|
+
return maxClaims;
|
|
2546
|
+
}
|
|
2547
|
+
// mixed:
|
|
2548
|
+
const maxIterations = 100;
|
|
2549
|
+
for (let n = currentClaimCount + 1; n <= currentClaimCount + maxIterations; n++) {
|
|
2550
|
+
if (!meetsDynamicConditions(dynamicObj, dynamicGroup, n)) {
|
|
2551
|
+
return n - 1;
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
return currentClaimCount + maxIterations;
|
|
2555
|
+
}
|
|
2369
2556
|
/**
|
|
2370
2557
|
* Evaluates a group of dynamic conditions with logical links (AND, OR, AND NOT).
|
|
2371
2558
|
* @param dynamicObj - The player's dynamic object with any key and string or number value.
|
|
@@ -2468,5 +2655,5 @@ const rewardSchema = {
|
|
|
2468
2655
|
image: String,
|
|
2469
2656
|
};
|
|
2470
2657
|
|
|
2471
|
-
export { AssetHelper, ConnectionState, EventEmitter, OfferEvent, OfferStore, OfferwallClient, PlayerOfferStatuses, SSEConnection, hasConditions, meetsBaseConditions, meetsClaimableConditions, meetsCompletionConditions, meetsCompletionConditionsBeforeExpiry, meetsDynamicConditions, meetsSurfacingConditions, offerListenerEvents, offerMeetsCompletionConditions, rewardKinds, rewardSchema };
|
|
2658
|
+
export { AssetHelper, ConnectionState, EventEmitter, OfferEvent, OfferStore, OfferwallClient, PlayerOfferStatuses, SSEConnection, getMaxClaimsForDynamicCondition, getMaxClaimsForDynamicGroup, hasConditions, meetsBaseConditions, meetsClaimableConditions, meetsCompletionConditions, meetsCompletionConditionsBeforeExpiry, meetsDynamicConditions, meetsSurfacingConditions, offerListenerEvents, offerMeetsCompletionConditions, rewardKinds, rewardSchema };
|
|
2472
2659
|
//# sourceMappingURL=index.esm.js.map
|