@@ -62,13 +62,22 @@ const OpenApi3_0DereferenceVisitor = stampit({
62
62
reference : null ,
63
63
options : null ,
64
64
ancestors : null ,
65
+ refractCache : null ,
65
66
} ,
66
- init ( { indirections = [ ] , reference, namespace, options, ancestors = new AncestorLineage ( ) } ) {
67
+ init ( {
68
+ indirections = [ ] ,
69
+ reference,
70
+ namespace,
71
+ options,
72
+ ancestors = new AncestorLineage ( ) ,
73
+ refractCache = new Map ( ) ,
74
+ } ) {
67
75
this . indirections = indirections ;
68
76
this . namespace = namespace ;
69
77
this . reference = reference ;
70
78
this . options = options ;
71
79
this . ancestors = new AncestorLineage ( ...ancestors ) ;
80
+ this . refractCache = refractCache ;
72
81
} ,
73
82
methods : {
74
83
toBaseURI ( uri : string ) : string {
@@ -154,15 +163,20 @@ const OpenApi3_0DereferenceVisitor = stampit({
154
163
// applying semantics to a fragment
155
164
if ( isPrimitiveElement ( referencedElement ) ) {
156
165
const referencedElementType = toValue ( referencingElement . meta . get ( 'referenced-element' ) ) ;
166
+ const cacheKey = `${ referencedElementType } -${ toValue ( identityManager . identify ( referencedElement ) ) } ` ;
157
167
158
- if ( isReferenceLikeElement ( referencedElement ) ) {
168
+ if ( this . refractCache . has ( cacheKey ) ) {
169
+ referencedElement = this . refractCache . get ( cacheKey ) ;
170
+ } else if ( isReferenceLikeElement ( referencedElement ) ) {
159
171
// handling indirect references
160
172
referencedElement = ReferenceElement . refract ( referencedElement ) ;
161
173
referencedElement . setMetaProperty ( 'referenced-element' , referencedElementType ) ;
174
+ this . refractCache . set ( cacheKey , referencedElement ) ;
162
175
} else {
163
176
// handling direct references
164
177
const ElementClass = this . namespace . getElementClass ( referencedElementType ) ;
165
178
referencedElement = ElementClass . refract ( referencedElement ) ;
179
+ this . refractCache . set ( cacheKey , referencedElement ) ;
166
180
}
167
181
}
168
182
@@ -188,6 +202,7 @@ const OpenApi3_0DereferenceVisitor = stampit({
188
202
indirections : [ ...this . indirections ] ,
189
203
options : this . options ,
190
204
ancestors : ancestorsLineage ,
205
+ refractCache : this . refractCache ,
191
206
} ) ;
192
207
referencedElement = await visitAsync ( referencedElement , visitor , {
193
208
keyMap,
@@ -277,7 +292,14 @@ const OpenApi3_0DereferenceVisitor = stampit({
277
292
278
293
// applying semantics to a referenced element
279
294
if ( isPrimitiveElement ( referencedElement ) ) {
280
- referencedElement = PathItemElement . refract ( referencedElement ) ;
295
+ const cacheKey = `pathItem-${ toValue ( identityManager . identify ( referencedElement ) ) } ` ;
296
+
297
+ if ( this . refractCache . has ( cacheKey ) ) {
298
+ referencedElement = this . refractCache . get ( cacheKey ) ;
299
+ } else {
300
+ referencedElement = PathItemElement . refract ( referencedElement ) ;
301
+ this . refractCache . set ( cacheKey , referencedElement ) ;
302
+ }
281
303
}
282
304
283
305
// detect direct or indirect reference
@@ -302,6 +324,7 @@ const OpenApi3_0DereferenceVisitor = stampit({
302
324
indirections : [ ...this . indirections ] ,
303
325
options : this . options ,
304
326
ancestors : ancestorsLineage ,
327
+ refractCache : this . refractCache ,
305
328
} ) ;
306
329
referencedElement = await visitAsync ( referencedElement , visitor , {
307
330
keyMap,
0 commit comments