Class: Proscenium::Importer

Inherits:
ActiveSupport::CurrentAttributes
  • Object
show all
Defined in:
lib/proscenium/importer.rb

Constant Summary collapse

JS_EXTENSIONS =
%w[.tsx .ts .jsx .js].freeze
CSS_EXTENSIONS =
%w[.module.css .css].freeze

Class Method Summary collapse

Class Method Details

.css_imported?Boolean

Returns:

  • (Boolean)


121
122
123
# File 'lib/proscenium/importer.rb', line 121

def css_imported?
  imported&.keys&.any? { |x| x.end_with?(*CSS_EXTENSIONS) }
end

.each_javascript(delete: false) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/proscenium/importer.rb', line 109

def each_javascript(delete: false)
  return if imported.blank?

  blk = proc do |key, options|
    if key.end_with?(*JS_EXTENSIONS)
      yield(key, options)
      true
    end
  end
  delete ? imported.delete_if(&blk) : imported.each(&blk)
end

.each_stylesheet(delete: false) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/proscenium/importer.rb', line 96

def each_stylesheet(delete: false)
  return if imported.blank?

  blk = proc do |key, options|
    if key.end_with?(*CSS_EXTENSIONS)
      yield(key, options)
      true
    end
  end

  delete ? imported.delete_if(&blk) : imported.each(&blk)
end

.import(filepath = nil, resolve: nil) ⇒ String

Import the given ‘filepath`. This is idempotent - it will never include duplicates.

Parameters:

  • filepath (String) (defaults to: nil)

    Absolute URL path (relative to Rails root) of the file to import. Should be the actual asset file, eg. app.css, some/component.js.

  • resolve (String) (defaults to: nil)

    description of the file to resolve and import.

Returns:

  • (String)

    the digest of the imported file path if a css module (*.module.css).



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/proscenium/importer.rb', line 28

def import(filepath = nil, resolve: nil, **)
  self.imported ||= {}

  filepath = Resolver.resolve(resolve) if !filepath && resolve
  css_module = filepath.end_with?('.module.css')

  unless self.imported.key?(filepath)
    # ActiveSupport::Notifications.instrument('sideload.proscenium', identifier: value)

    self.imported[filepath] = { ** }
    self.imported[filepath][:digest] = Utils.digest(filepath) if css_module
  end

  css_module ? self.imported[filepath][:digest] : nil
end

.imported?(filepath = nil) ⇒ Boolean

Returns:

  • (Boolean)


129
130
131
# File 'lib/proscenium/importer.rb', line 129

def imported?(filepath = nil)
  filepath ? imported&.key?(filepath) : !imported.blank?
end

.js_imported?Boolean

Returns:

  • (Boolean)


125
126
127
# File 'lib/proscenium/importer.rb', line 125

def js_imported?
  imported&.keys&.any? { |x| x.end_with?(*JS_EXTENSIONS) }
end

.sideload(filepath, **options) ⇒ Object

Sideloads JS and CSS assets for the given Ruby filepath.

Any files with the same base name and matching a supported extension will be sideloaded. Only one JS and one CSS file will be sideloaded, with the first match used in the following order:

- JS extensions: .tsx, .ts, .jsx, and .js.
- CSS extensions: .css.module, and .css.

Example:

- `app/views/layouts/application.rb`
- `app/views/layouts/application.css`
- `app/views/layouts/application.js`
- `app/views/layouts/application.tsx`

A request to sideload ‘app/views/layouts/application.rb` will result in `application.css` and `application.tsx` being sideloaded. `application.js` will not be sideloaded because the `.tsx` extension is matched first.

Parameters:

  • filepath (Pathname)

    Absolute file system path of the Ruby file to sideload.



63
64
65
66
67
68
# File 'lib/proscenium/importer.rb', line 63

def sideload(filepath, **options)
  return if !Proscenium.config.side_load || (options[:js] == false && options[:css] == false)

  sideload_js(filepath, **options) unless options[:js] == false
  sideload_css(filepath, **options) unless options[:css] == false
end

.sideload_css(filepath, **options) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/proscenium/importer.rb', line 83

def sideload_css(filepath, **options)
  return unless Proscenium.config.side_load

  filepath = Rails.root.join(filepath) unless filepath.is_a?(Pathname)
  filepath = filepath.sub_ext('')

  CSS_EXTENSIONS.find do |x|
    if (fp = filepath.sub_ext(x)).exist?
      import(Resolver.resolve(fp.to_s), sideloaded: true, **options)
    end
  end
end

.sideload_js(filepath, **options) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/proscenium/importer.rb', line 70

def sideload_js(filepath, **options)
  return unless Proscenium.config.side_load

  filepath = Rails.root.join(filepath) unless filepath.is_a?(Pathname)
  filepath = filepath.sub_ext('')

  JS_EXTENSIONS.find do |x|
    if (fp = filepath.sub_ext(x)).exist?
      import(Resolver.resolve(fp.to_s), sideloaded: true, **options)
    end
  end
end