@@ -97,10 +97,28 @@ const wrapper = function(jsonld) {
97
97
/** Registered RDF dataset parsers hashed by content-type. */
98
98
const _rdfParsers = { } ;
99
99
100
- // resolved context cache
101
- // TODO: consider basing max on context size rather than number
100
+ // resolved context caches
101
+ // TODO: add controls for cache resource usage
102
+ // cache size per document loader
102
103
const RESOLVED_CONTEXT_CACHE_MAX_SIZE = 100 ;
103
- const _resolvedContextCache = new LRU ( { max : RESOLVED_CONTEXT_CACHE_MAX_SIZE } ) ;
104
+ // caches are created and indexed per documentLoader
105
+ // resources are cleaned up with WeakMap semantics for the documentLoaders
106
+ const _resolvedContextCaches = new WeakMap ( ) ;
107
+ // default key to use when no documentLoader used
108
+ const _defaultDocumentLoaderKey = { } ;
109
+
110
+ // make a ContextResolver using a per-documentLoader shared cache
111
+ function _makeContextResolver ( { documentLoader = _defaultDocumentLoaderKey } ) {
112
+ let cache = _resolvedContextCaches . get ( documentLoader ) ;
113
+ if ( ! cache ) {
114
+ // TODO: consider basing max on context size rather than number
115
+ cache = new LRU ( { max : RESOLVED_CONTEXT_CACHE_MAX_SIZE } ) ;
116
+ _resolvedContextCaches . set ( documentLoader , cache ) ;
117
+ }
118
+ return new ContextResolver ( {
119
+ sharedCache : cache
120
+ } ) ;
121
+ }
104
122
105
123
/* Core API */
106
124
@@ -152,8 +170,9 @@ jsonld.compact = async function(input, ctx, options) {
152
170
skipExpansion : false ,
153
171
link : false ,
154
172
issuer : new IdentifierIssuer ( '_:b' ) ,
155
- contextResolver : new ContextResolver (
156
- { sharedCache : _resolvedContextCache } )
173
+ contextResolver : _makeContextResolver ( {
174
+ documentLoader : options ? options . documentLoader : undefined
175
+ } )
157
176
} ) ;
158
177
if ( options . link ) {
159
178
// force skip expansion when linking, "link" is not part of the public
@@ -269,8 +288,9 @@ jsonld.expand = async function(input, options) {
269
288
// set default options
270
289
options = _setDefaults ( options , {
271
290
keepFreeFloatingNodes : false ,
272
- contextResolver : new ContextResolver (
273
- { sharedCache : _resolvedContextCache } )
291
+ contextResolver : _makeContextResolver ( {
292
+ documentLoader : options ? options . documentLoader : undefined
293
+ } )
274
294
} ) ;
275
295
276
296
// build set of objects that may have @contexts to resolve
@@ -368,8 +388,9 @@ jsonld.flatten = async function(input, ctx, options) {
368
388
// set default options
369
389
options = _setDefaults ( options , {
370
390
base : _isString ( input ) ? input : '' ,
371
- contextResolver : new ContextResolver (
372
- { sharedCache : _resolvedContextCache } )
391
+ contextResolver : _makeContextResolver ( {
392
+ documentLoader : options ? options . documentLoader : undefined
393
+ } )
373
394
} ) ;
374
395
375
396
// expand input
@@ -423,8 +444,9 @@ jsonld.frame = async function(input, frame, options) {
423
444
requireAll : false ,
424
445
omitDefault : false ,
425
446
bnodesToClear : [ ] ,
426
- contextResolver : new ContextResolver (
427
- { sharedCache : _resolvedContextCache } )
447
+ contextResolver : _makeContextResolver ( {
448
+ documentLoader : options ? options . documentLoader : undefined
449
+ } )
428
450
} ) ;
429
451
430
452
// if frame is a string, attempt to dereference remote document
@@ -565,8 +587,9 @@ jsonld.normalize = jsonld.canonize = async function(input, options) {
565
587
algorithm : 'URDNA2015' ,
566
588
skipExpansion : false ,
567
589
safe : true ,
568
- contextResolver : new ContextResolver (
569
- { sharedCache : _resolvedContextCache } )
590
+ contextResolver : _makeContextResolver ( {
591
+ documentLoader : options ? options . documentLoader : undefined
592
+ } )
570
593
} ) ;
571
594
if ( 'inputFormat' in options ) {
572
595
if ( options . inputFormat !== 'application/n-quads' &&
@@ -674,8 +697,9 @@ jsonld.toRDF = async function(input, options) {
674
697
options = _setDefaults ( options , {
675
698
base : _isString ( input ) ? input : '' ,
676
699
skipExpansion : false ,
677
- contextResolver : new ContextResolver (
678
- { sharedCache : _resolvedContextCache } )
700
+ contextResolver : _makeContextResolver ( {
701
+ documentLoader : options ? options . documentLoader : undefined
702
+ } )
679
703
} ) ;
680
704
681
705
// TODO: support toRDF custom map?
@@ -726,8 +750,9 @@ jsonld.createNodeMap = async function(input, options) {
726
750
// set default options
727
751
options = _setDefaults ( options , {
728
752
base : _isString ( input ) ? input : '' ,
729
- contextResolver : new ContextResolver (
730
- { sharedCache : _resolvedContextCache } )
753
+ contextResolver : _makeContextResolver ( {
754
+ documentLoader : options ? options . documentLoader : undefined
755
+ } )
731
756
} ) ;
732
757
733
758
// expand input
@@ -774,8 +799,9 @@ jsonld.merge = async function(docs, ctx, options) {
774
799
775
800
// set default options
776
801
options = _setDefaults ( options , {
777
- contextResolver : new ContextResolver (
778
- { sharedCache : _resolvedContextCache } )
802
+ contextResolver : _makeContextResolver ( {
803
+ documentLoader : options ? options . documentLoader : undefined
804
+ } )
779
805
} ) ;
780
806
781
807
// expand all documents
@@ -926,8 +952,9 @@ jsonld.processContext = async function(
926
952
// set default options
927
953
options = _setDefaults ( options , {
928
954
base : '' ,
929
- contextResolver : new ContextResolver (
930
- { sharedCache : _resolvedContextCache } )
955
+ contextResolver : _makeContextResolver ( {
956
+ documentLoader : options ? options . documentLoader : undefined
957
+ } )
931
958
} ) ;
932
959
933
960
// return initial context early for null context
0 commit comments