@crawlee/core 4.0.0-beta.99 → 4.0.0-rc.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/autoscaling/autoscaled_pool.d.ts +3 -21
- package/autoscaling/autoscaled_pool.js +105 -97
- package/autoscaling/concurrency_system.d.ts +7 -22
- package/autoscaling/concurrency_system.js +112 -100
- package/autoscaling/cpu_load_signal.d.ts +1 -2
- package/autoscaling/cpu_load_signal.js +11 -10
- package/autoscaling/event_loop_load_signal.d.ts +1 -4
- package/autoscaling/event_loop_load_signal.js +18 -18
- package/autoscaling/index.d.ts +1 -1
- package/autoscaling/index.js +1 -1
- package/autoscaling/load_signal.d.ts +8 -7
- package/autoscaling/load_signal.js +14 -12
- package/autoscaling/memory_load_signal.d.ts +3 -12
- package/autoscaling/memory_load_signal.js +41 -41
- package/autoscaling/snapshotter.d.ts +7 -10
- package/autoscaling/snapshotter.js +18 -18
- package/autoscaling/{client_load_signal.d.ts → storage_backend_load_signal.d.ts} +14 -17
- package/autoscaling/{client_load_signal.js → storage_backend_load_signal.js} +27 -27
- package/autoscaling/system_status.d.ts +9 -11
- package/autoscaling/system_status.js +13 -13
- package/configuration.d.ts +16 -16
- package/configuration.js +6 -6
- package/crawlers/context_pipeline.js +6 -6
- package/crawlers/crawler_commons.d.ts +14 -112
- package/crawlers/crawler_commons.js +1 -107
- package/crawlers/error_snapshotter.d.ts +2 -4
- package/crawlers/error_snapshotter.js +5 -5
- package/crawlers/index.d.ts +1 -1
- package/crawlers/index.js +0 -1
- package/crawlers/statistics.d.ts +164 -45
- package/crawlers/statistics.js +339 -153
- package/debug.js +4 -4
- package/enqueue_links/enqueue_links.d.ts +51 -159
- package/enqueue_links/enqueue_links.js +38 -231
- package/enqueue_links/shared.d.ts +34 -24
- package/enqueue_links/shared.js +54 -36
- package/errors.d.ts +43 -12
- package/errors.js +48 -9
- package/events/event_manager.d.ts +2 -2
- package/events/event_manager.js +7 -6
- package/events/local_event_manager.d.ts +1 -1
- package/events/local_event_manager.js +5 -5
- package/http.d.ts +9 -0
- package/http.js +28 -0
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/log.js +5 -1
- package/memory-storage/memory-storage.d.ts +3 -11
- package/memory-storage/memory-storage.js +42 -48
- package/memory-storage/resource-clients/dataset.d.ts +1 -1
- package/memory-storage/resource-clients/dataset.js +8 -13
- package/memory-storage/resource-clients/key-value-store.d.ts +1 -1
- package/memory-storage/resource-clients/key-value-store.js +36 -38
- package/memory-storage/resource-clients/request-queue.d.ts +4 -23
- package/memory-storage/resource-clients/request-queue.js +68 -80
- package/owned_or_injected.d.ts +1 -3
- package/owned_or_injected.js +17 -17
- package/package.json +8 -9
- package/proxy_configuration.d.ts +1 -3
- package/proxy_configuration.js +18 -14
- package/recoverable_state.d.ts +80 -45
- package/recoverable_state.js +163 -75
- package/request.d.ts +3 -4
- package/request.js +57 -44
- package/router.d.ts +6 -9
- package/router.js +23 -23
- package/serialization.js +14 -13
- package/service_locator.d.ts +19 -10
- package/service_locator.js +57 -48
- package/session_pool/session.d.ts +3 -14
- package/session_pool/session.js +76 -74
- package/session_pool/session_pool.d.ts +6 -12
- package/session_pool/session_pool.js +85 -77
- package/storages/batched_adds.d.ts +37 -0
- package/storages/batched_adds.js +73 -0
- package/storages/dataset.d.ts +12 -1
- package/storages/dataset.js +133 -32
- package/storages/index.d.ts +2 -1
- package/storages/index.js +2 -1
- package/storages/key_value_store.d.ts +19 -4
- package/storages/key_value_store.js +204 -75
- package/storages/request_dedup_cache.d.ts +1 -2
- package/storages/request_dedup_cache.js +9 -9
- package/storages/request_list.d.ts +4 -23
- package/storages/request_list.js +103 -96
- package/storages/request_loader.d.ts +5 -0
- package/storages/request_manager_tandem.d.ts +1 -10
- package/storages/request_manager_tandem.js +27 -27
- package/storages/request_queue.d.ts +21 -18
- package/storages/request_queue.js +318 -177
- package/storages/sitemap_request_loader.d.ts +22 -70
- package/storages/sitemap_request_loader.js +122 -116
- package/storages/storage_instance_manager.d.ts +1 -2
- package/storages/storage_instance_manager.js +17 -17
- package/storages/storage_stats.d.ts +1 -1
- package/storages/storage_stats.js +4 -4
- package/storages/throttling_request_manager.d.ts +239 -0
- package/storages/throttling_request_manager.js +646 -0
- package/storages/transaction.d.ts +252 -0
- package/storages/transaction.js +251 -0
- package/storages/utils.d.ts +6 -3
- package/storages/utils.js +11 -2
- package/system-info/runtime.js +7 -7
- package/url.d.ts +9 -0
- package/url.js +11 -0
- package/validators.d.ts +22 -25
- package/validators.js +13 -25
- package/storages/access_checking.d.ts +0 -12
- package/storages/access_checking.js +0 -17
package/storages/dataset.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { tryCancel } from '@apify/timeout';
|
|
3
3
|
import { Configuration } from '../configuration.js';
|
|
4
4
|
import { serviceLocator } from '../service_locator.js';
|
|
5
|
-
import {
|
|
5
|
+
import { parseArgument, schemas, validators } from '../validators.js';
|
|
6
|
+
import { activeStorageTransaction, rejectOperationInTransaction, snapshotValue } from './transaction.js';
|
|
6
7
|
import { KeyValueStore } from './key_value_store.js';
|
|
7
8
|
import { StorageStatsTracker } from './storage_stats.js';
|
|
8
9
|
import { resolveStorageIdentifier } from './storage_instance_manager.js';
|
|
9
10
|
import { createDualIterable, purgeDefaultStorages } from './utils.js';
|
|
11
|
+
const openOptionsSchema = z.strictObject({
|
|
12
|
+
configuration: z.instanceof(Configuration).optional(),
|
|
13
|
+
storageBackend: validators.storageBackend.optional(),
|
|
14
|
+
});
|
|
10
15
|
/** @internal */
|
|
11
16
|
export const DATASET_ITERATORS_DEFAULT_LIMIT = 10000;
|
|
12
17
|
/**
|
|
@@ -88,7 +93,7 @@ export class Dataset {
|
|
|
88
93
|
name;
|
|
89
94
|
backend;
|
|
90
95
|
log;
|
|
91
|
-
statsTracker = new StorageStatsTracker({
|
|
96
|
+
#statsTracker = new StorageStatsTracker({
|
|
92
97
|
readCount: 0,
|
|
93
98
|
writeCount: 0,
|
|
94
99
|
});
|
|
@@ -107,7 +112,7 @@ export class Dataset {
|
|
|
107
112
|
* the underlying storage backend). Counted per backend call.
|
|
108
113
|
*/
|
|
109
114
|
get stats() {
|
|
110
|
-
return this
|
|
115
|
+
return this.#statsTracker.current;
|
|
111
116
|
}
|
|
112
117
|
/**
|
|
113
118
|
* Stores an object or an array of objects to the dataset.
|
|
@@ -121,24 +126,33 @@ export class Dataset {
|
|
|
121
126
|
* The objects must be serializable to JSON.
|
|
122
127
|
*/
|
|
123
128
|
async pushData(data) {
|
|
124
|
-
|
|
125
|
-
|
|
129
|
+
const transaction = activeStorageTransaction();
|
|
130
|
+
parseArgument(data, schemas.anyObject);
|
|
126
131
|
// Normalize to array and validate each item
|
|
127
132
|
const items = Array.isArray(data) ? data : [data];
|
|
128
133
|
for (let i = 0; i < items.length; i++) {
|
|
129
134
|
assertJsonSerializable(items[i], i);
|
|
130
135
|
}
|
|
131
|
-
|
|
136
|
+
if (transaction) {
|
|
137
|
+
// One snapshot serves both the reads and the commit replay, so the two cannot disagree.
|
|
138
|
+
transaction.recordJournalEntry({
|
|
139
|
+
type: 'dataset',
|
|
140
|
+
participant: this,
|
|
141
|
+
storageId: this.id,
|
|
142
|
+
items: snapshotValue(items),
|
|
143
|
+
recordedAt: new Date(),
|
|
144
|
+
});
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
this.#statsTracker.add('writeCount');
|
|
132
148
|
await this.backend.pushData(items);
|
|
133
149
|
}
|
|
134
150
|
/**
|
|
135
151
|
* Returns {@link DatasetContent} object holding the items in the dataset based on the provided parameters.
|
|
136
152
|
*/
|
|
137
153
|
async getData(options = {}) {
|
|
138
|
-
checkStorageAccess();
|
|
139
154
|
try {
|
|
140
|
-
this.
|
|
141
|
-
return await this.backend.getData(options);
|
|
155
|
+
return await this.readPage(options);
|
|
142
156
|
}
|
|
143
157
|
catch (e) {
|
|
144
158
|
const error = e;
|
|
@@ -148,12 +162,93 @@ export class Dataset {
|
|
|
148
162
|
throw e;
|
|
149
163
|
}
|
|
150
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* The single transaction-aware page read all dataset read paths go through — both `getData()` and
|
|
167
|
+
* the private `fetchPages()`. Returns the real page concatenated with the current transaction's
|
|
168
|
+
* buffered items, with `offset` / `limit` / `desc` windowing applied across the concatenation.
|
|
169
|
+
*/
|
|
170
|
+
async readPage(options) {
|
|
171
|
+
const buffered = this.bufferedJournalEntries()?.flatMap((entry) => entry.items);
|
|
172
|
+
// Every branch below hits the backend exactly once.
|
|
173
|
+
this.#statsTracker.add('readCount');
|
|
174
|
+
if (!buffered?.length) {
|
|
175
|
+
return this.backend.getData(options);
|
|
176
|
+
}
|
|
177
|
+
const { offset = 0, limit, desc = false } = options;
|
|
178
|
+
if (!desc) {
|
|
179
|
+
const realPage = await this.backend.getData(options);
|
|
180
|
+
// Buffered items sit past `realPage.total`, so the window bounds must come from that - not
|
|
181
|
+
// from the page's shortfall, which `skipEmpty` produces without exhausting the real items.
|
|
182
|
+
const bufferedStart = Math.max(0, offset - realPage.total);
|
|
183
|
+
const bufferedEnd = limit === undefined ? buffered.length : Math.max(0, offset + limit - realPage.total);
|
|
184
|
+
const items = [...realPage.items, ...buffered.slice(bufferedStart, bufferedEnd)];
|
|
185
|
+
return {
|
|
186
|
+
items,
|
|
187
|
+
total: realPage.total + buffered.length,
|
|
188
|
+
offset,
|
|
189
|
+
// A caller that passed no limit wants everything, so the backend-reported `limit` is
|
|
190
|
+
// passed through - backends are free to report a page size or a sentinel there.
|
|
191
|
+
limit: limit ?? realPage.limit,
|
|
192
|
+
count: items.length,
|
|
193
|
+
desc,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
// Descending order: the buffered items are the newest, so they come first, reversed.
|
|
197
|
+
const reversedBuffer = [...buffered].reverse();
|
|
198
|
+
const fromBuffer = limit === undefined ? reversedBuffer.slice(offset) : reversedBuffer.slice(offset, offset + limit);
|
|
199
|
+
const needed = limit === undefined ? Infinity : limit - fromBuffer.length;
|
|
200
|
+
if (needed <= 0) {
|
|
201
|
+
// The whole window is served from the buffer; only the real total is missing.
|
|
202
|
+
const { itemCount } = await this.backend.getMetadata();
|
|
203
|
+
return {
|
|
204
|
+
items: fromBuffer,
|
|
205
|
+
total: itemCount + buffered.length,
|
|
206
|
+
offset,
|
|
207
|
+
limit: limit,
|
|
208
|
+
count: fromBuffer.length,
|
|
209
|
+
desc,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
const realPage = await this.backend.getData({
|
|
213
|
+
...options,
|
|
214
|
+
offset: Math.max(0, offset - buffered.length),
|
|
215
|
+
...(limit === undefined ? {} : { limit: needed }),
|
|
216
|
+
});
|
|
217
|
+
return {
|
|
218
|
+
items: [...fromBuffer, ...realPage.items],
|
|
219
|
+
total: realPage.total + buffered.length,
|
|
220
|
+
offset,
|
|
221
|
+
limit: limit ?? realPage.limit,
|
|
222
|
+
count: fromBuffer.length + realPage.items.length,
|
|
223
|
+
desc,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
/** The active transaction's buffered writes to this dataset, derived from its journal. */
|
|
227
|
+
bufferedJournalEntries() {
|
|
228
|
+
const transaction = activeStorageTransaction();
|
|
229
|
+
return transaction?.journal.filter((entry) => entry.type === 'dataset' && entry.participant === this);
|
|
230
|
+
}
|
|
231
|
+
/** @internal */
|
|
232
|
+
async commitJournalEntries(entries) {
|
|
233
|
+
const items = [];
|
|
234
|
+
for (const entry of entries) {
|
|
235
|
+
if (entry.type === 'dataset') {
|
|
236
|
+
items.push(...entry.items);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// One backend call with all journaled items, in order - as close to atomic as the backend allows.
|
|
240
|
+
// Straight to the backend: the items were validated and snapshotted at write time.
|
|
241
|
+
if (items.length > 0) {
|
|
242
|
+
this.#statsTracker.add('writeCount');
|
|
243
|
+
await this.backend.pushData(items);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
151
246
|
/**
|
|
152
247
|
* Returns all the data from the dataset. This will iterate through the whole dataset
|
|
153
248
|
* via the `listItems()` client method, which gives you only paginated results.
|
|
154
249
|
*/
|
|
155
250
|
async export(options = {}) {
|
|
156
|
-
|
|
251
|
+
tryCancel();
|
|
157
252
|
const items = [];
|
|
158
253
|
for await (const page of this.fetchPages(options)) {
|
|
159
254
|
items.push(...page.items);
|
|
@@ -179,6 +274,7 @@ export class Dataset {
|
|
|
179
274
|
const keys = options?.collectAllKeys
|
|
180
275
|
? Array.from(new Set(items.flatMap(Object.keys)))
|
|
181
276
|
: Object.keys(items[0]);
|
|
277
|
+
const { stringify } = await import('csv-stringify/sync');
|
|
182
278
|
const value = stringify([
|
|
183
279
|
keys,
|
|
184
280
|
...items.map((item) => {
|
|
@@ -219,7 +315,7 @@ export class Dataset {
|
|
|
219
315
|
* @param [options] An optional options object where you can provide the dataset and target KVS name.
|
|
220
316
|
*/
|
|
221
317
|
static async exportToJSON(key, options) {
|
|
222
|
-
|
|
318
|
+
tryCancel();
|
|
223
319
|
const dataset = await this.open(options?.fromDataset);
|
|
224
320
|
await dataset.exportToJSON(key, options);
|
|
225
321
|
}
|
|
@@ -230,7 +326,7 @@ export class Dataset {
|
|
|
230
326
|
* @param [options] An optional options object where you can provide the dataset and target KVS name.
|
|
231
327
|
*/
|
|
232
328
|
static async exportToCSV(key, options) {
|
|
233
|
-
|
|
329
|
+
tryCancel();
|
|
234
330
|
const dataset = await this.open(options?.fromDataset);
|
|
235
331
|
await dataset.exportToCSV(key, options);
|
|
236
332
|
}
|
|
@@ -252,8 +348,17 @@ export class Dataset {
|
|
|
252
348
|
* @throws If the underlying storage no longer exists (e.g. it was deleted externally).
|
|
253
349
|
*/
|
|
254
350
|
async getInfo() {
|
|
255
|
-
|
|
256
|
-
|
|
351
|
+
const buffered = this.bufferedJournalEntries();
|
|
352
|
+
const metadata = await this.backend.getMetadata();
|
|
353
|
+
if (buffered?.length) {
|
|
354
|
+
const lastWriteAt = buffered[buffered.length - 1].recordedAt;
|
|
355
|
+
return {
|
|
356
|
+
...metadata,
|
|
357
|
+
itemCount: metadata.itemCount + buffered.reduce((sum, entry) => sum + entry.items.length, 0),
|
|
358
|
+
modifiedAt: metadata.modifiedAt > lastWriteAt ? metadata.modifiedAt : lastWriteAt,
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
return metadata;
|
|
257
362
|
}
|
|
258
363
|
/**
|
|
259
364
|
* Iterates over dataset items, yielding each in turn to an `iteratee` function.
|
|
@@ -276,7 +381,7 @@ export class Dataset {
|
|
|
276
381
|
* @default 0
|
|
277
382
|
*/
|
|
278
383
|
async forEach(iteratee, options = {}, index = 0) {
|
|
279
|
-
|
|
384
|
+
tryCancel();
|
|
280
385
|
if (!options.offset)
|
|
281
386
|
options.offset = 0;
|
|
282
387
|
if (options.format && options.format !== 'json')
|
|
@@ -303,7 +408,7 @@ export class Dataset {
|
|
|
303
408
|
* @param [options] All `map()` parameters.
|
|
304
409
|
*/
|
|
305
410
|
async map(iteratee, options = {}) {
|
|
306
|
-
|
|
411
|
+
tryCancel();
|
|
307
412
|
const result = [];
|
|
308
413
|
await this.forEach(async (item, index) => {
|
|
309
414
|
const res = await iteratee(item, index);
|
|
@@ -312,7 +417,7 @@ export class Dataset {
|
|
|
312
417
|
return result;
|
|
313
418
|
}
|
|
314
419
|
async reduce(iteratee, memo, options = {}) {
|
|
315
|
-
|
|
420
|
+
tryCancel();
|
|
316
421
|
let currentMemo = memo;
|
|
317
422
|
const wrappedFunc = async (item, index) => {
|
|
318
423
|
if (index === 0 && currentMemo === undefined) {
|
|
@@ -344,8 +449,7 @@ export class Dataset {
|
|
|
344
449
|
const fetchLimit = totalLimit !== undefined ? Math.min(pageSize, totalLimit - yielded) : pageSize;
|
|
345
450
|
if (fetchLimit <= 0)
|
|
346
451
|
break;
|
|
347
|
-
this.
|
|
348
|
-
const page = await this.backend.getData({ ...options, offset, limit: fetchLimit });
|
|
452
|
+
const page = await this.readPage({ ...options, offset, limit: fetchLimit });
|
|
349
453
|
yield page;
|
|
350
454
|
yielded += page.items.length;
|
|
351
455
|
if (page.items.length < fetchLimit || offset + page.items.length >= page.total)
|
|
@@ -377,7 +481,7 @@ export class Dataset {
|
|
|
377
481
|
* @param options Options for the iteration.
|
|
378
482
|
*/
|
|
379
483
|
values(options = {}) {
|
|
380
|
-
|
|
484
|
+
tryCancel();
|
|
381
485
|
return createDualIterable({
|
|
382
486
|
createPages: () => this.fetchPages(options),
|
|
383
487
|
extractItems: (page) => page.items,
|
|
@@ -407,7 +511,7 @@ export class Dataset {
|
|
|
407
511
|
* @param options Options for the iteration.
|
|
408
512
|
*/
|
|
409
513
|
entries(options = {}) {
|
|
410
|
-
|
|
514
|
+
tryCancel();
|
|
411
515
|
return createDualIterable({
|
|
412
516
|
createPages: () => this.fetchEntryPages(options),
|
|
413
517
|
extractItems: (page) => page.items,
|
|
@@ -433,7 +537,7 @@ export class Dataset {
|
|
|
433
537
|
* depending on the mode of operation.
|
|
434
538
|
*/
|
|
435
539
|
async drop() {
|
|
436
|
-
|
|
540
|
+
rejectOperationInTransaction('Dataset.drop()');
|
|
437
541
|
await this.backend.drop();
|
|
438
542
|
serviceLocator.getStorageInstanceManager().removeFromCache(this);
|
|
439
543
|
}
|
|
@@ -453,14 +557,11 @@ export class Dataset {
|
|
|
453
557
|
* @param [options] Storage manager options.
|
|
454
558
|
*/
|
|
455
559
|
static async open(identifier, options = {}) {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
})
|
|
461
|
-
options.configuration ??= Configuration.getGlobalConfiguration();
|
|
462
|
-
const storageBackend = options.storageBackend ?? serviceLocator.getStorageBackend();
|
|
463
|
-
await purgeDefaultStorages({ onlyPurgeOnce: true, storageBackend, configuration: options.configuration });
|
|
560
|
+
tryCancel();
|
|
561
|
+
const parsedOptions = parseArgument(options, openOptionsSchema);
|
|
562
|
+
const configuration = parsedOptions.configuration ?? Configuration.getGlobalConfiguration();
|
|
563
|
+
const storageBackend = parsedOptions.storageBackend ?? serviceLocator.getStorageBackend();
|
|
564
|
+
await purgeDefaultStorages({ onlyPurgeOnce: true, storageBackend, configuration });
|
|
464
565
|
const resolved = await resolveStorageIdentifier(identifier, storageBackend, 'Dataset');
|
|
465
566
|
return serviceLocator.getStorageInstanceManager().openStorage(this, {
|
|
466
567
|
...resolved,
|
package/storages/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export * from './request_queue.js';
|
|
|
8
8
|
export * from './storage_instance_manager.js';
|
|
9
9
|
export * from './storage_stats.js';
|
|
10
10
|
export * from './utils.js';
|
|
11
|
-
export * from './
|
|
11
|
+
export * from './transaction.js';
|
|
12
12
|
export * from './sitemap_request_loader.js';
|
|
13
13
|
export * from './request_manager_tandem.js';
|
|
14
|
+
export * from './throttling_request_manager.js';
|
package/storages/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export * from './request_queue.js';
|
|
|
6
6
|
export * from './storage_instance_manager.js';
|
|
7
7
|
export * from './storage_stats.js';
|
|
8
8
|
export * from './utils.js';
|
|
9
|
-
export * from './
|
|
9
|
+
export * from './transaction.js';
|
|
10
10
|
export * from './sitemap_request_loader.js';
|
|
11
11
|
export * from './request_manager_tandem.js';
|
|
12
|
+
export * from './throttling_request_manager.js';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Awaitable, Dictionary, KeyValueStoreBackend, KeyValueStoreInfo } from '@crawlee/types';
|
|
2
2
|
import { Configuration } from '../configuration.js';
|
|
3
|
+
import type { JournalEntry } from './transaction.js';
|
|
3
4
|
import type { KeyValueStoreStats } from './storage_stats.js';
|
|
4
5
|
import type { StorageOpenOptions } from './utils.js';
|
|
5
6
|
import type { StorageIdentifier } from './storage_instance_manager.js';
|
|
@@ -60,14 +61,11 @@ import type { StorageIdentifier } from './storage_instance_manager.js';
|
|
|
60
61
|
* @category Result Stores
|
|
61
62
|
*/
|
|
62
63
|
export declare class KeyValueStore {
|
|
64
|
+
#private;
|
|
63
65
|
readonly configuration: Configuration;
|
|
64
66
|
readonly id: string;
|
|
65
67
|
readonly name?: string;
|
|
66
68
|
private readonly backend;
|
|
67
|
-
private persistStateEventStarted;
|
|
68
|
-
/** Cache for persistent (auto-saved) values. When we try to set such value, the cache will be updated automatically. */
|
|
69
|
-
private readonly cache;
|
|
70
|
-
private readonly statsTracker;
|
|
71
69
|
/**
|
|
72
70
|
* @internal
|
|
73
71
|
*/
|
|
@@ -141,6 +139,21 @@ export declare class KeyValueStore {
|
|
|
141
139
|
* on the MIME content type of the record, or the default value if the key is missing from the store.
|
|
142
140
|
*/
|
|
143
141
|
getValue<T = unknown>(key: string, defaultValue: T): Promise<T>;
|
|
142
|
+
/**
|
|
143
|
+
* The active transaction's last buffered write per key for this store, derived from its journal.
|
|
144
|
+
* An entry with a `null` value is a tombstone (an in-transaction deletion).
|
|
145
|
+
*/
|
|
146
|
+
private bufferedJournalEntries;
|
|
147
|
+
/**
|
|
148
|
+
* The single transaction-aware record read shared by `getValue`, `getRecord`, `recordExists` and the
|
|
149
|
+
* listing paths: buffered key → serialized through the standard codec (same fidelity as a real
|
|
150
|
+
* round-trip); tombstoned key → `null`; otherwise the backend.
|
|
151
|
+
*
|
|
152
|
+
* The per-key buffered lookup requires the whole journal to be reduced to a last-write-per-key map,
|
|
153
|
+
* which is O(journal). Single-record callers let it default (rebuilt per call); the listing paths,
|
|
154
|
+
* which read many keys, pass a map built once so the read stays O(1) per key instead of O(journal).
|
|
155
|
+
*/
|
|
156
|
+
private readRecord;
|
|
144
157
|
/**
|
|
145
158
|
* Reads a record from the key-value store without parsing the value.
|
|
146
159
|
*
|
|
@@ -223,6 +236,8 @@ export declare class KeyValueStore {
|
|
|
223
236
|
* @param [options] Record options.
|
|
224
237
|
*/
|
|
225
238
|
setValue<T>(key: string, value: T | null, options?: RecordOptions): Promise<void>;
|
|
239
|
+
/** @internal */
|
|
240
|
+
commitJournalEntries(entries: JournalEntry[]): Promise<void>;
|
|
226
241
|
/**
|
|
227
242
|
* Removes the key-value store either from the Apify cloud storage or from the local directory,
|
|
228
243
|
* depending on the mode of operation.
|