@p2pdotme/sdk 1.2.0 → 1.2.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/orders.mjs CHANGED
@@ -5174,7 +5174,8 @@ var OrderRoutingError = class extends SdkError {
5174
5174
  // src/orders/internal/routing/validation.ts
5175
5175
  import { z as z5 } from "zod";
5176
5176
  var ZodCircleScoreStateSchema = z5.object({
5177
- activeMerchantsCount: z5.coerce.number()
5177
+ activeMerchantsCount: z5.coerce.number(),
5178
+ availableMerchantsCount: z5.coerce.number()
5178
5179
  });
5179
5180
  var ZodCircleMetricsForRoutingSchema = z5.object({
5180
5181
  circleScore: z5.coerce.number(),
@@ -5390,8 +5391,9 @@ import { errAsync as errAsync2, okAsync as okAsync3 } from "neverthrow";
5390
5391
  var EPSILON = 0.25;
5391
5392
  var RECOVERY_SCALE = 0.3;
5392
5393
  var BOOTSTRAP_MAX_WEIGHT = 25;
5394
+ var BOOTSTRAP_RESERVE = 0.1;
5393
5395
  var MAX_VALIDATION_ATTEMPTS = 3;
5394
- function circleWeight(c) {
5396
+ function baseScore(c) {
5395
5397
  const score = c.metrics.circleScore;
5396
5398
  if (c.metrics.circleStatus === "paused") {
5397
5399
  return score * RECOVERY_SCALE;
@@ -5401,8 +5403,13 @@ function circleWeight(c) {
5401
5403
  }
5402
5404
  return score;
5403
5405
  }
5406
+ function circleWeight(c) {
5407
+ return baseScore(c) * c.metrics.scoreState.availableMerchantsCount;
5408
+ }
5404
5409
  function filterEligibleCircles(circles, orderCurrency) {
5405
- return circles.filter((c) => c.currency.toLowerCase() === orderCurrency.toLowerCase());
5410
+ return circles.filter(
5411
+ (c) => c.currency.toLowerCase() === orderCurrency.toLowerCase() && c.metrics.scoreState.availableMerchantsCount > 0
5412
+ );
5406
5413
  }
5407
5414
  function weightedRandomChoice(arr, weights) {
5408
5415
  const totalWeight = weights.reduce((sum, w) => sum + w, 0);
@@ -5422,8 +5429,14 @@ function selectCircle(eligible) {
5422
5429
  if (eligible.length === 0) {
5423
5430
  return null;
5424
5431
  }
5432
+ const bootstrapCircles = eligible.filter((c) => c.metrics.circleStatus === "bootstrap");
5425
5433
  const activeCircles = eligible.filter((c) => c.metrics.circleStatus === "active");
5426
- const isExplore = Math.random() < EPSILON;
5434
+ const r = Math.random();
5435
+ if (r < BOOTSTRAP_RESERVE && bootstrapCircles.length > 0) {
5436
+ const weights2 = bootstrapCircles.map(circleWeight);
5437
+ return weightedRandomChoice(bootstrapCircles, weights2);
5438
+ }
5439
+ const isExplore = r < BOOTSTRAP_RESERVE + EPSILON;
5427
5440
  if (isExplore) {
5428
5441
  const weights2 = eligible.map(circleWeight);
5429
5442
  return weightedRandomChoice(eligible, weights2);
@@ -5432,7 +5445,7 @@ function selectCircle(eligible) {
5432
5445
  const weights2 = eligible.map(circleWeight);
5433
5446
  return weightedRandomChoice(eligible, weights2);
5434
5447
  }
5435
- const weights = activeCircles.map((c) => c.metrics.circleScore);
5448
+ const weights = activeCircles.map(circleWeight);
5436
5449
  return weightedRandomChoice(activeCircles, weights);
5437
5450
  }
5438
5451
  function selectCircleForOrderAsync(circles, orderCurrency, validateCircle, logger = noopLogger) {
@@ -5517,6 +5530,7 @@ var CIRCLES_FOR_ROUTING_QUERY = (
5517
5530
  circleStatus
5518
5531
  scoreState {
5519
5532
  activeMerchantsCount
5533
+ availableMerchantsCount
5520
5534
  }
5521
5535
  }
5522
5536
  }
@@ -5543,11 +5557,11 @@ function getCirclesForRouting(subgraphUrl, currency, logger = noopLogger) {
5543
5557
  (message, cause, d) => new OrderRoutingError(message, { code: "VALIDATION_ERROR", cause, context: { data: d } })
5544
5558
  ).map((validated) => {
5545
5559
  const circles = validated.circles.filter(
5546
- (item) => Number(item.metrics.scoreState.activeMerchantsCount) > 0
5560
+ (item) => Number(item.metrics.scoreState.availableMerchantsCount) > 0
5547
5561
  );
5548
5562
  logger.info("fetched circles from subgraph", {
5549
5563
  total: validated.circles.length,
5550
- withActiveMerchants: circles.length,
5564
+ withAvailableMerchants: circles.length,
5551
5565
  circles
5552
5566
  });
5553
5567
  return circles;