zephyr_rb 1.0.0

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.
Files changed (6) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +569 -0
  3. data/dist/zephyrRB.js +3511 -0
  4. data/lib/cli.rb +228 -0
  5. data/lib/version.rb +7 -0
  6. metadata +39 -0
data/lib/cli.rb ADDED
@@ -0,0 +1,228 @@
1
+ # lib/zephyr_rb/cli.rb
2
+ # frozen_string_literal: true
3
+
4
+ require 'fileutils'
5
+ require 'json'
6
+ require_relative 'version'
7
+
8
+ module ZephyrRb
9
+ class CLI
10
+ class << self
11
+ def run(args)
12
+ command = args[0]
13
+
14
+ case command
15
+ when 'build'
16
+ build
17
+ when 'version', '-v', '--version'
18
+ puts "ZephyrRb v#{VERSION}"
19
+ when 'help', '-h', '--help', nil
20
+ show_help
21
+ else
22
+ puts "Unknown command: #{command}"
23
+ show_help
24
+ end
25
+ end
26
+
27
+ def build
28
+ puts "🔨 Building ZephyrRb v#{VERSION}..."
29
+ puts "đŸ“Ļ Bundling Ruby WASM #{RUBY_WASM_VERSION}..."
30
+
31
+ Builder.new.build
32
+
33
+ puts "✅ Build complete!"
34
+ end
35
+
36
+ def show_help
37
+ puts <<~HELP
38
+ ZephyrRb - Build reactive web components using Ruby and WebAssembly
39
+
40
+ Usage:
41
+ zephyr-rb <command> [options]
42
+
43
+ Commands:
44
+ build Build the bundled zephyr.js distribution file
45
+ version Show version information
46
+ help Show this help message
47
+
48
+ Examples:
49
+ zephyr-rb build
50
+ zephyr-rb version
51
+ HELP
52
+ end
53
+ end
54
+ end
55
+
56
+ class Builder
57
+ DIST_DIR = File.expand_path('../../../dist', __dir__)
58
+ SRC_DIR = File.expand_path('../../../src', __dir__)
59
+
60
+ def build
61
+ ensure_directories
62
+ download_ruby_wasm if needs_ruby_wasm?
63
+ bundle_distribution
64
+ generate_metadata
65
+ end
66
+
67
+ private
68
+
69
+ def ensure_directories
70
+ FileUtils.mkdir_p(DIST_DIR)
71
+ FileUtils.mkdir_p(File.join(SRC_DIR, 'vendor'))
72
+ end
73
+
74
+ def needs_ruby_wasm?
75
+ wasm_file = File.join(SRC_DIR, 'vendor', 'browser.script.iife.js')
76
+ !File.exist?(wasm_file)
77
+ end
78
+
79
+ def download_ruby_wasm
80
+ require 'open-uri'
81
+
82
+ url = "https://cdn.jsdelivr.net/npm/@ruby/#{ZephyrRb::RUBY_WASM_VERSION}/dist/browser.script.iife.js"
83
+ target = File.join(SRC_DIR, 'vendor', 'browser.script.iife.js')
84
+
85
+ puts "âŦ‡ī¸ Downloading Ruby WASM from CDN..."
86
+
87
+ URI.open(url) do |remote|
88
+ File.write(target, remote.read)
89
+ end
90
+
91
+ file_size = (File.size(target) / 1024.0).round(1)
92
+ puts "✓ Downloaded browser.script.iife.js (#{file_size} KB)"
93
+ end
94
+
95
+ def bundle_distribution
96
+ output = []
97
+
98
+ # 1. Add header comment
99
+ output << build_header
100
+
101
+ # 2. Embed Ruby WASM runtime
102
+ wasm_path = File.join(SRC_DIR, 'vendor', 'browser.script.iife.js')
103
+ output << "// Ruby WASM Runtime"
104
+ output << File.read(wasm_path)
105
+
106
+ # 3. Wait for Ruby VM to be ready
107
+ output << ruby_vm_ready_wrapper
108
+
109
+ # 4. Embed core Ruby files
110
+ ruby_files = [
111
+ 'registry.rb',
112
+ 'dom_builder.rb',
113
+ 'component.rb',
114
+ 'zephyr_wasm.rb'
115
+ ]
116
+
117
+ output << "// Core ZephyrRb Ruby Files"
118
+ ruby_files.each do |file|
119
+ ruby_code = File.read(File.join(SRC_DIR, file))
120
+ output << wrap_ruby_code(file, ruby_code)
121
+ end
122
+
123
+ # 5. Embed the JavaScript bridge
124
+ output << "// JavaScript Bridge"
125
+ output << File.read(File.join(SRC_DIR, 'zephyr-bridge.js'))
126
+
127
+ # 6. Add initialization code
128
+ output << initialization_code
129
+
130
+ # Write bundled file
131
+ dist_file = File.join(DIST_DIR, 'zephyr.js')
132
+ File.write(dist_file, output.join("\n\n"))
133
+
134
+ file_size = (File.size(dist_file) / 1024.0).round(1)
135
+ puts "✓ Generated dist/zephyr.js (#{file_size} KB)"
136
+
137
+ # Also create minified version info
138
+ puts "â„šī¸ Tip: Use a tool like terser to minify for production"
139
+ end
140
+
141
+ def build_header
142
+ <<~JS
143
+ /*!
144
+ * ZephyrRb v#{ZephyrRb::VERSION}
145
+ * Build reactive web components using Ruby and WebAssembly
146
+ *
147
+ * Ruby WASM: #{ZephyrRb::RUBY_WASM_VERSION}
148
+ *
149
+ * https://github.com/RPDevJesco/ZephyrRb
150
+ * Released under the MIT License
151
+ */
152
+ JS
153
+ end
154
+
155
+ def ruby_vm_ready_wrapper
156
+ <<~JS
157
+ // Wait for Ruby VM to initialize
158
+ (function() {
159
+ const waitForRuby = () => {
160
+ return new Promise((resolve) => {
161
+ if (window.RubyVM) {
162
+ resolve();
163
+ } else {
164
+ const checkInterval = setInterval(() => {
165
+ if (window.RubyVM) {
166
+ clearInterval(checkInterval);
167
+ resolve();
168
+ }
169
+ }, 50);
170
+ }
171
+ });
172
+ };
173
+
174
+ window.ZephyrRbReady = waitForRuby();
175
+ })();
176
+ JS
177
+ end
178
+
179
+ def wrap_ruby_code(filename, code)
180
+ escaped_code = code.gsub('\\', '\\\\\\\\').gsub('`', '\\`').gsub('${', '\\${')
181
+
182
+ <<~JS
183
+ // Embedded: #{filename}
184
+ (async function() {
185
+ await window.ZephyrRbReady;
186
+ const rubyCode = `#{escaped_code}`;
187
+
188
+ try {
189
+ window.RubyVM.eval(rubyCode);
190
+ } catch (error) {
191
+ console.error('Error loading #{filename}:', error);
192
+ }
193
+ })();
194
+ JS
195
+ end
196
+
197
+ def initialization_code
198
+ <<~JS
199
+ // ZephyrRb Initialization
200
+ (async function() {
201
+ await window.ZephyrRbReady;
202
+ console.log('✅ ZephyrRb v#{ZephyrRb::VERSION} loaded');
203
+
204
+ // Dispatch ready event for user code
205
+ window.dispatchEvent(new CustomEvent('zephyr:ready', {
206
+ detail: { version: '#{ZephyrRb::VERSION}' }
207
+ }));
208
+ })();
209
+ JS
210
+ end
211
+
212
+ def generate_metadata
213
+ metadata = {
214
+ version: ZephyrRb::VERSION,
215
+ ruby_wasm_version: ZephyrRb::RUBY_WASM_VERSION,
216
+ built_at: Time.now.utc.iso8601,
217
+ files: {
218
+ main: 'zephyr.js',
219
+ size_kb: (File.size(File.join(DIST_DIR, 'zephyr.js')) / 1024.0).round(2)
220
+ }
221
+ }
222
+
223
+ metadata_file = File.join(DIST_DIR, 'metadata.json')
224
+ File.write(metadata_file, JSON.pretty_generate(metadata))
225
+ puts "✓ Generated dist/metadata.json"
226
+ end
227
+ end
228
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,7 @@
1
+ # lib/zephyr_rb/version.rb
2
+ # frozen_string_literal: true
3
+
4
+ module ZephyrRb
5
+ VERSION = "1.0.0"
6
+ RUBY_WASM_VERSION = "3.4-wasm-wasi@2.7.1"
7
+ end
metadata ADDED
@@ -0,0 +1,39 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zephyr_rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jesse Glover
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ executables: []
13
+ extensions: []
14
+ extra_rdoc_files: []
15
+ files:
16
+ - README.md
17
+ - dist/zephyrRB.js
18
+ - lib/cli.rb
19
+ - lib/version.rb
20
+ licenses: []
21
+ metadata: {}
22
+ rdoc_options: []
23
+ require_paths:
24
+ - lib
25
+ required_ruby_version: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ required_rubygems_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ requirements: []
36
+ rubygems_version: 3.6.9
37
+ specification_version: 4
38
+ summary: Build reactive web components using Ruby and WebAssembly
39
+ test_files: []