wasmify-rails 0.1.3 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 683d693ae789d6a5681cbab9e6f66f8a8fbd52a23d4dc440ff78d14e13c3085d
4
- data.tar.gz: e8c18abb0382cbec70d562debbf4f16d82eeece71c9dcdb0a82f916216c3f7a5
3
+ metadata.gz: 0ec3282837b68355a92061618b21324e72476610f34c9a99538f7af28461836e
4
+ data.tar.gz: 195c3113bfa6d07d8e8f589739e415bbeff0518d5fb3248b8450c997c084fd4e
5
5
  SHA512:
6
- metadata.gz: d7aafd09c3e716080f96efa987aeb1825ab5307be9cc1dae32e657f30a4f40314fd65e4ec610b8f271c40b3cd7ad0c951eff9be5cc9e3cd80456edaedec19a6c
7
- data.tar.gz: 44619a0600d773ecd96e9f012b0245d6567e5d140b04397577560665ae5b49a9f7983755431f644274ebdb6dc76a3e33c91bf37eee5da56d8e4bfdc8f70a9e9b
6
+ metadata.gz: 3429caf51620abc60aa2de1ec5b0a81743e15cf95bfc2c39081c48e764e738ae7ec78a6bc8e3b44e0b213238593abf774dbd5a2260217d820e887f663d75c26e
7
+ data.tar.gz: 47907d81582be81de0e2ac6225d70356ca2157a42e627af19dde13dbbe2e59105736c953ac8e7d45acd49f1442423398256adb3a140c15a64f498c53134fad45
data/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.1.5
6
+
7
+ - Added async mode to rack.js.
8
+
9
+ - Added ability to pass env vars to Ruby VM.
10
+
11
+ - Rails 8 support for `sqlite3_wasm` adapter.
12
+
13
+ ## 0.1.4
14
+
15
+ - Improve `wasmify:install`.
16
+
17
+ Make it work with the `rails new` app without any manual steps.
18
+
5
19
  ## 0.1.3
6
20
 
7
21
  - Check if `cookieStore` is available and only manipulate cookies if it is.
data/README.md CHANGED
@@ -4,6 +4,9 @@
4
4
 
5
5
  This gem provides tools and extensions to compile Rails applications to WebAssembly.
6
6
 
7
+ > [!NOTE]
8
+ > Read more in our handbook: [Rails on Wasm](https://writebook-on-wasm.fly.dev/5/ruby-on-rails-on-webassembly)
9
+
7
10
  ## Installation
8
11
 
9
12
  Adding to your Gemfile:
@@ -31,6 +34,8 @@ The script will tweak you configuration files and create a couple of new ones:
31
34
 
32
35
  - `config/wasmify.yml` — this is a configuration file for different _wasmify_ commands (see below).
33
36
 
37
+ It also adds the `wasm` group to your Gemfile (see below on that).
38
+
34
39
  ### Step 2: `bin/rails wasmify:build:core`
35
40
 
36
41
  Now, it's time to build a ruby.wasm with all your project dependencies (from the Gemfile). This is gonna be a base Wasm module
@@ -57,7 +62,9 @@ end
57
62
  ...
58
63
  ```
59
64
 
60
- **NOTE:** If you use `ruby file: ".ruby-version"` in your Gemfile, you should probably configure the Ruby version for Wasm platform
65
+ We try to mark gems as wasm-compatible during the `wasmify:install` phase, but it's likely that you will need to adjust the Gemfile manually.
66
+
67
+ If you use `ruby file: ".ruby-version"` in your Gemfile, you should probably configure the Ruby version for Wasm platform
61
68
  a bit differently (since patch versions might not match). For example:
62
69
 
63
70
  ```ruby
@@ -68,6 +75,12 @@ else
68
75
  end
69
76
  ```
70
77
 
78
+ Or just disable the Ruby version check for the Wasm platform:
79
+
80
+ ```ruby
81
+ ruby file: ".ruby-version" unless RUBY_PLATFORM =~ /wasm/
82
+ ```
83
+
71
84
  Now, try to run the following command:
72
85
 
73
86
  ```sh
@@ -1,3 +1,14 @@
1
+ # Rails 8 compatibility
2
+ module SQLite3
3
+ module ForkSafety
4
+ def self.suppress_warnings!
5
+ end
6
+ end
7
+
8
+ class BusyException < StandardError
9
+ end
10
+ end
11
+
1
12
  require "active_record/connection_adapters/sqlite3_adapter"
2
13
 
3
14
  module SQLite3
@@ -33,6 +44,12 @@ module ActiveRecord
33
44
  JS.global[js_interface].exec(...)
34
45
  end
35
46
 
47
+ def execute_batch2(...)
48
+ # TODO: it's used by fixtures and truncate_all, so
49
+ # we don't need it right now
50
+ raise NotImplementedError, "sqlite3_wasm#execute_batch2 is not implemented yet"
51
+ end
52
+
36
53
  def busy_timeout(...) = nil
37
54
 
38
55
  def execute(sql)
@@ -106,6 +123,8 @@ module ActiveRecord
106
123
  @rows
107
124
  end
108
125
 
126
+ def column_count = columns.size
127
+
109
128
  def execute
110
129
  return if @rows
111
130
 
@@ -182,6 +201,29 @@ module ActiveRecord
182
201
  def database_exists? = true
183
202
 
184
203
  def database_version = SQLite3Adapter::Version.new("3.45.1")
204
+
205
+ # Rails 8 interface
206
+ def perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notification_payload:, batch: false)
207
+ if batch
208
+ raw_connection.execute_batch2(sql)
209
+ elsif prepare
210
+ raise NotImplementedError, "sqlite3_wasm prepared statements are not implemented yet"
211
+ else
212
+ stmt = raw_connection.prepare(sql)
213
+ result =
214
+ if stmt.column_count.zero?
215
+ ActiveRecord::Result.empty
216
+ else
217
+ ActiveRecord::Result.new(stmt.columns, stmt.to_a)
218
+ end
219
+ end
220
+
221
+ @last_affected_rows = raw_connection.changes
222
+ verified!
223
+
224
+ notification_payload[:row_count] = result&.length || 0
225
+ result
226
+ end
185
227
  end
186
228
  end
187
229
  end
@@ -54,25 +54,87 @@ class Wasmify::InstallGenerator < Rails::Generators::Base
54
54
 
55
55
  # Disable bootsnap if any
56
56
  inject_into_file "config/boot.rb", after: /require ['"]bootsnap\/setup['"]/ do
57
+ %q( unless ENV["RAILS_ENV"] == "wasm")
58
+ end
59
+ end
60
+
61
+ def disable_ruby_version_check_in_gemfile
62
+ inject_into_file "Gemfile", after: /^ruby[^#\n]+/ do
57
63
  " unless RUBY_PLATFORM =~ /wasm/"
58
64
  end
59
65
  end
60
66
 
61
67
  def add_tzinfo_data_to_gemfile
68
+ # First, comment out the existing tzinfo-data gem declaration
69
+ comment_lines "Gemfile", /^gem ['"]tzinfo-data['"]/
70
+
62
71
  append_to_file "Gemfile", <<~RUBY
63
72
 
64
73
  group :wasm do
65
74
  gem "tzinfo-data"
66
75
  end
67
76
  RUBY
77
+ end
68
78
 
69
- run "bundle install"
79
+ KNOWN_NO_WASM_GEMS = %w[
80
+ bootsnap
81
+ puma
82
+ sqlite3
83
+ activerecord-enhancedsqlite3-adapter
84
+ pg
85
+ mysql2
86
+ redis
87
+ solid_cable
88
+ solid_queue
89
+ solid_cache
90
+ jsbundling-rails
91
+ cssbundling-rails
92
+ thruster
93
+ kamal
94
+ byebug
95
+ web-console
96
+ listen
97
+ spring
98
+ debug
99
+ ].freeze
100
+
101
+ def add_wasm_group_to_gemfile
102
+ # This is a very straightforward implementation:
103
+ # - scan the Gemfile for _root_ dependencies (not within groups)
104
+ # - add `group: [:default, :wasm]` to those not from the exclude list
105
+
106
+ top_gems = []
107
+
108
+ File.read("Gemfile").then do |gemfile|
109
+ gemfile.scan(/^gem ['"]([^'"]+)['"](.*)$/).each do |match|
110
+ gem_name = match.first
111
+ top_gems << gem_name unless match.last&.include?(":wasm")
112
+ end
113
+ end
114
+
115
+ gems_to_include = top_gems - KNOWN_NO_WASM_GEMS
116
+
117
+ return if gems_to_include.empty?
118
+
119
+ regexp = /^gem ['"](?:#{gems_to_include.join("|")})['"][^#\n]*/
120
+
121
+ gsub_file "Gemfile", regexp do |match|
122
+ match << ", group: [:default, :wasm]"
123
+ end
124
+ end
125
+
126
+ def fix_solid_queeue_production_config
127
+ inject_into_file "config/environments/production.rb", after: %r{config.solid_queue.connects_to = [^#\n]+} do
128
+ " if config.respond_to?(:solid_queue)"
129
+ end
70
130
  end
71
131
 
72
132
  def finish
133
+ run "bundle install"
134
+
73
135
  say_status :info, "✅ The application is prepared for Wasm-ificaiton!\n\n" \
74
136
  "Next steps are:\n" \
75
- " - Gemfile: Add `group: [:default, :wasm]` to the dependencies required in Wasm runtime" \
137
+ " - Check your Gemfile: add `group: [:default, :wasm]` to the dependencies required in Wasm runtime" \
76
138
  " - Run `bin/rails wasmify:build:core:verify` to see if the bundle compiles"
77
139
  end
78
140
  end
@@ -10,7 +10,7 @@
10
10
  "preview": "vite preview"
11
11
  },
12
12
  "devDependencies": {
13
- "vite": "^5.4.7",
13
+ "vite": "^4.4.5",
14
14
  "vite-plugin-pwa": "^0.20.5"
15
15
  },
16
16
  "dependencies": {
@@ -2,6 +2,11 @@
2
2
 
3
3
  module Wasmify
4
4
  module Rails
5
+ RUBY_VERSION_TO_WASM_RUBY_VERSION = {
6
+ "3.3" => "3.3.3",
7
+ "3.2" => "3.2.4"
8
+ }
9
+
5
10
  class Configuration
6
11
  attr_reader :pack_directories, :exclude_gems, :ruby_version,
7
12
  :tmp_dir, :output_dir,
@@ -29,12 +34,16 @@ module Wasmify
29
34
  end
30
35
  end
31
36
 
37
+ def ruby_version = @ruby_version ||= ruby_version_from_file || "3.3"
38
+
32
39
  private
33
40
 
34
41
  def ruby_version_from_file
35
42
  return unless File.file?(::Rails.root.join(".ruby-version"))
36
43
 
37
- File.read(::Rails.root.join(".ruby-version")).strip
44
+ File.read(::Rails.root.join(".ruby-version")).strip.match(/(\d+\.\d+(?:\.d+)?)/).then do |matches|
45
+ matches[1] if matches
46
+ end
38
47
  end
39
48
  end
40
49
  end
@@ -14,7 +14,7 @@ namespace :wasmify do
14
14
  desc "Build ruby.wasm with all dependencies"
15
15
  task :build do
16
16
  unless ENV["BUNDLE_ONLY"] == "wasm"
17
- next spawn("BUNDLE_ONLY=wasm bundle exec rails wasmify:build").then { Process.wait(_1) }
17
+ next spawn("RAILS_ENV=wasm BUNDLE_ONLY=wasm bundle exec rails wasmify:build").then { Process.wait(_1) }
18
18
  end
19
19
 
20
20
  require "wasmify/rails/builder"
@@ -27,7 +27,7 @@ namespace :wasmify do
27
27
  desc "Build ruby.wasm with all dependencies but JS shim (to use with wasmtime)"
28
28
  task :core do
29
29
  unless ENV["BUNDLE_ONLY"] == "wasm"
30
- next spawn("BUNDLE_ONLY=wasm bundle exec rails wasmify:build:core").then { Process.wait(_1) }
30
+ next spawn("RAILS_ENV=wasm BUNDLE_ONLY=wasm bundle exec rails wasmify:build:core").then { Process.wait(_1) }
31
31
  end
32
32
 
33
33
  require "wasmify/rails/builder"
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Wasmify
4
4
  module Rails # :nodoc:
5
- VERSION = "0.1.3"
5
+ VERSION = "0.1.5"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wasmify-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-27 00:00:00.000000000 Z
11
+ date: 2024-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties