@devvit/cache 0.12.1-next-2025-10-09-21-45-29-add2ad79f.0 → 0.12.1-next-2025-10-09-23-10-17-c0793c292.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/PromiseCache.d.ts CHANGED
@@ -24,7 +24,7 @@ export type Clock = {
24
24
  export declare const SystemClock: Clock;
25
25
  export type CacheOptions = {
26
26
  /**
27
- * Time to live in milliseconds.
27
+ * Time to live in seconds.
28
28
  */
29
29
  ttl: number;
30
30
  /**
package/PromiseCache.js CHANGED
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _PromiseCache_instances, _PromiseCache_redis, _PromiseCache_localCache, _PromiseCache_clock, _PromiseCache_randomizer, _PromiseCache_localCachedAnswer, _PromiseCache_maybeRefreshCache, _PromiseCache_refreshCache, _PromiseCache_pollForCache, _PromiseCache_updateCache, _PromiseCache_calculateRamp, _PromiseCache_redisEntry, _PromiseCache_enforceTTL;
12
+ var _PromiseCache_instances, _PromiseCache_redis, _PromiseCache_localCache, _PromiseCache_clock, _PromiseCache_randomizer, _PromiseCache_localCachedAnswer, _PromiseCache_maybeRefreshCache, _PromiseCache_refreshCache, _PromiseCache_pollForCache, _PromiseCache_updateCache, _PromiseCache_calculateRamp, _PromiseCache_redisEntry;
13
13
  // Isolate the random() method to avoid passing the Math package around
14
14
  export const MathRandomizer = {
15
15
  random() {
@@ -27,9 +27,9 @@ export function _namespaced(key) {
27
27
  export function _lock(key) {
28
28
  return `__devvit_cache_lock__${key}`;
29
29
  }
30
+ const minTtlMsValue = 5000; // milliseconds
30
31
  const pollEvery = 300; // milliseconds
31
32
  const maxPollingTimeout = 1000; // milliseconds
32
- const minTtlValue = 5000; // milliseconds
33
33
  export const retryLimit = 3;
34
34
  const errorRetryProbability = 0.1;
35
35
  export const clientRetryDelay = 1000; // milliseconds
@@ -101,13 +101,18 @@ export class PromiseCache {
101
101
  * - SET __lock__${key} '1' and DEL __lock__${key} to acquire and release a lock for a given key
102
102
  */
103
103
  async cache(closure, options) {
104
- __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_enforceTTL).call(this, options);
105
- const localCachedAnswer = __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_localCachedAnswer).call(this, options.key);
104
+ const { key } = options;
105
+ let ttlMs = options.ttl * 1000; // convert to milliseconds without mutating the original options object
106
+ if (ttlMs < minTtlMsValue) {
107
+ console.warn(`Cache TTL cannot be less than ${minTtlMsValue / 1000} seconds! Updating ttl value to ${minTtlMsValue / 1000} seconds.`);
108
+ ttlMs = minTtlMsValue;
109
+ }
110
+ const localCachedAnswer = __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_localCachedAnswer).call(this, key);
106
111
  if (localCachedAnswer !== undefined) {
107
112
  return localCachedAnswer;
108
113
  }
109
- const existing = await __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_redisEntry).call(this, options.key);
110
- const entry = await __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_maybeRefreshCache).call(this, options, existing, closure);
114
+ const existing = await __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_redisEntry).call(this, key);
115
+ const entry = await __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_maybeRefreshCache).call(this, key, ttlMs, existing, closure);
111
116
  return _unwrap(entry);
112
117
  }
113
118
  }
@@ -137,7 +142,7 @@ _PromiseCache_redis = new WeakMap(), _PromiseCache_localCache = new WeakMap(), _
137
142
  *
138
143
  * We'll always refresh if missing or expired, but its probabilistic if we'll refresh if about to expire or if we have an error.
139
144
  */
140
- async function _PromiseCache_maybeRefreshCache(options, entry, closure) {
145
+ async function _PromiseCache_maybeRefreshCache(key, ttlMs, entry, closure) {
141
146
  const expires = entry?.expires;
142
147
  const rampProbability = expires ? __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_calculateRamp).call(this, expires) : 1;
143
148
  if (!entry ||
@@ -145,7 +150,7 @@ async function _PromiseCache_maybeRefreshCache(options, entry, closure) {
145
150
  entry.errorCount < retryLimit &&
146
151
  errorRetryProbability > __classPrivateFieldGet(this, _PromiseCache_randomizer, "f").random()) ||
147
152
  rampProbability > __classPrivateFieldGet(this, _PromiseCache_randomizer, "f").random()) {
148
- return __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_refreshCache).call(this, options, entry, closure);
153
+ return __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_refreshCache).call(this, key, ttlMs, entry, closure);
149
154
  }
150
155
  else {
151
156
  return entry;
@@ -157,19 +162,19 @@ async function _PromiseCache_maybeRefreshCache(options, entry, closure) {
157
162
  *
158
163
  * If you don't win the lock, you'll poll for the cache. If you don't get the cache within maxPollingTimeout, you'll throw an error.
159
164
  */
160
- async function _PromiseCache_refreshCache(options, entry, closure) {
161
- const lockKey = _lock(options.key);
165
+ async function _PromiseCache_refreshCache(key, ttlMs, entry, closure) {
166
+ const lockKey = _lock(key);
162
167
  const now = __classPrivateFieldGet(this, _PromiseCache_clock, "f").now().getTime();
163
168
  /**
164
169
  * The write lock should last for a while, but not the full TTL. Hopefully write attempts settle down after a while.
165
170
  */
166
- const lockExpiration = new Date(now + options.ttl / 2);
171
+ const lockExpiration = new Date(now + ttlMs / 2);
167
172
  const lockObtained = await __classPrivateFieldGet(this, _PromiseCache_redis, "f").set(lockKey, '1', {
168
173
  expiration: lockExpiration,
169
174
  nx: true,
170
175
  });
171
176
  if (lockObtained) {
172
- return __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_updateCache).call(this, options.key, entry, closure, options.ttl);
177
+ return __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_updateCache).call(this, key, entry, closure, ttlMs);
173
178
  }
174
179
  else if (entry) {
175
180
  // This entry is still valid, return it
@@ -177,10 +182,10 @@ async function _PromiseCache_refreshCache(options, entry, closure) {
177
182
  }
178
183
  else {
179
184
  const start = __classPrivateFieldGet(this, _PromiseCache_clock, "f").now();
180
- return __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_pollForCache).call(this, start, options.key, options.ttl);
185
+ return __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_pollForCache).call(this, start, key, ttlMs);
181
186
  }
182
- }, _PromiseCache_pollForCache = async function _PromiseCache_pollForCache(start, key, ttl) {
183
- const pollingTimeout = Math.min(ttl, maxPollingTimeout);
187
+ }, _PromiseCache_pollForCache = async function _PromiseCache_pollForCache(start, key, ttlMs) {
188
+ const pollingTimeout = Math.min(ttlMs, maxPollingTimeout);
184
189
  const existing = await __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_redisEntry).call(this, key);
185
190
  if (existing) {
186
191
  return existing;
@@ -189,13 +194,13 @@ async function _PromiseCache_refreshCache(options, entry, closure) {
189
194
  throw new Error(`Cache request timed out trying to get data at key: ${key}`);
190
195
  }
191
196
  await new Promise((resolve) => setTimeout(resolve, pollEvery));
192
- return __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_pollForCache).call(this, start, key, ttl);
197
+ return __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_pollForCache).call(this, start, key, ttlMs);
193
198
  }, _PromiseCache_updateCache =
194
199
  /**
195
200
  * Actually update the cache. This is the method that will be called if we have the lock.
196
201
  */
197
- async function _PromiseCache_updateCache(key, entry, closure, ttl) {
198
- const expires = __classPrivateFieldGet(this, _PromiseCache_clock, "f").now().getTime() + ttl;
202
+ async function _PromiseCache_updateCache(key, entry, closure, ttlMs) {
203
+ const expires = __classPrivateFieldGet(this, _PromiseCache_clock, "f").now().getTime() + ttlMs;
199
204
  entry = entry ?? {
200
205
  value: null,
201
206
  expires,
@@ -255,9 +260,4 @@ async function _PromiseCache_updateCache(key, entry, closure, ttl) {
255
260
  return entry;
256
261
  }
257
262
  return undefined;
258
- }, _PromiseCache_enforceTTL = function _PromiseCache_enforceTTL(options) {
259
- if (options.ttl < minTtlValue) {
260
- console.warn(`Cache TTL cannot be less than ${minTtlValue} milliseconds! Updating ttl value of ${options.ttl} to ${minTtlValue}.`);
261
- options.ttl = minTtlValue;
262
- }
263
263
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devvit/cache",
3
- "version": "0.12.1-next-2025-10-09-21-45-29-add2ad79f.0",
3
+ "version": "0.12.1-next-2025-10-09-23-10-17-c0793c292.0",
4
4
  "license": "BSD-3-Clause",
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,15 +31,15 @@
31
31
  "test:unit-with-coverage": "vitest run --coverage"
32
32
  },
33
33
  "dependencies": {
34
- "@devvit/redis": "0.12.1-next-2025-10-09-21-45-29-add2ad79f.0",
35
- "@devvit/shared-types": "0.12.1-next-2025-10-09-21-45-29-add2ad79f.0"
34
+ "@devvit/redis": "0.12.1-next-2025-10-09-23-10-17-c0793c292.0",
35
+ "@devvit/shared-types": "0.12.1-next-2025-10-09-23-10-17-c0793c292.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@devvit/repo-tools": "0.12.1-next-2025-10-09-21-45-29-add2ad79f.0",
39
- "@devvit/tsconfig": "0.12.1-next-2025-10-09-21-45-29-add2ad79f.0",
38
+ "@devvit/repo-tools": "0.12.1-next-2025-10-09-23-10-17-c0793c292.0",
39
+ "@devvit/tsconfig": "0.12.1-next-2025-10-09-23-10-17-c0793c292.0",
40
40
  "eslint": "9.11.1",
41
41
  "typescript": "5.8.3",
42
42
  "vitest": "1.6.1"
43
43
  },
44
- "gitHead": "e51c2e6fbb23434d3bc2053c7a835c1ab8f1d225"
44
+ "gitHead": "704e966f3a13c15799c23625bb48ebeef2f8e2bd"
45
45
  }