@gravito/stasis 3.1.0 → 3.2.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.
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Unique identifier for a cached item.
3
+ *
4
+ * Used to reference and retrieve specific data entries within the cache storage.
5
+ *
6
+ * @public
7
+ * @since 3.0.0
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const key: CacheKey = 'user:123:profile';
12
+ * ```
13
+ */
14
+ export type CacheKey = string;
15
+ /**
16
+ * Time-to-live (TTL) configuration for cache entries.
17
+ *
18
+ * Defines the duration or point in time when a cache entry becomes invalid.
19
+ * - `number`: Relative duration in seconds from the current time.
20
+ * - `Date`: Absolute point in time for expiration.
21
+ * - `null`: Persistent storage that never expires automatically.
22
+ * - `undefined`: Fallback to the default TTL configured in the store or repository.
23
+ *
24
+ * @public
25
+ * @since 3.0.0
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const ttl: CacheTtl = 3600; // 1 hour
30
+ * const absoluteTtl: CacheTtl = new Date('2026-12-31');
31
+ * ```
32
+ */
33
+ export type CacheTtl = number | Date | null | undefined;
34
+ /**
35
+ * Result of a cache retrieval operation.
36
+ *
37
+ * Represents the cached data of type `T`, or `null` if the entry is missing or has expired.
38
+ *
39
+ * @public
40
+ * @since 3.0.0
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * const val: CacheValue<string> = 'cached content';
45
+ * const miss: CacheValue<number> = null;
46
+ * ```
47
+ */
48
+ export type CacheValue<T = unknown> = T | null;
49
+ /**
50
+ * Validates and prepares a cache key for storage operations.
51
+ *
52
+ * Ensures the key meets the minimum requirements for cache storage, such as being non-empty.
53
+ *
54
+ * @param key - The raw string to be used as a cache key.
55
+ * @returns The validated cache key.
56
+ * @throws {Error} Thrown if the provided key is an empty string or falsy.
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const key = normalizeCacheKey('user_profile_123');
61
+ * ```
62
+ *
63
+ * @public
64
+ * @since 3.0.0
65
+ */
66
+ export declare function normalizeCacheKey(key: string): string;
67
+ /**
68
+ * Converts a flexible TTL definition into an absolute Unix epoch timestamp.
69
+ *
70
+ * Normalizes various TTL formats into a consistent millisecond-based timestamp
71
+ * used for expiration checks.
72
+ *
73
+ * @param ttl - The TTL configuration to convert.
74
+ * @param now - Reference timestamp in milliseconds for relative calculations. Defaults to current time.
75
+ * @returns The expiration timestamp in milliseconds, `null` for permanent storage, or `undefined` for default behavior.
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * // Relative TTL (60 seconds)
80
+ * const expiresAt = ttlToExpiresAt(60);
81
+ *
82
+ * // Absolute Date
83
+ * const expiresAtDate = ttlToExpiresAt(new Date('2026-12-31'));
84
+ * ```
85
+ *
86
+ * @public
87
+ * @since 3.0.0
88
+ */
89
+ export declare function ttlToExpiresAt(ttl: CacheTtl, now?: number): number | null | undefined;
90
+ /**
91
+ * Evaluates whether a cache entry has exceeded its expiration time.
92
+ *
93
+ * Compares the provided expiration timestamp against a reference time to determine
94
+ * if the cached data should be considered stale.
95
+ *
96
+ * @param expiresAt - The expiration timestamp in milliseconds, or `null`/`undefined` for non-expiring entries.
97
+ * @param now - Reference timestamp in milliseconds for the comparison. Defaults to current time.
98
+ * @returns `true` if the current time has passed the expiration point; otherwise `false`.
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * const expired = isExpired(Date.now() - 1000); // true
103
+ * const persistent = isExpired(null); // false
104
+ * ```
105
+ *
106
+ * @public
107
+ * @since 3.0.0
108
+ */
109
+ export declare function isExpired(expiresAt: number | null | undefined, now?: number): boolean;
110
+ /**
111
+ * Options for data compression within the cache.
112
+ *
113
+ * Defines how and when data should be compressed before storage to save space
114
+ * and reduce I/O overhead.
115
+ *
116
+ * @public
117
+ * @since 3.1.0
118
+ *
119
+ * @example
120
+ * ```typescript
121
+ * const options: CompressionOptions = {
122
+ * enabled: true,
123
+ * minSize: 2048,
124
+ * level: 9
125
+ * };
126
+ * ```
127
+ */
128
+ export type CompressionOptions = {
129
+ /**
130
+ * Whether to enable compression for cached values.
131
+ *
132
+ * @defaultValue false
133
+ */
134
+ enabled: boolean;
135
+ /**
136
+ * Minimum size in bytes for the value to be compressed.
137
+ * Values smaller than this threshold will be stored uncompressed.
138
+ *
139
+ * @defaultValue 1024
140
+ */
141
+ minSize?: number;
142
+ /**
143
+ * Compression level for zlib (1-9).
144
+ * Higher levels provide better compression but require more CPU.
145
+ *
146
+ * @defaultValue 6
147
+ */
148
+ level?: number;
149
+ };
@@ -0,0 +1,104 @@
1
+ /**
2
+ * A generic LRU (Least Recently Used) cache implementation.
3
+ *
4
+ * Uses a Map for O(1) lookups and a Doubly Linked List for O(1) updates to the access order.
5
+ * When the cache reaches its maximum capacity, the least recently accessed item is evicted.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const cache = new LRUCache<number>(100, (key, value) => {
10
+ * console.log(`Evicted: ${key} = ${value}`);
11
+ * });
12
+ * cache.set('key1', 42);
13
+ * const val = cache.get('key1'); // 42
14
+ * ```
15
+ */
16
+ export declare class LRUCache<T> {
17
+ private maxSize;
18
+ private onEvict?;
19
+ private map;
20
+ private head;
21
+ private tail;
22
+ /**
23
+ * Creates a new LRU cache instance.
24
+ *
25
+ * @param maxSize - The maximum number of items allowed in the cache. Set to 0 for unlimited.
26
+ * @param onEvict - Optional callback triggered when an item is evicted due to capacity limits.
27
+ */
28
+ constructor(maxSize: number, onEvict?: (key: string, value: T) => void);
29
+ /**
30
+ * The current number of items stored in the cache.
31
+ */
32
+ get size(): number;
33
+ /**
34
+ * Checks if a key exists in the cache without updating its access order.
35
+ *
36
+ * @param key - The identifier to look for.
37
+ * @returns True if the key exists, false otherwise.
38
+ */
39
+ has(key: string): boolean;
40
+ /**
41
+ * Retrieves an item from the cache and marks it as most recently used.
42
+ *
43
+ * @param key - The identifier of the item to retrieve.
44
+ * @returns The cached value, or undefined if not found.
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const value = cache.get('my-key');
49
+ * ```
50
+ */
51
+ get(key: string): T | undefined;
52
+ /**
53
+ * Retrieves an item from the cache without updating its access order.
54
+ *
55
+ * Useful for inspecting the cache without affecting eviction priority.
56
+ *
57
+ * @param key - The identifier of the item to peek.
58
+ * @returns The cached value, or undefined if not found.
59
+ */
60
+ peek(key: string): T | undefined;
61
+ /**
62
+ * Adds or updates an item in the cache, marking it as most recently used.
63
+ *
64
+ * If the cache is at capacity, the least recently used item will be evicted.
65
+ *
66
+ * @param key - The identifier for the item.
67
+ * @param value - The data to store.
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * cache.set('user:1', { name: 'Alice' });
72
+ * ```
73
+ */
74
+ set(key: string, value: T): void;
75
+ /**
76
+ * Removes an item from the cache.
77
+ *
78
+ * @param key - The identifier of the item to remove.
79
+ * @returns True if the item was found and removed, false otherwise.
80
+ */
81
+ delete(key: string): boolean;
82
+ /**
83
+ * Removes all items from the cache.
84
+ */
85
+ clear(): void;
86
+ /**
87
+ * Moves a node to the head of the linked list (most recently used).
88
+ *
89
+ * @param node - The node to promote.
90
+ */
91
+ private moveToHead;
92
+ /**
93
+ * Removes a node from the linked list.
94
+ *
95
+ * @param node - The node to remove.
96
+ */
97
+ private removeNode;
98
+ /**
99
+ * Evicts the least recently used item (the tail of the list).
100
+ *
101
+ * Triggers the `onEvict` callback if provided.
102
+ */
103
+ private evict;
104
+ }
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@gravito/stasis",
3
- "version": "3.1.0",
3
+ "sideEffects": false,
4
+ "version": "3.2.0",
4
5
  "publishConfig": {
5
6
  "access": "public"
6
7
  },
@@ -11,6 +12,7 @@
11
12
  "types": "dist/index.d.ts",
12
13
  "exports": {
13
14
  ".": {
15
+ "bun": "./src/index.ts",
14
16
  "types": "./dist/index.d.ts",
15
17
  "import": "./dist/index.js",
16
18
  "require": "./dist/index.cjs"
@@ -22,12 +24,13 @@
22
24
  "LICENSE"
23
25
  ],
24
26
  "scripts": {
25
- "build": "tsup src/index.ts --format esm,cjs --dts",
27
+ "build": "bun run build.ts",
28
+ "build:dts": "bun run build.ts --dts-only",
26
29
  "test": "bun test --timeout=10000",
27
30
  "test:coverage": "bun test --timeout=10000 --coverage --coverage-reporter=lcov --coverage-dir coverage && bun run --bun scripts/check-coverage.ts",
28
31
  "test:ci": "bun test --timeout=10000 --coverage --coverage-reporter=lcov --coverage-dir coverage && bun run --bun scripts/check-coverage.ts",
29
32
  "typecheck": "bun tsc -p tsconfig.json --noEmit --skipLibCheck",
30
- "test:unit": "bun test tests/ --timeout=10000",
33
+ "test:unit": "bun test $(find tests -name '*.test.ts' ! -name '*.integration.test.ts' 2>/dev/null | tr '\\n' ' ') --timeout=10000",
31
34
  "test:integration": "test $(find tests -name '*.integration.test.ts' 2>/dev/null | wc -l) -gt 0 && find tests -name '*.integration.test.ts' -print0 | xargs -0 bun test --timeout=10000 || echo 'No integration tests found'"
32
35
  },
33
36
  "keywords": [
@@ -40,15 +43,14 @@
40
43
  "author": "Carl Lee <carllee0520@gmail.com>",
41
44
  "license": "MIT",
42
45
  "peerDependencies": {
43
- "@gravito/core": "workspace:*",
44
- "@gravito/plasma": "workspace:*"
46
+ "@gravito/core": "^2.0.0",
47
+ "@gravito/plasma": "^2.0.0"
45
48
  },
46
49
  "devDependencies": {
47
50
  "@gravito/plasma": "workspace:*",
48
51
  "@gravito/core": "workspace:*",
49
52
  "@gravito/photon": "workspace:*",
50
53
  "bun-types": "latest",
51
- "tsup": "^8.5.1",
52
54
  "typescript": "^5.9.3"
53
55
  },
54
56
  "homepage": "https://github.com/gravito-framework/gravito#readme",