@pixels-online/pixels-client-js-sdk 1.17.0 → 1.18.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/index.esm.js CHANGED
@@ -1919,6 +1919,8 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
1919
1919
  const claimMultiplier = shouldScale ? (playerOffer.claimedCount || 0) + 1 : 1;
1920
1920
  const conditionData = [];
1921
1921
  let isValid = true;
1922
+ let maxTotalClaimsFromScaling = Infinity;
1923
+ const updateMax = (limit) => (maxTotalClaimsFromScaling = Math.min(maxTotalClaimsFromScaling, limit));
1922
1924
  if (completionConditions?.context?.id) {
1923
1925
  const hasTrackedContext = completionTrackers?.context &&
1924
1926
  completionConditions.context.id === completionTrackers.context;
@@ -1935,17 +1937,22 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
1935
1937
  }
1936
1938
  else {
1937
1939
  if (isDisqualify)
1938
- return { isValid: false };
1940
+ return { isValid: false, availableClaimsNow: 0 };
1939
1941
  }
1940
1942
  }
1941
1943
  if (conditions?.buyItem) {
1942
- const scaledAmount = (conditions.buyItem.amount || 1) * claimMultiplier;
1943
- const isDisqualify = (completionTrackers?.buyItem || 0) < scaledAmount;
1944
+ const baseAmount = conditions.buyItem.amount || 1;
1945
+ const scaledAmount = baseAmount * claimMultiplier;
1946
+ const trackerValue = completionTrackers?.buyItem || 0;
1947
+ const isDisqualify = trackerValue < scaledAmount;
1948
+ if (shouldScale && baseAmount > 0) {
1949
+ updateMax(Math.floor(trackerValue / baseAmount));
1950
+ }
1944
1951
  if (addDetails) {
1945
1952
  conditionData.push({
1946
1953
  isMet: !isDisqualify,
1947
1954
  kind: 'buyItem',
1948
- trackerAmount: completionTrackers?.buyItem || 0,
1955
+ trackerAmount: trackerValue,
1949
1956
  text: `Buy ${scaledAmount} ${conditions.buyItem.name}`,
1950
1957
  });
1951
1958
  if (isDisqualify)
@@ -1953,17 +1960,22 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
1953
1960
  }
1954
1961
  else {
1955
1962
  if (isDisqualify)
1956
- return { isValid: false };
1963
+ return { isValid: false, availableClaimsNow: 0 };
1957
1964
  }
1958
1965
  }
1959
1966
  if (conditions?.spendCurrency) {
1960
- const scaledAmount = (conditions.spendCurrency.amount || 1) * claimMultiplier;
1961
- const isDisqualify = (completionTrackers?.spendCurrency || 0) < scaledAmount;
1967
+ const baseAmount = conditions.spendCurrency.amount || 1;
1968
+ const scaledAmount = baseAmount * claimMultiplier;
1969
+ const trackerValue = completionTrackers?.spendCurrency || 0;
1970
+ const isDisqualify = trackerValue < scaledAmount;
1971
+ if (shouldScale && baseAmount > 0) {
1972
+ updateMax(Math.floor(trackerValue / baseAmount));
1973
+ }
1962
1974
  if (addDetails) {
1963
1975
  conditionData.push({
1964
1976
  isMet: !isDisqualify,
1965
1977
  kind: 'spendCurrency',
1966
- trackerAmount: completionTrackers?.spendCurrency || 0,
1978
+ trackerAmount: trackerValue,
1967
1979
  text: `Spend ${scaledAmount} ${conditions.spendCurrency.name}`,
1968
1980
  });
1969
1981
  if (isDisqualify)
@@ -1971,17 +1983,22 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
1971
1983
  }
1972
1984
  else {
1973
1985
  if (isDisqualify)
1974
- return { isValid: false };
1986
+ return { isValid: false, availableClaimsNow: 0 };
1975
1987
  }
1976
1988
  }
1977
1989
  if (conditions?.depositCurrency) {
1978
- const scaledAmount = (conditions.depositCurrency.amount || 1) * claimMultiplier;
1979
- const isDisqualify = (completionTrackers?.depositCurrency || 0) < scaledAmount;
1990
+ const baseAmount = conditions.depositCurrency.amount || 1;
1991
+ const scaledAmount = baseAmount * claimMultiplier;
1992
+ const trackerValue = completionTrackers?.depositCurrency || 0;
1993
+ const isDisqualify = trackerValue < scaledAmount;
1994
+ if (shouldScale && baseAmount > 0) {
1995
+ updateMax(Math.floor(trackerValue / baseAmount));
1996
+ }
1980
1997
  if (addDetails) {
1981
1998
  conditionData.push({
1982
1999
  isMet: !isDisqualify,
1983
2000
  kind: 'depositCurrency',
1984
- trackerAmount: completionTrackers?.depositCurrency || 0,
2001
+ trackerAmount: trackerValue,
1985
2002
  text: `Deposit ${scaledAmount} ${conditions.depositCurrency.name}`,
1986
2003
  });
1987
2004
  if (isDisqualify)
@@ -1989,7 +2006,7 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
1989
2006
  }
1990
2007
  else {
1991
2008
  if (isDisqualify)
1992
- return { isValid: false };
2009
+ return { isValid: false, availableClaimsNow: 0 };
1993
2010
  }
1994
2011
  }
1995
2012
  if (conditions?.login) {
@@ -2006,7 +2023,7 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
2006
2023
  }
2007
2024
  else {
2008
2025
  if (!isMet)
2009
- return { isValid: false };
2026
+ return { isValid: false, availableClaimsNow: 0 };
2010
2027
  }
2011
2028
  }
2012
2029
  if (conditions?.loginStreak) {
@@ -2026,7 +2043,7 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
2026
2043
  }
2027
2044
  else {
2028
2045
  if (isDisqualify)
2029
- return { isValid: false };
2046
+ return { isValid: false, availableClaimsNow: 0 };
2030
2047
  }
2031
2048
  }
2032
2049
  if (conditions?.social) {
@@ -2048,6 +2065,17 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
2048
2065
  if (likes < minLikes || views < minViews || comments < minComments) {
2049
2066
  isDisqualify = true;
2050
2067
  }
2068
+ if (shouldScale && mode === 'accumulate' && hasContent) {
2069
+ const baseLikes = cSocial?.minLikes || 0;
2070
+ const baseViews = cSocial?.minViews || 0;
2071
+ const baseComments = cSocial?.minComments || 0;
2072
+ if (baseLikes > 0)
2073
+ updateMax(Math.floor(likes / baseLikes));
2074
+ if (baseViews > 0)
2075
+ updateMax(Math.floor(views / baseViews));
2076
+ if (baseComments > 0)
2077
+ updateMax(Math.floor(comments / baseComments));
2078
+ }
2051
2079
  if (addDetails) {
2052
2080
  const platformMap = {
2053
2081
  tiktok: 'TikTok',
@@ -2119,14 +2147,18 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
2119
2147
  }
2120
2148
  else {
2121
2149
  if (isDisqualify)
2122
- return { isValid: false };
2150
+ return { isValid: false, availableClaimsNow: 0 };
2123
2151
  }
2124
2152
  }
2125
2153
  // Linked completions - wait for N linked entities to complete
2126
2154
  if (conditions?.linkedCompletions?.min) {
2155
+ const baseMin = conditions.linkedCompletions.min;
2127
2156
  const currentCount = completionTrackers?.linkedCompletions || 0;
2128
- const scaledMin = conditions.linkedCompletions.min * claimMultiplier;
2157
+ const scaledMin = baseMin * claimMultiplier;
2129
2158
  const isDisqualify = currentCount < scaledMin;
2159
+ if (shouldScale && baseMin > 0) {
2160
+ updateMax(Math.floor(currentCount / baseMin));
2161
+ }
2130
2162
  if (addDetails) {
2131
2163
  conditionData.push({
2132
2164
  isMet: !isDisqualify,
@@ -2139,7 +2171,7 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
2139
2171
  }
2140
2172
  else {
2141
2173
  if (isDisqualify)
2142
- return { isValid: false };
2174
+ return { isValid: false, availableClaimsNow: 0 };
2143
2175
  }
2144
2176
  }
2145
2177
  if (conditions?.dynamicTracker?.conditions?.length) {
@@ -2149,6 +2181,13 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
2149
2181
  ...conditions.dynamicTracker,
2150
2182
  conditions: resolvedConditions,
2151
2183
  }, claimMultiplier);
2184
+ if (shouldScale) {
2185
+ const dynamicMax = getMaxClaimsForDynamicGroup(completionTrackers?.dynamicTracker || {}, {
2186
+ ...conditions.dynamicTracker,
2187
+ conditions: resolvedConditions,
2188
+ }, playerOffer.claimedCount || 0);
2189
+ updateMax(dynamicMax);
2190
+ }
2152
2191
  if (addDetails) {
2153
2192
  conditionData.push({
2154
2193
  isMet: dynamicResult,
@@ -2160,7 +2199,7 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
2160
2199
  }
2161
2200
  else {
2162
2201
  if (!dynamicResult)
2163
- return { isValid: false };
2202
+ return { isValid: false, availableClaimsNow: 0 };
2164
2203
  }
2165
2204
  }
2166
2205
  const r = meetsBaseConditions({
@@ -2171,9 +2210,18 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
2171
2210
  });
2172
2211
  isValid = isValid && r.isValid;
2173
2212
  conditionData.push(...(r.conditionData || []));
2174
- return { isValid, conditionData };
2175
- }
2176
- return { isValid: true, conditionData: [] };
2213
+ if (maxClaimCount && maxClaimCount > 0) {
2214
+ updateMax(maxClaimCount);
2215
+ }
2216
+ const claimedCount = playerOffer.claimedCount || 0;
2217
+ let availableClaimsNow = !isValid
2218
+ ? 0
2219
+ : maxTotalClaimsFromScaling === Infinity
2220
+ ? -1
2221
+ : Math.max(0, maxTotalClaimsFromScaling - claimedCount);
2222
+ return { isValid, conditionData, availableClaimsNow };
2223
+ }
2224
+ return { isValid: true, conditionData: [], availableClaimsNow: -1 };
2177
2225
  };
2178
2226
  /**
2179
2227
  * Checks if completion conditions were met before a specific expiry time.
@@ -2338,26 +2386,30 @@ function evaluateDynamicCondition(dynamicObj, cond, claimMultiplier = 1) {
2338
2386
  }
2339
2387
  }
2340
2388
  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
2389
  if (isNumber && typeof compareTo === 'number') {
2390
+ const skipMultiplier = cond.operator === '==' || cond.operator === '!=';
2391
+ const scaledCompareTo = skipMultiplier ? compareTo : compareTo * claimMultiplier;
2348
2392
  switch (cond.operator) {
2393
+ case '==':
2394
+ return val === scaledCompareTo;
2395
+ case '!=':
2396
+ return val !== scaledCompareTo;
2349
2397
  case '>':
2350
- return val > compareTo * claimMultiplier;
2398
+ return val > scaledCompareTo;
2351
2399
  case '>=':
2352
- return val >= compareTo * claimMultiplier;
2400
+ return val >= scaledCompareTo;
2353
2401
  case '<':
2354
- return val < compareTo * claimMultiplier;
2402
+ return val < scaledCompareTo;
2355
2403
  case '<=':
2356
- return val <= compareTo * claimMultiplier;
2404
+ return val <= scaledCompareTo;
2357
2405
  }
2358
2406
  }
2359
2407
  else if (!isNumber && typeof compareTo === 'string') {
2360
2408
  switch (cond.operator) {
2409
+ case '==':
2410
+ return val === compareTo;
2411
+ case '!=':
2412
+ return val !== compareTo;
2361
2413
  case 'has':
2362
2414
  return val.includes(compareTo);
2363
2415
  case 'not_has':
@@ -2366,6 +2418,98 @@ function evaluateDynamicCondition(dynamicObj, cond, claimMultiplier = 1) {
2366
2418
  }
2367
2419
  return false;
2368
2420
  }
2421
+ /**
2422
+ * Calculates the maximum number of claims supported by a single dynamic condition.
2423
+ */
2424
+ function getMaxClaimsForDynamicCondition(dynamicObj, cond) {
2425
+ if (!dynamicObj)
2426
+ return 0;
2427
+ const val = dynamicObj[cond.key];
2428
+ if (val === undefined)
2429
+ return 0;
2430
+ if (typeof val === 'number') {
2431
+ const base = Number(cond.compareTo);
2432
+ if (isNaN(base)) {
2433
+ return evaluateDynamicCondition(dynamicObj, cond, 1) ? Infinity : 0;
2434
+ }
2435
+ switch (cond.operator) {
2436
+ case '>=':
2437
+ if (base === 0)
2438
+ return val >= 0 ? Infinity : 0;
2439
+ if (base < 0)
2440
+ return val >= base ? Infinity : 0;
2441
+ return Math.max(0, Math.floor(val / base));
2442
+ case '>':
2443
+ if (base === 0)
2444
+ return val > 0 ? Infinity : 0;
2445
+ if (base < 0)
2446
+ return val > base ? Infinity : 0;
2447
+ if (val <= 0)
2448
+ return 0;
2449
+ return Math.max(0, Math.ceil(val / base) - 1);
2450
+ case '==':
2451
+ return val === base ? Infinity : 0;
2452
+ case '!=':
2453
+ return val !== base ? Infinity : 0;
2454
+ case '<=':
2455
+ if (base === 0)
2456
+ return val <= 0 ? Infinity : 0;
2457
+ if (base > 0)
2458
+ return evaluateDynamicCondition(dynamicObj, cond, 1) ? Infinity : 0;
2459
+ if (val >= 0)
2460
+ return 0;
2461
+ return Math.max(0, Math.floor(val / base));
2462
+ case '<':
2463
+ if (base === 0)
2464
+ return val < 0 ? Infinity : 0;
2465
+ if (base > 0)
2466
+ return evaluateDynamicCondition(dynamicObj, cond, 1) ? Infinity : 0;
2467
+ if (val >= 0)
2468
+ return 0;
2469
+ return Math.max(0, Math.ceil(val / base) - 1);
2470
+ }
2471
+ }
2472
+ // we don't scale the rest, they are always true or always false
2473
+ return evaluateDynamicCondition(dynamicObj, cond, 1) ? Infinity : 0;
2474
+ }
2475
+ /**
2476
+ * Calculates the maximum number of claims supported by a group of dynamic conditions.
2477
+ */
2478
+ function getMaxClaimsForDynamicGroup(dynamicObj, dynamicGroup, currentClaimCount = 0) {
2479
+ const { conditions, links } = dynamicGroup;
2480
+ if (!conditions || conditions.length === 0)
2481
+ return Infinity;
2482
+ // AND only
2483
+ if (!links || links.length === 0 || links.every((l) => l === 'AND')) {
2484
+ let minClaims = Infinity;
2485
+ for (const cond of conditions) {
2486
+ const max = getMaxClaimsForDynamicCondition(dynamicObj, cond);
2487
+ if (max === 0)
2488
+ return 0;
2489
+ minClaims = Math.min(minClaims, max);
2490
+ }
2491
+ return minClaims;
2492
+ }
2493
+ // OR only
2494
+ if (links.every((l) => l === 'OR')) {
2495
+ let maxClaims = 0;
2496
+ for (const cond of conditions) {
2497
+ const max = getMaxClaimsForDynamicCondition(dynamicObj, cond);
2498
+ if (max === Infinity)
2499
+ return Infinity;
2500
+ maxClaims = Math.max(maxClaims, max);
2501
+ }
2502
+ return maxClaims;
2503
+ }
2504
+ // mixed:
2505
+ const maxIterations = 100;
2506
+ for (let n = currentClaimCount + 1; n <= currentClaimCount + maxIterations; n++) {
2507
+ if (!meetsDynamicConditions(dynamicObj, dynamicGroup, n)) {
2508
+ return n - 1;
2509
+ }
2510
+ }
2511
+ return currentClaimCount + maxIterations;
2512
+ }
2369
2513
  /**
2370
2514
  * Evaluates a group of dynamic conditions with logical links (AND, OR, AND NOT).
2371
2515
  * @param dynamicObj - The player's dynamic object with any key and string or number value.
@@ -2468,5 +2612,5 @@ const rewardSchema = {
2468
2612
  image: String,
2469
2613
  };
2470
2614
 
2471
- export { AssetHelper, ConnectionState, EventEmitter, OfferEvent, OfferStore, OfferwallClient, PlayerOfferStatuses, SSEConnection, hasConditions, meetsBaseConditions, meetsClaimableConditions, meetsCompletionConditions, meetsCompletionConditionsBeforeExpiry, meetsDynamicConditions, meetsSurfacingConditions, offerListenerEvents, offerMeetsCompletionConditions, rewardKinds, rewardSchema };
2615
+ export { AssetHelper, ConnectionState, EventEmitter, OfferEvent, OfferStore, OfferwallClient, PlayerOfferStatuses, SSEConnection, getMaxClaimsForDynamicCondition, getMaxClaimsForDynamicGroup, hasConditions, meetsBaseConditions, meetsClaimableConditions, meetsCompletionConditions, meetsCompletionConditionsBeforeExpiry, meetsDynamicConditions, meetsSurfacingConditions, offerListenerEvents, offerMeetsCompletionConditions, rewardKinds, rewardSchema };
2472
2616
  //# sourceMappingURL=index.esm.js.map