@crawlee/core 4.0.0-beta.98 → 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.
Files changed (109) hide show
  1. package/autoscaling/autoscaled_pool.d.ts +3 -21
  2. package/autoscaling/autoscaled_pool.js +105 -97
  3. package/autoscaling/concurrency_system.d.ts +7 -22
  4. package/autoscaling/concurrency_system.js +112 -100
  5. package/autoscaling/cpu_load_signal.d.ts +1 -2
  6. package/autoscaling/cpu_load_signal.js +11 -10
  7. package/autoscaling/event_loop_load_signal.d.ts +1 -4
  8. package/autoscaling/event_loop_load_signal.js +18 -18
  9. package/autoscaling/index.d.ts +1 -1
  10. package/autoscaling/index.js +1 -1
  11. package/autoscaling/load_signal.d.ts +8 -7
  12. package/autoscaling/load_signal.js +14 -12
  13. package/autoscaling/memory_load_signal.d.ts +3 -12
  14. package/autoscaling/memory_load_signal.js +41 -41
  15. package/autoscaling/snapshotter.d.ts +7 -10
  16. package/autoscaling/snapshotter.js +18 -18
  17. package/autoscaling/{client_load_signal.d.ts → storage_backend_load_signal.d.ts} +14 -17
  18. package/autoscaling/{client_load_signal.js → storage_backend_load_signal.js} +27 -27
  19. package/autoscaling/system_status.d.ts +9 -11
  20. package/autoscaling/system_status.js +13 -13
  21. package/configuration.d.ts +16 -16
  22. package/configuration.js +6 -6
  23. package/crawlers/context_pipeline.js +6 -6
  24. package/crawlers/crawler_commons.d.ts +14 -116
  25. package/crawlers/crawler_commons.js +1 -107
  26. package/crawlers/error_snapshotter.d.ts +2 -4
  27. package/crawlers/error_snapshotter.js +5 -5
  28. package/crawlers/index.d.ts +1 -1
  29. package/crawlers/index.js +0 -1
  30. package/crawlers/statistics.d.ts +164 -45
  31. package/crawlers/statistics.js +339 -153
  32. package/debug.js +4 -4
  33. package/enqueue_links/enqueue_links.d.ts +51 -159
  34. package/enqueue_links/enqueue_links.js +38 -231
  35. package/enqueue_links/shared.d.ts +34 -24
  36. package/enqueue_links/shared.js +54 -36
  37. package/errors.d.ts +43 -12
  38. package/errors.js +48 -9
  39. package/events/event_manager.d.ts +2 -2
  40. package/events/event_manager.js +7 -6
  41. package/events/local_event_manager.d.ts +1 -1
  42. package/events/local_event_manager.js +5 -5
  43. package/http.d.ts +9 -0
  44. package/http.js +28 -0
  45. package/index.d.ts +1 -1
  46. package/index.js +1 -1
  47. package/log.js +5 -1
  48. package/memory-storage/memory-storage.d.ts +3 -11
  49. package/memory-storage/memory-storage.js +42 -48
  50. package/memory-storage/resource-clients/dataset.d.ts +1 -1
  51. package/memory-storage/resource-clients/dataset.js +8 -13
  52. package/memory-storage/resource-clients/key-value-store.d.ts +1 -1
  53. package/memory-storage/resource-clients/key-value-store.js +36 -38
  54. package/memory-storage/resource-clients/request-queue.d.ts +4 -23
  55. package/memory-storage/resource-clients/request-queue.js +68 -80
  56. package/owned_or_injected.d.ts +1 -3
  57. package/owned_or_injected.js +17 -17
  58. package/package.json +8 -9
  59. package/proxy_configuration.d.ts +1 -3
  60. package/proxy_configuration.js +18 -14
  61. package/recoverable_state.d.ts +80 -45
  62. package/recoverable_state.js +163 -75
  63. package/request.d.ts +3 -4
  64. package/request.js +57 -44
  65. package/router.d.ts +6 -10
  66. package/router.js +23 -23
  67. package/serialization.js +14 -13
  68. package/service_locator.d.ts +19 -10
  69. package/service_locator.js +57 -48
  70. package/session_pool/session.d.ts +3 -14
  71. package/session_pool/session.js +76 -74
  72. package/session_pool/session_pool.d.ts +6 -12
  73. package/session_pool/session_pool.js +85 -77
  74. package/storages/batched_adds.d.ts +37 -0
  75. package/storages/batched_adds.js +73 -0
  76. package/storages/dataset.d.ts +12 -1
  77. package/storages/dataset.js +133 -32
  78. package/storages/index.d.ts +2 -1
  79. package/storages/index.js +2 -1
  80. package/storages/key_value_store.d.ts +19 -4
  81. package/storages/key_value_store.js +204 -75
  82. package/storages/request_dedup_cache.d.ts +1 -2
  83. package/storages/request_dedup_cache.js +9 -9
  84. package/storages/request_list.d.ts +4 -23
  85. package/storages/request_list.js +103 -96
  86. package/storages/request_loader.d.ts +5 -0
  87. package/storages/request_manager_tandem.d.ts +1 -10
  88. package/storages/request_manager_tandem.js +27 -27
  89. package/storages/request_queue.d.ts +21 -21
  90. package/storages/request_queue.js +318 -177
  91. package/storages/sitemap_request_loader.d.ts +22 -70
  92. package/storages/sitemap_request_loader.js +122 -116
  93. package/storages/storage_instance_manager.d.ts +1 -4
  94. package/storages/storage_instance_manager.js +17 -19
  95. package/storages/storage_stats.d.ts +1 -1
  96. package/storages/storage_stats.js +4 -4
  97. package/storages/throttling_request_manager.d.ts +239 -0
  98. package/storages/throttling_request_manager.js +646 -0
  99. package/storages/transaction.d.ts +252 -0
  100. package/storages/transaction.js +251 -0
  101. package/storages/utils.d.ts +6 -3
  102. package/storages/utils.js +11 -2
  103. package/system-info/runtime.js +7 -7
  104. package/url.d.ts +9 -0
  105. package/url.js +11 -0
  106. package/validators.d.ts +22 -25
  107. package/validators.js +13 -25
  108. package/storages/access_checking.d.ts +0 -12
  109. package/storages/access_checking.js +0 -17
@@ -2,13 +2,15 @@ import { randomUUID } from 'node:crypto';
2
2
  import { DatasetBackend } from './resource-clients/dataset.js';
3
3
  import { KeyValueStoreBackend } from './resource-clients/key-value-store.js';
4
4
  import { RequestQueueBackend } from './resource-clients/request-queue.js';
5
+ /** The alias the default (unnamed) storage is opened under. */
6
+ const DEFAULT_STORAGE_ALIAS = '__default__';
5
7
  export class MemoryStorageBackend {
6
8
  logger;
7
9
  /**
8
10
  * Unique per-instance cache partition key. Mirrors the way `FileSystemStorageBackend` partitions its
9
11
  * cache by storage directory: two distinct `MemoryStorageBackend` instances must not share cached backends.
10
12
  */
11
- instanceCacheKey = `MemoryStorageBackend:${randomUUID()}`;
13
+ #instanceCacheKey = `MemoryStorageBackend:${randomUUID()}`;
12
14
  keyValueStoreBackendCache = [];
13
15
  datasetBackendCache = [];
14
16
  requestQueueBackendCache = [];
@@ -20,24 +22,26 @@ export class MemoryStorageBackend {
20
22
  * cache partitions in the storage backend cache.
21
23
  */
22
24
  getStorageBackendCacheKey() {
23
- return this.instanceCacheKey;
25
+ return this.#instanceCacheKey;
24
26
  }
25
- static resolveStorageKey(options) {
26
- const isAlias = 'alias' in options && !!options.alias;
27
- const rawKey = isAlias ? options.alias : (options.name ?? options.id);
27
+ static #resolveStorageKey(options) {
28
+ // No identifier at all means the default storage, which is opened under the reserved alias
29
+ // same rule as `resolveStorageIdentifier` in the storage frontends, so that a backend used
30
+ // directly lands on the very storage the frontends would have opened.
31
+ const alias = options.alias || (!options.id && !options.name ? DEFAULT_STORAGE_ALIAS : undefined);
32
+ // `alias` covers the identifier-less case, so one of the three is always set.
33
+ const rawKey = alias ?? options.name ?? options.id;
28
34
  // Normalize the internal __default__ alias to the user-facing 'default' name.
29
- const cacheKey = rawKey === '__default__' ? 'default' : rawKey;
30
- return { isAlias, cacheKey };
35
+ const cacheKey = rawKey === DEFAULT_STORAGE_ALIAS ? 'default' : rawKey;
36
+ return { isAlias: alias !== undefined, cacheKey };
31
37
  }
32
38
  async createDatasetBackend(options = {}) {
33
- const { isAlias, cacheKey } = MemoryStorageBackend.resolveStorageKey(options);
34
- if (cacheKey) {
35
- const found = this.datasetBackendCache.find((store) => store.id === cacheKey ||
36
- store.name?.toLowerCase() === cacheKey.toLowerCase() ||
37
- store.cacheKey.toLowerCase() === cacheKey.toLowerCase());
38
- if (found) {
39
- return found;
40
- }
39
+ const { isAlias, cacheKey } = MemoryStorageBackend.#resolveStorageKey(options);
40
+ const found = this.datasetBackendCache.find((store) => store.id === cacheKey ||
41
+ store.name?.toLowerCase() === cacheKey.toLowerCase() ||
42
+ store.cacheKey.toLowerCase() === cacheKey.toLowerCase());
43
+ if (found) {
44
+ return found;
41
45
  }
42
46
  const newStore = new DatasetBackend({
43
47
  name: isAlias ? undefined : cacheKey,
@@ -48,14 +52,12 @@ export class MemoryStorageBackend {
48
52
  return newStore;
49
53
  }
50
54
  async createKeyValueStoreBackend(options = {}) {
51
- const { isAlias, cacheKey } = MemoryStorageBackend.resolveStorageKey(options);
52
- if (cacheKey) {
53
- const found = this.keyValueStoreBackendCache.find((store) => store.id === cacheKey ||
54
- store.name?.toLowerCase() === cacheKey.toLowerCase() ||
55
- store.cacheKey.toLowerCase() === cacheKey.toLowerCase());
56
- if (found) {
57
- return found;
58
- }
55
+ const { isAlias, cacheKey } = MemoryStorageBackend.#resolveStorageKey(options);
56
+ const found = this.keyValueStoreBackendCache.find((store) => store.id === cacheKey ||
57
+ store.name?.toLowerCase() === cacheKey.toLowerCase() ||
58
+ store.cacheKey.toLowerCase() === cacheKey.toLowerCase());
59
+ if (found) {
60
+ return found;
59
61
  }
60
62
  const newStore = new KeyValueStoreBackend({
61
63
  name: isAlias ? undefined : cacheKey,
@@ -66,14 +68,12 @@ export class MemoryStorageBackend {
66
68
  return newStore;
67
69
  }
68
70
  async createRequestQueueBackend(options = {}) {
69
- const { isAlias, cacheKey } = MemoryStorageBackend.resolveStorageKey(options);
70
- if (cacheKey) {
71
- const found = this.requestQueueBackendCache.find((queue) => queue.id === cacheKey ||
72
- queue.name?.toLowerCase() === cacheKey.toLowerCase() ||
73
- queue.cacheKey.toLowerCase() === cacheKey.toLowerCase());
74
- if (found) {
75
- return found;
76
- }
71
+ const { isAlias, cacheKey } = MemoryStorageBackend.#resolveStorageKey(options);
72
+ const found = this.requestQueueBackendCache.find((queue) => queue.id === cacheKey ||
73
+ queue.name?.toLowerCase() === cacheKey.toLowerCase() ||
74
+ queue.cacheKey.toLowerCase() === cacheKey.toLowerCase());
75
+ if (found) {
76
+ return found;
77
77
  }
78
78
  const newStore = new RequestQueueBackend({
79
79
  name: isAlias ? undefined : cacheKey,
@@ -102,28 +102,22 @@ export class MemoryStorageBackend {
102
102
  return backends.some((store) => store.id === id);
103
103
  }
104
104
  /**
105
- * Cleans up the default storages before the run starts. For the in-memory storage this simply
106
- * resets the in-memory state of the cached default dataset, key-value store and request queue.
107
- *
108
- * As with `FileSystemStorageBackend`, the run's input (the `INPUT` key in the default key-value
109
- * store) is preserved — only the rest of the default storages is cleared.
105
+ * Cleans up the run-scoped storages before the run starts. For the in-memory storage this simply
106
+ * resets the in-memory state of the cached backends.
110
107
  */
111
108
  async purge() {
112
- // The run default is opened via `{ alias: '__default__' }`, which `resolveStorageKey`
113
- // normalizes to `cacheKey === 'default'` (with `name === undefined`) that is the clause
114
- // that actually matches it. The `name === 'default'` clause additionally covers a store a user
115
- // explicitly opened via `{ name: 'default' }`. (`'__default__'` never reaches `cacheKey`,
116
- // as it is always normalized to `'default'` first, so it does not need to be checked here.)
109
+ // `#resolveStorageKey` leaves `name` unset for the default and alias-keyed storages, which is what
110
+ // marks them as run-scoped. `'default'` is the exceptionit collapses onto the default storage.
111
+ const isRunScoped = (store) => store.name === undefined || store.name === 'default';
117
112
  const isDefault = (store) => store.name === 'default' || store.cacheKey === 'default';
118
- const purgeDefaults = async (cache, purgeStore) => {
119
- await Promise.all(cache.filter(isDefault).map(async (store) => purgeStore(store)));
113
+ const purgeRunScoped = async (cache, purgeStore) => {
114
+ await Promise.all(cache.filter(isRunScoped).map(async (store) => purgeStore(store)));
120
115
  };
121
116
  await Promise.all([
122
- // Preserve the run input (INPUT) when purging the default key-value store, matching
123
- // `FileSystemStorageBackend`.
124
- purgeDefaults(this.keyValueStoreBackendCache, async (store) => store.purgeExceptInput()),
125
- purgeDefaults(this.datasetBackendCache, async (store) => store.purge()),
126
- purgeDefaults(this.requestQueueBackendCache, async (store) => store.purge()),
117
+ // Only the default store holds the run input, so it is the only one that keeps `INPUT`.
118
+ purgeRunScoped(this.keyValueStoreBackendCache, async (store) => isDefault(store) ? store.purgeExceptInput() : store.purge()),
119
+ purgeRunScoped(this.datasetBackendCache, async (store) => store.purge()),
120
+ purgeRunScoped(this.requestQueueBackendCache, async (store) => store.purge()),
127
121
  ]);
128
122
  }
129
123
  /**
@@ -14,6 +14,7 @@ export interface DatasetBackendOptions {
14
14
  storageBackend: MemoryStorageBackend;
15
15
  }
16
16
  export declare class DatasetBackend<Data extends Dictionary = Dictionary> extends BaseClient implements storage.DatasetBackend<Data> {
17
+ #private;
17
18
  name?: string;
18
19
  /**
19
20
  * The key used for cache lookup. For named storages, this equals the name. For alias (unnamed)
@@ -24,7 +25,6 @@ export declare class DatasetBackend<Data extends Dictionary = Dictionary> extend
24
25
  accessedAt: Date;
25
26
  modifiedAt: Date;
26
27
  itemCount: number;
27
- private readonly datasetEntries;
28
28
  private readonly storageBackend;
29
29
  constructor(options: DatasetBackendOptions);
30
30
  getMetadata(): Promise<storage.DatasetInfo>;
@@ -1,5 +1,5 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- import { s } from '@sapphire/shapeshift';
2
+ import { parseArgument, schemas } from '@crawlee/utils/internal';
3
3
  import { BaseClient } from './common/base-client.js';
4
4
  /**
5
5
  * This is what API returns in the x-apify-pagination-limit
@@ -22,7 +22,8 @@ export class DatasetBackend extends BaseClient {
22
22
  accessedAt = new Date();
23
23
  modifiedAt = new Date();
24
24
  itemCount = 0;
25
- datasetEntries = new Map();
25
+ #datasetEntries = new Map();
26
+ // kept as TS-private: storage-backend tests read this field at runtime
26
27
  storageBackend;
27
28
  constructor(options) {
28
29
  super(options.id ?? randomUUID());
@@ -39,22 +40,16 @@ export class DatasetBackend extends BaseClient {
39
40
  if (storeIndex !== -1) {
40
41
  const [oldBackend] = this.storageBackend.datasetBackendCache.splice(storeIndex, 1);
41
42
  oldBackend.itemCount = 0;
42
- oldBackend.datasetEntries.clear();
43
+ oldBackend.#datasetEntries.clear();
43
44
  }
44
45
  }
45
46
  async purge() {
46
47
  this.itemCount = 0;
47
- this.datasetEntries.clear();
48
+ this.#datasetEntries.clear();
48
49
  this.updateTimestamps(true);
49
50
  }
50
51
  getData(options = {}) {
51
- const { desc, limit, offset } = s
52
- .object({
53
- desc: s.boolean().optional(),
54
- limit: s.number().int().optional(),
55
- offset: s.number().int().optional(),
56
- })
57
- .parse(options);
52
+ const { desc, limit, offset } = parseArgument(options, schemas.datasetListItemsOptions);
58
53
  return this.getDataPage({
59
54
  desc,
60
55
  offset: offset ?? 0,
@@ -67,7 +62,7 @@ export class DatasetBackend extends BaseClient {
67
62
  const items = [];
68
63
  for (let idx = start; idx < end; idx++) {
69
64
  const entryNumber = this.generateLocalEntryName(idx);
70
- items.push(this.datasetEntries.get(entryNumber));
65
+ items.push(this.#datasetEntries.get(entryNumber));
71
66
  }
72
67
  this.updateTimestamps(false);
73
68
  return {
@@ -82,7 +77,7 @@ export class DatasetBackend extends BaseClient {
82
77
  async pushData(items) {
83
78
  for (const entry of items) {
84
79
  const idx = this.generateLocalEntryName(++this.itemCount);
85
- this.datasetEntries.set(idx, JSON.parse(JSON.stringify(entry)));
80
+ this.#datasetEntries.set(idx, JSON.parse(JSON.stringify(entry)));
86
81
  }
87
82
  this.updateTimestamps(true);
88
83
  }
@@ -19,6 +19,7 @@ export interface InternalKeyRecord {
19
19
  extension: string;
20
20
  }
21
21
  export declare class KeyValueStoreBackend extends BaseClient implements storage.KeyValueStoreBackend {
22
+ #private;
22
23
  name?: string;
23
24
  /**
24
25
  * The key used for cache lookup. For named storages, this equals the name. For alias (unnamed)
@@ -28,7 +29,6 @@ export declare class KeyValueStoreBackend extends BaseClient implements storage.
28
29
  createdAt: Date;
29
30
  accessedAt: Date;
30
31
  modifiedAt: Date;
31
- private readonly keyValueEntries;
32
32
  private readonly storageBackend;
33
33
  constructor(options: KeyValueStoreBackendOptions);
34
34
  getMetadata(): Promise<storage.KeyValueStoreInfo>;
@@ -1,9 +1,25 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- import { s } from '@sapphire/shapeshift';
2
+ import { parseArgument, schemas } from '@crawlee/utils/internal';
3
+ import { z } from 'zod';
3
4
  import { isStream, toBuffer } from '../utils.js';
4
5
  import { BaseClient } from './common/base-client.js';
5
6
  import mime from 'mime-types';
6
7
  const DEFAULT_LOCAL_FILE_EXTENSION = 'bin';
8
+ const keySchema = z.string();
9
+ const inputRecordSchema = z.object({
10
+ key: z.string().min(1),
11
+ value: z.union([
12
+ z.null(),
13
+ z.string(),
14
+ z.number(),
15
+ z.instanceof(Buffer),
16
+ z.instanceof(ArrayBuffer),
17
+ schemas.typedArray,
18
+ // only checks the value is an actual object, not null, nor array
19
+ schemas.plainObject,
20
+ ]),
21
+ contentType: z.string().min(1).optional(),
22
+ });
7
23
  /**
8
24
  * Key under which a run's input is stored in the default key-value store. Matches Crawlee's default
9
25
  * `inputKey` (`CRAWLEE_INPUT_KEY`) and the `INPUT` files `FileSystemStorageBackend` preserves on purge.
@@ -19,7 +35,8 @@ export class KeyValueStoreBackend extends BaseClient {
19
35
  createdAt = new Date();
20
36
  accessedAt = new Date();
21
37
  modifiedAt = new Date();
22
- keyValueEntries = new Map();
38
+ #keyValueEntries = new Map();
39
+ // kept as TS-private: storage-backend tests read this field at runtime
23
40
  storageBackend;
24
41
  constructor(options) {
25
42
  super(options.id ?? randomUUID());
@@ -35,11 +52,11 @@ export class KeyValueStoreBackend extends BaseClient {
35
52
  const storeIndex = this.storageBackend.keyValueStoreBackendCache.findIndex((store) => store.id === this.id);
36
53
  if (storeIndex !== -1) {
37
54
  const [oldBackend] = this.storageBackend.keyValueStoreBackendCache.splice(storeIndex, 1);
38
- oldBackend.keyValueEntries.clear();
55
+ oldBackend.#keyValueEntries.clear();
39
56
  }
40
57
  }
41
58
  async purge() {
42
- this.keyValueEntries.clear();
59
+ this.#keyValueEntries.clear();
43
60
  this.updateTimestamps(true);
44
61
  }
45
62
  /**
@@ -49,23 +66,17 @@ export class KeyValueStoreBackend extends BaseClient {
49
66
  * preserve the bare `INPUT` key only.
50
67
  */
51
68
  async purgeExceptInput() {
52
- for (const key of this.keyValueEntries.keys()) {
69
+ for (const key of this.#keyValueEntries.keys()) {
53
70
  if (key !== KEY_VALUE_STORE_INPUT_KEY) {
54
- this.keyValueEntries.delete(key);
71
+ this.#keyValueEntries.delete(key);
55
72
  }
56
73
  }
57
74
  this.updateTimestamps(true);
58
75
  }
59
76
  async listKeys(options = {}) {
60
- const { prefix, exclusiveStartKey, limit } = s
61
- .object({
62
- prefix: s.string().optional(),
63
- exclusiveStartKey: s.string().optional(),
64
- limit: s.number().int().greaterThan(0).optional(),
65
- })
66
- .parse(options);
77
+ const { prefix, exclusiveStartKey, limit } = parseArgument(options, schemas.keyValueStoreListKeysOptions);
67
78
  const items = [];
68
- for (const record of this.keyValueEntries.values()) {
79
+ for (const record of this.#keyValueEntries.values()) {
69
80
  const size = Buffer.byteLength(record.value);
70
81
  items.push({
71
82
  key: record.key,
@@ -103,7 +114,7 @@ export class KeyValueStoreBackend extends BaseClient {
103
114
  * @param key The key of the record to generate the public URL for.
104
115
  */
105
116
  async getPublicUrl(key) {
106
- s.string().parse(key);
117
+ parseArgument(key, keySchema);
107
118
  return undefined;
108
119
  }
109
120
  /**
@@ -113,12 +124,12 @@ export class KeyValueStoreBackend extends BaseClient {
113
124
  * @returns `true` if the record exists, `false` if it does not.
114
125
  */
115
126
  async recordExists(key) {
116
- s.string().parse(key);
117
- return this.keyValueEntries.has(key);
127
+ parseArgument(key, keySchema);
128
+ return this.#keyValueEntries.has(key);
118
129
  }
119
130
  async getValue(key) {
120
- s.string().parse(key);
121
- const entry = this.keyValueEntries.get(key);
131
+ parseArgument(key, keySchema);
132
+ const entry = this.#keyValueEntries.get(key);
122
133
  if (!entry) {
123
134
  return undefined;
124
135
  }
@@ -135,20 +146,7 @@ export class KeyValueStoreBackend extends BaseClient {
135
146
  return record;
136
147
  }
137
148
  async setValue(record) {
138
- s.object({
139
- key: s.string().lengthGreaterThan(0),
140
- value: s.union([
141
- s.null(),
142
- s.string(),
143
- s.number(),
144
- s.instance(Buffer),
145
- s.instance(ArrayBuffer),
146
- s.typedArray(),
147
- // disabling validation will make shapeshift only check the object given is an actual object, not null, nor array
148
- s.object({}).setValidationEnabled(false),
149
- ]),
150
- contentType: s.string().lengthGreaterThan(0).optional(),
151
- }).parse(record);
149
+ parseArgument(record, inputRecordSchema);
152
150
  const { key } = record;
153
151
  let { value } = record;
154
152
  // The frontend (KeyValueStore codec) serializes the value and resolves its content type
@@ -169,19 +167,19 @@ export class KeyValueStoreBackend extends BaseClient {
169
167
  const normalizedValue = typeof value === 'string'
170
168
  ? Buffer.from(value, 'utf-8')
171
169
  : toBuffer(value);
172
- const _record = {
170
+ const normalizedRecord = {
173
171
  extension,
174
172
  key,
175
173
  value: normalizedValue,
176
174
  contentType,
177
175
  };
178
- this.keyValueEntries.set(key, _record);
176
+ this.#keyValueEntries.set(key, normalizedRecord);
179
177
  this.updateTimestamps(true);
180
178
  }
181
179
  async deleteValue(key) {
182
- s.string().parse(key);
183
- if (this.keyValueEntries.has(key)) {
184
- this.keyValueEntries.delete(key);
180
+ parseArgument(key, keySchema);
181
+ if (this.#keyValueEntries.has(key)) {
182
+ this.#keyValueEntries.delete(key);
185
183
  this.updateTimestamps(true);
186
184
  }
187
185
  }
@@ -22,6 +22,7 @@ export interface InternalRequest {
22
22
  json: string;
23
23
  }
24
24
  export declare class RequestQueueBackend extends BaseClient implements storage.RequestQueueBackend {
25
+ #private;
25
26
  name?: string;
26
27
  /**
27
28
  * The key used for cache lookup. For named storages, this equals the name. For alias (unnamed)
@@ -33,26 +34,6 @@ export declare class RequestQueueBackend extends BaseClient implements storage.R
33
34
  modifiedAt: Date;
34
35
  handledRequestCount: number;
35
36
  pendingRequestCount: number;
36
- /**
37
- * Serializes every operation that reads-then-writes this backend's shared queue state — the
38
- * `requests` map, the `forefrontRequestIds` array, the `inProgressRequestIds` set and the request
39
- * counts. Those mutations span `await` points, so without this mutex a concurrent operation could
40
- * interleave and corrupt them (e.g. a head scan pruning `forefrontRequestIds` while
41
- * `addBatchOfRequests` pushes to it). Held by every mutating method as well as by `isEmpty`/
42
- * `isFinished`, whose head scan also prunes `forefrontRequestIds`.
43
- */
44
- private readonly queueStateMutex;
45
- private forefrontRequestIds;
46
- /**
47
- * IDs of requests currently fetched but not yet handled or reclaimed. A request in this set is
48
- * "in progress" and will not be handed out again by {@link fetchNextRequest}.
49
- *
50
- * Unlike the file-system / platform clients, the in-memory queue lives entirely within a single
51
- * process and is never shared with another consumer, so there is no need for an expiring,
52
- * cross-process-visible lock — tracking in-progress requests in this set is enough.
53
- */
54
- private readonly inProgressRequestIds;
55
- private readonly requests;
56
37
  private readonly storageBackend;
57
38
  constructor(options: RequestQueueBackendOptions);
58
39
  getMetadata(): Promise<storage.RequestQueueInfo>;
@@ -90,7 +71,7 @@ export declare class RequestQueueBackend extends BaseClient implements storage.R
90
71
  listItems(): Promise<storage.UpdateRequestSchema[]>;
91
72
  toRequestQueueInfo(): storage.RequestQueueInfo;
92
73
  private updateTimestamps;
93
- private _jsonToRequest;
94
- private _createInternalRequest;
95
- private _calculateOrderNo;
74
+ private jsonToRequest;
75
+ private createInternalRequest;
76
+ private calculateOrderNo;
96
77
  }