apify 3.7.3-beta.9 → 4.0.0-beta.13

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.
@@ -0,0 +1,54 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import type { CreateDatasetClientOptions, CreateKeyValueStoreClientOptions, CreateRequestQueueClientOptions, DatasetClient, KeyValueStoreClient, RequestQueueClient, StorageClient } from '@crawlee/types';
3
+ import type { ApifyClient } from 'apify-client';
4
+ import { type ChargeResult, type ChargingManager } from './charging.js';
5
+ import type { Configuration } from './configuration.js';
6
+ type StorageType = 'Dataset' | 'KeyValueStore' | 'RequestQueue';
7
+ /** Marks a dataset client whose `pushItems` charges for pay-per-event. @internal */
8
+ export declare const USES_PUSH_DATA_INTERCEPTION: unique symbol;
9
+ /**
10
+ * Context of a single `Actor.pushData()` call, shared with the intercepted
11
+ * `pushItems()` calls so they can (1) know which event to charge and
12
+ * (2) aggregate the {@link ChargeResult} across the multiple `pushItems()`
13
+ * calls a single `pushData()` may trigger (Crawlee batches large pushes).
14
+ */
15
+ export interface PpeAwarePushDataContext {
16
+ eventName: string | undefined;
17
+ chargeResult?: ChargeResult;
18
+ }
19
+ export declare const pushDataChargingContext: AsyncLocalStorage<PpeAwarePushDataContext>;
20
+ /**
21
+ * Bridges `apify-client`'s synchronous resource accessors (`dataset(id)`,
22
+ * `keyValueStore(id)`, `requestQueue(id, options?)`) to crawlee v4's
23
+ * `StorageClient` interface (async factory methods accepting either an `id`
24
+ * or a `name`).
25
+ *
26
+ * For the run's default dataset it transparently swaps in a charging-aware
27
+ * dataset client (pay-per-event on `Actor.pushData()`), provided a charging
28
+ * manager is supplied and a default-dataset-item price is configured.
29
+ *
30
+ * `storageExists()` lets `Dataset.open(idOrName)` resolve a string to an id
31
+ * first (when one exists on the platform) and fall back to a name otherwise —
32
+ * otherwise crawlee's `resolveStorageIdentifier` treats every string as a name
33
+ * and the SDK would silently create a new storage named like the passed id.
34
+ */
35
+ export declare class ApifyStorageClient implements StorageClient {
36
+ private readonly client;
37
+ private readonly config?;
38
+ private readonly getChargingManager?;
39
+ constructor(client: ApifyClient, config?: Configuration | undefined, getChargingManager?: (() => ChargingManager) | undefined);
40
+ storageExists(id: string, type: StorageType): Promise<boolean>;
41
+ createDatasetClient(options?: CreateDatasetClientOptions): Promise<DatasetClient>;
42
+ createKeyValueStoreClient(options?: CreateKeyValueStoreClientOptions): Promise<KeyValueStoreClient>;
43
+ createRequestQueueClient(options?: CreateRequestQueueClientOptions): Promise<RequestQueueClient>;
44
+ /**
45
+ * Returns a charging-aware dataset client when `id` is the run's default
46
+ * dataset and a default-dataset-item price is configured; otherwise
47
+ * `undefined` (caller uses the plain client).
48
+ */
49
+ private chargingDatasetClient;
50
+ private resolveId;
51
+ private resourceClient;
52
+ private collectionClient;
53
+ }
54
+ export {};
@@ -0,0 +1,152 @@
1
+ /* eslint-disable max-classes-per-file */
2
+ import { AsyncLocalStorage } from 'node:async_hooks';
3
+ import { DatasetClient as ApifyDatasetClient } from 'apify-client';
4
+ import { DEFAULT_DATASET_ITEM_EVENT, mergeChargeResults, pushDataAndCharge, } from './charging.js';
5
+ const DEFAULT_ID_CONFIG_KEY = {
6
+ Dataset: 'defaultDatasetId',
7
+ KeyValueStore: 'defaultKeyValueStoreId',
8
+ RequestQueue: 'defaultRequestQueueId',
9
+ };
10
+ /** Marks a dataset client whose `pushItems` charges for pay-per-event. @internal */
11
+ export const USES_PUSH_DATA_INTERCEPTION = Symbol('apify:uses-push-data-interception');
12
+ export const pushDataChargingContext = new AsyncLocalStorage();
13
+ /**
14
+ * Default `DatasetClient` that charges for pushed items (pay-per-event). Used
15
+ * only for the run's default dataset when a `apify-default-dataset-item` price
16
+ * is configured; for everything else the plain `apify-client` dataset client is
17
+ * used.
18
+ */
19
+ class PpeAwareDatasetClient extends ApifyDatasetClient {
20
+ getChargingManager;
21
+ constructor(options, getChargingManager) {
22
+ super(options);
23
+ this.getChargingManager = getChargingManager;
24
+ }
25
+ normalizeItems(items) {
26
+ if (typeof items === 'string') {
27
+ const parsed = JSON.parse(items);
28
+ return Array.isArray(parsed) ? parsed : [parsed];
29
+ }
30
+ if (Array.isArray(items)) {
31
+ return items.flatMap((item) => typeof item === 'string' ? JSON.parse(item) : item);
32
+ }
33
+ return [items];
34
+ }
35
+ async pushItems(items) {
36
+ const context = pushDataChargingContext.getStore();
37
+ // A single JSON string may encode multiple items (e.g. '[{...},{...}]'),
38
+ // which the charging logic would miscount — parse strings into arrays so
39
+ // each logical item is counted individually.
40
+ const normalizedItems = this.normalizeItems(items);
41
+ const result = await pushDataAndCharge({
42
+ chargingManager: this.getChargingManager(),
43
+ items: normalizedItems,
44
+ eventName: context?.eventName,
45
+ isDefaultDataset: true,
46
+ // stringify for faster validation in the Apify client
47
+ pushFn: async (limitedItems) => super.pushItems(JSON.stringify(limitedItems)),
48
+ });
49
+ if (!context)
50
+ return;
51
+ // One `Actor.pushData()` may map to several `pushItems()` calls — aggregate.
52
+ context.chargeResult =
53
+ context.chargeResult === undefined ? result : mergeChargeResults(context.chargeResult, result);
54
+ }
55
+ }
56
+ /**
57
+ * Bridges `apify-client`'s synchronous resource accessors (`dataset(id)`,
58
+ * `keyValueStore(id)`, `requestQueue(id, options?)`) to crawlee v4's
59
+ * `StorageClient` interface (async factory methods accepting either an `id`
60
+ * or a `name`).
61
+ *
62
+ * For the run's default dataset it transparently swaps in a charging-aware
63
+ * dataset client (pay-per-event on `Actor.pushData()`), provided a charging
64
+ * manager is supplied and a default-dataset-item price is configured.
65
+ *
66
+ * `storageExists()` lets `Dataset.open(idOrName)` resolve a string to an id
67
+ * first (when one exists on the platform) and fall back to a name otherwise —
68
+ * otherwise crawlee's `resolveStorageIdentifier` treats every string as a name
69
+ * and the SDK would silently create a new storage named like the passed id.
70
+ */
71
+ export class ApifyStorageClient {
72
+ client;
73
+ config;
74
+ getChargingManager;
75
+ constructor(client, config, getChargingManager) {
76
+ this.client = client;
77
+ this.config = config;
78
+ this.getChargingManager = getChargingManager;
79
+ }
80
+ async storageExists(id, type) {
81
+ // Apify's `GET /v2/{kind}/{idOrName}` matches by either id or name;
82
+ // confirm it was an *id* match so crawlee can fall through to `{ name }`.
83
+ const info = await this.resourceClient(id, type).get();
84
+ return info?.id === id;
85
+ }
86
+ async createDatasetClient(options) {
87
+ const id = await this.resolveId(options, 'Dataset');
88
+ const datasetClient = this.chargingDatasetClient(id) ?? this.client.dataset(id);
89
+ // apify-client's resource clients overlap with `@crawlee/types`' shapes
90
+ // but don't implement the v4-added members (`getMetadata`,
91
+ // `getRecordPublicUrl`), so cast through.
92
+ return datasetClient;
93
+ }
94
+ async createKeyValueStoreClient(options) {
95
+ const id = await this.resolveId(options, 'KeyValueStore');
96
+ return this.client.keyValueStore(id);
97
+ }
98
+ async createRequestQueueClient(options) {
99
+ const id = await this.resolveId(options, 'RequestQueue');
100
+ return this.client.requestQueue(id, options?.clientKey ? { clientKey: options.clientKey } : undefined);
101
+ }
102
+ /**
103
+ * Returns a charging-aware dataset client when `id` is the run's default
104
+ * dataset and a default-dataset-item price is configured; otherwise
105
+ * `undefined` (caller uses the plain client).
106
+ */
107
+ chargingDatasetClient(id) {
108
+ const { getChargingManager } = this;
109
+ if (!getChargingManager)
110
+ return undefined;
111
+ if (id !== this.config?.defaultDatasetId)
112
+ return undefined;
113
+ const hasDefaultDatasetItemEvent = DEFAULT_DATASET_ITEM_EVENT in getChargingManager().getPricingInfo().perEventPrices;
114
+ if (!hasDefaultDatasetItemEvent)
115
+ return undefined;
116
+ const datasetClient = new PpeAwareDatasetClient({
117
+ id,
118
+ baseUrl: this.client.baseUrl,
119
+ publicBaseUrl: this.client.publicBaseUrl,
120
+ apifyClient: this.client,
121
+ httpClient: this.client.httpClient,
122
+ }, getChargingManager);
123
+ Object.assign(datasetClient, {
124
+ [USES_PUSH_DATA_INTERCEPTION]: true,
125
+ });
126
+ return datasetClient;
127
+ }
128
+ async resolveId(options, type) {
129
+ if (options?.id)
130
+ return options.id;
131
+ if (options?.name) {
132
+ return (await this.collectionClient(type).getOrCreate(options.name)).id;
133
+ }
134
+ // No id/name (crawlee's `__default__` alias): use the default storage
135
+ // id from the run's environment. apify-client rejects an empty id.
136
+ return this.config?.[DEFAULT_ID_CONFIG_KEY[type]] ?? '';
137
+ }
138
+ resourceClient(id, type) {
139
+ if (type === 'Dataset')
140
+ return this.client.dataset(id);
141
+ if (type === 'KeyValueStore')
142
+ return this.client.keyValueStore(id);
143
+ return this.client.requestQueue(id);
144
+ }
145
+ collectionClient(type) {
146
+ if (type === 'Dataset')
147
+ return this.client.datasets();
148
+ if (type === 'KeyValueStore')
149
+ return this.client.keyValueStores();
150
+ return this.client.requestQueues();
151
+ }
152
+ }
package/dist/charging.js CHANGED
@@ -1,13 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ChargingManager = exports.DEFAULT_DATASET_ITEM_EVENT = void 0;
4
- exports.mergeChargeResults = mergeChargeResults;
5
- exports.pushDataAndCharge = pushDataAndCharge;
6
- const tslib_1 = require("tslib");
7
- const core_1 = require("@crawlee/core");
8
- const log_1 = tslib_1.__importDefault(require("@apify/log"));
9
- exports.DEFAULT_DATASET_ITEM_EVENT = 'apify-default-dataset-item';
10
- function mergeChargeResults(a, b) {
1
+ import { Dataset, KeyValueStore } from '@crawlee/core';
2
+ import log from '@apify/log';
3
+ export const DEFAULT_DATASET_ITEM_EVENT = 'apify-default-dataset-item';
4
+ export function mergeChargeResults(a, b) {
11
5
  return {
12
6
  eventChargeLimitReached: a.eventChargeLimitReached || b.eventChargeLimitReached,
13
7
  chargedCount: a.chargedCount + b.chargedCount,
@@ -20,108 +14,39 @@ function mergeChargeResults(a, b) {
20
14
  /**
21
15
  * Handles pay-per-event charging.
22
16
  */
23
- class ChargingManager {
17
+ export class ChargingManager {
18
+ configuration;
19
+ LOCAL_CHARGING_LOG_DATASET_NAME = 'charging_log';
20
+ PLATFORM_CHARGING_LOG_DATASET_ID_KEY = 'CHARGING_LOG_DATASET_ID';
21
+ maxTotalChargeUsd;
22
+ isAtHome;
23
+ actorRunId;
24
+ pricingModel;
25
+ purgeChargingLogDataset;
26
+ useChargingLogDataset;
27
+ notPpeWarningPrinted = false;
28
+ pricingInfo = {};
29
+ chargingState;
30
+ chargingLogDataset;
31
+ apifyClient;
24
32
  constructor(configuration, apifyClient) {
25
- Object.defineProperty(this, "configuration", {
26
- enumerable: true,
27
- configurable: true,
28
- writable: true,
29
- value: configuration
30
- });
31
- Object.defineProperty(this, "LOCAL_CHARGING_LOG_DATASET_NAME", {
32
- enumerable: true,
33
- configurable: true,
34
- writable: true,
35
- value: 'charging_log'
36
- });
37
- Object.defineProperty(this, "PLATFORM_CHARGING_LOG_DATASET_ID_KEY", {
38
- enumerable: true,
39
- configurable: true,
40
- writable: true,
41
- value: 'CHARGING_LOG_DATASET_ID'
42
- });
43
- Object.defineProperty(this, "maxTotalChargeUsd", {
44
- enumerable: true,
45
- configurable: true,
46
- writable: true,
47
- value: void 0
48
- });
49
- Object.defineProperty(this, "isAtHome", {
50
- enumerable: true,
51
- configurable: true,
52
- writable: true,
53
- value: void 0
54
- });
55
- Object.defineProperty(this, "actorRunId", {
56
- enumerable: true,
57
- configurable: true,
58
- writable: true,
59
- value: void 0
60
- });
61
- Object.defineProperty(this, "pricingModel", {
62
- enumerable: true,
63
- configurable: true,
64
- writable: true,
65
- value: void 0
66
- });
67
- Object.defineProperty(this, "purgeChargingLogDataset", {
68
- enumerable: true,
69
- configurable: true,
70
- writable: true,
71
- value: void 0
72
- });
73
- Object.defineProperty(this, "useChargingLogDataset", {
74
- enumerable: true,
75
- configurable: true,
76
- writable: true,
77
- value: void 0
78
- });
79
- Object.defineProperty(this, "notPpeWarningPrinted", {
80
- enumerable: true,
81
- configurable: true,
82
- writable: true,
83
- value: false
84
- });
85
- Object.defineProperty(this, "pricingInfo", {
86
- enumerable: true,
87
- configurable: true,
88
- writable: true,
89
- value: {}
90
- });
91
- Object.defineProperty(this, "chargingState", {
92
- enumerable: true,
93
- configurable: true,
94
- writable: true,
95
- value: void 0
96
- });
97
- Object.defineProperty(this, "chargingLogDataset", {
98
- enumerable: true,
99
- configurable: true,
100
- writable: true,
101
- value: void 0
102
- });
103
- Object.defineProperty(this, "apifyClient", {
104
- enumerable: true,
105
- configurable: true,
106
- writable: true,
107
- value: void 0
108
- });
109
- this.maxTotalChargeUsd = configuration.get('maxTotalChargeUsd') || Infinity; // convert `0` to `Infinity` in case the value is an empty string
110
- this.isAtHome = configuration.get('isAtHome');
111
- this.actorRunId = configuration.get('actorRunId');
112
- this.purgeChargingLogDataset = configuration.get('purgeOnStart');
113
- this.useChargingLogDataset = configuration.get('useChargingLogDataset');
33
+ this.configuration = configuration;
34
+ this.maxTotalChargeUsd = configuration.maxTotalChargeUsd || Infinity; // convert `0` to `Infinity` in case the value is an empty string
35
+ this.isAtHome = configuration.isAtHome;
36
+ this.actorRunId = configuration.actorRunId;
37
+ this.purgeChargingLogDataset = configuration.purgeOnStart;
38
+ this.useChargingLogDataset = configuration.useChargingLogDataset;
114
39
  this.apifyClient = apifyClient;
115
40
  }
116
41
  get isPayPerEvent() {
117
42
  return this.pricingModel === 'PAY_PER_EVENT';
118
43
  }
119
44
  async fetchPricingInfo() {
120
- if (this.configuration.get('actorPricingInfo') && this.configuration.get('chargedEventCounts')) {
45
+ if (this.configuration.actorPricingInfo && this.configuration.chargedEventCounts) {
121
46
  return {
122
- pricingInfo: JSON.parse(this.configuration.get('actorPricingInfo')),
123
- chargedEventCounts: JSON.parse(this.configuration.get('chargedEventCounts')),
124
- maxTotalChargeUsd: this.configuration.get('maxTotalChargeUsd') || Infinity,
47
+ pricingInfo: JSON.parse(this.configuration.actorPricingInfo),
48
+ chargedEventCounts: JSON.parse(this.configuration.chargedEventCounts),
49
+ maxTotalChargeUsd: this.configuration.maxTotalChargeUsd || Infinity,
125
50
  };
126
51
  }
127
52
  if (this.isAtHome) {
@@ -141,7 +66,7 @@ class ChargingManager {
141
66
  return {
142
67
  pricingInfo: undefined,
143
68
  chargedEventCounts: {},
144
- maxTotalChargeUsd: this.configuration.get('maxTotalChargeUsd') || Infinity,
69
+ maxTotalChargeUsd: this.configuration.maxTotalChargeUsd || Infinity,
145
70
  };
146
71
  }
147
72
  /**
@@ -152,18 +77,18 @@ class ChargingManager {
152
77
  if (this.useChargingLogDataset && this.isAtHome) {
153
78
  throw new Error('Using the ACTOR_USE_CHARGING_LOG_DATASET environment variable is only supported in a local development environment');
154
79
  }
155
- if (this.configuration.get('testPayPerEvent')) {
80
+ if (this.configuration.testPayPerEvent) {
156
81
  if (this.isAtHome) {
157
82
  throw new Error('Using the ACTOR_TEST_PAY_PER_EVENT environment variable is only supported in a local development environment');
158
83
  }
159
84
  }
160
85
  // Retrieve pricing information
161
86
  const { pricingInfo, chargedEventCounts, maxTotalChargeUsd } = await this.fetchPricingInfo();
162
- if (this.configuration.get('testPayPerEvent')) {
87
+ if (this.configuration.testPayPerEvent) {
163
88
  this.pricingModel = 'PAY_PER_EVENT';
164
89
  }
165
90
  else {
166
- this.pricingModel ?? (this.pricingModel = pricingInfo?.pricingModel);
91
+ this.pricingModel ??= pricingInfo?.pricingModel;
167
92
  }
168
93
  // Load per-event pricing information
169
94
  if (pricingInfo?.pricingModel === 'PAY_PER_EVENT') {
@@ -188,18 +113,18 @@ class ChargingManager {
188
113
  // Set up charging log dataset
189
114
  if (this.isAtHome) {
190
115
  const datasetId = await this.ensureChargingLogDatasetOnPlatform();
191
- this.chargingLogDataset = await core_1.Dataset.open(datasetId);
116
+ this.chargingLogDataset = await Dataset.open(datasetId);
192
117
  }
193
118
  else {
194
119
  if (this.purgeChargingLogDataset) {
195
- const dataset = await core_1.Dataset.open(this.LOCAL_CHARGING_LOG_DATASET_NAME);
120
+ const dataset = await Dataset.open(this.LOCAL_CHARGING_LOG_DATASET_NAME);
196
121
  await dataset.drop();
197
122
  }
198
- this.chargingLogDataset = await core_1.Dataset.open(this.LOCAL_CHARGING_LOG_DATASET_NAME);
123
+ this.chargingLogDataset = await Dataset.open(this.LOCAL_CHARGING_LOG_DATASET_NAME);
199
124
  }
200
125
  }
201
126
  async ensureChargingLogDatasetOnPlatform() {
202
- const defaultStore = await core_1.KeyValueStore.open();
127
+ const defaultStore = await KeyValueStore.open();
203
128
  const storedDatasetId = await defaultStore.getValue(this.PLATFORM_CHARGING_LOG_DATASET_ID_KEY);
204
129
  if (storedDatasetId !== null) {
205
130
  return storedDatasetId;
@@ -239,11 +164,10 @@ class ChargingManager {
239
164
  * @param options The name of the event to charge for and the number of events to be charged.
240
165
  */
241
166
  async charge({ eventName, count = 1 }) {
242
- var _a;
243
167
  const calculateChargeableWithinLimit = () => Object.fromEntries(Object.keys(this.pricingInfo).map((name) => [name, this.calculateMaxEventChargeCountWithinLimit(name)]));
244
168
  if (!this.isPayPerEvent) {
245
169
  if (!this.notPpeWarningPrinted) {
246
- log_1.default.warning('Ignored attempt to charge for an event - the Actor does not use the pay-per-event pricing');
170
+ log.warning('Ignored attempt to charge for an event - the Actor does not use the pay-per-event pricing');
247
171
  this.notPpeWarningPrinted = true;
248
172
  }
249
173
  return {
@@ -280,10 +204,10 @@ class ChargingManager {
280
204
  price: this.isAtHome ? 0 : 1, // Use a nonzero price for local development so that the maximum budget can be reached
281
205
  title: `Unknown event '${eventName}'`,
282
206
  };
283
- (_a = this.chargingState)[eventName] ?? (_a[eventName] = {
207
+ this.chargingState[eventName] ??= {
284
208
  chargeCount: 0,
285
209
  totalChargedAmount: 0,
286
- });
210
+ };
287
211
  this.chargingState[eventName].chargeCount += chargedCount;
288
212
  this.chargingState[eventName].totalChargedAmount += chargedCount * pricingInfo.price;
289
213
  /* END OF CRITICAL SECTION */
@@ -296,7 +220,7 @@ class ChargingManager {
296
220
  await this.apifyClient.run(this.actorRunId).charge({ eventName, count: chargedCount });
297
221
  }
298
222
  else {
299
- log_1.default.warning(`Attempting to charge for an unknown event '${eventName}'`);
223
+ log.warning(`Attempting to charge for an unknown event '${eventName}'`);
300
224
  }
301
225
  }
302
226
  const timestamp = new Date().toISOString();
@@ -311,7 +235,7 @@ class ChargingManager {
311
235
  }
312
236
  if (chargedCount < count) {
313
237
  const subject = count === 1 ? 'instance' : 'instances';
314
- log_1.default.info(`Charging ${count} ${subject} of '${eventName}' event would exceed maxTotalChargeUsd - only ${chargedCount} events were charged`);
238
+ log.info(`Charging ${count} ${subject} of '${eventName}' event would exceed maxTotalChargeUsd - only ${chargedCount} events were charged`);
315
239
  }
316
240
  return {
317
241
  eventChargeLimitReached: this.calculateMaxEventChargeCountWithinLimit(eventName) <= 0,
@@ -387,7 +311,7 @@ class ChargingManager {
387
311
  };
388
312
  }
389
313
  const itemPrice = ((eventName !== undefined ? this.calculateEventPrice(eventName) : undefined) ?? 0) +
390
- ((isDefaultDataset ? this.calculateEventPrice(exports.DEFAULT_DATASET_ITEM_EVENT) : undefined) ?? 0);
314
+ ((isDefaultDataset ? this.calculateEventPrice(DEFAULT_DATASET_ITEM_EVENT) : undefined) ?? 0);
391
315
  const maxChargedCount = itemPrice > 0 ? this.calculateMaxChargesByPrice(itemPrice) : Infinity;
392
316
  const itemsToKeep = (() => {
393
317
  if (maxChargedCount >= itemsArray.length) {
@@ -408,7 +332,7 @@ class ChargingManager {
408
332
  eventsToCharge[eventName] = itemsToKeep;
409
333
  }
410
334
  if (isDefaultDataset && itemsToKeep > 0) {
411
- eventsToCharge[exports.DEFAULT_DATASET_ITEM_EVENT] = itemsToKeep;
335
+ eventsToCharge[DEFAULT_DATASET_ITEM_EVENT] = itemsToKeep;
412
336
  }
413
337
  return {
414
338
  limitedItems: itemsToKeep >= itemsArray.length ? itemsArray : itemsArray.slice(0, itemsToKeep),
@@ -416,7 +340,6 @@ class ChargingManager {
416
340
  };
417
341
  }
418
342
  }
419
- exports.ChargingManager = ChargingManager;
420
343
  /**
421
344
  * Helper for PPE-aware pushing of data to the dataset.
422
345
  *
@@ -426,7 +349,7 @@ exports.ChargingManager = ChargingManager;
426
349
  *
427
350
  * @internal
428
351
  */
429
- async function pushDataAndCharge({ chargingManager, items, eventName, isDefaultDataset, pushFn, }) {
352
+ export async function pushDataAndCharge({ chargingManager, items, eventName, isDefaultDataset, pushFn, }) {
430
353
  const { limitedItems, eventsToCharge } = chargingManager.calculatePushDataLimits({
431
354
  items,
432
355
  eventName,