Class: MaquinaStream::Generators::InstallGenerator
- Inherits:
-
Rails::Generators::Base
- Object
- Rails::Generators::Base
- MaquinaStream::Generators::InstallGenerator
- Defined in:
- lib/generators/maquina_stream/install/install_generator.rb
Overview
Wires the engine into a host: the initializer, the mount, the importmap pins, the Stimulus registration and the stylesheets.
bin/rails generate maquina_stream:install
Every step is idempotent and none of them overwrites a host file. A step whose ingredient is missing — no importmap, no Stimulus entrypoint, no layout — says what to do by hand instead of failing or silently doing nothing, because a generator that no-ops quietly is worse than one that is not there.
Two things it exists to prevent, both learned the hard way:
- Turbo must be pinned by the host. Repair applies Turbo Stream
morphs; with
window.Turboundefined every repair fails inside a catch and nothing in the browser says so. - A deferred-renderer pin needs
preload: false. importmap-rails preloads by default, which fetches the library on every page and defeats the lazy import it exists to avoid.
Constant Summary collapse
- INITIALIZER =
"config/initializers/maquina_stream.rb"- ROUTES =
"config/routes.rb"- IMPORTMAP =
"config/importmap.rb"- LAYOUT =
"app/views/layouts/application.html.erb"- ENTRYPOINTS =
Where
registerMaquinaStreamControllers(application)can go, best first. Both have anapplicationin scope in a stock importmap app. %w[ app/javascript/controllers/index.js app/javascript/application.js ].freeze
- MOUNT =
'mount MaquinaStream::Engine => "/maquina_stream"'- TURBO_PIN =
<<~RUBY # Required by maquina_stream: repair applies Turbo Stream morphs, and with # `window.Turbo` undefined every repair fails silently inside a catch. pin "@hotwired/turbo-rails", to: "turbo.min.js" RUBY
- DEFERRED_PINS =
<<~RUBY # Libraries the client-deferred renderers import lazily. `preload: false` is # load-bearing: importmap-rails preloads by default, which would emit a # <link rel="modulepreload"> and fetch both on every page — exactly the cost # the lazy import inside `ms-deferred#library()` exists to avoid. pin "mermaid", to: "https://cdn.jsdelivr.net/npm/[email protected]/+esm", preload: false pin "katex", to: "https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.mjs", preload: false RUBY
- REGISTRATION =
<<~JS // maquina_stream registers its own Stimulus identifiers rather than relying // on an eager-load glob: those identifiers are part of the DOM contract. import { registerMaquinaStreamControllers } from "maquina_stream" registerMaquinaStreamControllers(application) JS
- STYLESHEETS =
<<~ERB <%= stylesheet_link_tag "maquina_stream/reveal" %> <%= stylesheet_link_tag "maquina_stream/themes/light" %> <%= stylesheet_link_tag "maquina_stream/themes/dark" %> ERB
Instance Method Summary collapse
- #create_initializer ⇒ Object
- #link_stylesheets ⇒ Object
- #mount_engine ⇒ Object
- #pin_deferred_renderers ⇒ Object
- #pin_turbo ⇒ Object
- #register_controllers ⇒ Object
- #report_the_two_seams ⇒ Object
Instance Method Details
#create_initializer ⇒ Object
78 79 80 81 82 83 84 |
# File 'lib/generators/maquina_stream/install/install_generator.rb', line 78 def create_initializer if exists?(INITIALIZER) skip INITIALIZER, "already exists — left untouched" else template "initializer.rb.tt", INITIALIZER end end |
#link_stylesheets ⇒ Object
117 118 119 120 121 122 |
# File 'lib/generators/maquina_stream/install/install_generator.rb', line 117 def link_stylesheets return by_hand(LAYOUT, STYLESHEETS) unless exists?(LAYOUT) return skip(LAYOUT, "stylesheets already linked") if read(LAYOUT).include?("maquina_stream/reveal") inject_into_file LAYOUT, STYLESHEETS.gsub(/^/, " "), before: %r{^\s*</head>} end |
#mount_engine ⇒ Object
86 87 88 89 90 91 |
# File 'lib/generators/maquina_stream/install/install_generator.rb', line 86 def mount_engine return by_hand(ROUTES, MOUNT) unless exists?(ROUTES) return skip(ROUTES, "engine already mounted") if read(ROUTES).include?("MaquinaStream::Engine") route MOUNT end |
#pin_deferred_renderers ⇒ Object
101 102 103 104 105 106 107 |
# File 'lib/generators/maquina_stream/install/install_generator.rb', line 101 def pin_deferred_renderers return unless [:deferred_renderers] return by_hand(IMPORTMAP, DEFERRED_PINS) unless exists?(IMPORTMAP) return skip(IMPORTMAP, "mermaid and katex already pinned") if read(IMPORTMAP).include?('pin "mermaid"') append_to_file IMPORTMAP, "\n#{DEFERRED_PINS}" end |
#pin_turbo ⇒ Object
93 94 95 96 97 98 99 |
# File 'lib/generators/maquina_stream/install/install_generator.rb', line 93 def pin_turbo return by_hand(IMPORTMAP, TURBO_PIN, importmap_absent_note) unless exists?(IMPORTMAP) return skip(IMPORTMAP, "@hotwired/turbo-rails already pinned") if read(IMPORTMAP).include?("@hotwired/turbo-rails") return turbo_missing unless turbo_available? append_to_file IMPORTMAP, "\n#{TURBO_PIN}" end |
#register_controllers ⇒ Object
109 110 111 112 113 114 115 |
# File 'lib/generators/maquina_stream/install/install_generator.rb', line 109 def register_controllers entrypoint = ENTRYPOINTS.find { |path| exists?(path) && read(path).match?(/\bapplication\b/) } return by_hand(ENTRYPOINTS.first, REGISTRATION, entrypoint_absent_note) if entrypoint.nil? return skip(entrypoint, "controllers already registered") if read(entrypoint).include?("registerMaquinaStreamControllers") append_to_file entrypoint, "\n#{REGISTRATION}" end |
#report_the_two_seams ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/generators/maquina_stream/install/install_generator.rb', line 124 def report_the_two_seams say "" say "maquina_stream is wired. Two things are still yours:", :green say "" say " 1. #{INITIALIZER} — `authorize` is a stub that denies everything." say " Until you replace it every repair request is refused, which is safe" say " and also broken: the browser can never repair a message." say "" say " 2. bin/rails generate maquina_stream:streamable Message" say " — the migration and the model macro, and it fills in `find_stream`." say "" end |