@@ -81,7 +81,49 @@ const requestToAbsolute = (context, relativePath) => {
8181 return relativePath ;
8282} ;
8383
84- const makeCacheable = fn => {
84+ const makeCacheable = realFn => {
85+ /** @type {WeakMap<object, Map<string, ParsedResource>> } */
86+ const cache = new WeakMap ( ) ;
87+
88+ const getCache = associatedObjectForCache => {
89+ const entry = cache . get ( associatedObjectForCache ) ;
90+ if ( entry !== undefined ) return entry ;
91+ /** @type {Map<string, ParsedResource> } */
92+ const map = new Map ( ) ;
93+ cache . set ( associatedObjectForCache , map ) ;
94+ return map ;
95+ } ;
96+
97+ /**
98+ * @param {string } str the path with query and fragment
99+ * @param {Object= } associatedObjectForCache an object to which the cache will be attached
100+ * @returns {ParsedResource } parsed parts
101+ */
102+ const fn = ( str , associatedObjectForCache ) => {
103+ if ( ! associatedObjectForCache ) return realFn ( str ) ;
104+ const cache = getCache ( associatedObjectForCache ) ;
105+ const entry = cache . get ( str ) ;
106+ if ( entry !== undefined ) return entry ;
107+ const result = realFn ( str ) ;
108+ cache . set ( str , result ) ;
109+ return result ;
110+ } ;
111+
112+ fn . bindCache = associatedObjectForCache => {
113+ const cache = getCache ( associatedObjectForCache ) ;
114+ return str => {
115+ const entry = cache . get ( str ) ;
116+ if ( entry !== undefined ) return entry ;
117+ const result = realFn ( str ) ;
118+ cache . set ( str , result ) ;
119+ return result ;
120+ } ;
121+ } ;
122+
123+ return fn ;
124+ } ;
125+
126+ const makeCacheableWithContext = fn => {
85127 /** @type {WeakMap<object, Map<string, Map<string, string>>> } */
86128 const cache = new WeakMap ( ) ;
87129
@@ -215,7 +257,7 @@ const _makePathsRelative = (context, identifier) => {
215257 . join ( "" ) ;
216258} ;
217259
218- exports . makePathsRelative = makeCacheable ( _makePathsRelative ) ;
260+ exports . makePathsRelative = makeCacheableWithContext ( _makePathsRelative ) ;
219261
220262/**
221263 *
@@ -230,7 +272,7 @@ const _makePathsAbsolute = (context, identifier) => {
230272 . join ( "" ) ;
231273} ;
232274
233- exports . makePathsAbsolute = makeCacheable ( _makePathsAbsolute ) ;
275+ exports . makePathsAbsolute = makeCacheableWithContext ( _makePathsAbsolute ) ;
234276
235277/**
236278 * @param {string } context absolute context path
@@ -244,7 +286,7 @@ const _contextify = (context, request) => {
244286 . join ( "!" ) ;
245287} ;
246288
247- const contextify = makeCacheable ( _contextify ) ;
289+ const contextify = makeCacheableWithContext ( _contextify ) ;
248290exports . contextify = contextify ;
249291
250292/**
@@ -259,13 +301,15 @@ const _absolutify = (context, request) => {
259301 . join ( "!" ) ;
260302} ;
261303
262- const absolutify = makeCacheable ( _absolutify ) ;
304+ const absolutify = makeCacheableWithContext ( _absolutify ) ;
263305exports . absolutify = absolutify ;
264306
265307const PATH_QUERY_FRAGMENT_REGEXP =
266308 / ^ ( (?: \0 .| [ ^ ? # \0 ] ) * ) ( \? (?: \0 .| [ ^ # \0 ] ) * ) ? ( # .* ) ? $ / ;
309+ const PATH_QUERY_REGEXP = / ^ ( (?: \0 .| [ ^ ? # \0 ] ) * ) ( \? .* ) ? $ / ;
267310
268311/** @typedef {{ resource: string, path: string, query: string, fragment: string } } ParsedResource */
312+ /** @typedef {{ resource: string, path: string, query: string } } ParsedResourceWithoutFragment */
269313
270314/**
271315 * @param {string } str the path with query and fragment
@@ -280,47 +324,24 @@ const _parseResource = str => {
280324 fragment : match [ 3 ] || ""
281325 } ;
282326} ;
283- exports . parseResource = ( realFn => {
284- /** @type {WeakMap<object, Map<string, ParsedResource>> } */
285- const cache = new WeakMap ( ) ;
327+ exports . parseResource = makeCacheable ( _parseResource ) ;
286328
287- const getCache = associatedObjectForCache => {
288- const entry = cache . get ( associatedObjectForCache ) ;
289- if ( entry !== undefined ) return entry ;
290- /** @type {Map<string, ParsedResource> } */
291- const map = new Map ( ) ;
292- cache . set ( associatedObjectForCache , map ) ;
293- return map ;
294- } ;
295-
296- /**
297- * @param {string } str the path with query and fragment
298- * @param {Object= } associatedObjectForCache an object to which the cache will be attached
299- * @returns {ParsedResource } parsed parts
300- */
301- const fn = ( str , associatedObjectForCache ) => {
302- if ( ! associatedObjectForCache ) return realFn ( str ) ;
303- const cache = getCache ( associatedObjectForCache ) ;
304- const entry = cache . get ( str ) ;
305- if ( entry !== undefined ) return entry ;
306- const result = realFn ( str ) ;
307- cache . set ( str , result ) ;
308- return result ;
309- } ;
310-
311- fn . bindCache = associatedObjectForCache => {
312- const cache = getCache ( associatedObjectForCache ) ;
313- return str => {
314- const entry = cache . get ( str ) ;
315- if ( entry !== undefined ) return entry ;
316- const result = realFn ( str ) ;
317- cache . set ( str , result ) ;
318- return result ;
319- } ;
329+ /**
330+ * Parse resource, skips fragment part
331+ * @param {string } str the path with query and fragment
332+ * @returns {ParsedResourceWithoutFragment } parsed parts
333+ */
334+ const _parseResourceWithoutFragment = str => {
335+ const match = PATH_QUERY_REGEXP . exec ( str ) ;
336+ return {
337+ resource : str ,
338+ path : match [ 1 ] . replace ( / \0 ( .) / g, "$1" ) ,
339+ query : match [ 2 ] ? match [ 2 ] . replace ( / \0 ( .) / g, "$1" ) : ""
320340 } ;
321-
322- return fn ;
323- } ) ( _parseResource ) ;
341+ } ;
342+ exports . parseResourceWithoutFragment = makeCacheable (
343+ _parseResourceWithoutFragment
344+ ) ;
324345
325346/**
326347 * @param {string } filename the filename which should be undone
0 commit comments