@@ -3,189 +3,165 @@ import { is } from '@julr/utils/is'
3
3
4
4
import { errors } from '../../errors.js'
5
5
import { resolveTtl } from '../../helpers.js'
6
- import type { FactoryError } from '../../errors.js'
7
6
import type { Duration , RawCommonOptions } from '../../types/main.js'
8
7
9
8
const toId = hexoid ( 12 )
10
9
11
- export class CacheEntryOptions {
12
- /**
13
- * The options that were passed to the constructor
14
- */
15
- #options: RawCommonOptions
16
-
17
- /**
18
- * Unique identifier that will be used when logging
19
- * debug information.
20
- */
21
- id : string
22
-
23
- /**
24
- * Logical TTL is when the value is considered expired
25
- * but still can be in the cache ( Grace period )
26
- */
27
- logicalTtl ?: number
28
-
29
- /**
30
- * Physical TTL is the time when value will be automatically
31
- * removed from the cache. This is the Grace period
32
- * duration
33
- */
34
- physicalTtl ?: number
35
-
36
- /**
37
- * Timeouts for the cache operations
38
- */
39
- timeout ?: number
40
- hardTimeout ?: number
41
-
42
- /**
43
- * Resolved grace period options
44
- */
45
- grace : number
46
- graceBackoff : number
47
-
48
- /**
49
- * Max time to wait for the lock to be acquired
50
- */
51
- lockTimeout ?: number
52
- onFactoryError ?: ( error : FactoryError ) => void
53
-
54
- constructor ( options : RawCommonOptions = { } , defaults : Partial < RawCommonOptions > = { } ) {
55
- this . id = toId ( )
56
-
57
- this . #options = { ...defaults , ...options }
58
-
59
- this . grace = this . #resolveGrace( )
60
- this . graceBackoff = resolveTtl ( this . #options. graceBackoff , null ) ?? 0
61
- this . logicalTtl = this . #resolveLogicalTtl( )
62
- this . physicalTtl = this . #resolvePhysicalTtl( )
63
- this . timeout = resolveTtl ( this . #options. timeout , null )
64
- this . hardTimeout = resolveTtl ( this . #options. hardTimeout , null )
65
- this . lockTimeout = resolveTtl ( this . #options. lockTimeout , null )
66
- this . onFactoryError = this . #options. onFactoryError ?? defaults . onFactoryError
67
- }
10
+ export type CacheEntryOptions = ReturnType < typeof createCacheEntryOptions >
68
11
69
- /**
70
- * Resolve the grace period options
71
- */
72
- #resolveGrace( ) {
73
- if ( this . #options. grace === false ) return 0
74
- return resolveTtl ( this . #options. grace , null ) ?? 0
75
- }
12
+ /**
13
+ * Resolve the grace options
14
+ */
15
+ function resolveGrace ( options : RawCommonOptions ) {
16
+ if ( options . grace === false ) return 0
76
17
77
- /**
78
- * Returns a new instance of `CacheItemOptions` with the same
79
- * options as the current instance, but with any provided
80
- * options overriding the current
81
- *
82
- * For performance reasons, if no options are provided, the
83
- * current instance is returned
84
- */
85
- cloneWith ( options ?: Partial < RawCommonOptions > ) {
86
- return options ? new CacheEntryOptions ( options , this . #options) : this
87
- }
18
+ return resolveTtl ( options . grace , null ) ?? 0
19
+ }
88
20
89
- /**
90
- * Resolve the logical TTL to a duration in milliseconds
91
- */
92
- #resolveLogicalTtl( ) {
93
- return resolveTtl ( this . #options. ttl )
94
- }
21
+ /**
22
+ * Cache Entry Options. Define how a cache operation should behave
23
+ *
24
+ * Yes, this is a fake class. Initially, this was a class, but
25
+ * since CacheEntryOptions is initialized each time a cache
26
+ * operation is performed, it was converted to this
27
+ * fake class to have way better performance.
28
+ */
29
+ export function createCacheEntryOptions (
30
+ newOptions : RawCommonOptions = { } ,
31
+ defaults : Partial < RawCommonOptions > = { } ,
32
+ ) {
33
+ const options = { ...defaults , ...newOptions }
34
+
35
+ const grace = resolveGrace ( options )
36
+ const graceBackoff = resolveTtl ( options . graceBackoff , null ) ?? 0
37
+
38
+ let logicalTtl = resolveTtl ( options . ttl )
39
+ let physicalTtl = grace > 0 ? grace : logicalTtl
40
+
41
+ const timeout = resolveTtl ( options . timeout , null )
42
+ const hardTimeout = resolveTtl ( options . hardTimeout , null )
43
+ const lockTimeout = resolveTtl ( options . lockTimeout , null )
44
+
45
+ const self = {
46
+ /**
47
+ * Unique identifier that will be used when logging
48
+ * debug information.
49
+ */
50
+ id : toId ( ) ,
95
51
96
- /**
97
- * Resolve the physical TTL to a duration in milliseconds
98
- *
99
- * If grace period is not enabled then the physical TTL
100
- * is the same as the logical TTL
101
- */
102
- #resolvePhysicalTtl( ) {
103
- return this . isGraceEnabled ? this . grace : this . logicalTtl
104
- }
52
+ /**
53
+ * Resolved grace period options
54
+ */
55
+ grace,
56
+ graceBackoff,
105
57
106
- get isGraceEnabled ( ) {
107
- return this . grace > 0
108
- }
58
+ /**
59
+ * Logical TTL is when the value is considered expired
60
+ * but still can be in the cache ( Grace period )
61
+ */
62
+ logicalTtl,
109
63
110
- get suppressL2Errors ( ) {
111
- return this . #options. suppressL2Errors
112
- }
64
+ /**
65
+ * Physical TTL is the time when value will be automatically
66
+ * removed from the cache. This is the Grace period
67
+ * duration
68
+ */
69
+ physicalTtl,
113
70
114
- /**
115
- * Set a new logical TTL
116
- */
117
- setLogicalTtl ( ttl : Duration ) {
118
- this . #options . ttl = ttl
71
+ /**
72
+ * Timeouts for the cache operations
73
+ */
74
+ timeout ,
75
+ hardTimeout ,
119
76
120
- this . logicalTtl = this . #resolveLogicalTtl( )
121
- this . physicalTtl = this . #resolvePhysicalTtl( )
77
+ /**
78
+ * Max time to wait for the lock to be acquired
79
+ */
80
+ lockTimeout,
81
+ onFactoryError : options . onFactoryError ?? defaults . onFactoryError ,
82
+ isGraceEnabled : grace > 0 ,
83
+ suppressL2Errors : options . suppressL2Errors ,
122
84
123
- return this
124
- }
85
+ /**
86
+ * Returns a new instance of `CacheItemOptions` with the same
87
+ * options as the current instance, but with any provided
88
+ * options overriding the current
89
+ *
90
+ * For performance reasons, if no options are provided, the
91
+ * current instance is returned
92
+ */
93
+ cloneWith ( newOptions ?: Partial < RawCommonOptions > ) {
94
+ return newOptions ? createCacheEntryOptions ( newOptions , options ) : self
95
+ } ,
125
96
126
- /**
127
- * Compute the logical TTL timestamp from now
128
- */
129
- logicalTtlFromNow ( ) {
130
- if ( ! this . logicalTtl ) return undefined
131
- return Date . now ( ) + this . logicalTtl
132
- }
97
+ /**
98
+ * Set a new logical TTL
99
+ */
100
+ setLogicalTtl ( newTtl : Duration ) {
101
+ options . ttl = newTtl
133
102
134
- /**
135
- * Compute the physical TTL timestamp from now
136
- */
137
- physicalTtlFromNow ( ) {
138
- if ( ! this . physicalTtl ) return undefined
139
- return Date . now ( ) + this . physicalTtl
140
- }
103
+ logicalTtl = resolveTtl ( options . ttl )
104
+ physicalTtl = self . isGraceEnabled ? grace : logicalTtl
141
105
142
- /**
143
- * Compute the lock timeout we should use for the
144
- * factory
145
- */
146
- factoryTimeout ( hasFallbackValue : boolean ) {
147
- if ( hasFallbackValue && this . isGraceEnabled && is . number ( this . timeout ) ) {
148
- return {
149
- type : 'soft' ,
150
- duration : this . timeout ,
151
- exception : errors . E_FACTORY_SOFT_TIMEOUT ,
152
- }
153
- }
106
+ return self
107
+ } ,
154
108
155
- if ( this . hardTimeout ) {
156
- return {
157
- type : 'hard' ,
158
- duration : this . hardTimeout ,
159
- exception : errors . E_FACTORY_HARD_TIMEOUT ,
160
- }
161
- }
109
+ /**
110
+ * Compute the logical TTL timestamp from now
111
+ */
112
+ logicalTtlFromNow ( ) {
113
+ if ( ! logicalTtl ) return
162
114
163
- return
164
- }
115
+ return Date . now ( ) + logicalTtl
116
+ } ,
165
117
166
- /**
167
- * Determine if we should use the SWR strategy
168
- */
169
- shouldSwr ( hasFallback : boolean ) {
170
- return this . isGraceEnabled && this . timeout === 0 && hasFallback
171
- }
118
+ /**
119
+ * Compute the physical TTL timestamp from now
120
+ */
121
+ physicalTtlFromNow ( ) {
122
+ if ( ! physicalTtl ) return
172
123
173
- /**
174
- * Compute the maximum time we should wait for the
175
- * lock to be acquired
176
- */
177
- getApplicableLockTimeout ( hasFallbackValue : boolean ) {
178
- if ( this . lockTimeout ) {
179
- return this . lockTimeout
180
- }
124
+ return Date . now ( ) + physicalTtl
125
+ } ,
181
126
182
127
/**
183
- * If we have a fallback value and grace period is enabled,
184
- * that means we should wait at most for the soft timeout
185
- * duration.
128
+ * Compute the lock timeout we should use for the
129
+ * factory
186
130
*/
187
- if ( hasFallbackValue && this . isGraceEnabled && typeof this . timeout === 'number' ) {
188
- return this . timeout
189
- }
131
+ factoryTimeout ( hasFallbackValue : boolean ) {
132
+ if ( hasFallbackValue && self . isGraceEnabled && is . number ( timeout ) ) {
133
+ return { type : 'soft' , duration : timeout , exception : errors . E_FACTORY_SOFT_TIMEOUT }
134
+ }
135
+
136
+ if ( hardTimeout ) {
137
+ return { type : 'hard' , duration : hardTimeout , exception : errors . E_FACTORY_HARD_TIMEOUT }
138
+ }
139
+ } ,
140
+
141
+ /**
142
+ * Determine if we should use the SWR strategy
143
+ */
144
+ shouldSwr ( hasFallback : boolean ) {
145
+ return self . isGraceEnabled && timeout === 0 && hasFallback
146
+ } ,
147
+
148
+ /**
149
+ * Compute the maximum time we should wait for the
150
+ * lock to be acquired
151
+ */
152
+ getApplicableLockTimeout ( hasFallbackValue : boolean ) {
153
+ if ( lockTimeout ) return lockTimeout
154
+
155
+ /**
156
+ * If we have a fallback value and grace period is enabled,
157
+ * that means we should wait at most for the soft timeout
158
+ * duration.
159
+ */
160
+ if ( hasFallbackValue && self . isGraceEnabled && typeof timeout === 'number' ) {
161
+ return timeout
162
+ }
163
+ } ,
190
164
}
165
+
166
+ return self
191
167
}
0 commit comments