@dereekb/util 13.26.0 → 13.27.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/oidc/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@dereekb/util/oidc",
3
- "version": "13.26.0",
3
+ "version": "13.27.0",
4
4
  "peerDependencies": {
5
- "@dereekb/util": "13.26.0"
5
+ "@dereekb/util": "13.27.0"
6
6
  },
7
7
  "exports": {
8
8
  "./package.json": "./package.json",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dereekb/util",
3
- "version": "13.26.0",
3
+ "version": "13.27.0",
4
4
  "sideEffects": false,
5
5
  "exports": {
6
6
  "./test": {
@@ -0,0 +1,101 @@
1
+ import { type Maybe } from '../value/maybe.type';
2
+ import { type DateOrUnixDateTimeMillisecondsNumber, type Milliseconds } from '../date/date';
3
+ import { type ExpirationDetails } from '../date/expires';
4
+ import { type FactoryWithInput, type Getter } from './getter';
5
+ import { type CachedFactoryWithInput } from './getter.cache';
6
+ /**
7
+ * Function that derives the expiration for a cached value.
8
+ *
9
+ * Returns the absolute Date/epoch-milliseconds at which `value` should expire, or null/undefined for a
10
+ * value that never expires. `loadedAt` is the time the value was loaded into the cache, so a value-derived
11
+ * TTL is expressed as `addMilliseconds(loadedAt, ttl)`.
12
+ */
13
+ export type ExpiringCachedGetterExpirationFunction<T> = (value: T, loadedAt: Date) => Maybe<DateOrUnixDateTimeMillisecondsNumber>;
14
+ /**
15
+ * Configuration for {@link expiringCachedGetter}().
16
+ */
17
+ export interface ExpiringCachedGetterConfig<T, A = unknown> {
18
+ /**
19
+ * The getter/factory whose result is cached. It is wrapped by an internal {@link cachedGetter}, which owns
20
+ * the load/init/reset/used mechanics — this getter only layers expiration on top.
21
+ */
22
+ readonly getter: FactoryWithInput<T, A>;
23
+ /**
24
+ * Fixed time-to-live in milliseconds, measured from the moment the value is loaded. Ignored when
25
+ * `expiration` is provided.
26
+ */
27
+ readonly ttl?: Maybe<Milliseconds>;
28
+ /**
29
+ * Derives the expiration from the loaded value itself (a "value-derived" expiring cache). Takes precedence
30
+ * over `ttl`. Return null/undefined for a value that never expires.
31
+ *
32
+ * When the value is (or contains) an `Expires`, pass `(value) => value.expiresAt`; for a value-derived TTL
33
+ * use `(value, loadedAt) => addMilliseconds(loadedAt, ttlOf(value))`.
34
+ */
35
+ readonly expiration?: Maybe<ExpiringCachedGetterExpirationFunction<T>>;
36
+ /**
37
+ * How the expiration details are resolved:
38
+ * - `false` (default): the details are computed ONCE, when the value is loaded, and reused for every check.
39
+ * - `true` (dynamic): the details are recomputed from the cached value on every retrieval and on every
40
+ * {@link ExpiringCachedGetter.expirationDetails} call. Use this when the derived expiration can change
41
+ * after the value is loaded.
42
+ */
43
+ readonly dynamic?: Maybe<boolean>;
44
+ /**
45
+ * A freshly-loaded value is returned WITHOUT an expiration check by default — it was just produced by the
46
+ * source, so it is assumed valid. Set this true to check a freshly-loaded value too: if the source returns
47
+ * a value that is ALREADY expired, an error is thrown rather than caching a dead-on-arrival value. Applies
48
+ * to the initial load and to every reload after expiry.
49
+ */
50
+ readonly checkExpirationOnFirstGet?: Maybe<boolean>;
51
+ /**
52
+ * Getter for the current time. Defaults to `() => new Date()`. Override to make expiry deterministic in tests.
53
+ */
54
+ readonly now?: Maybe<Getter<Date>>;
55
+ }
56
+ /**
57
+ * A cached getter whose cached value expires; once the value has expired the next retrieval reloads it from
58
+ * the source.
59
+ *
60
+ * Extends the {@link CachedGetter} surface (`set`/`reset`/`init`/`used`, all delegated to an internal
61
+ * {@link cachedGetter}) with a single expiration probe.
62
+ */
63
+ export type ExpiringCachedGetter<T, A = unknown> = CachedFactoryWithInput<T, A> & {
64
+ /**
65
+ * Returns the {@link ExpirationDetails} of the currently cached value, or null when no value is cached.
66
+ *
67
+ * In `dynamic` mode the details are recomputed from the current value on each call; otherwise the details
68
+ * computed at load time are returned. Use the returned object's `hasExpired()` / `getExpirationDate()`.
69
+ */
70
+ expirationDetails(): Maybe<ExpirationDetails>;
71
+ };
72
+ /**
73
+ * Creates an {@link ExpiringCachedGetter} from the input configuration.
74
+ *
75
+ * The value is loaded and cached by an internal {@link cachedGetter}; this getter layers expiration on top —
76
+ * once the cached value expires the next retrieval resets the internal cache and reloads. Expiration is
77
+ * configured one of two ways:
78
+ *
79
+ * - **Fixed TTL** — pass `ttl` (milliseconds); the value expires that long after it is loaded.
80
+ * - **Value-derived** — pass an `expiration` function deriving the expiration Date/epoch-ms from the loaded
81
+ * value (e.g. `(value) => value.expiresAt`, or `(value, loadedAt) => addMilliseconds(loadedAt, ttlOf(value))`).
82
+ * Returning null/undefined means "never expires". `expiration` takes precedence over `ttl`; with neither set
83
+ * the value never expires (matching {@link cachedGetter}).
84
+ *
85
+ * A freshly-loaded value is returned without an expiration check; set `checkExpirationOnFirstGet` to reject a
86
+ * dead-on-arrival value with an error instead. Set `dynamic` to recompute the expiration details on every
87
+ * retrieval rather than once at load. Use {@link ExpiringCachedGetter.expirationDetails} to inspect the current
88
+ * expiration state.
89
+ *
90
+ * @param config - The getter to cache plus its expiration configuration.
91
+ * @returns An ExpiringCachedGetter that caches the value until it expires.
92
+ *
93
+ * @dbxUtil
94
+ * @dbxUtilCategory getter
95
+ * @dbxUtilKind factory
96
+ * @dbxUtilTags getter, cache, expire, expiring, ttl, time-to-live, refresh, memoize, lazy, factory
97
+ * @dbxUtilRelated cached-getter, expiration-details, is-expired, calculate-expiration-date
98
+ *
99
+ * @__NO_SIDE_EFFECTS__
100
+ */
101
+ export declare function expiringCachedGetter<T, A = unknown>(config: ExpiringCachedGetterConfig<T, A>): ExpiringCachedGetter<T, A>;
@@ -2,4 +2,5 @@ export * from './type';
2
2
  export * from './getter';
3
3
  export * from './getter.util';
4
4
  export * from './getter.cache';
5
+ export * from './getter.cache.expiring';
5
6
  export * from './getter.map';
package/test/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@dereekb/util/test",
3
- "version": "13.26.0",
3
+ "version": "13.27.0",
4
4
  "peerDependencies": {
5
- "@dereekb/util": "13.26.0",
5
+ "@dereekb/util": "13.27.0",
6
6
  "make-error": "^1.3.6"
7
7
  },
8
8
  "exports": {