@@ -241,6 +241,9 @@ pub const Page = struct {
241241
242242 scope : * Env.Scope ,
243243
244+ // List of modules currently fetched/loaded.
245+ module_map : std .StringHashMapUnmanaged ([]const u8 ),
246+
244247 // current_script is the script currently evaluated by the page.
245248 // current_script could by fetch module to resolve module's url to fetch.
246249 current_script : ? * const Script = null ,
@@ -267,6 +270,7 @@ pub const Page = struct {
267270 .http_client = browser .http_client ,
268271 },
269272 .scope = try session .executor .startScope (& self .window , & self .state , self , true ),
273+ .module_map = .empty ,
270274 };
271275
272276 // load polyfills
@@ -298,10 +302,20 @@ pub const Page = struct {
298302 const self : * Page = @ptrCast (@alignCast (ctx ));
299303
300304 log .debug ("fetch module: specifier: {s}" , .{specifier });
301- return try self .fetchData (
302- specifier ,
303- if (self .current_script ) | s | s .src else null ,
304- );
305+
306+ const base = if (self .current_script ) | s | s .src else null ;
307+
308+ const file_src = blk : {
309+ if (base ) | _base | {
310+ break :blk try URL .stitch (self .arena , specifier , _base );
311+ } else break :blk specifier ;
312+ };
313+
314+ if (self .module_map .getEntry (file_src )) | entry | return entry .value_ptr .* ;
315+
316+ const module = try self .fetchData (specifier , base );
317+ if (module ) | _module | try self .module_map .putNoClobber (self .arena , file_src , _module );
318+ return module ;
305319 }
306320
307321 pub fn wait (self : * Page ) ! void {
0 commit comments