scrapely 1.2.23 → 1.2.24

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.
@@ -93,10 +93,22 @@ export declare class ChargingManager {
93
93
  */
94
94
  private platformOtherUsd;
95
95
  private lastRemainingBudgetNd;
96
+ /** True once the platform reported a remaining budget (its usage is then in the local budget). */
97
+ private platformBudgetSeen;
96
98
  /** maxTotalChargeUsd minus this SDK's charges and the platform's other run spend. */
97
99
  private remainingBudgetUsd;
98
100
  /** Fold the last charge response's remainingBudgetNd into the local budget (monotonic). */
99
101
  private syncPlatformBudget;
102
+ /**
103
+ * @internal Whole rows a multi-event retry can pay for after a short answer:
104
+ * what the voided attempt was accepted (budget the void gives back) at the
105
+ * full per-row cost, or the local remaining budget once the platform has
106
+ * reported it (then it includes the leftover after the short answer).
107
+ */
108
+ _rowsAfterShort(attempt: Array<{
109
+ name: string;
110
+ charged: number;
111
+ }>, perRow: Record<string, number>): number;
100
112
  /** @internal Platform spend outside this SDK's charges (tests). */
101
113
  _platformOtherUsd(): number;
102
114
  /** @internal Called by Actor shutdown before the final flush. */
package/dist/charging.js CHANGED
@@ -172,6 +172,8 @@ class ChargingManager {
172
172
  */
173
173
  platformOtherUsd = 0;
174
174
  lastRemainingBudgetNd = null;
175
+ /** True once the platform reported a remaining budget (its usage is then in the local budget). */
176
+ platformBudgetSeen = false;
175
177
  /** maxTotalChargeUsd minus this SDK's charges and the platform's other run spend. */
176
178
  remainingBudgetUsd() {
177
179
  return this.maxTotalChargeUsd - this.calculateTotalChargedAmount() - this.platformOtherUsd;
@@ -182,10 +184,28 @@ class ChargingManager {
182
184
  this.lastRemainingBudgetNd = null;
183
185
  if (nd === null || nd < 0 || !Number.isFinite(this.maxTotalChargeUsd))
184
186
  return;
187
+ this.platformBudgetSeen = true;
185
188
  const other = Number((this.maxTotalChargeUsd - nd / 1e9 - this.calculateTotalChargedAmount()).toFixed(9));
186
189
  if (other > this.platformOtherUsd)
187
190
  this.platformOtherUsd = other;
188
191
  }
192
+ /**
193
+ * @internal Whole rows a multi-event retry can pay for after a short answer:
194
+ * what the voided attempt was accepted (budget the void gives back) at the
195
+ * full per-row cost, or the local remaining budget once the platform has
196
+ * reported it (then it includes the leftover after the short answer).
197
+ */
198
+ _rowsAfterShort(attempt, perRow) {
199
+ const rowCost = Object.entries(perRow).reduce((a, [n, c]) => a + (this.calculateEventPrice(n) ?? 0) * c, 0);
200
+ if (rowCost <= 0)
201
+ return 0;
202
+ const spent = attempt.reduce((a, op) => a + (this.calculateEventPrice(op.name) ?? 0) * op.charged, 0);
203
+ let fit = Math.floor(Number((spent / rowCost).toFixed(4)));
204
+ if (this.platformBudgetSeen && Number.isFinite(this.maxTotalChargeUsd)) {
205
+ fit = Math.max(fit, Math.floor(Number((this.remainingBudgetUsd() / rowCost).toFixed(4))));
206
+ }
207
+ return Math.max(0, fit);
208
+ }
189
209
  /** @internal Platform spend outside this SDK's charges (tests). */
190
210
  _platformOtherUsd() {
191
211
  return this.platformOtherUsd;
@@ -1361,7 +1381,7 @@ async function pushDataWithCharges({ chargingManager, items, charges, isDefaultD
1361
1381
  };
1362
1382
  const order = Object.entries(perRow).sort(([a], [b]) => Number(isSyntheticEvent(a)) - Number(isSyntheticEvent(b)) || a.localeCompare(b));
1363
1383
  let ops = [];
1364
- for (let attempt = 0; attempt < 4 && rows > 0; attempt++) {
1384
+ for (let attempt = 0; attempt < 6 && rows > 0; attempt++) {
1365
1385
  ops = [];
1366
1386
  let shortTo = null;
1367
1387
  for (const [name, n] of order) {
@@ -1389,10 +1409,14 @@ async function pushDataWithCharges({ chargingManager, items, charges, isDefaultD
1389
1409
  }
1390
1410
  if (shortTo === null)
1391
1411
  break;
1392
- // An event came back short: void this attempt and retry with the rows it pays for.
1412
+ // An event came back short: void this attempt and retry with the whole
1413
+ // rows the budget covers at the FULL per-row cost (sizing from the short
1414
+ // event alone came back short again: appstore 64df0a3608d74af88, 0 saved).
1415
+ // At least one single-row try: the last affordable row may still fit.
1416
+ const attemptOps = ops.map((op) => ({ name: op.name, charged: op.charged }));
1393
1417
  await undo(ops);
1394
1418
  ops = [];
1395
- rows = shortTo;
1419
+ rows = Math.min(rows - 1, Math.max(chargingManager._rowsAfterShort(attemptOps, perRow), 1));
1396
1420
  }
1397
1421
  if (rows <= 0 || ops.length === 0) {
1398
1422
  await undo(ops);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scrapely",
3
- "version": "1.2.23",
3
+ "version": "1.2.24",
4
4
  "description": "Scrapely SDK for building JavaScript and TypeScript Actors",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",