isomorfeus-asset-manager 0.12.3 → 0.12.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/lib/isomorfeus/asset_manager/asset.rb +25 -0
 - data/lib/isomorfeus/asset_manager/config.rb +8 -2
 - data/lib/isomorfeus/asset_manager/rack_middleware.rb +53 -49
 - data/lib/isomorfeus/asset_manager/server_socket_processor.rb +21 -55
 - data/lib/isomorfeus/asset_manager/version.rb +1 -1
 - data/lib/isomorfeus/asset_manager.rb +55 -19
 - data/lib/isomorfeus-asset-manager.rb +3 -0
 - data/node_modules/.package-lock.json +3 -3
 - data/node_modules/esbuild-wasm/esbuild.wasm +0 -0
 - data/node_modules/esbuild-wasm/esm/browser.d.ts +19 -0
 - data/node_modules/esbuild-wasm/esm/browser.js +43 -5
 - data/node_modules/esbuild-wasm/esm/browser.min.js +7 -7
 - data/node_modules/esbuild-wasm/lib/browser.d.ts +19 -0
 - data/node_modules/esbuild-wasm/lib/browser.js +43 -5
 - data/node_modules/esbuild-wasm/lib/browser.min.js +13 -5
 - data/node_modules/esbuild-wasm/lib/main.d.ts +19 -0
 - data/node_modules/esbuild-wasm/lib/main.js +85 -16
 - data/node_modules/esbuild-wasm/package.json +1 -1
 - data/package.json +1 -1
 - metadata +34 -6
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 6f2bba888a2b50846a6384f6b5a04036b3e5e7e9e367f867b4cb23996ceb8ba1
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 2ef547ce6fb466c561b1c4964d561c2c5612a2a641179b1dfdb33f555142f6b0
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 5b65f19ea35eb669fc45e946afe44b7da36b75910d28b69c4f9fdd9657f23c446c0f22e5fb505bf78755537428f91dcddd391edd4d818f9cabc8b2b3ca115e68
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 7acea3a93903a46f1d59ae45f83617c619812836015c58bbbab9b7ebf1e24c21708b013021eb1898ab9cfcdafaf991ae0f821db6dddbd256097a170118a0a133
         
     | 
| 
         @@ -63,6 +63,31 @@ module Isomorfeus 
     | 
|
| 
       63 
63 
     | 
    
         
             
                    end
         
     | 
| 
       64 
64 
     | 
    
         
             
                    js << "\n" if !@js_imports.empty? && !@ruby_imports.empty?
         
     | 
| 
       65 
65 
     | 
    
         
             
                    unless @ruby_imports.empty?
         
     | 
| 
      
 66 
     | 
    
         
            +
                      if Isomorfeus.development? && @target == :browser
         
     | 
| 
      
 67 
     | 
    
         
            +
                        js << <<~JAVASCRIPT
         
     | 
| 
      
 68 
     | 
    
         
            +
                        // Isomorfeus Asset Manager HMR code begin
         
     | 
| 
      
 69 
     | 
    
         
            +
                        let ws_protocol = (window.location.protocol == 'https:') ? 'wss:' : 'ws:';
         
     | 
| 
      
 70 
     | 
    
         
            +
                        let ws_url = ws_protocol + '//' + window.location.host + "#{Isomorfeus.assets_websocket_path}";
         
     | 
| 
      
 71 
     | 
    
         
            +
                        let hmr_ws = new WebSocket(ws_url);
         
     | 
| 
      
 72 
     | 
    
         
            +
                        hmr_ws.onmessage = function(event) {
         
     | 
| 
      
 73 
     | 
    
         
            +
                          let update = JSON.parse(event.data);
         
     | 
| 
      
 74 
     | 
    
         
            +
                          if (typeof update.error !== 'undefined') { console.error(update.error); return; }
         
     | 
| 
      
 75 
     | 
    
         
            +
                          let start_index = '/* Generated by Opal 1.2.0 */\\nOpal.modules[\\"'.length;
         
     | 
| 
      
 76 
     | 
    
         
            +
                          let end_index = update.javascript.indexOf('"', start_index);
         
     | 
| 
      
 77 
     | 
    
         
            +
                          let opal_module_name = update.javascript.substr(start_index, end_index - start_index);
         
     | 
| 
      
 78 
     | 
    
         
            +
                          console.log('Updating ', opal_module_name);
         
     | 
| 
      
 79 
     | 
    
         
            +
                          if (typeof Opal !== 'undefined' && typeof Opal.require_table !== "undefined" && Opal.require_table['corelib/module']) {
         
     | 
| 
      
 80 
     | 
    
         
            +
                            try {
         
     | 
| 
      
 81 
     | 
    
         
            +
                              eval(update.javascript);
         
     | 
| 
      
 82 
     | 
    
         
            +
                              if (Opal.require_table[opal_module_name]) { Opal.load.call(Opal, opal_module_name); } 
         
     | 
| 
      
 83 
     | 
    
         
            +
                              else { Opal.require.call(Opal, opal_module_name); }
         
     | 
| 
      
 84 
     | 
    
         
            +
                              Opal.Isomorfeus.$force_render();
         
     | 
| 
      
 85 
     | 
    
         
            +
                            } catch (e) { console.error(e); return; }
         
     | 
| 
      
 86 
     | 
    
         
            +
                          }
         
     | 
| 
      
 87 
     | 
    
         
            +
                        }
         
     | 
| 
      
 88 
     | 
    
         
            +
                        // Isomorfeus Asset Manager HMR code end
         
     | 
| 
      
 89 
     | 
    
         
            +
                        JAVASCRIPT
         
     | 
| 
      
 90 
     | 
    
         
            +
                      end
         
     | 
| 
       66 
91 
     | 
    
         
             
                      js << "#{@ruby_imports.map(&:to_s).join("\n")}"
         
     | 
| 
       67 
92 
     | 
    
         
             
                    end
         
     | 
| 
       68 
93 
     | 
    
         
             
                    js
         
     | 
| 
         @@ -1,18 +1,20 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Isomorfeus
         
     | 
| 
       2 
2 
     | 
    
         
             
              # available settings
         
     | 
| 
       3 
3 
     | 
    
         
             
              if RUBY_ENGINE == 'opal'
         
     | 
| 
       4 
     | 
    
         
            -
                add_client_option(:assets_websocket_path)
         
     | 
| 
       5 
4 
     | 
    
         
             
                add_client_option(:assets_path)
         
     | 
| 
       6 
     | 
    
         
            -
                add_client_option(:opal_assets_path)
         
     | 
| 
       7 
5 
     | 
    
         
             
              else
         
     | 
| 
       8 
6 
     | 
    
         
             
                class << self
         
     | 
| 
       9 
7 
     | 
    
         
             
                  attr_reader :env
         
     | 
| 
       10 
8 
     | 
    
         
             
                  attr_accessor :root
         
     | 
| 
       11 
9 
     | 
    
         
             
                  attr_accessor :app_root
         
     | 
| 
       12 
10 
     | 
    
         
             
                  attr_accessor :assets_path
         
     | 
| 
      
 11 
     | 
    
         
            +
                  attr_accessor :assets_websocket_path 
         
     | 
| 
       13 
12 
     | 
    
         
             
                  attr_accessor :asset_manager_tmpdir
         
     | 
| 
      
 13 
     | 
    
         
            +
                  attr_accessor :asset_manager_hmr_channel
         
     | 
| 
      
 14 
     | 
    
         
            +
                  attr_accessor :asset_manager_hmr_dirs
         
     | 
| 
       14 
15 
     | 
    
         
             
                  attr_accessor :node_paths
         
     | 
| 
       15 
16 
     | 
    
         
             
                  attr_accessor :assets
         
     | 
| 
      
 17 
     | 
    
         
            +
                  attr_accessor :hmr_listener
         
     | 
| 
       16 
18 
     | 
    
         | 
| 
       17 
19 
     | 
    
         
             
                  def add_web_js_import(*args)
         
     | 
| 
       18 
20 
     | 
    
         
             
                    Isomorfeus.assets['web.js'].add_js_import(*args)
         
     | 
| 
         @@ -62,6 +64,10 @@ module Isomorfeus 
     | 
|
| 
       62 
64 
     | 
    
         
             
                end
         
     | 
| 
       63 
65 
     | 
    
         
             
              end
         
     | 
| 
       64 
66 
     | 
    
         | 
| 
      
 67 
     | 
    
         
            +
              self.hmr_listener = nil
         
     | 
| 
      
 68 
     | 
    
         
            +
              self.asset_manager_hmr_channel = :isomorfeus_asset_manager_module_updates
         
     | 
| 
      
 69 
     | 
    
         
            +
              self.asset_manager_hmr_dirs = %w[channels, components, data, operations, policies]
         
     | 
| 
      
 70 
     | 
    
         
            +
              self.assets_websocket_path = '/_assets_websocket'
         
     | 
| 
       65 
71 
     | 
    
         
             
              self.assets_path = '/assets'
         
     | 
| 
       66 
72 
     | 
    
         
             
              self.assets = {
         
     | 
| 
       67 
73 
     | 
    
         
             
                'web.js' => Isomorfeus::AssetManager::Asset.new(:browser),
         
     | 
| 
         @@ -3,10 +3,11 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module Isomorfeus
         
     | 
| 
       4 
4 
     | 
    
         
             
              class AssetManager
         
     | 
| 
       5 
5 
     | 
    
         
             
                class RackMiddleware
         
     | 
| 
       6 
     | 
    
         
            -
                  WS_RESPONSE = [0, {}, []]
         
     | 
| 
      
 6 
     | 
    
         
            +
                  WS_RESPONSE = [0, {}, []].freeze
         
     | 
| 
       7 
7 
     | 
    
         
             
                  attr_reader :asset_manager
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
                  def initialize(app)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    STDERR.puts "asset manager"
         
     | 
| 
       10 
11 
     | 
    
         
             
                    @app = app
         
     | 
| 
       11 
12 
     | 
    
         
             
                    @asset_manager = Isomorfeus::AssetManager.new
         
     | 
| 
       12 
13 
     | 
    
         
             
                    @compressible_types = %w[application/javascript text/javascript]
         
     | 
| 
         @@ -17,67 +18,70 @@ module Isomorfeus 
     | 
|
| 
       17 
18 
     | 
    
         
             
                      @assets_path = Isomorfeus.assets_path + '/'
         
     | 
| 
       18 
19 
     | 
    
         
             
                      @assets_path_size = @assets_path.size
         
     | 
| 
       19 
20 
     | 
    
         
             
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  rescue Exception => e
         
     | 
| 
      
 22 
     | 
    
         
            +
                    STDERR.puts "#{e.message}\n#{e.backtrace.join("\n")}\n"
         
     | 
| 
       20 
23 
     | 
    
         
             
                  end
         
     | 
| 
       21 
24 
     | 
    
         | 
| 
       22 
25 
     | 
    
         
             
                  def call(env)
         
     | 
| 
       23 
     | 
    
         
            -
                     
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                       
     | 
| 
       26 
     | 
    
         
            -
                        asset_key = path_info[@assets_path_size..-1]
         
     | 
| 
      
 26 
     | 
    
         
            +
                    path_info = env['PATH_INFO']
         
     | 
| 
      
 27 
     | 
    
         
            +
                    if path_info.start_with?(@assets_path)
         
     | 
| 
      
 28 
     | 
    
         
            +
                      asset_key = path_info[@assets_path_size..-1]
         
     | 
| 
       27 
29 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                          end
         
     | 
| 
       45 
     | 
    
         
            -
                        
         
     | 
| 
       46 
     | 
    
         
            -
                        # get source map
         
     | 
| 
       47 
     | 
    
         
            -
                        elsif asset_key.end_with?('.js.map')
         
     | 
| 
       48 
     | 
    
         
            -
                          asset = Isomorfeus.assets[asset_key[0..-5]]
         
     | 
| 
       49 
     | 
    
         
            -
                          if asset && asset.target != :node
         
     | 
| 
       50 
     | 
    
         
            -
                            asset_manager.transition(asset_key, asset) unless asset.bundled?
         
     | 
| 
       51 
     | 
    
         
            -
                            headers = {}
         
     | 
| 
       52 
     | 
    
         
            -
                            headers['Last-Modified'] = asset.mtime
         
     | 
| 
       53 
     | 
    
         
            -
                            headers[Rack::CONTENT_TYPE] = 'application/json'
         
     | 
| 
       54 
     | 
    
         
            -
                            if should_gzip?(env)
         
     | 
| 
       55 
     | 
    
         
            -
                              headers['Content-Encoding'] = "gzip"
         
     | 
| 
       56 
     | 
    
         
            -
                              headers[Rack::CONTENT_LENGTH] = asset.bundle_map_gz.size
         
     | 
| 
       57 
     | 
    
         
            -
                              return [200, headers, asset.bundle_map_gz]
         
     | 
| 
       58 
     | 
    
         
            -
                            else
         
     | 
| 
       59 
     | 
    
         
            -
                              headers[Rack::CONTENT_LENGTH] = asset.bundle_map.size
         
     | 
| 
       60 
     | 
    
         
            -
                              return [200, {}, asset.bundle_map]
         
     | 
| 
       61 
     | 
    
         
            -
                            end 
         
     | 
| 
       62 
     | 
    
         
            -
                          end
         
     | 
| 
      
 30 
     | 
    
         
            +
                      # get js
         
     | 
| 
      
 31 
     | 
    
         
            +
                      if Isomorfeus.assets.key?(asset_key)
         
     | 
| 
      
 32 
     | 
    
         
            +
                        asset = Isomorfeus.assets[asset_key]
         
     | 
| 
      
 33 
     | 
    
         
            +
                        if asset && asset.target != :node
         
     | 
| 
      
 34 
     | 
    
         
            +
                          asset_manager.transition(asset_key, asset)
         
     | 
| 
      
 35 
     | 
    
         
            +
                          headers = {}
         
     | 
| 
      
 36 
     | 
    
         
            +
                          headers['Last-Modified'] = asset.mtime
         
     | 
| 
      
 37 
     | 
    
         
            +
                          headers[Rack::CONTENT_TYPE] = 'application/javascript'
         
     | 
| 
      
 38 
     | 
    
         
            +
                          if should_gzip?(env)
         
     | 
| 
      
 39 
     | 
    
         
            +
                            headers['Content-Encoding'] = "gzip"
         
     | 
| 
      
 40 
     | 
    
         
            +
                            headers[Rack::CONTENT_LENGTH] = asset.bundle_gz_size
         
     | 
| 
      
 41 
     | 
    
         
            +
                            return [200, headers, asset.bundle_gz]
         
     | 
| 
      
 42 
     | 
    
         
            +
                          else
         
     | 
| 
      
 43 
     | 
    
         
            +
                            headers[Rack::CONTENT_LENGTH] = asset.bundle_size
         
     | 
| 
      
 44 
     | 
    
         
            +
                            return [200, {}, asset.bundle]
         
     | 
| 
      
 45 
     | 
    
         
            +
                          end              
         
     | 
| 
       63 
46 
     | 
    
         
             
                        end
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
                         
     | 
| 
       68 
     | 
    
         
            -
                         
     | 
| 
      
 47 
     | 
    
         
            +
                      
         
     | 
| 
      
 48 
     | 
    
         
            +
                      # get source map
         
     | 
| 
      
 49 
     | 
    
         
            +
                      elsif asset_key.end_with?('.js.map')
         
     | 
| 
      
 50 
     | 
    
         
            +
                        asset = Isomorfeus.assets[asset_key[0..-5]]
         
     | 
| 
      
 51 
     | 
    
         
            +
                        if asset && asset.target != :node
         
     | 
| 
      
 52 
     | 
    
         
            +
                          asset_manager.transition(asset_key, asset) unless asset.bundled?
         
     | 
| 
      
 53 
     | 
    
         
            +
                          headers = {}
         
     | 
| 
      
 54 
     | 
    
         
            +
                          headers['Last-Modified'] = asset.mtime
         
     | 
| 
      
 55 
     | 
    
         
            +
                          headers[Rack::CONTENT_TYPE] = 'application/json'
         
     | 
| 
      
 56 
     | 
    
         
            +
                          if should_gzip?(env)
         
     | 
| 
      
 57 
     | 
    
         
            +
                            headers['Content-Encoding'] = "gzip"
         
     | 
| 
      
 58 
     | 
    
         
            +
                            headers[Rack::CONTENT_LENGTH] = asset.bundle_map_gz.size
         
     | 
| 
      
 59 
     | 
    
         
            +
                            return [200, headers, asset.bundle_map_gz]
         
     | 
| 
      
 60 
     | 
    
         
            +
                          else
         
     | 
| 
      
 61 
     | 
    
         
            +
                            headers[Rack::CONTENT_LENGTH] = asset.bundle_map.size
         
     | 
| 
      
 62 
     | 
    
         
            +
                            return [200, {}, asset.bundle_map]
         
     | 
| 
      
 63 
     | 
    
         
            +
                          end 
         
     | 
| 
      
 64 
     | 
    
         
            +
                        end
         
     | 
| 
      
 65 
     | 
    
         
            +
                      end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                    # hot reloading subscription
         
     | 
| 
      
 68 
     | 
    
         
            +
                    elsif Isomorfeus.development? && path_info == Isomorfeus.assets_websocket_path
         
     | 
| 
      
 69 
     | 
    
         
            +
                      if env['rack.upgrade?'] == :websocket
         
     | 
| 
      
 70 
     | 
    
         
            +
                        env['rack.upgrade'] = Isomorfeus::AssetManager::ServerSocketProcessor.new
         
     | 
| 
       69 
71 
     | 
    
         
             
                      end
         
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
      
 72 
     | 
    
         
            +
                      WS_RESPONSE
         
     | 
| 
      
 73 
     | 
    
         
            +
                    else
         
     | 
| 
       72 
74 
     | 
    
         
             
                      @app.call(env)
         
     | 
| 
       73 
75 
     | 
    
         
             
                    end
         
     | 
| 
      
 76 
     | 
    
         
            +
                  rescue Exception => e
         
     | 
| 
      
 77 
     | 
    
         
            +
                    STDERR.puts "#{e.message}\n#{e.backtrace.join("\n")}\n"
         
     | 
| 
       74 
78 
     | 
    
         
             
                    @app.call(env)
         
     | 
| 
       75 
79 
     | 
    
         
             
                  end
         
     | 
| 
       76 
80 
     | 
    
         | 
| 
       77 
81 
     | 
    
         
             
                  def should_gzip?(env)
         
     | 
| 
       78 
     | 
    
         
            -
                    return true if env. 
     | 
| 
      
 82 
     | 
    
         
            +
                    return true if env.key?('HTTP_ACCEPT_ENCODING') && env['HTTP_ACCEPT_ENCODING'].match?(/\bgzip\b/)
         
     | 
| 
       79 
83 
     | 
    
         
             
                    return false if /\bno-transform\b/.match?(env[Rack::CACHE_CONTROL].to_s) || env['Content-Encoding']&.!~(/\bidentity\b/)
         
     | 
| 
       80 
     | 
    
         
            -
                    return false if @compressible_types && !(env. 
     | 
| 
      
 84 
     | 
    
         
            +
                    return false if @compressible_types && !(env.key?(Rack::CONTENT_TYPE) && @compressible_types.include?(env[Rack::CONTENT_TYPE][/[^;]*/]))
         
     | 
| 
       81 
85 
     | 
    
         
             
                    true
         
     | 
| 
       82 
86 
     | 
    
         
             
                  end
         
     | 
| 
       83 
87 
     | 
    
         
             
                end
         
     | 
| 
         @@ -1,55 +1,21 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module Isomorfeus
         
     | 
| 
       2 
     | 
    
         
            -
              class AssetManager
         
     | 
| 
       3 
     | 
    
         
            -
                class ServerSocketProcessor
         
     | 
| 
       4 
     | 
    
         
            -
                   
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
                   
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
                   
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
                   
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                   
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                   
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
                   
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                   
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                  #   handler_instance_cache.each_value do |handler|
         
     | 
| 
       23 
     | 
    
         
            -
                  #     handler.resolve if handler.resolving?
         
     | 
| 
       24 
     | 
    
         
            -
                  #   end
         
     | 
| 
       25 
     | 
    
         
            -
                  #   result = {}
         
     | 
| 
       26 
     | 
    
         
            -
                  #   response_agent_array.each do |response_agent|
         
     | 
| 
       27 
     | 
    
         
            -
                  #     result.deep_merge!(response_agent.result)
         
     | 
| 
       28 
     | 
    
         
            -
                  #   end
         
     | 
| 
       29 
     | 
    
         
            -
                  #   client.write Oj.dump(result, mode: :strict) unless result.empty?
         
     | 
| 
       30 
     | 
    
         
            -
                  # ensure
         
     | 
| 
       31 
     | 
    
         
            -
                  #   Thread.current[:isomorfeus_user] = nil
         
     | 
| 
       32 
     | 
    
         
            -
                  #   Thread.current[:isomorfeus_pub_sub_client] = nil
         
     | 
| 
       33 
     | 
    
         
            -
                  #   Isomorfeus.zeitwerk_lock.release_read_lock if Isomorfeus.development?
         
     | 
| 
       34 
     | 
    
         
            -
                  # end
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                  # def on_close(client)
         
     | 
| 
       37 
     | 
    
         
            -
                  #   # nothing for now
         
     | 
| 
       38 
     | 
    
         
            -
                  # end
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                  # def on_open(client)
         
     | 
| 
       41 
     | 
    
         
            -
                  #   # nothing for now
         
     | 
| 
       42 
     | 
    
         
            -
                  # end
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                  # def on_shutdown(client)
         
     | 
| 
       45 
     | 
    
         
            -
                  #   # nothing for now
         
     | 
| 
       46 
     | 
    
         
            -
                  # end
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                  # def user(client)
         
     | 
| 
       49 
     | 
    
         
            -
                  #   current_user = client.instance_variable_get(:@isomorfeus_user)
         
     | 
| 
       50 
     | 
    
         
            -
                  #   return current_user if current_user
         
     | 
| 
       51 
     | 
    
         
            -
                  #   Anonymous.new
         
     | 
| 
       52 
     | 
    
         
            -
                  # end
         
     | 
| 
       53 
     | 
    
         
            -
                end
         
     | 
| 
       54 
     | 
    
         
            -
              end
         
     | 
| 
       55 
     | 
    
         
            -
            end
         
     | 
| 
      
 1 
     | 
    
         
            +
            module Isomorfeus
         
     | 
| 
      
 2 
     | 
    
         
            +
              class AssetManager
         
     | 
| 
      
 3 
     | 
    
         
            +
                class ServerSocketProcessor
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def on_message(client, data)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    # nothing for now
         
     | 
| 
      
 6 
     | 
    
         
            +
                  end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def on_close(client)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    # client.unsubscribe Isomorfeus.asset_manager_hmr_channel
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  def on_open(client)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    client.subscribe Isomorfeus.asset_manager_hmr_channel
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def on_shutdown(client)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    # nothing for now
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -8,6 +8,7 @@ module Isomorfeus 
     | 
|
| 
       8 
8 
     | 
    
         
             
                  @output_path = File.join(@tmpdir, 'output')
         
     | 
| 
       9 
9 
     | 
    
         
             
                  FileUtils.mkdir_p(@imports_path)
         
     | 
| 
       10 
10 
     | 
    
         
             
                  FileUtils.mkdir_p(@output_path)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @server_path = File.join(Isomorfeus.app_root, 'server')
         
     | 
| 
       11 
12 
     | 
    
         | 
| 
       12 
13 
     | 
    
         
             
                  @context = ExecJS.permissive_compile(init_js)
         
     | 
| 
       13 
14 
     | 
    
         | 
| 
         @@ -20,16 +21,18 @@ module Isomorfeus 
     | 
|
| 
       20 
21 
     | 
    
         
             
                    ssr_imports_file = File.join(imports_path, 'ssr.js')
         
     | 
| 
       21 
22 
     | 
    
         
             
                    Isomorfeus.add_ssr_js_import(ssr_imports_file) if File.exist?(ssr_imports_file)
         
     | 
| 
       22 
23 
     | 
    
         
             
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  init_hmr_listener if Isomorfeus.development? && !Isomorfeus.hmr_listener
         
     | 
| 
       23 
26 
     | 
    
         
             
                end
         
     | 
| 
       24 
27 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
                def transition(asset_key, asset)
         
     | 
| 
      
 28 
     | 
    
         
            +
                def transition(asset_key, asset, analyze: false)
         
     | 
| 
       26 
29 
     | 
    
         
             
                  return if !Isomorfeus.development? && asset.bundled?
         
     | 
| 
       27 
30 
     | 
    
         
             
                  asset.mutex.synchronize do
         
     | 
| 
       28 
31 
     | 
    
         
             
                    return if !Isomorfeus.development? && asset.bundled?
         
     | 
| 
       29 
32 
     | 
    
         
             
                    asset.touch
         
     | 
| 
       30 
     | 
    
         
            -
                     
     | 
| 
      
 33 
     | 
    
         
            +
                    build_ruby_and_save(asset_key, asset)
         
     | 
| 
       31 
34 
     | 
    
         
             
                    save_imports(asset_key, asset)
         
     | 
| 
       32 
     | 
    
         
            -
                    run_esbuild(asset_key, asset)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    run_esbuild(asset_key, asset, analyze)
         
     | 
| 
       33 
36 
     | 
    
         
             
                    asset.bundle = bundled_asset(asset_key)
         
     | 
| 
       34 
37 
     | 
    
         
             
                    asset.bundle_map = bundled_asset_map(asset_key) unless Isomorfeus.production?
         
     | 
| 
       35 
38 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -49,12 +52,12 @@ module Isomorfeus 
     | 
|
| 
       49 
52 
     | 
    
         
             
                  File.write(File.join(@imports_path, asset_key), asset.to_s)
         
     | 
| 
       50 
53 
     | 
    
         
             
                end
         
     | 
| 
       51 
54 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
                def  
     | 
| 
      
 55 
     | 
    
         
            +
                def build_ruby_and_save(asset_key, asset)
         
     | 
| 
       53 
56 
     | 
    
         
             
                  asset.ruby_imports.each do |ruby_import|
         
     | 
| 
       54 
57 
     | 
    
         
             
                    out_file = File.join(@imports_path, ruby_import.module_name + '.js')
         
     | 
| 
       55 
58 
     | 
    
         
             
                    next if !Isomorfeus.development? && File.exist?(out_file)
         
     | 
| 
       56 
59 
     | 
    
         
             
                    js_map_path = File.join(@imports_path, ruby_import.module_name + '.js.map')
         
     | 
| 
       57 
     | 
    
         
            -
                    result = Opal::Builder.build(ruby_import.resolved_path, {  
     | 
| 
      
 60 
     | 
    
         
            +
                    result = Opal::Builder.build(ruby_import.resolved_path, { esm: true })
         
     | 
| 
       58 
61 
     | 
    
         
             
                    FileUtils.mkdir_p(File.join(*[@imports_path].concat(ruby_import.module_name.split('/')[0...-1]))) if ruby_import.module_name.include?('/')
         
     | 
| 
       59 
62 
     | 
    
         
             
                    js = result.to_s
         
     | 
| 
       60 
63 
     | 
    
         
             
                    unless Isomorfeus.production?
         
     | 
| 
         @@ -65,6 +68,13 @@ module Isomorfeus 
     | 
|
| 
       65 
68 
     | 
    
         
             
                  end
         
     | 
| 
       66 
69 
     | 
    
         
             
                end
         
     | 
| 
       67 
70 
     | 
    
         | 
| 
      
 71 
     | 
    
         
            +
                def compile_ruby(file)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  source = File.read(file)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  module_file = file[(Isomorfeus.app_root.size + 1)..-1]
         
     | 
| 
      
 74 
     | 
    
         
            +
                  compiler = Opal::Compiler.new(source, requirable: true, file: module_file)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  { javascript: compiler.compile }
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
       68 
78 
     | 
    
         
             
                def print_message(m, level)
         
     | 
| 
       69 
79 
     | 
    
         
             
                  l = m['location']
         
     | 
| 
       70 
80 
     | 
    
         
             
                  STDERR.puts "#{l['file']}:#{l['line']}:#{l['column']}: #{level}: #{m['text']}"
         
     | 
| 
         @@ -72,17 +82,6 @@ module Isomorfeus 
     | 
|
| 
       72 
82 
     | 
    
         
             
                end
         
     | 
| 
       73 
83 
     | 
    
         | 
| 
       74 
84 
     | 
    
         
             
                def handle_errors(asset_key, result)
         
     | 
| 
       75 
     | 
    
         
            -
                  # Todo simplify
         
     | 
| 
       76 
     | 
    
         
            -
                  unless result['warnings'].empty?
         
     | 
| 
       77 
     | 
    
         
            -
                    result['warnings'].each do |w|
         
     | 
| 
       78 
     | 
    
         
            -
                      print_message(w, 'warning')
         
     | 
| 
       79 
     | 
    
         
            -
                      unless w['notes'].empty?
         
     | 
| 
       80 
     | 
    
         
            -
                        w['notes'].each do |n|
         
     | 
| 
       81 
     | 
    
         
            -
                          print_message(n, 'note')
         
     | 
| 
       82 
     | 
    
         
            -
                        end
         
     | 
| 
       83 
     | 
    
         
            -
                      end
         
     | 
| 
       84 
     | 
    
         
            -
                    end
         
     | 
| 
       85 
     | 
    
         
            -
                  end
         
     | 
| 
       86 
85 
     | 
    
         
             
                  unless result['errors'].empty?
         
     | 
| 
       87 
86 
     | 
    
         
             
                    result['errors'].each do |e|
         
     | 
| 
       88 
87 
     | 
    
         
             
                      print_message(w, 'error')
         
     | 
| 
         @@ -92,7 +91,7 @@ module Isomorfeus 
     | 
|
| 
       92 
91 
     | 
    
         
             
                        end
         
     | 
| 
       93 
92 
     | 
    
         
             
                      end
         
     | 
| 
       94 
93 
     | 
    
         
             
                    end
         
     | 
| 
       95 
     | 
    
         
            -
                    raise " 
     | 
| 
      
 94 
     | 
    
         
            +
                    raise "Asset Manager: error bundling '#{asset_key}'" 
         
     | 
| 
       96 
95 
     | 
    
         
             
                  end
         
     | 
| 
       97 
96 
     | 
    
         
             
                end
         
     | 
| 
       98 
97 
     | 
    
         | 
| 
         @@ -109,23 +108,52 @@ module Isomorfeus 
     | 
|
| 
       109 
108 
     | 
    
         
             
                  JAVASCRIPT
         
     | 
| 
       110 
109 
     | 
    
         
             
                end
         
     | 
| 
       111 
110 
     | 
    
         | 
| 
      
 111 
     | 
    
         
            +
                def init_hmr_listener
         
     | 
| 
      
 112 
     | 
    
         
            +
                  return unless Dir.exist?(Isomorfeus.app_root)
         
     | 
| 
      
 113 
     | 
    
         
            +
                  listen_dirs = []
         
     | 
| 
      
 114 
     | 
    
         
            +
                  Isomorfeus.asset_manager_hmr_dirs.each do |dir|
         
     | 
| 
      
 115 
     | 
    
         
            +
                    if File.absolute_path?(dir)
         
     | 
| 
      
 116 
     | 
    
         
            +
                      listen_dirs << dir if Dir.exist?(dir)
         
     | 
| 
      
 117 
     | 
    
         
            +
                    else
         
     | 
| 
      
 118 
     | 
    
         
            +
                      listen_dir = File.join(Isomorfeus.app_root, dir)
         
     | 
| 
      
 119 
     | 
    
         
            +
                      listen_dirs << listen_dir if Dir.exist?(listen_dir)
         
     | 
| 
      
 120 
     | 
    
         
            +
                    end
         
     | 
| 
      
 121 
     | 
    
         
            +
                  end
         
     | 
| 
      
 122 
     | 
    
         
            +
                  Isomorfeus.hmr_listener = Listen.to(*listen_dirs) do |modified, added, _|
         
     | 
| 
      
 123 
     | 
    
         
            +
                    (modified + added).each do |file|
         
     | 
| 
      
 124 
     | 
    
         
            +
                      next if file.start_with?(@server_path)
         
     | 
| 
      
 125 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 126 
     | 
    
         
            +
                        update = compile_ruby(file)
         
     | 
| 
      
 127 
     | 
    
         
            +
                        update_json = Oj.dump(update, mode: :strict)
         
     | 
| 
      
 128 
     | 
    
         
            +
                        Iodine.publish(Isomorfeus.asset_manager_hmr_channel, update_json)
         
     | 
| 
      
 129 
     | 
    
         
            +
                      rescue Exception => e
         
     | 
| 
      
 130 
     | 
    
         
            +
                        message = "#{e.message}\n#{e.backtrace.join("\n")}"
         
     | 
| 
      
 131 
     | 
    
         
            +
                        STDERR.puts message
         
     | 
| 
      
 132 
     | 
    
         
            +
                        Iodine.publish(Isomorfeus.asset_manager_hmr_channel, Oj.dump({ error: message }, mode: :struct))
         
     | 
| 
      
 133 
     | 
    
         
            +
                      end
         
     | 
| 
      
 134 
     | 
    
         
            +
                    end
         
     | 
| 
      
 135 
     | 
    
         
            +
                  end
         
     | 
| 
      
 136 
     | 
    
         
            +
                  Isomorfeus.hmr_listener.start
         
     | 
| 
      
 137 
     | 
    
         
            +
                end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
       112 
139 
     | 
    
         
             
                # possible future improvement
         
     | 
| 
       113 
140 
     | 
    
         
             
                # loader: {
         
     | 
| 
       114 
141 
     | 
    
         
             
                #   '.png': 'dataurl',
         
     | 
| 
       115 
142 
     | 
    
         
             
                #   '.svg': 'text',
         
     | 
| 
       116 
143 
     | 
    
         
             
                # },
         
     | 
| 
       117 
     | 
    
         
            -
                def run_esbuild(asset_key, asset)
         
     | 
| 
      
 144 
     | 
    
         
            +
                def run_esbuild(asset_key, asset, analyze = false)
         
     | 
| 
       118 
145 
     | 
    
         
             
                  resolve_paths = ENV['NODE_PATH'].split(Gem.win_platform? ? ';' : ':')
         
     | 
| 
       119 
146 
     | 
    
         
             
                  resolve_paths << 'node_modules'
         
     | 
| 
       120 
147 
     | 
    
         
             
                  resolve_paths.uniq!
         
     | 
| 
       121 
148 
     | 
    
         | 
| 
       122 
149 
     | 
    
         
             
                  result = @context.exec <<~JAVASCRIPT
         
     | 
| 
       123 
     | 
    
         
            -
                   
     | 
| 
      
 150 
     | 
    
         
            +
                  let res = esbuild.buildSync({
         
     | 
| 
       124 
151 
     | 
    
         
             
                    entryPoints: [path.resolve(global.imports_path, '#{asset_key}')],
         
     | 
| 
       125 
152 
     | 
    
         
             
                    bundle: true,
         
     | 
| 
       126 
153 
     | 
    
         
             
                    color: false,
         
     | 
| 
       127 
154 
     | 
    
         
             
                    format: '#{asset.target == :node ? 'cjs' : 'iife'}',
         
     | 
| 
       128 
155 
     | 
    
         
             
                    legalComments: 'linked',
         
     | 
| 
      
 156 
     | 
    
         
            +
                    metafile: true,
         
     | 
| 
       129 
157 
     | 
    
         
             
                    minify: #{Isomorfeus.production? ? 'true' : 'false'},
         
     | 
| 
       130 
158 
     | 
    
         
             
                    nodePaths: #{resolve_paths},
         
     | 
| 
       131 
159 
     | 
    
         
             
                    outdir: global.output_path,
         
     | 
| 
         @@ -136,7 +164,15 @@ module Isomorfeus 
     | 
|
| 
       136 
164 
     | 
    
         
             
                    target: 'es6',
         
     | 
| 
       137 
165 
     | 
    
         
             
                    write: true
         
     | 
| 
       138 
166 
     | 
    
         
             
                  });
         
     | 
| 
      
 167 
     | 
    
         
            +
                  global.res_meta = res.metafile;
         
     | 
| 
      
 168 
     | 
    
         
            +
                  return res;
         
     | 
| 
       139 
169 
     | 
    
         
             
                  JAVASCRIPT
         
     | 
| 
      
 170 
     | 
    
         
            +
                  if analyze
         
     | 
| 
      
 171 
     | 
    
         
            +
                    analysis = @context.await <<~JAVASCRIPT
         
     | 
| 
      
 172 
     | 
    
         
            +
                    esbuild.analyzeMetafile(global.res_meta, { verbose: true });
         
     | 
| 
      
 173 
     | 
    
         
            +
                    JAVASCRIPT
         
     | 
| 
      
 174 
     | 
    
         
            +
                    STDOUT.puts "Bundle analysis for #{asset_key}:\n#{analysis}\n"
         
     | 
| 
      
 175 
     | 
    
         
            +
                  end
         
     | 
| 
       140 
176 
     | 
    
         
             
                  handle_errors(asset_key, result)
         
     | 
| 
       141 
177 
     | 
    
         
             
                end
         
     | 
| 
       142 
178 
     | 
    
         
             
              end
         
     |