@@ -56,13 +56,22 @@ const AsyncApi2DereferenceVisitor = stampit({
56
56
reference : null ,
57
57
options : null ,
58
58
ancestors : null ,
59
+ refractCache : null ,
59
60
} ,
60
- init ( { indirections = [ ] , reference, namespace, options, ancestors = new AncestorLineage ( ) } ) {
61
+ init ( {
62
+ indirections = [ ] ,
63
+ reference,
64
+ namespace,
65
+ options,
66
+ ancestors = new AncestorLineage ( ) ,
67
+ refractCache = new Map ( ) ,
68
+ } ) {
61
69
this . indirections = indirections ;
62
70
this . namespace = namespace ;
63
71
this . reference = reference ;
64
72
this . options = options ;
65
73
this . ancestors = new AncestorLineage ( ...ancestors ) ;
74
+ this . refractCache = refractCache ;
66
75
} ,
67
76
methods : {
68
77
toBaseURI ( uri : string ) : string {
@@ -148,15 +157,20 @@ const AsyncApi2DereferenceVisitor = stampit({
148
157
// applying semantics to a fragment
149
158
if ( isPrimitiveElement ( referencedElement ) ) {
150
159
const referencedElementType = toValue ( referencingElement . meta . get ( 'referenced-element' ) ) ;
160
+ const cacheKey = `${ referencedElementType } -${ toValue ( identityManager . identify ( referencedElement ) ) } ` ;
151
161
152
- if ( isReferenceLikeElement ( referencedElement ) ) {
162
+ if ( this . refractCache . has ( cacheKey ) ) {
163
+ referencedElement = this . refractCache . get ( cacheKey ) ;
164
+ } else if ( isReferenceLikeElement ( referencedElement ) ) {
153
165
// handling indirect references
154
166
referencedElement = ReferenceElement . refract ( referencedElement ) ;
155
167
referencedElement . setMetaProperty ( 'referenced-element' , referencedElementType ) ;
168
+ this . refractCache . set ( cacheKey , referencedElement ) ;
156
169
} else {
157
170
// handling direct references
158
171
const ElementClass = this . namespace . getElementClass ( referencedElementType ) ;
159
172
referencedElement = ElementClass . refract ( referencedElement ) ;
173
+ this . refractCache . set ( cacheKey , referencedElement ) ;
160
174
}
161
175
}
162
176
@@ -182,6 +196,7 @@ const AsyncApi2DereferenceVisitor = stampit({
182
196
indirections : [ ...this . indirections ] ,
183
197
options : this . options ,
184
198
ancestors : ancestorsLineage ,
199
+ refractCache : this . refractCache ,
185
200
} ) ;
186
201
referencedElement = await visitAsync ( referencedElement , visitor , {
187
202
keyMap,
@@ -288,7 +303,14 @@ const AsyncApi2DereferenceVisitor = stampit({
288
303
289
304
// applying semantics to a referenced element
290
305
if ( isPrimitiveElement ( referencedElement ) ) {
291
- referencedElement = ChannelItemElement . refract ( referencedElement ) ;
306
+ const cacheKey = `channel-${ toValue ( identityManager . identify ( referencedElement ) ) } ` ;
307
+
308
+ if ( this . refractCache . has ( cacheKey ) ) {
309
+ referencedElement = this . refractCache . get ( cacheKey ) ;
310
+ } else {
311
+ referencedElement = ChannelItemElement . refract ( referencedElement ) ;
312
+ this . refractCache . set ( cacheKey , referencedElement ) ;
313
+ }
292
314
}
293
315
294
316
// detect direct or indirect reference
@@ -313,6 +335,7 @@ const AsyncApi2DereferenceVisitor = stampit({
313
335
indirections : [ ...this . indirections ] ,
314
336
options : this . options ,
315
337
ancestors : ancestorsLineage ,
338
+ refractCache : this . refractCache ,
316
339
} ) ;
317
340
referencedElement = await visitAsync ( referencedElement , visitor , {
318
341
keyMap,
0 commit comments