@valkey/valkey-glide 2.3.1 → 2.4.0-rc2

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.
@@ -5,7 +5,7 @@ import * as net from "net";
5
5
  import { Buffer, Writer } from "protobufjs/minimal";
6
6
  import { AggregationType, BaseScanOptions, BitFieldGet, // eslint-disable-line @typescript-eslint/no-unused-vars
7
7
  BitFieldSubCommands, // eslint-disable-line @typescript-eslint/no-unused-vars
8
- BitOffsetOptions, BitwiseOperation, Boundary, ConnectionError, ExpireOptions, GeoAddOptions, // eslint-disable-line @typescript-eslint/no-unused-vars
8
+ BitOffsetOptions, BitwiseOperation, Boundary, ClientSideCache, CompressionConfiguration, ConnectionError, ExpireOptions, GeoAddOptions, // eslint-disable-line @typescript-eslint/no-unused-vars
9
9
  GeoSearchResultOptions, GeoSearchShape, GeoSearchStoreResultOptions, GeoUnit, GeospatialData, GlideClientConfiguration, GlideClusterClientConfiguration, HExpireOptions, HGetExOptions, HScanOptions, HSetExOptions, InsertPosition, KeyWeight, LPosOptions, ListDirection, RangeByIndex, RangeByLex, RangeByScore, RequestError, RestoreOptions, Routes, ScoreFilter, Script, SearchOrigin, SetOptions, SortOptions, StreamAddOptions, StreamClaimOptions, StreamGroupOptions, StreamPendingOptions, StreamReadGroupOptions, StreamReadOptions, StreamTrimOptions, TimeUnit, ValkeyError, ZAddOptions, ZScanOptions } from ".";
10
10
  import { command_request, connection_request, response } from "../build-ts/ProtobufMessage";
11
11
  type PromiseFunction = (value?: any) => void;
@@ -184,7 +184,23 @@ export type ReadFrom =
184
184
  | "AZAffinity"
185
185
  /** Spread the read requests among all nodes within the client's Availability Zone (AZ) in a round robin manner,
186
186
  prioritizing local replicas, then the local primary, and falling back to any replica or the primary if needed.*/
187
- | "AZAffinityReplicasAndPrimary";
187
+ | "AZAffinityReplicasAndPrimary"
188
+ /** Spread the read requests between all nodes (primary and replicas) in a round robin manner.*/
189
+ | "allNodes";
190
+ /**
191
+ * Controls how the client discovers node roles and topology in standalone mode.
192
+ */
193
+ export declare enum NodeDiscoveryMode {
194
+ /** Default: verify node roles via INFO REPLICATION, use only provided addresses. */
195
+ Standard = 0,
196
+ /** Skip role detection entirely. Trust provided addresses as-is; first address is primary.
197
+ * Use when connecting through a proxy (e.g., Envoy) or when the topology is known and static.
198
+ * Note: Do not set `clientName` when using this mode with a proxy. */
199
+ Static = 1,
200
+ /** Discover full topology (primary + all replicas) from any starting node.
201
+ * Provide any single node address and the client will find and connect to all other nodes. */
202
+ DiscoverAll = 2
203
+ }
188
204
  /**
189
205
  * Configuration settings for creating a client. Shared settings for standalone and cluster clients.
190
206
  *
@@ -450,6 +466,54 @@ export interface BaseClientConfiguration {
450
466
  * ```
451
467
  */
452
468
  lazyConnect?: boolean;
469
+ /**
470
+ * Configuration for automatic compression of values.
471
+ * When enabled, values that meet the minimum size threshold will be
472
+ * automatically compressed before being sent to the server and
473
+ * decompressed when retrieved.
474
+ *
475
+ * @example
476
+ * ```typescript
477
+ * const client = await GlideClient.createClient({
478
+ * addresses: [{ host: "localhost", port: 6379 }],
479
+ * compression: { enabled: true },
480
+ * });
481
+ * ```
482
+ */
483
+ compression?: CompressionConfiguration;
484
+ /**
485
+ * Client-side cache configuration.
486
+ *
487
+ * @remarks
488
+ * When provided, enables client-side caching for cacheable commands (GET, HGETALL, SMEMBERS).
489
+ * The cache reduces network round-trips and server load by storing frequently accessed data locally.
490
+ *
491
+ * - **Memory Management**: The cache respects the configured memory limit and evicts entries based on the specified policy.
492
+ * - **TTL Support**: Entries can have optional time-to-live values for automatic expiration.
493
+ * - **Shared Caches**: Multiple clients can share the same cache instance using the same cache ID.
494
+ * - **Metrics**: Optional metrics collection provides insights into cache performance.
495
+ *
496
+ * @example
497
+ * ```typescript
498
+ * // Simple cache configuration
499
+ * const config: BaseClientConfiguration = {
500
+ * addresses: [{ host: 'localhost', port: 6379 }],
501
+ * clientSideCache: ClientSideCache.create(1024, 0), // 1MB cache, no TTL
502
+ * };
503
+ *
504
+ * // Advanced cache configuration
505
+ * const advancedConfig: BaseClientConfiguration = {
506
+ * addresses: [{ host: 'localhost', port: 6379 }],
507
+ * clientSideCache: new ClientSideCache({
508
+ * maxCacheKb: 2048,
509
+ * entryTtlMs: 300000,
510
+ * evictionPolicy: EvictionPolicy.LFU,
511
+ * enableMetrics: true,
512
+ * }),
513
+ * };
514
+ * ```
515
+ */
516
+ clientSideCache?: ClientSideCache;
453
517
  }
454
518
  /**
455
519
  * Represents advanced configuration settings for a client, including connection-related options.
@@ -603,6 +667,7 @@ export declare class BaseClient {
603
667
  protected ensureClientIsOpen(): void;
604
668
  protected createUpdateConnectionPasswordPromise(command: command_request.UpdateConnectionPassword): Promise<GlideString>;
605
669
  protected createRefreshIamTokenPromise(command: command_request.RefreshIamToken): Promise<GlideString>;
670
+ protected createGetCacheMetricsPromise(command: command_request.GetCacheMetrics): Promise<number>;
606
671
  protected createScriptInvocationPromise<T = GlideString>(command: command_request.ScriptInvocation, options?: {
607
672
  keys?: GlideString[];
608
673
  args?: GlideString[];
@@ -2664,7 +2729,7 @@ export declare class BaseClient {
2664
2729
  scard(key: GlideString): Promise<number>;
2665
2730
  /** Gets the intersection of all the given sets.
2666
2731
  *
2667
- * @see {@link https://valkey.io/docs/latest/commands/sinter/|valkey.io} for more details.
2732
+ * @see {@link https://valkey.io/commands/sinter/|valkey.io} for more details.
2668
2733
  * @remarks When in cluster mode, all `keys` must map to the same hash slot.
2669
2734
  *
2670
2735
  * @param keys - The `keys` of the sets to get the intersection.
@@ -6491,6 +6556,84 @@ export declare class BaseClient {
6491
6556
  * ```
6492
6557
  */
6493
6558
  refreshIamToken(): Promise<GlideString>;
6559
+ /**
6560
+ * Get the cache hit rate (hits / total requests).
6561
+ *
6562
+ * @returns The cache hit rate as a number between 0.0 and 1.0.
6563
+ * @throws RequestError if client-side caching is not enabled or metrics tracking is disabled.
6564
+ * @example
6565
+ * ```typescript
6566
+ * const hitRate = await client.getCacheHitRate();
6567
+ * console.log(`Cache hit rate: ${(hitRate * 100).toFixed(2)}%`);
6568
+ * // Output: Cache hit rate: 85.50%
6569
+ * ```
6570
+ */
6571
+ getCacheHitRate(): Promise<number>;
6572
+ /**
6573
+ * Get the cache miss rate (misses / total requests).
6574
+ *
6575
+ * @returns The cache miss rate as a number between 0.0 and 1.0.
6576
+ * @throws RequestError if client-side caching is not enabled or metrics tracking is disabled.
6577
+ * @example
6578
+ * ```typescript
6579
+ * const missRate = await client.getCacheMissRate();
6580
+ * console.log(`Cache miss rate: ${(missRate * 100).toFixed(2)}%`);
6581
+ * // Output: Cache miss rate: 14.50%
6582
+ * ```
6583
+ */
6584
+ getCacheMissRate(): Promise<number>;
6585
+ /**
6586
+ * Get the current number of entries in the client-side cache.
6587
+ *
6588
+ * @returns The number of entries in the cache.
6589
+ * @throws RequestError if client-side caching is not enabled.
6590
+ * @example
6591
+ * ```typescript
6592
+ * const entryCount = await client.getCacheEntryCount();
6593
+ * console.log(`Cache entry count: ${entryCount}`);
6594
+ * // Output: Cache entry count: 1500
6595
+ * ```
6596
+ */
6597
+ getCacheEntryCount(): Promise<number>;
6598
+ /**
6599
+ * Get the total number of entries evicted from the client-side cache due to memory constraints.
6600
+ *
6601
+ * @returns The number of evictions.
6602
+ * @throws RequestError if client-side caching is not enabled or metrics tracking is disabled.
6603
+ * @example
6604
+ * ```typescript
6605
+ * const evictions = await client.getCacheEvictions();
6606
+ * console.log(`Cache evictions: ${evictions}`);
6607
+ * // Output: Cache evictions: 100
6608
+ * ```
6609
+ */
6610
+ getCacheEvictions(): Promise<number>;
6611
+ /**
6612
+ * Get the total number of entries expired from the client-side cache.
6613
+ *
6614
+ * @returns The number of expirations.
6615
+ * @throws RequestError if client-side caching is not enabled or metrics tracking is disabled.
6616
+ * @example
6617
+ * ```typescript
6618
+ * const expirations = await client.getCacheExpirations();
6619
+ * console.log(`Cache expirations: ${expirations}`);
6620
+ * // Output: Cache expirations: 250
6621
+ * ```
6622
+ */
6623
+ getCacheExpirations(): Promise<number>;
6624
+ /**
6625
+ * Get the total number of cache lookups (hits + misses).
6626
+ *
6627
+ * @returns The total number of cache lookups.
6628
+ * @throws RequestError if client-side caching is not enabled or metrics tracking is disabled.
6629
+ * @example
6630
+ * ```typescript
6631
+ * const totalLookups = await client.getCacheTotalLookups();
6632
+ * console.log(`Total cache lookups: ${totalLookups}`);
6633
+ * // Output: Total cache lookups: 5000
6634
+ * ```
6635
+ */
6636
+ getCacheTotalLookups(): Promise<number>;
6494
6637
  /**
6495
6638
  * Subscribes the client to the specified channels (non-blocking).
6496
6639
  * Returns immediately without waiting for subscription confirmation.
@@ -39,7 +39,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
39
39
  return (mod && mod.__esModule) ? mod : { "default": mod };
40
40
  };
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
- exports.BaseClient = exports.ObjectType = exports.ServiceType = exports.ALL_PATTERNS = exports.ALL_CHANNELS = exports.Decoder = exports.ProtocolVersion = void 0;
42
+ exports.BaseClient = exports.ObjectType = exports.NodeDiscoveryMode = exports.ServiceType = exports.ALL_PATTERNS = exports.ALL_CHANNELS = exports.Decoder = exports.ProtocolVersion = void 0;
43
43
  exports.convertGlideRecord = convertGlideRecord;
44
44
  exports.convertGlideRecordToRecord = convertGlideRecordToRecord;
45
45
  exports.isGlideRecord = isGlideRecord;
@@ -185,6 +185,21 @@ var ServiceType;
185
185
  ServiceType["Elasticache"] = "Elasticache";
186
186
  ServiceType["MemoryDB"] = "MemoryDB";
187
187
  })(ServiceType || (exports.ServiceType = ServiceType = {}));
188
+ /**
189
+ * Controls how the client discovers node roles and topology in standalone mode.
190
+ */
191
+ var NodeDiscoveryMode;
192
+ (function (NodeDiscoveryMode) {
193
+ /** Default: verify node roles via INFO REPLICATION, use only provided addresses. */
194
+ NodeDiscoveryMode[NodeDiscoveryMode["Standard"] = 0] = "Standard";
195
+ /** Skip role detection entirely. Trust provided addresses as-is; first address is primary.
196
+ * Use when connecting through a proxy (e.g., Envoy) or when the topology is known and static.
197
+ * Note: Do not set `clientName` when using this mode with a proxy. */
198
+ NodeDiscoveryMode[NodeDiscoveryMode["Static"] = 1] = "Static";
199
+ /** Discover full topology (primary + all replicas) from any starting node.
200
+ * Provide any single node address and the client will find and connect to all other nodes. */
201
+ NodeDiscoveryMode[NodeDiscoveryMode["DiscoverAll"] = 2] = "DiscoverAll";
202
+ })(NodeDiscoveryMode || (exports.NodeDiscoveryMode = NodeDiscoveryMode = {}));
188
203
  /**
189
204
  * Enum of Valkey data types
190
205
  * `STRING`
@@ -556,6 +571,33 @@ class BaseClient {
556
571
  });
557
572
  });
558
573
  }
574
+ createGetCacheMetricsPromise(command) {
575
+ this.ensureClientIsOpen();
576
+ return new Promise((resolve, reject) => {
577
+ const callbackIdx = this.getCallbackIndex();
578
+ this.promiseCallbackFunctions[callbackIdx] = [resolve, reject];
579
+ this.writeOrBufferRequest(new ProtobufMessage_1.command_request.CommandRequest({
580
+ callbackIdx,
581
+ getCacheMetrics: command,
582
+ }), (message, writer) => {
583
+ ProtobufMessage_1.command_request.CommandRequest.encodeDelimited(message, writer);
584
+ });
585
+ });
586
+ }
587
+ /**
588
+ * @internal
589
+ * Get cache metrics.
590
+ *
591
+ * @param metricsType - Type of metric to retrieve (e.g., hit rate, miss rate).
592
+ * @returns The requested cache metric.
593
+ * @throws RequestError if client-side caching is not enabled or metrics tracking is disabled.
594
+ */
595
+ async getCacheMetrics(metricsType) {
596
+ const getCacheMetrics = ProtobufMessage_1.command_request.GetCacheMetrics.create({
597
+ metricsTypes: metricsType,
598
+ });
599
+ return await this.createGetCacheMetricsPromise(getCacheMetrics);
600
+ }
559
601
  createScriptInvocationPromise(command, options = {}) {
560
602
  this.ensureClientIsOpen();
561
603
  return new Promise((resolve, reject) => {
@@ -2950,7 +2992,7 @@ class BaseClient {
2950
2992
  }
2951
2993
  /** Gets the intersection of all the given sets.
2952
2994
  *
2953
- * @see {@link https://valkey.io/docs/latest/commands/sinter/|valkey.io} for more details.
2995
+ * @see {@link https://valkey.io/commands/sinter/|valkey.io} for more details.
2954
2996
  * @remarks When in cluster mode, all `keys` must map to the same hash slot.
2955
2997
  *
2956
2998
  * @param keys - The `keys` of the sets to get the intersection.
@@ -5559,6 +5601,7 @@ class BaseClient {
5559
5601
  preferReplica: ProtobufMessage_1.connection_request.ReadFrom.PreferReplica,
5560
5602
  AZAffinity: ProtobufMessage_1.connection_request.ReadFrom.AZAffinity,
5561
5603
  AZAffinityReplicasAndPrimary: ProtobufMessage_1.connection_request.ReadFrom.AZAffinityReplicasAndPrimary,
5604
+ allNodes: ProtobufMessage_1.connection_request.ReadFrom.AllNodes,
5562
5605
  };
5563
5606
  /**
5564
5607
  * Returns the number of messages that were successfully acknowledged by the consumer group member of a stream.
@@ -7026,7 +7069,19 @@ class BaseClient {
7026
7069
  !options.clientAz) {
7027
7070
  throw new _1.ConfigurationError(`clientAz must be set when readFrom is set to ${options.readFrom}`);
7028
7071
  }
7029
- return {
7072
+ // Configure client-side cache if provided
7073
+ let clientSideCache;
7074
+ if (options.clientSideCache) {
7075
+ const cache = options.clientSideCache;
7076
+ clientSideCache = ProtobufMessage_1.connection_request.ClientSideCache.create({
7077
+ cacheId: cache.cacheId,
7078
+ maxCacheKb: cache.maxCacheKb,
7079
+ entryTtlMs: cache.entryTtlMs,
7080
+ evictionPolicy: cache.evictionPolicy,
7081
+ enableMetrics: cache.enableMetrics,
7082
+ });
7083
+ }
7084
+ const request = {
7030
7085
  protocol,
7031
7086
  clientName: options.clientName,
7032
7087
  addresses: options.addresses,
@@ -7042,7 +7097,13 @@ class BaseClient {
7042
7097
  clientAz: options.clientAz ?? null,
7043
7098
  connectionRetryStrategy: options.connectionBackoff,
7044
7099
  lazyConnect: options.lazyConnect ?? false,
7100
+ clientSideCache,
7045
7101
  };
7102
+ if (options.compression) {
7103
+ (0, _1.validateCompressionConfiguration)(options.compression);
7104
+ request.compressionConfig = (0, _1.compressionConfigToProtobuf)(options.compression, ProtobufMessage_1.connection_request);
7105
+ }
7106
+ return request;
7046
7107
  }
7047
7108
  /**
7048
7109
  * @internal
@@ -7221,6 +7282,96 @@ class BaseClient {
7221
7282
  const response = await this.createRefreshIamTokenPromise(refresh);
7222
7283
  return response; // "OK"
7223
7284
  }
7285
+ /**
7286
+ * Get the cache hit rate (hits / total requests).
7287
+ *
7288
+ * @returns The cache hit rate as a number between 0.0 and 1.0.
7289
+ * @throws RequestError if client-side caching is not enabled or metrics tracking is disabled.
7290
+ * @example
7291
+ * ```typescript
7292
+ * const hitRate = await client.getCacheHitRate();
7293
+ * console.log(`Cache hit rate: ${(hitRate * 100).toFixed(2)}%`);
7294
+ * // Output: Cache hit rate: 85.50%
7295
+ * ```
7296
+ */
7297
+ async getCacheHitRate() {
7298
+ return await this.getCacheMetrics(ProtobufMessage_1.command_request.CacheMetricsType.HitRate);
7299
+ }
7300
+ /**
7301
+ * Get the cache miss rate (misses / total requests).
7302
+ *
7303
+ * @returns The cache miss rate as a number between 0.0 and 1.0.
7304
+ * @throws RequestError if client-side caching is not enabled or metrics tracking is disabled.
7305
+ * @example
7306
+ * ```typescript
7307
+ * const missRate = await client.getCacheMissRate();
7308
+ * console.log(`Cache miss rate: ${(missRate * 100).toFixed(2)}%`);
7309
+ * // Output: Cache miss rate: 14.50%
7310
+ * ```
7311
+ */
7312
+ async getCacheMissRate() {
7313
+ return await this.getCacheMetrics(ProtobufMessage_1.command_request.CacheMetricsType.MissRate);
7314
+ }
7315
+ /**
7316
+ * Get the current number of entries in the client-side cache.
7317
+ *
7318
+ * @returns The number of entries in the cache.
7319
+ * @throws RequestError if client-side caching is not enabled.
7320
+ * @example
7321
+ * ```typescript
7322
+ * const entryCount = await client.getCacheEntryCount();
7323
+ * console.log(`Cache entry count: ${entryCount}`);
7324
+ * // Output: Cache entry count: 1500
7325
+ * ```
7326
+ */
7327
+ async getCacheEntryCount() {
7328
+ return await this.getCacheMetrics(ProtobufMessage_1.command_request.CacheMetricsType.EntryCount);
7329
+ }
7330
+ /**
7331
+ * Get the total number of entries evicted from the client-side cache due to memory constraints.
7332
+ *
7333
+ * @returns The number of evictions.
7334
+ * @throws RequestError if client-side caching is not enabled or metrics tracking is disabled.
7335
+ * @example
7336
+ * ```typescript
7337
+ * const evictions = await client.getCacheEvictions();
7338
+ * console.log(`Cache evictions: ${evictions}`);
7339
+ * // Output: Cache evictions: 100
7340
+ * ```
7341
+ */
7342
+ async getCacheEvictions() {
7343
+ return await this.getCacheMetrics(ProtobufMessage_1.command_request.CacheMetricsType.Evictions);
7344
+ }
7345
+ /**
7346
+ * Get the total number of entries expired from the client-side cache.
7347
+ *
7348
+ * @returns The number of expirations.
7349
+ * @throws RequestError if client-side caching is not enabled or metrics tracking is disabled.
7350
+ * @example
7351
+ * ```typescript
7352
+ * const expirations = await client.getCacheExpirations();
7353
+ * console.log(`Cache expirations: ${expirations}`);
7354
+ * // Output: Cache expirations: 250
7355
+ * ```
7356
+ */
7357
+ async getCacheExpirations() {
7358
+ return await this.getCacheMetrics(ProtobufMessage_1.command_request.CacheMetricsType.Expirations);
7359
+ }
7360
+ /**
7361
+ * Get the total number of cache lookups (hits + misses).
7362
+ *
7363
+ * @returns The total number of cache lookups.
7364
+ * @throws RequestError if client-side caching is not enabled or metrics tracking is disabled.
7365
+ * @example
7366
+ * ```typescript
7367
+ * const totalLookups = await client.getCacheTotalLookups();
7368
+ * console.log(`Total cache lookups: ${totalLookups}`);
7369
+ * // Output: Total cache lookups: 5000
7370
+ * ```
7371
+ */
7372
+ async getCacheTotalLookups() {
7373
+ return await this.getCacheMetrics(ProtobufMessage_1.command_request.CacheMetricsType.TotalLookups);
7374
+ }
7224
7375
  /**
7225
7376
  * Subscribes the client to the specified channels (non-blocking).
7226
7377
  * Returns immediately without waiting for subscription confirmation.
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0
3
+ */
4
+ import { EvictionPolicy } from "./EvictionPolicy.js";
5
+ /**
6
+ * Configuration options for creating a ClientSideCache.
7
+ */
8
+ export interface ClientSideCacheConfig {
9
+ /**
10
+ * Maximum memory limit for the cache in kilobytes.
11
+ * Must be greater than zero.
12
+ */
13
+ maxCacheKb: number;
14
+ /**
15
+ * Time-To-Live for cache entries in milliseconds.
16
+ * Set to 0 to disable TTL expiration (entries remain until evicted or invalidated).
17
+ */
18
+ entryTtlMs: number;
19
+ /**
20
+ * Optional eviction policy to use when cache reaches memory limit.
21
+ * Defaults to LRU if not specified.
22
+ */
23
+ evictionPolicy?: EvictionPolicy;
24
+ /**
25
+ * Whether to enable metrics collection for this cache.
26
+ * Defaults to false if not specified.
27
+ */
28
+ enableMetrics?: boolean;
29
+ }
30
+ /**
31
+ * Optional configuration options for the static create method.
32
+ */
33
+ export interface ClientSideCacheOptions {
34
+ /**
35
+ * Optional eviction policy to use when cache reaches memory limit.
36
+ */
37
+ evictionPolicy?: EvictionPolicy;
38
+ /**
39
+ * Whether to enable metrics collection for this cache.
40
+ */
41
+ enableMetrics?: boolean;
42
+ }
43
+ /**
44
+ * Configuration class for client-side caching.
45
+ *
46
+ * Client-side caching reduces network round-trips and server load by storing
47
+ * frequently accessed data locally on the client. This class provides
48
+ * configurable TTL-based expiration, multiple eviction policies, and
49
+ * comprehensive metrics tracking.
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * // Create cache with auto-generated ID
54
+ * const cache = ClientSideCache.create(1024, 60000); // 1MB cache, 1 min TTL
55
+ *
56
+ * // Create cache with custom configuration
57
+ * const customCache = new ClientSideCache({
58
+ * maxCacheKb: 2048,
59
+ * entryTtlMs: 300000,
60
+ * evictionPolicy: EvictionPolicy.LFU,
61
+ * enableMetrics: true
62
+ * });
63
+ * ```
64
+ */
65
+ export declare class ClientSideCache {
66
+ /**
67
+ * Maximum memory limit for the cache in kilobytes.
68
+ */
69
+ readonly maxCacheKb: number;
70
+ /**
71
+ * Time-To-Live for cache entries in milliseconds. 0 means no expiration.
72
+ */
73
+ readonly entryTtlMs: number;
74
+ /**
75
+ * Optional eviction policy to use when cache reaches memory limit.
76
+ */
77
+ readonly evictionPolicy?: EvictionPolicy;
78
+ /**
79
+ * Whether metrics collection is enabled for this cache.
80
+ */
81
+ readonly enableMetrics: boolean;
82
+ /**
83
+ * Creates a new ClientSideCache instance.
84
+ *
85
+ * @param config - Configuration options for the cache
86
+ * @throws {Error} If maxCacheKb is not a positive number
87
+ * @throws {Error} If entryTtlMs is negative
88
+ */
89
+ constructor(config: ClientSideCacheConfig);
90
+ /**
91
+ * Factory method to create a ClientSideCache with auto-generated cache ID.
92
+ *
93
+ * @param maxCacheKb - Maximum memory limit for the cache in kilobytes
94
+ * @param entryTtlMs - TTL for cache entries in milliseconds. Use 0 for no expiration.
95
+ * @param options - Optional configuration options
96
+ * @returns A new ClientSideCache instance with auto-generated cache ID
97
+ * @throws {Error} If maxCacheKb is not a positive number
98
+ * @throws {Error} If entryTtlMs is negative
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * // Simple cache with 1MB limit and no TTL
103
+ * const cache = ClientSideCache.create(1024, 0);
104
+ *
105
+ * // Cache with TTL and LFU eviction
106
+ * const cacheWithOptions = ClientSideCache.create(2048, 300000, {
107
+ * evictionPolicy: EvictionPolicy.LFU,
108
+ * enableMetrics: false
109
+ * });
110
+ * ```
111
+ */
112
+ static create(maxCacheKb: number, entryTtlMs: number, options?: ClientSideCacheOptions): ClientSideCache;
113
+ }
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ClientSideCache = void 0;
7
+ const crypto_1 = require("crypto");
8
+ /**
9
+ * Configuration class for client-side caching.
10
+ *
11
+ * Client-side caching reduces network round-trips and server load by storing
12
+ * frequently accessed data locally on the client. This class provides
13
+ * configurable TTL-based expiration, multiple eviction policies, and
14
+ * comprehensive metrics tracking.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * // Create cache with auto-generated ID
19
+ * const cache = ClientSideCache.create(1024, 60000); // 1MB cache, 1 min TTL
20
+ *
21
+ * // Create cache with custom configuration
22
+ * const customCache = new ClientSideCache({
23
+ * maxCacheKb: 2048,
24
+ * entryTtlMs: 300000,
25
+ * evictionPolicy: EvictionPolicy.LFU,
26
+ * enableMetrics: true
27
+ * });
28
+ * ```
29
+ */
30
+ class ClientSideCache {
31
+ /**
32
+ * @internal
33
+ * Unique identifier for the cache instance. Auto-generated using UUID.
34
+ */
35
+ cacheId;
36
+ /**
37
+ * Maximum memory limit for the cache in kilobytes.
38
+ */
39
+ maxCacheKb;
40
+ /**
41
+ * Time-To-Live for cache entries in milliseconds. 0 means no expiration.
42
+ */
43
+ entryTtlMs;
44
+ /**
45
+ * Optional eviction policy to use when cache reaches memory limit.
46
+ */
47
+ evictionPolicy;
48
+ /**
49
+ * Whether metrics collection is enabled for this cache.
50
+ */
51
+ enableMetrics;
52
+ /**
53
+ * Creates a new ClientSideCache instance.
54
+ *
55
+ * @param config - Configuration options for the cache
56
+ * @throws {Error} If maxCacheKb is not a positive number
57
+ * @throws {Error} If entryTtlMs is negative
58
+ */
59
+ constructor(config) {
60
+ if (config.maxCacheKb <= 0) {
61
+ throw new Error("maxCacheKb must be a positive number");
62
+ }
63
+ if (config.entryTtlMs < 0) {
64
+ throw new Error("entryTtlMs must be non-negative (0 = no expiration)");
65
+ }
66
+ this.cacheId = (0, crypto_1.randomUUID)();
67
+ this.maxCacheKb = config.maxCacheKb;
68
+ this.entryTtlMs = config.entryTtlMs;
69
+ this.evictionPolicy = config.evictionPolicy;
70
+ this.enableMetrics = config.enableMetrics ?? false;
71
+ }
72
+ /**
73
+ * Factory method to create a ClientSideCache with auto-generated cache ID.
74
+ *
75
+ * @param maxCacheKb - Maximum memory limit for the cache in kilobytes
76
+ * @param entryTtlMs - TTL for cache entries in milliseconds. Use 0 for no expiration.
77
+ * @param options - Optional configuration options
78
+ * @returns A new ClientSideCache instance with auto-generated cache ID
79
+ * @throws {Error} If maxCacheKb is not a positive number
80
+ * @throws {Error} If entryTtlMs is negative
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * // Simple cache with 1MB limit and no TTL
85
+ * const cache = ClientSideCache.create(1024, 0);
86
+ *
87
+ * // Cache with TTL and LFU eviction
88
+ * const cacheWithOptions = ClientSideCache.create(2048, 300000, {
89
+ * evictionPolicy: EvictionPolicy.LFU,
90
+ * enableMetrics: false
91
+ * });
92
+ * ```
93
+ */
94
+ static create(maxCacheKb, entryTtlMs, options) {
95
+ return new ClientSideCache({
96
+ maxCacheKb,
97
+ entryTtlMs,
98
+ evictionPolicy: options?.evictionPolicy,
99
+ enableMetrics: options?.enableMetrics,
100
+ });
101
+ }
102
+ }
103
+ exports.ClientSideCache = ClientSideCache;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0
3
+ */
4
+ /**
5
+ * Compression backend to use for automatic value compression.
6
+ */
7
+ export declare enum CompressionBackend {
8
+ /** Use zstd compression backend. */
9
+ ZSTD = 0,
10
+ /** Use lz4 compression backend. */
11
+ LZ4 = 1
12
+ }
13
+ /**
14
+ * Configuration for automatic compression of values sent to the server.
15
+ *
16
+ * NOTE: This is an experimental feature. The API may change in future releases.
17
+ *
18
+ * When compression is enabled, values that meet the minimum size threshold
19
+ * will be automatically compressed before being sent to the server and
20
+ * decompressed when retrieved.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // Enable compression with defaults (ZSTD, 64 byte threshold)
25
+ * const config: CompressionConfiguration = { enabled: true };
26
+ *
27
+ * // Enable compression with LZ4 backend and custom threshold
28
+ * const config: CompressionConfiguration = {
29
+ * enabled: true,
30
+ * backend: CompressionBackend.LZ4,
31
+ * minCompressionSize: 128,
32
+ * };
33
+ *
34
+ * // Enable compression with custom max decompressed size limit
35
+ * const config: CompressionConfiguration = {
36
+ * enabled: true,
37
+ * maxDecompressedSize: 100 * 1024 * 1024, // 100MB limit
38
+ * };
39
+ * ```
40
+ */
41
+ export interface CompressionConfiguration {
42
+ /**
43
+ * Whether compression is enabled. Defaults to false.
44
+ */
45
+ enabled: boolean;
46
+ /**
47
+ * The compression backend to use. Defaults to ZSTD.
48
+ */
49
+ backend?: CompressionBackend;
50
+ /**
51
+ * The compression level. If not set, the backend's default level is used.
52
+ * Valid ranges are backend-specific and validated by the Rust core.
53
+ * ZSTD default is 3, LZ4 default is 0.
54
+ */
55
+ compressionLevel?: number;
56
+ /**
57
+ * Minimum size in bytes for values to be compressed.
58
+ * Values smaller than this will not be compressed.
59
+ * Must be at least 6 bytes. Defaults to 64 bytes.
60
+ */
61
+ minCompressionSize?: number;
62
+ /**
63
+ * Maximum allowed size in bytes for decompressed data.
64
+ * This limit prevents decompression bombs (maliciously crafted compressed data
65
+ * that expands to huge sizes).
66
+ * If not set, defaults to 512MB (matching Valkey's proto-max-bulk-len).
67
+ */
68
+ maxDecompressedSize?: number;
69
+ }