islandjs-rails 0.4.0 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3efc622c722a226faf6ab715f92302e3476aa46be3c186dabd7ec8e51cf49166
4
- data.tar.gz: 5c6fa3546df97f4c8430e6b9c06b320a6cd06432b6493025bc05a5c4242f88e9
3
+ metadata.gz: 161513f810a18384f6f80fd33826774b01027e0a3167e7cdfea5af2903419ccc
4
+ data.tar.gz: 756c73ddf0f8347c4ca86c484fff6c62cb01600304a04abc84f54b693555062b
5
5
  SHA512:
6
- metadata.gz: ec382c1d892648a353afed3dec2420b895bf14eae349f3b4a2877aade87bcf8dd2954f3bf1715aa93c6e9fd1f4b3ffed2089c86c356957b0b830aca71387fa03
7
- data.tar.gz: 6fd2a2440a750bf0b284452b6faf5835d6a5635e5fef7e4213eb439d77ae95d7667e934eec36e5ff077ea7f1e58d9fbe2d60c140d49ec3c795eae7fe429fe9ad
6
+ metadata.gz: 3ca585f21d6501f6fca88792b125fdd9f70ed839867509445a59eca25f521919a6918554168f834d3deb36d9e9e7eb39c05d36c32222e8d354f7442ea4ca394e
7
+ data.tar.gz: 6f6eacf4afa87d6f130a71c88724deaa0e17d9d8e06cde38cb883b2a1bc35253604b5163e8d40580fbe0c40e8811fd723c424b3f769c96a495962a38ff3aedda
data/CHANGELOG.md CHANGED
@@ -5,10 +5,22 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.6.0] - 2025-10-24
9
+
10
+ - **React 19 Support Added**
11
+ - **Enhanced version parsing** in `cdn_package_name` with nil/empty string handling and exception safety
12
+ - **SSL certificate issues** with improved fallback mechanism for CDN downloads
13
+
14
+ ## [0.5.0] - 2025-09-29
15
+
16
+ ### Added
17
+ - **CSP support for script tags**: All IslandJS-generated `<script>` tags now automatically include a CSP nonce when one is present in the Rails request.
18
+ - **Flexible script attributes**: Helpers (`react_component`, `vue_component`, etc.) now support passing standard script attributes (`nonce`, `defer`, `async`, `crossorigin`, `integrity`).
19
+
8
20
  ## [0.4.0] - 2025-08-10
9
21
 
10
22
  ### Added
11
- - Add ENV flag to control the dev UMD bundle info footer. The floating footer is now disabled by default and only shows in development when `ISLANDJS_RAILS_SHOW_UMD_DEBUG` is truthy.
23
+ - Add ENV flag to control the dev UMD bundle info footer. The floating footer is disabled by default and only shows in development when `ISLANDJS_RAILS_SHOW_UMD_DEBUG` is truthy.
12
24
 
13
25
  ## [0.3.0] - 2025-08-09
14
26
 
data/README.md CHANGED
@@ -3,8 +3,8 @@
3
3
  **Launch quickly:** *upgrade with vite only if necessary (MYAGNI).*
4
4
 
5
5
  [![CI](https://github.com/praxis-emergent/islandjs-rails/actions/workflows/github-actions-demo.yml/badge.svg)](https://github.com/praxis-emergent/islandjs-rails/actions/workflows/github-actions-demo.yml)
6
- [![Test Coverage](https://img.shields.io/badge/coverage-89.09%25-brightgreen.svg)](coverage/index.html)
7
- [![RSpec Tests](https://img.shields.io/badge/tests-162%20passing-brightgreen.svg)](spec/)
6
+ [![Test Coverage](https://img.shields.io/badge/coverage-86.63%25-brightgreen.svg)](coverage/index.html)
7
+ [![RSpec Tests](https://img.shields.io/badge/tests-367%20passing-brightgreen.svg)](spec/)
8
8
  [![Rails 8 Ready](https://img.shields.io/badge/Rails%208-Ready-brightgreen.svg)](#rails-8-ready)
9
9
 
10
10
  IslandJS Rails supports the development of React islands in Rails apps by synchronizing `package.json` dependencies with UMD libraries served in `public/islands/vendor`.
@@ -31,8 +31,8 @@ rails islandjs:init
31
31
 
32
32
  ### Install React
33
33
  ```bash
34
- rails "islandjs:install[react,18.3.1]"
35
- rails "islandjs:install[react-dom,18.3.1]"
34
+ rails "islandjs:install[react,19.2.0]"
35
+ rails "islandjs:install[react-dom,19.2.0]"
36
36
  ```
37
37
 
38
38
  ### Run Yarn In Development
@@ -115,7 +115,7 @@ Modern Rails developers face a painful choice:
115
115
  ### The IslandJS Rails Solution
116
116
  ```bash
117
117
  # Instead of complex vite/webpack configuration:
118
- rails "islandjs:install[react,18.3.1]"
118
+ rails "islandjs:install[react,19.2.0]"
119
119
  rails "islandjs:install[react-beautiful-dnd]"
120
120
  rails "islandjs:install[quill]"
121
121
  rails "islandjs:install[recharts]"
@@ -132,7 +132,7 @@ const quill = new window.Quill("#editor", {
132
132
  });
133
133
  ```
134
134
 
135
- **Important Note:** IslandJS Rails works with packages that ship UMD builds. Many popular packages have UMD builds, but some modern packages do not React 19+ removed UMD builds entirely. Future versions of IslandJS Rails will support local UMD generation for some packages (such as [React 19+](https://github.com/lofcz/umd-react)).
135
+ **Important Note:** IslandJS Rails works with packages that ship UMD builds. Many popular packages have UMD builds, but some modern packages do not. Starting with **React 19**, official UMD builds were removed, but IslandJS Rails now automatically fetches React 19+ UMD builds from the community-maintained [`umd-react`](https://github.com/lofcz/umd-react) package. No manual setup needed.
136
136
 
137
137
  If you absolutely need a package that doesn't ship UMD builds, you have a few options:
138
138
 
@@ -170,12 +170,12 @@ rails islandjs:init
170
170
 
171
171
  # Install packages (adds to package.json + saves to vendor directory)
172
172
  rails "islandjs:install[react]"
173
- rails "islandjs:install[react,18.3.1]" # With specific version
173
+ rails "islandjs:install[react,19.2.0]" # With specific version
174
174
  rails "islandjs:install[lodash]"
175
175
 
176
176
  # Update packages (updates package.json + refreshes vendor files)
177
177
  rails "islandjs:update[react]"
178
- rails "islandjs:update[react,18.3.1]" # To specific version
178
+ rails "islandjs:update[react,19.2.0]" # To specific version
179
179
 
180
180
  # Remove packages (removes from package.json + deletes vendor files)
181
181
  rails "islandjs:remove[react]"
@@ -354,7 +354,7 @@ rails "islandjs:install[@solana/web3]" # ❌ Wrong
354
354
  | Command | What it does | Example |
355
355
  |---------|--------------|---------|
356
356
  | `install` | Adds package via yarn + downloads UMD + saves to vendor | `rails islandjs:install[react]` |
357
- | `update` | Updates package version + refreshes UMD | `rails islandjs:update[react,18.3.1]` |
357
+ | `update` | Updates package version + refreshes UMD | `rails islandjs:update[react,19.2.0]` |
358
358
  | `remove` | Removes package via yarn + deletes vendor files | `rails islandjs:remove[react]` |
359
359
  | `clean` | Removes ALL vendor files (destructive!) | `rails islandjs:clean` |
360
360
 
@@ -420,6 +420,7 @@ Renders a React component with Turbo-compatible lifecycle and optional placehold
420
420
  - `class`: CSS class for container
421
421
  - `placeholder_class`: CSS class for placeholder content
422
422
  - `placeholder_style`: Inline styles for placeholder content
423
+ - Script attributes: `nonce` (auto-detected for CSP), `defer`, `async`, `crossorigin`, `integrity`
423
424
 
424
425
  ## Placeholder Support
425
426
 
@@ -27,6 +27,20 @@ module IslandjsRails
27
27
  '@babel/preset-env' => 'babel-preset-env',
28
28
  '@babel/preset-react' => 'babel-preset-react'
29
29
  }.freeze
30
+
31
+ # Maps packages to alternate CDN names (e.g., React 19+ → umd-react).
32
+ def cdn_package_name(package_name, version)
33
+ # Handle nil or empty version strings
34
+ return package_name if version.nil? || version.empty?
35
+
36
+ # Check if React 19+ to use community-maintained umd-react package
37
+ if ['react', 'react-dom'].include?(package_name)
38
+ major_version = version.split('.').first.to_i rescue 0
39
+ return 'umd-react' if major_version >= 19
40
+ end
41
+
42
+ package_name
43
+ end
30
44
 
31
45
  # Vendor file helper methods
32
46
  def vendor_manifest_path
@@ -63,8 +63,8 @@ module IslandjsRails
63
63
 
64
64
  puts "\n🎉 IslandjsRails initialized successfully!"
65
65
  puts "\n📋 Next steps:"
66
- puts "1. Install libraries: rails \"islandjs:install[react,18.3.1]\""
67
- puts " rails \"islandjs:install[react-dom,18.3.1]\" "
66
+ puts "1. Install libraries: rails \"islandjs:install[react,19.2.0]\""
67
+ puts " rails \"islandjs:install[react-dom,19.2.0]\" "
68
68
  puts "2. Start dev: yarn watch"
69
69
  puts "3. Use components: <%= react_component('HelloWorld') %>"
70
70
  puts "4. Build for prod: yarn build"
@@ -281,6 +281,9 @@ module IslandjsRails
281
281
  version ||= version_for(package_name)
282
282
  return nil unless version
283
283
 
284
+ # Use cdn_package_name to handle React 19+ mapping to umd-react
285
+ cdn_package = configuration.cdn_package_name(package_name, version)
286
+
284
287
  # Use original package name for URL, but get clean name for {name} substitution
285
288
  clean_name = (Configuration::SCOPED_PACKAGE_MAPPINGS[package_name] || package_name).split('/').last
286
289
 
@@ -292,8 +295,7 @@ module IslandjsRails
292
295
  else
293
296
  pattern # Use pattern as-is for fixed filenames like IIFE
294
297
  end
295
- url = "#{cdn_base}/#{package_name}@#{version}/#{path}"
296
-
298
+ url = "#{cdn_base}/#{cdn_package}@#{version}/#{path}"
297
299
 
298
300
  if url_accessible?(url)
299
301
  puts "✓ Found island: #{url}"
@@ -306,20 +308,6 @@ module IslandjsRails
306
308
  nil
307
309
  end
308
310
 
309
- def download_umd_content(url)
310
- require 'net/http'
311
- require 'uri'
312
-
313
- uri = URI(url)
314
- response = Net::HTTP.get_response(uri)
315
-
316
- unless response.code == '200'
317
- raise IslandjsRails::Error, "Failed to download UMD from #{url}: #{response.code}"
318
- end
319
-
320
- response.body
321
- end
322
-
323
311
  def find_working_umd_url(package_name, version)
324
312
  puts " 🔍 Searching for UMD build..."
325
313
 
@@ -334,7 +322,7 @@ module IslandjsRails
334
322
  else
335
323
  pattern # Use pattern as-is for fixed filenames like IIFE
336
324
  end
337
- url = "#{cdn_base}/#{package_name}@#{version}/#{path}"
325
+ url = "#{cdn_base}/#{configuration.cdn_package_name(package_name, version)}@#{version}/#{path}"
338
326
 
339
327
 
340
328
  if url_accessible?(url)
@@ -353,18 +341,6 @@ module IslandjsRails
353
341
  end
354
342
 
355
343
  private
356
-
357
- # Check if a URL is accessible (returns 200 status)
358
- def url_accessible?(url)
359
- require 'net/http'
360
- require 'uri'
361
-
362
- uri = URI(url)
363
- response = Net::HTTP.get_response(uri)
364
- response.code == '200'
365
- rescue => e
366
- false
367
- end
368
344
 
369
345
  # Check if a package has a partial file
370
346
  def has_partial?(package_name)
@@ -37,8 +37,16 @@ module IslandjsRails
37
37
  return
38
38
  end
39
39
 
40
+ # Skip prompt in non-interactive mode
41
+ unless STDIN.tty?
42
+ puts "\n💡 To render your HelloWorld component:"
43
+ puts " In any view: <%= react_component('HelloWorld') %>"
44
+ puts " Don't forget to: yarn build && rails server"
45
+ return
46
+ end
47
+
40
48
  print "\n❓ Would you like to create a demo route at /islandjs/react to showcase your HelloWorld component? (y/n): "
41
- answer = STDIN.gets.chomp.downcase
49
+ answer = STDIN.gets&.chomp&.downcase
42
50
 
43
51
  if answer == 'y' || answer == 'yes'
44
52
  create_demo_route!
@@ -393,15 +401,36 @@ module IslandjsRails
393
401
  create_partial_file(package_name, umd_content, global_name)
394
402
  end
395
403
 
396
- def download_umd_content(url)
404
+ def download_umd_content(url, use_ssl_verification = true)
405
+ require 'openssl'
397
406
  uri = URI(url)
398
- response = Net::HTTP.get_response(uri)
399
407
 
400
- if response.code == '200'
408
+ http_options = {
409
+ use_ssl: uri.scheme == 'https',
410
+ verify_mode: use_ssl_verification ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
411
+ }
412
+
413
+ begin
414
+ body = Net::HTTP.start(uri.host, uri.port, **http_options) do |http|
415
+ request = Net::HTTP::Get.new(uri.request_uri)
416
+ response = http.request(request)
417
+
418
+ if response.code == '200'
419
+ response.body
420
+ else
421
+ raise IslandjsRails::Error, "Failed to download UMD from #{url}: #{response.code}"
422
+ end
423
+ end
424
+
401
425
  # Force UTF-8 encoding to avoid encoding errors when writing to file
402
- response.body.force_encoding('UTF-8')
403
- else
404
- raise IslandjsRails::Error, "Failed to download UMD from #{url}: #{response.code}"
426
+ body.force_encoding('UTF-8')
427
+ rescue OpenSSL::SSL::SSLError => ssl_error
428
+ if use_ssl_verification
429
+ $stderr.puts "⚠️ SSL verification failed, retrying without verification: #{ssl_error.message}"
430
+ return download_umd_content(url, false)
431
+ else
432
+ raise IslandjsRails::Error, "Failed to download UMD from #{url}: #{ssl_error.message}"
433
+ end
405
434
  end
406
435
  end
407
436
 
@@ -536,10 +565,45 @@ module IslandjsRails
536
565
  copy_template_file('webpack.config.js', configuration.webpack_config_path)
537
566
  end
538
567
 
539
- def url_accessible?(url)
568
+ def url_accessible?(url, limit = 5, use_ssl_verification = true)
569
+ require 'openssl'
570
+ return false if limit == 0
571
+
540
572
  uri = URI(url)
541
- response = Net::HTTP.get_response(uri)
542
- response.code == '200'
573
+
574
+ # Use proper SSL verification by default, but allow fallback for certificate issues
575
+ http_options = {
576
+ use_ssl: uri.scheme == 'https',
577
+ verify_mode: use_ssl_verification ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
578
+ }
579
+
580
+ begin
581
+ Net::HTTP.start(uri.host, uri.port, **http_options) do |http|
582
+ request = Net::HTTP::Get.new(uri.request_uri)
583
+ response = http.request(request)
584
+
585
+ case response
586
+ when Net::HTTPSuccess
587
+ return true
588
+ when Net::HTTPRedirection
589
+ # Follow redirects
590
+ location = response['location']
591
+ return url_accessible?(location, limit - 1, use_ssl_verification)
592
+ else
593
+ return false
594
+ end
595
+ end
596
+ rescue OpenSSL::SSL::SSLError => ssl_error
597
+ # If SSL verification fails and we're using verification, try once without it
598
+ # This handles local certificate store issues while still attempting security first
599
+ if use_ssl_verification
600
+ $stderr.puts "⚠️ SSL verification failed, retrying without verification: #{ssl_error.message}"
601
+ return url_accessible?(url, limit, false)
602
+ else
603
+ # Already tried without verification, give up
604
+ false
605
+ end
606
+ end
543
607
  rescue => e
544
608
  false
545
609
  end
@@ -1,10 +1,13 @@
1
1
  module IslandjsRails
2
2
  module RailsHelpers
3
+ # Script attributes that can be passed through options
4
+ SCRIPT_ATTRIBUTES = %i[nonce defer async crossorigin integrity].freeze
5
+
3
6
  # Main helper method that combines all IslandJS functionality
4
- def islands
7
+ def islands(**attributes)
5
8
  output = []
6
9
  output << island_partials # Now uses vendor UMD partial
7
- output << island_bundle_script
10
+ output << island_bundle_script(**attributes)
8
11
  output << umd_versions_debug if umd_debug_enabled?
9
12
  output.compact.join("\n").html_safe
10
13
  end
@@ -22,29 +25,32 @@ module IslandjsRails
22
25
  end
23
26
 
24
27
  # Render the main IslandJS bundle script tag
25
- def island_bundle_script
28
+ def island_bundle_script(**attributes)
26
29
  manifest_path = Rails.root.join('public', 'islands_manifest.json')
27
30
  bundle_path = '/islands_bundle.js'
28
-
31
+
32
+ # Get formatted HTML attributes with defaults (including auto-nonce and defer)
33
+ html_attributes = script_html_attributes(defer: true, **attributes)
34
+
29
35
  unless File.exist?(manifest_path)
30
36
  # Fallback to direct bundle path when no manifest
31
- return html_safe_string("<script src=\"#{bundle_path}\" defer></script>")
37
+ return html_safe_string("<script src=\"#{bundle_path}\"#{html_attributes}></script>")
32
38
  end
33
-
39
+
34
40
  begin
35
41
  manifest = JSON.parse(File.read(manifest_path))
36
42
  # Look for islands_bundle.js in manifest
37
43
  bundle_file = manifest['islands_bundle.js']
38
-
44
+
39
45
  if bundle_file
40
- html_safe_string("<script src=\"#{bundle_file}\" defer></script>")
46
+ html_safe_string("<script src=\"#{bundle_file}\"#{html_attributes}></script>")
41
47
  else
42
48
  # Fallback to direct bundle path
43
- html_safe_string("<script src=\"#{bundle_path}\" defer></script>")
49
+ html_safe_string("<script src=\"#{bundle_path}\"#{html_attributes}></script>")
44
50
  end
45
51
  rescue JSON::ParserError
46
52
  # Fallback to direct bundle path on manifest parse error
47
- html_safe_string("<script src=\"#{bundle_path}\" defer></script>")
53
+ html_safe_string("<script src=\"#{bundle_path}\"#{html_attributes}></script>")
48
54
  end
49
55
  end
50
56
 
@@ -66,7 +72,11 @@ module IslandjsRails
66
72
  # Handle placeholder options
67
73
  placeholder_class = options[:placeholder_class]
68
74
  placeholder_style = options[:placeholder_style]
69
-
75
+
76
+ # Extract script attributes from options
77
+ script_attributes = options.slice(*SCRIPT_ATTRIBUTES)
78
+ script_attributes.compact!
79
+
70
80
  # For turbo-cache compatibility, store initial state as JSON in data attribute
71
81
  initial_state_json = props.to_json
72
82
 
@@ -91,7 +101,7 @@ module IslandjsRails
91
101
  end
92
102
 
93
103
  # Generate the mounting script - pass container_id as the only prop for turbo-cache pattern
94
- mount_script = generate_react_mount_script(component_name, component_id, namespace, namespace_with_optional)
104
+ mount_script = generate_react_mount_script(component_name, component_id, namespace, namespace_with_optional, **script_attributes)
95
105
 
96
106
  # Return the container div with data-initial-state and script
97
107
  data_part = data_attrs.empty? ? '' : " #{data_attrs}"
@@ -133,9 +143,13 @@ module IslandjsRails
133
143
  # Extract options
134
144
  tag_name = options[:tag] || 'div'
135
145
  css_class = options[:class] || ''
136
-
146
+
147
+ # Extract script attributes from options
148
+ script_attributes = options.slice(*SCRIPT_ATTRIBUTES)
149
+ script_attributes.compact!
150
+
137
151
  # Generate the mounting script
138
- mount_script = generate_vue_mount_script(component_name, component_id, props_json)
152
+ mount_script = generate_vue_mount_script(component_name, component_id, props_json, **script_attributes)
139
153
 
140
154
  # Return the container div and script
141
155
  container_html = "<#{tag_name} id=\"#{component_id}\" class=\"#{css_class}\"></#{tag_name}>"
@@ -237,6 +251,37 @@ module IslandjsRails
237
251
 
238
252
  private
239
253
 
254
+ # Format HTML attributes into a string
255
+ # Returns a string like ' nonce="abc123" defer' or empty string if no attributes
256
+ def format_html_attributes(**attributes)
257
+ return '' if attributes.empty?
258
+
259
+ attributes.filter_map do |key, value|
260
+ next if value.nil? || value == false
261
+ key_str = key.to_s.tr('_', '-')
262
+ value == true ? " #{key_str}" : " #{key_str}=\"#{value}\""
263
+ end.join
264
+ end
265
+
266
+ # Get default script attributes with auto-nonce detection
267
+ def default_script_attributes(**user_attributes)
268
+ attributes = {}
269
+
270
+ # Auto-add nonce if CSP is enabled and not explicitly provided
271
+ if !user_attributes.key?(:nonce) && respond_to?(:content_security_policy_nonce)
272
+ nonce = content_security_policy_nonce
273
+ attributes[:nonce] = nonce if nonce
274
+ end
275
+
276
+ attributes.merge(user_attributes)
277
+ end
278
+
279
+ # Get formatted HTML attributes string for script tags
280
+ def script_html_attributes(**attributes)
281
+ script_attributes = default_script_attributes(**attributes)
282
+ format_html_attributes(**script_attributes)
283
+ end
284
+
240
285
  # Whether the floating UMD versions debug footer should render
241
286
  def umd_debug_enabled?
242
287
  return false unless Rails.env.development?
@@ -274,9 +319,11 @@ module IslandjsRails
274
319
  end
275
320
 
276
321
  # Generate React component mounting script with Turbo compatibility
277
- def generate_react_mount_script(component_name, component_id, namespace, namespace_with_optional)
322
+ def generate_react_mount_script(component_name, component_id, namespace, namespace_with_optional, **attributes)
323
+ html_attributes = script_html_attributes(**attributes)
324
+
278
325
  <<~JAVASCRIPT
279
- <script>
326
+ <script#{html_attributes}>
280
327
  (function() {
281
328
  function mount#{component_name}() {
282
329
  const container = document.getElementById('#{component_id}');
@@ -307,13 +354,13 @@ module IslandjsRails
307
354
  const element = React.createElement(#{namespace_with_optional}.#{component_name}, props);
308
355
 
309
356
  try {
310
- // Use React 18 createRoot if available, fallback to React 17 render
357
+ // Use React 19 createRoot if available, fallback to React 17 render
311
358
  if (window.ReactDOM.createRoot) {
312
359
  if (!container._reactRoot) {
313
360
  container._reactRoot = window.ReactDOM.createRoot(container);
314
361
  }
315
362
  container._reactRoot.render(element);
316
- // React 18 automatically clears container - no manual cleanup needed
363
+ // React 19 automatically clears container - no manual cleanup needed
317
364
  } else {
318
365
  // React 17 - render is synchronous and clears container automatically
319
366
  window.ReactDOM.render(element, container);
@@ -328,7 +375,7 @@ module IslandjsRails
328
375
  const container = document.getElementById('#{component_id}');
329
376
  if (!container) return;
330
377
 
331
- // React 18 unmount
378
+ // React 19 unmount
332
379
  if (container._reactRoot) {
333
380
  container._reactRoot.unmount();
334
381
  container._reactRoot = null;
@@ -360,9 +407,11 @@ module IslandjsRails
360
407
  end
361
408
 
362
409
  # Generate Vue component mounting script with Turbo compatibility
363
- def generate_vue_mount_script(component_name, component_id, props_json)
410
+ def generate_vue_mount_script(component_name, component_id, props_json, **attributes)
411
+ html_attributes = script_html_attributes(**attributes)
412
+
364
413
  <<~JAVASCRIPT
365
- <script>
414
+ <script#{html_attributes}>
366
415
  (function() {
367
416
  let vueApp = null;
368
417
 
@@ -13,7 +13,7 @@ namespace :islandjs do
13
13
 
14
14
  if package_name.nil?
15
15
  puts "❌ Package name is required"
16
- puts "Usage: rails \"islandjs:install[react,18.3.1]\""
16
+ puts "Usage: rails \"islandjs:install[react,19.2.0]\""
17
17
  exit 1
18
18
  end
19
19
 
@@ -27,7 +27,7 @@ namespace :islandjs do
27
27
 
28
28
  if package_name.nil?
29
29
  puts "❌ Package name is required"
30
- puts "Usage: rails \"islandjs:update[react,18.3.1]\""
30
+ puts "Usage: rails \"islandjs:update[react,19.2.0]\""
31
31
  exit 1
32
32
  end
33
33
 
@@ -1,3 +1,3 @@
1
1
  module IslandjsRails
2
- VERSION = "0.4.0"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -22,6 +22,8 @@ module IslandjsRails
22
22
  'umd/{name}.production.min.js',
23
23
  'umd/{name}.development.js',
24
24
  'umd/{name}.min.js',
25
+ 'umd/{name}.js',
26
+ 'dist/{name}.production.min.js',
25
27
  'umd/{name}.js',
26
28
  'dist/{name}.min.js',
27
29
  'dist/{name}.js',
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: islandjs-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Arnold