lib/importmap/map.rb in importmap-rails-0.2.2 vs lib/importmap/map.rb in importmap-rails-0.2.3

- old
+ new

@@ -1,60 +1,91 @@ class Importmap::Map attr_reader :files, :directories + attr_accessor :cached def initialize @files, @directories = {}, {} end def draw(&block) instance_eval(&block) end - def pin(name, to:) - @files[name] = to + def pin(name, to: nil, preload: true) + @files[name] = MappedFile.new(name: name, path: to || "#{name}.js", preload: preload) end - def pin_all_from(path, append_base_path: false) - @directories[path] = append_base_path + def pin_all_from(path, under: nil, preload: true) + @directories[path] = MappedDir.new(path: path, under: under, preload: preload) end - def to_json(resolver) - { "imports" => resolve_asset_paths(resolver) }.to_json + def preloaded_module_paths(resolver:) + cache_as(:preloaded_module_paths) do + resolve_asset_paths(expanded_preloading_files_and_directories, resolver: resolver).values + end end + def to_json(resolver:) + cache_as(:json) do + { "imports" => resolve_asset_paths(expanded_files_and_directories, resolver: resolver) }.to_json + end + end + private - def resolve_asset_paths(resolver) - expanded_files_and_directories.transform_values do |path| + MappedFile = Struct.new(:name, :path, :preload, keyword_init: true) + MappedDir = Struct.new(:path, :under, :preload, keyword_init: true) + + def cache_as(name) + if (cached && result = instance_variable_get("@cached_#{name}")) + result + else + instance_variable_set("@cached_#{name}", yield) + end + end + + def resolve_asset_paths(paths, resolver:) + paths.transform_values do |mapping| begin - resolver.asset_path(path) + resolver.asset_path(mapping.path) rescue Sprockets::Rails::Helper::AssetNotFound - Rails.logger.warn "Importmap skipped missing path: #{path}" + Rails.logger.warn "Importmap skipped missing path: #{mapping.path}" nil end end.compact end + def expanded_preloading_files_and_directories + expanded_files_and_directories.select { |name, mapping| mapping.preload } + end + def expanded_files_and_directories @files.dup.tap { |expanded| expand_directories_into expanded } end def expand_directories_into(paths) - @directories.each do |(path, append_base_path)| - if (absolute_path = absolute_root_of(path)).exist? + @directories.values.each do |mapping| + if (absolute_path = absolute_root_of(mapping.path)).exist? find_javascript_files_in_tree(absolute_path).each do |filename| module_filename = filename.relative_path_from(absolute_path) - module_name = module_name_from(module_filename) - module_path = append_base_path ? absolute_path.basename.join(module_filename).to_s : module_filename.to_s + module_name = module_name_from(module_filename, mapping.under) + module_path = mapping.under ? absolute_path.basename.join(module_filename).to_s : module_filename.to_s - paths[module_name] = module_path + paths[module_name] = MappedFile.new(name: module_name, path: module_path, preload: mapping.preload) end end end end # Strip off the extension, /index, or any versioning data for an absolute module name. - def module_name_from(filename) - filename.to_s.remove(filename.extname).remove("/index").split("@").first + def module_name_from(filename, under) + filename_without_ext = filename.to_s.remove(filename.extname) + + if filename_without_ext == "index" && under + under + else + module_name = filename_without_ext.split("@").first + under ? "#{under}/#{module_name}" : module_name + end end def find_javascript_files_in_tree(path) Dir[path.join("**/*.js{,m}")].collect { |file| Pathname.new(file) }.select(&:file?) end