pakyow-assets 1.0.0.rc5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/lib/pakyow/application/actions/assets/process.rb +65 -0
  4. data/lib/pakyow/application/actions/assets/public.rb +77 -0
  5. data/lib/pakyow/{assets → application}/behavior/assets.rb +2 -2
  6. data/lib/pakyow/application/behavior/assets/externals.rb +61 -0
  7. data/lib/pakyow/application/behavior/assets/packs.rb +164 -0
  8. data/lib/pakyow/application/behavior/assets/prelaunching.rb +21 -0
  9. data/lib/pakyow/application/behavior/assets/processing.rb +29 -0
  10. data/lib/pakyow/application/behavior/assets/silencing.rb +37 -0
  11. data/lib/pakyow/application/behavior/assets/watching.rb +27 -0
  12. data/lib/pakyow/{assets/behavior/config.rb → application/config/assets.rb} +3 -3
  13. data/lib/pakyow/assets.rb +3 -3
  14. data/lib/pakyow/assets/framework.rb +20 -20
  15. data/lib/pakyow/presenter/renderer/behavior/assets/install_assets.rb +41 -0
  16. data/lib/pakyow/{assets/tasks → tasks/assets}/precompile.rake +0 -0
  17. data/lib/pakyow/{assets/tasks → tasks/assets}/update.rake +0 -0
  18. metadata +28 -27
  19. data/lib/pakyow/actions/assets/process.rb +0 -63
  20. data/lib/pakyow/actions/assets/public.rb +0 -75
  21. data/lib/pakyow/assets/behavior/externals.rb +0 -59
  22. data/lib/pakyow/assets/behavior/packs.rb +0 -162
  23. data/lib/pakyow/assets/behavior/prelaunching.rb +0 -19
  24. data/lib/pakyow/assets/behavior/processing.rb +0 -27
  25. data/lib/pakyow/assets/behavior/rendering/install_assets.rb +0 -39
  26. data/lib/pakyow/assets/behavior/silencing.rb +0 -35
  27. data/lib/pakyow/assets/behavior/watching.rb +0 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c3f1a35dd0d09ca7a3d69237efe8e7025bf41950aaf4e71d451dd2cdf98b951
4
- data.tar.gz: 4699e827b358f61137c48b41518620d6bd9db2b5cad381e406138dc8fa28ce8f
3
+ metadata.gz: 7357562921c8d3675d55cbb3f8a4cfee62703be2f32ecad38812ade2e279df78
4
+ data.tar.gz: c93e8b3c23a969ea6fb01fb9771d593da48babad12d0844e3b14ea7ae15ab667
5
5
  SHA512:
6
- metadata.gz: 5b499aadd5fdc1429280b1b3f12d558880a106295c7930b4e14674d106b0efc07d17c862b507842712f5fa4edc9437b61d6cd5258d9334aa1be7d98f1bc0e772
7
- data.tar.gz: 42a7c1acf7c0f73902841fb13b1f71721626c8bfedb89c12500f6cfcb4c570bb6aeafe8b77bd217fa8c9316c61711c0a07598e4b22fb0e98525f5e1aa1a760e2
6
+ metadata.gz: 2d1fafecd727a1e6155a154ea95d1bad80d0b40399f1f8c7e73411d460990739bdae381d4e0800223d2839663aae8a18608616ea12ae1ddf211b5488d94251a9
7
+ data.tar.gz: 3eb3b99bf5d6d9e9eb28cd4a7462649f0e6424078d7b8b740917c0df87d4c17e95e32dbfacc8f5892aca5bb3e0db56a7b40be9fe6f497c8a4c699707c481fcee
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # UNRELEASED
2
+
3
+ # 1.0
4
+
5
+ * Hello, Web
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pakyow
4
+ class Application
5
+ module Actions
6
+ module Assets
7
+ # Pipeline Action that processes assets at request time.
8
+ #
9
+ # This is intended for development use, please don't use it in production.
10
+ # Instead, precompile assets into the public directory.
11
+ #
12
+ class Process
13
+ def call(connection)
14
+ if connection.app.config.assets.process
15
+ # TODO: can we short circuit if the request path doesn't match the connection?
16
+ if asset = find_asset(connection) || find_pack(connection) || find_asset_map(connection) || find_pack_map(connection)
17
+ connection.set_header("content-type", asset.mime_type)
18
+ connection.body = asset
19
+ connection.halt
20
+ end
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def find_asset(connection, path = connection.path)
27
+ connection.app.state(:asset).find { |asset|
28
+ asset.public_path == path
29
+ }
30
+ end
31
+
32
+ def find_pack(connection, path = connection.path)
33
+ connection.app.state(:pack).lazy.map { |pack|
34
+ pack.packed(path)
35
+ }.find { |packed| !packed.nil? && packed.any? }
36
+ end
37
+
38
+ def find_asset_map(connection)
39
+ if wants_map?(connection)
40
+ if (asset = find_asset(connection, unmapped(connection))) && asset.source_map?
41
+ asset.source_map
42
+ end
43
+ end
44
+ end
45
+
46
+ def find_pack_map(connection)
47
+ if (pack = find_pack(connection, unmapped(connection))) && pack.source_map?
48
+ pack.source_map
49
+ else
50
+ nil
51
+ end
52
+ end
53
+
54
+ def wants_map?(connection)
55
+ connection.path.end_with?(".map")
56
+ end
57
+
58
+ def unmapped(connection)
59
+ File.join(File.dirname(connection.path), File.basename(connection.path, ".map"))
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mini_mime"
4
+
5
+ require "pakyow/support/core_refinements/string/normalization"
6
+
7
+ module Pakyow
8
+ class Application
9
+ module Actions
10
+ module Assets
11
+ class Public
12
+ using Support::Refinements::String::Normalization
13
+
14
+ # Pipeline Action that serves files out of your public directory.
15
+ #
16
+ def initialize(app)
17
+ @asset_paths = app.state(:asset).map(&:public_path) + app.state(:pack).flat_map { |pack|
18
+ [pack.public_css_path, pack.public_js_path]
19
+ }
20
+
21
+ @prefix = if app.is_a?(Plugin)
22
+ Pathname.new(app.class.mount_path)
23
+ else
24
+ Pathname.new("/")
25
+ end
26
+ end
27
+
28
+ def call(connection)
29
+ if connection.app.config.assets.public
30
+ public_path = public_path(connection)
31
+
32
+ if public?(public_path)
33
+ if mime = MiniMime.lookup_by_filename(public_path)
34
+ connection.set_header("content-type", mime.content_type)
35
+ end
36
+
37
+ if connection.app.config.assets.cache && asset?(connection)
38
+ set_cache_headers(connection, public_path)
39
+ end
40
+
41
+ connection.body = File.open(public_path)
42
+ connection.halt
43
+ end
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def public?(path)
50
+ File.file?(path)
51
+ end
52
+
53
+ def public_path(connection)
54
+ File.join(
55
+ connection.app.config.assets.public_path,
56
+ String.normalize_path(
57
+ Pathname.new(connection.path).relative_path_from(@prefix).to_s
58
+ )
59
+ )
60
+ end
61
+
62
+ def asset?(connection)
63
+ @asset_paths.include?(connection.path)
64
+ end
65
+
66
+ def set_cache_headers(connection, public_path)
67
+ mtime = File.mtime(public_path)
68
+ connection.set_header("age", (Time.now - mtime).to_i.to_s)
69
+ connection.set_header("cache-control", "public, max-age=31536000")
70
+ connection.set_header("vary", "accept-encoding")
71
+ connection.set_header("last-modified", mtime.httpdate)
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -5,7 +5,7 @@ require "pakyow/support/extension"
5
5
  require "pakyow/assets/asset"
6
6
 
7
7
  module Pakyow
8
- module Assets
8
+ class Application
9
9
  module Behavior
10
10
  # Registers assets from the app's frontend/assets directory.
11
11
  #
@@ -27,7 +27,7 @@ module Pakyow
27
27
  "/"
28
28
  end
29
29
 
30
- self.class.asset << Asset.new_from_path(
30
+ self.class.asset << Pakyow::Assets::Asset.new_from_path(
31
31
  path,
32
32
  config: config.assets,
33
33
  source_location: assets_path,
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/extension"
4
+
5
+ require "pakyow/assets/external"
6
+
7
+ module Pakyow
8
+ class Application
9
+ module Behavior
10
+ module Assets
11
+ module Externals
12
+ extend Support::Extension
13
+
14
+ def external_script(name, version = nil, package: nil, files: nil)
15
+ assets_config = if is_a?(Plugin)
16
+ parent.config.assets
17
+ else
18
+ config.assets
19
+ end
20
+
21
+ assets_config.externals.scripts << Pakyow::Assets::External.new(
22
+ name, version: version, package: package, files: files, config: assets_config
23
+ )
24
+ end
25
+
26
+ apply_extension do
27
+ after "boot", "fetch.assets.externals" do
28
+ if config.assets.externals.pakyow
29
+ external_script :pakyow, "^1.0.0", package: "@pakyow/js", files: [
30
+ "dist/pakyow.js",
31
+ "dist/components/confirmable.js",
32
+ "dist/components/form.js",
33
+ "dist/components/freshener.js",
34
+ "dist/components/navigator.js",
35
+ "dist/components/socket.js",
36
+ "dist/components/submittable.js"
37
+ ]
38
+ end
39
+
40
+ if config.assets.externals.fetch
41
+ fetched = false
42
+
43
+ config.assets.externals.scripts.each do |external_script|
44
+ unless external_script.exist?
45
+ external_script.fetch!
46
+ fetched = true
47
+ end
48
+ end
49
+
50
+ if fetched
51
+ FileUtils.mkdir_p "./tmp"
52
+ FileUtils.touch "./tmp/restart.txt"
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,164 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/extension"
4
+
5
+ module Pakyow
6
+ class Application
7
+ module Behavior
8
+ module Assets
9
+ module Packs
10
+ extend Support::Extension
11
+
12
+ apply_extension do
13
+ after "initialize", "initialize.assets.packs", priority: :high do
14
+ config.assets.packs.paths.each do |packs_path|
15
+ Pathname.glob(File.join(packs_path, "*.*")).group_by { |path|
16
+ File.join(File.dirname(path), File.basename(path, File.extname(path)))
17
+ }.to_a.sort { |pack_a, pack_b|
18
+ pack_b[1] <=> pack_a[1]
19
+ }.uniq { |pack_path, _|
20
+ accessible_pack_path(pack_path)
21
+ }.map { |pack_path, pack_asset_paths|
22
+ [accessible_pack_path(pack_path), pack_asset_paths]
23
+ }.reverse.each do |pack_path, pack_asset_paths|
24
+ prefix = if is_a?(Plugin)
25
+ self.class.mount_path
26
+ else
27
+ "/"
28
+ end
29
+
30
+ asset_pack = Pakyow::Assets::Pack.new(File.basename(pack_path).to_sym, config.assets, prefix: prefix)
31
+
32
+ pack_asset_paths.each do |pack_asset_path|
33
+ if config.assets.extensions.include?(File.extname(pack_asset_path))
34
+ asset_pack << Pakyow::Assets::Asset.new_from_path(
35
+ pack_asset_path,
36
+ config: config.assets,
37
+ related: state(:asset)
38
+ )
39
+ end
40
+ end
41
+
42
+ self.pack << asset_pack.finalize
43
+ end
44
+ end
45
+
46
+ state(:templates).each do |template_store|
47
+ build_layout_packs(template_store)
48
+ build_page_packs(template_store)
49
+ end
50
+ end
51
+ end
52
+
53
+ def packs(view)
54
+ (autoloaded_packs + view_packs(view) + component_packs(view)).uniq.each_with_object([]) { |pack_name, packs|
55
+ if found_pack = state(:pack).find { |pack| pack.name == pack_name.to_sym }
56
+ packs << found_pack
57
+ end
58
+ }
59
+ end
60
+
61
+ private
62
+
63
+ def accessible_pack_path(pack_path)
64
+ pack_path_parts = pack_path.split("/")
65
+ pack_path_parts[-1] = if pack_path_parts[-1].include?("__")
66
+ pack_path_parts[-1].split("__", 2)[1]
67
+ elsif pack_path_parts[-1].include?("@")
68
+ pack_path_parts[-1].split("@", 2)[0]
69
+ else
70
+ pack_path_parts[-1]
71
+ end
72
+
73
+ pack_path_parts.join("/")
74
+ end
75
+
76
+ def autoloaded_packs
77
+ config.assets.packs.autoload
78
+ end
79
+
80
+ def view_packs(view)
81
+ view.info(:packs).to_a
82
+ end
83
+
84
+ def component_packs(view)
85
+ view.object.each_significant_node(:component, descend: true).flat_map { |node|
86
+ node.label(:components).map { |component|
87
+ component[:name]
88
+ }
89
+ }
90
+ end
91
+
92
+ def build_layout_packs(template_store)
93
+ template_store.layouts.each do |layout_name, layout|
94
+ layout_pack = Pakyow::Assets::Pack.new(:"layouts/#{layout_name}", config.assets)
95
+ register_pack_with_view(layout_pack, layout)
96
+
97
+ Pathname.glob(File.join(template_store.layouts_path, "#{layout_name}.*")) do |potential_asset_path|
98
+ next if template_store.template?(potential_asset_path)
99
+ layout_pack << Pakyow::Assets::Asset.new_from_path(
100
+ potential_asset_path,
101
+ config: config.assets,
102
+ related: state(:asset)
103
+ )
104
+ end
105
+
106
+ self.pack << layout_pack.finalize
107
+ end
108
+ end
109
+
110
+ def build_page_packs(template_store)
111
+ template_store.paths.each do |view_path|
112
+ template_info = template_store.info(view_path)
113
+
114
+ page_pack = Pakyow::Assets::Pack.new(:"#{template_info[:page].logical_path[1..-1]}", config.assets)
115
+ register_pack_with_view(page_pack, template_info[:page])
116
+
117
+ # Find all partials used by the page.
118
+ #
119
+ partials = template_info[:page].container_views.each_with_object([]) { |page_container, page_container_partials|
120
+ page_container_partials.concat(page_container.find_partials(template_info[:partials]))
121
+ } + template_info[:layout].find_partials(template_info[:partials])
122
+
123
+ # Include assets for partials used by the page into the page pack.
124
+ #
125
+ partials.each do |partial_name|
126
+ if partial = template_info[:partials][partial_name]
127
+ Pathname.glob(File.join(config.presenter.path, "#{partial.logical_path}.*")) do |potential_asset_path|
128
+ next if template_store.template?(potential_asset_path)
129
+ page_pack << Pakyow::Assets::Asset.new_from_path(
130
+ potential_asset_path,
131
+ config: config.assets,
132
+ related: state(:asset)
133
+ )
134
+ end
135
+ end
136
+ end
137
+
138
+ # Include assets defined for the page itself.
139
+ #
140
+ Pathname.glob(File.join(template_info[:page].path.dirname, "#{template_info[:page].path.basename(template_info[:page].path.extname)}.*")) do |potential_asset_path|
141
+ next if template_store.template?(potential_asset_path)
142
+ page_pack << Pakyow::Assets::Asset.new_from_path(
143
+ potential_asset_path,
144
+ config: config.assets,
145
+ related: state(:asset)
146
+ )
147
+ end
148
+
149
+ self.pack << page_pack.finalize
150
+ end
151
+ end
152
+
153
+ def register_pack_with_view(pack, view)
154
+ unless view.info(:packs)
155
+ view.add_info(packs: [])
156
+ end
157
+
158
+ view.info(:packs) << pack.name
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/extension"
4
+
5
+ module Pakyow
6
+ class Application
7
+ module Behavior
8
+ module Assets
9
+ module Prelaunching
10
+ extend Support::Extension
11
+
12
+ apply_extension do
13
+ on "configure" do
14
+ config.tasks.prelaunch << "assets:precompile"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/extension"
4
+
5
+ module Pakyow
6
+ class Application
7
+ module Behavior
8
+ module Assets
9
+ module Processing
10
+ extend Support::Extension
11
+
12
+ apply_extension do
13
+ on "load" do
14
+ if self.class.includes_framework?(:presenter)
15
+ self.class.processor :html do |content|
16
+ state(:asset).each do |asset|
17
+ content.gsub!(asset.logical_path, File.join(config.assets.host, asset.public_path))
18
+ end
19
+
20
+ content
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end