inertia_hanami 0.1.0 → 0.1.1
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/CHANGELOG.md +6 -2
- data/README.md +6 -0
- data/lib/inertia_hanami/version.rb +1 -1
- metadata +1 -2
- data/PLAN.md +0 -193
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5fdb1da127e8e1768f47439a5b5a71e6d17e68dc0f4fd0a0535200024e7fa076
|
|
4
|
+
data.tar.gz: f142913ca589c4409a9ba99c6cc4abce692d05e1e047c9be80ec5dc26bece953
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e09beeb585c74bbe8a4cd73d9c0a89994595d2517a6e1ea64a5f401a8de9ce1367b647f9b383b113e63acbca5b9cf73908ceefc75a8c40e1e5fcaa540e3cff49
|
|
7
|
+
data.tar.gz: fe7db5d264688a5bce470b08851ed34416947084611a9794eb398d9a94693ba0c66c5c478b4cf223db703dde0b4e946dab0fa3ea556855c85621359d0c5fc498
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
## [
|
|
1
|
+
## [0.1.1] - 2026-08-29
|
|
2
|
+
|
|
3
|
+
- Exclude `PLAN.md` from the packaged gem.
|
|
4
|
+
|
|
5
|
+
## [0.1.0] - 2026-08-28
|
|
2
6
|
|
|
3
7
|
- Add encrypted history support: `Configuration#encrypt_history` global default, class-level
|
|
4
8
|
`encrypt_history` macro (inherited down subclasses), and instance-level `encrypt_history`/
|
|
@@ -13,6 +17,6 @@
|
|
|
13
17
|
per the `X-Inertia-Infinite-Scroll-Merge-Intent` header) instead of replacing the existing
|
|
14
18
|
prop, and reports pagination metadata via the response's `scrollProps` map.
|
|
15
19
|
|
|
16
|
-
## [0.
|
|
20
|
+
## [0.0.0] - 2026-08-20
|
|
17
21
|
|
|
18
22
|
- Initial release
|
data/README.md
CHANGED
|
@@ -398,6 +398,12 @@ inertia_reload_only("name")
|
|
|
398
398
|
expect(inertia).to have_exact_props(name: "Ada")
|
|
399
399
|
```
|
|
400
400
|
|
|
401
|
+
## Example applications
|
|
402
|
+
|
|
403
|
+
- [book_react_hanami](https://github.com/kamalogudah/book_react_hanami) - React
|
|
404
|
+
- [book_svelte_hanami](https://github.com/kamalogudah/book_svelte_hanami) - Svelte
|
|
405
|
+
- [book_vue_hanami](https://github.com/kamalogudah/book_vue_hanami) - Vue
|
|
406
|
+
|
|
401
407
|
## Development
|
|
402
408
|
|
|
403
409
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: inertia_hanami
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Paul Oguda
|
|
@@ -133,7 +133,6 @@ files:
|
|
|
133
133
|
- CHANGELOG.md
|
|
134
134
|
- CODE_OF_CONDUCT.md
|
|
135
135
|
- LICENSE.txt
|
|
136
|
-
- PLAN.md
|
|
137
136
|
- README.md
|
|
138
137
|
- Rakefile
|
|
139
138
|
- lib/generators/inertia_hanami/install_generator.rb
|
data/PLAN.md
DELETED
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
# inertia_hanami — Implementation Plan
|
|
2
|
-
|
|
3
|
-
Server-side adapter implementing the [Inertia.js protocol](https://inertiajs.com/docs/v2/installation/community-adapters)
|
|
4
|
-
for [Hanami](https://hanakai.org/hanami) (targeting **Hanami 3.0+**, Ruby 3.3+).
|
|
5
|
-
|
|
6
|
-
No prior Hanami/Inertia integration exists (verified via GitHub/forum search) — this is greenfield.
|
|
7
|
-
Design is synthesized from two existing Ruby adapters:
|
|
8
|
-
|
|
9
|
-
- **[inertia-rails](https://github.com/inertiajs/inertia-rails)** — the reference implementation. Full protocol
|
|
10
|
-
coverage (deferred/merge/once props, SSR, encrypted history, testing helpers). Deeply coupled to Rails/ActiveSupport
|
|
11
|
-
(`ActionController::Renderers`, `deep_merge!`, `HashWithIndifferentAccess`, Rails middleware stack, engine/railtie).
|
|
12
|
-
- **[inertia-rage](https://github.com/rage-rb/inertia-rage)** — proves the protocol is portable to a non-Rails,
|
|
13
|
-
non-ActiveSupport Ruby framework. Zero dependency on `inertia_rails`; clean-room reimplementation. Structurally the
|
|
14
|
-
closer template for us, since Rage (like Hanami) is Rack-based with its own controller/config/plugin conventions
|
|
15
|
-
and no ActiveSupport. It's missing SSR support and only ships RSpec helpers — gaps we should not blindly copy.
|
|
16
|
-
|
|
17
|
-
## What to take from each, concretely
|
|
18
|
-
|
|
19
|
-
| Concern | Take from | Why |
|
|
20
|
-
|---|---|---|
|
|
21
|
-
| Protocol envelope shape, header names, prop-type taxonomy | inertia-rails | It's the canonical spec; inertia-rage's prop set is a subset |
|
|
22
|
-
| Partial-reload resolution algorithm (only/except/reset/dot-paths) | inertia-rails (`props_resolver.rb`), cross-checked against inertia-rage's `protocol_builder.rb` | Same algorithm, inertia-rage's version is already ActiveSupport-free and shorter — better starting point to port |
|
|
23
|
-
| Prop wrapper classes (`Optional`, `Defer`, `Merge`, `Always`, `Once`) | inertia-rage's `Data`-based implementation | Ruby's builtin `Data` class needs no ActiveSupport; inertia-rails uses plain classes + mixins, functionally equivalent but rage's is more idiomatic modern Ruby |
|
|
24
|
-
| Controller/action integration pattern | Neither directly — Hanami's own `#auto_render?` + module `include` idiom | Hanami actions favor composition (`include Inertia::Action`) over subclassing a framework base class the way both Rails (`ActionController::Base`) and Rage (`RageController::Inertia`) do |
|
|
25
|
-
| Middleware (version-mismatch 409, redirect-to-303 rewrite) | inertia-rails logic, inertia-rage's leaner Rack-only style | Same responsibilities, but implement as plain Rack middleware with no framework hooks, registered via `config.middleware.use` |
|
|
26
|
-
| CSRF handling | **Neither** — reuse Hanami/Rack's own CSRF middleware | inertia-rails uses Rails' token CSRF; inertia-rage hand-rolls `Sec-Fetch-Site` checks. Hanami ships its own session/CSRF story via `hanami-controller` — bridge to that instead of reimplementing either |
|
|
27
|
-
| Configuration mechanism | Hanami's own `register_provider` / container DI | Neither Rails initializers nor Rage's `Rage::Extension` apply; Hanami's provider system is the idiomatic equivalent |
|
|
28
|
-
| Asset versioning | Concept from both (`ssr_bundle`/manifest hash, Vite manifest) | Adapted to `hanami-assets`' `assets.json` manifest instead of Vite's `manifest.json` |
|
|
29
|
-
| SSR | inertia-rails only (inertia-rage has none) | Defer to a later phase; inertia-rails' `SSRRenderer` (POST page JSON to a Node process, cache by content hash) is the pattern to port |
|
|
30
|
-
| Testing helpers | inertia-rails' RSpec matcher set (broader than inertia-rage's) | Port `have_props`, `have_exact_props`, `render_component`, `be_inertia_response`, etc. |
|
|
31
|
-
|
|
32
|
-
## Target Hanami integration points (from architecture research)
|
|
33
|
-
|
|
34
|
-
- `Hanami::Action#handle(request, response)` is the Rack entrypoint. `response.format=`, `response.body=`,
|
|
35
|
-
`response.headers`, `response[:key]=` (exposures) are all directly settable — no forced rendering step.
|
|
36
|
-
- `#auto_render?(response)` returning `false` is the exact bypass point for JSON-only Inertia XHR responses (avoids
|
|
37
|
-
Hanami auto-invoking the paired `Views::*` class for `X-Inertia: true` requests).
|
|
38
|
-
- Layouts (`config.layout = "app"`, `app/templates/layouts/app.html.erb` convention — confirmed against
|
|
39
|
-
`hanami-cli`'s app generator and `hanami-view`'s `layouts_dir`/`layout` config) are the analog of Rails'
|
|
40
|
-
`application.html.erb` — used only for the **initial full-page load**, rendering `<div id="app" data-page="...">`.
|
|
41
|
-
Note: `app/views/**/*.rb` holds `Hanami::View` subclasses; ERB markup (including layouts) lives under
|
|
42
|
-
`app/templates/**`, not `app/views/**` as an earlier draft of this doc assumed.
|
|
43
|
-
- View helpers meant to be callable unqualified from ERB templates/layouts (e.g. `inertia_root`) must be mixed
|
|
44
|
-
into `<App>::Views::Helpers` (`app/views/helpers.rb`), not into the `View` base class — Hanami's
|
|
45
|
-
`SliceConfiguredHelpers` auto-includes that module into the app's `Scope`/`Part` classes
|
|
46
|
-
(`hanami/extensions/view/slice_configured_helpers.rb`), whereas including into `Hanami::View` itself has no
|
|
47
|
-
effect on template scope.
|
|
48
|
-
- **Action exposures do not automatically become template/layout locals.** `response[:key] = value` only reaches
|
|
49
|
-
a view template as a local if the paired `Hanami::View` subclass declares `expose :key` (or a matching instance
|
|
50
|
-
method); unexposed keys are silently dropped (`Hanami::View::Exposures#call`). Further, **the layout template
|
|
51
|
-
receives a stricter, opt-in subset of the main template's locals** — only exposures declared
|
|
52
|
-
`expose :key, layout: true` are forwarded into the layout's scope (`Exposure#for_layout?` defaults to `false`).
|
|
53
|
-
So `inertia_root(page: page)` in a layout requires `expose :page, layout: true` in the view. (Verified
|
|
54
|
-
empirically against installed `hanami-view` 3.0.2; its own YARD example implying automatic pass-through does
|
|
55
|
-
not match runtime behavior.)
|
|
56
|
-
- `config/providers/*.rb` + `Hanami.app.register_provider` is where gem-level configuration
|
|
57
|
-
(`version`, `ssr_url`, `component_path_resolver`, etc.) gets registered as a container component
|
|
58
|
-
(`"inertia.config"`), consumed via `include Deps["inertia.config"]` — the Hanami equivalent of
|
|
59
|
-
`InertiaRails.configure`.
|
|
60
|
-
- Verified against the installed `hanami` (3.0.2) / `dry-system` (1.2.5) / `dry-configurable` (1.4.0)
|
|
61
|
-
gem source (Hanami's own built-in providers, e.g. `Hanami::Providers::DB`, `Hanami::Providers::I18n`,
|
|
62
|
-
follow the same pattern):
|
|
63
|
-
- **Namespacing is not automatic.** `register("config", obj)` inside a provider named `:inertia`
|
|
64
|
-
only resolves to container key `"inertia.config"` when the provider is registered with
|
|
65
|
-
`namespace: true` (`Hanami.app.register_provider(:inertia, namespace: true, source: InertiaHanami::Provider)`).
|
|
66
|
-
Without it, the key would just be `"config"`.
|
|
67
|
-
- **dry-configurable 1.4 does not delegate setting names onto the including instance.** A class that
|
|
68
|
-
`include Dry::Configurable` and defines `setting :version` does *not* get an instance method
|
|
69
|
-
`#version` — settings are only reachable via `#config` (e.g. `instance.config.version`). Confirmed
|
|
70
|
-
empirically (`instance.respond_to?(:version) # => false`) and in every built-in Hanami provider,
|
|
71
|
-
which reads its own settings as `config.foo`, never `self.foo`.
|
|
72
|
-
- Consequence for this doc's literal usage below (`Hanami.app["inertia.config"].version`) to hold with
|
|
73
|
-
no extra `.config.` hop: the provider must register the `Dry::Configurable::Config` object itself —
|
|
74
|
-
`register("config", InertiaHanami::Configuration.new.config)` — not the `Configuration` instance.
|
|
75
|
-
- `config.middleware.use` in `config/app.rb` registers Rack middleware app-wide; per-route middleware is also
|
|
76
|
-
supported via `use` inside route `scope` blocks.
|
|
77
|
-
- `hanami-assets` compiles to `public/assets/` with a manifest `assets.json` (source → hashed filename) — this
|
|
78
|
-
supplies the Inertia asset **version** string (hash of `assets.json`), same role Vite's `manifest.json` plays for
|
|
79
|
-
inertia-rage.
|
|
80
|
-
- Action testing is DI-based (`Action.new(deps...).call(params)`, no HTTP roundtrip needed) — good fit for unit
|
|
81
|
-
testing the prop-resolution engine directly; `rack-test` (bundled) covers full-stack request specs.
|
|
82
|
-
|
|
83
|
-
## Gem architecture
|
|
84
|
-
|
|
85
|
-
```
|
|
86
|
-
lib/inertia_hanami.rb # entrypoint, requires + configure block
|
|
87
|
-
lib/inertia_hanami/version.rb
|
|
88
|
-
lib/inertia_hanami/configuration.rb # `include Dry::Configurable`; settings (version, ssr, root_view,
|
|
89
|
-
# component_path_resolver, root_dom_id...) read via #config, dry-configurable 1.4 style
|
|
90
|
-
lib/inertia_hanami/provider.rb # Hanami::Provider::Source; registers Configuration.new.config as "config" under
|
|
91
|
-
# `register_provider(:inertia, namespace: true, ...)` -> resolves to "inertia.config"
|
|
92
|
-
lib/inertia_hanami/props.rb # Optional/Defer/Merge/Always/Once wrappers, Ruby Data-based (port from inertia-rage)
|
|
93
|
-
lib/inertia_hanami/prop_evaluator.rb # resolves Proc/BaseProp props against action instance
|
|
94
|
-
lib/inertia_hanami/protocol_builder.rb # partial-reload resolution: only/except/reset/dot-paths (port+adapt from inertia-rage)
|
|
95
|
-
lib/inertia_hanami/request_context.rb # parses X-Inertia-Partial-* / X-Inertia-Version headers off Rack env
|
|
96
|
-
lib/inertia_hanami/renderer.rb # builds the page envelope hash, decides JSON vs HTML branch
|
|
97
|
-
lib/inertia_hanami/action.rb # `Inertia::Action` module: include-able into Hanami::Action subclasses
|
|
98
|
-
# - #auto_render?(response) => false when request.inertia?
|
|
99
|
-
# - #inertia_render(component, props: {}, **opts)
|
|
100
|
-
# - #inertia_share(**props) class + instance macro
|
|
101
|
-
# - #inertia_location(url) for external redirects
|
|
102
|
-
lib/inertia_hanami/middleware/version.rb # 409 + X-Inertia-Location on version mismatch (GET only)
|
|
103
|
-
lib/inertia_hanami/middleware/redirects.rb # rewrite 301/302 -> 303 for PUT/PATCH/DELETE inertia requests
|
|
104
|
-
lib/inertia_hanami/ssr_renderer.rb # (phase 3) POST page JSON to Node SSR server, cache by digest
|
|
105
|
-
lib/inertia_hanami/helper.rb # view helper: inertia_root(page) -> data-page div/script tag
|
|
106
|
-
lib/inertia_hanami/errors.rb
|
|
107
|
-
lib/inertia_hanami/testing/rspec.rb # matchers: have_props, have_exact_props, be_inertia_response, render_component...
|
|
108
|
-
|
|
109
|
-
app/templates/layouts/app.html.erb (generator template) -> renders <%= inertia_root(page: page) %>
|
|
110
|
-
app/views/helpers.rb # `include InertiaHanami::Helper` into <App>::Views::Helpers,
|
|
111
|
-
# so `inertia_root` is callable unqualified in templates
|
|
112
|
-
lib/generators/inertia_hanami/install_generator.rb # (phase 2) scaffolds provider, layout, npm deps, example page
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## Protocol mechanics (ported from inertia-rails spec, verified against inertia-rage's leaner implementation)
|
|
116
|
-
|
|
117
|
-
- **Detection**: `request.env['HTTP_X_INERTIA'] == 'true'` (mirrors `ActionDispatch::Request#inertia?`).
|
|
118
|
-
- **Response envelope**: `{component, props, url, version, encryptHistory, clearHistory}` (+ `deferredProps`,
|
|
119
|
-
`mergeProps`, `deepMergeProps`, `matchPropsOn` metadata when relevant props are present).
|
|
120
|
-
- **On Inertia request** (`X-Inertia: true` header present): set `X-Inertia: true` response header,
|
|
121
|
-
`response.format = :json`, `response.body = [page.to_json]`. Skip Hanami's auto view rendering via `#auto_render? => false`.
|
|
122
|
-
- **On initial load** (no `X-Inertia` header): render the layout with `inertia_root(page:)` embedding
|
|
123
|
-
`<div id="app" data-page="#{page.to_json}"></div>`.
|
|
124
|
-
- **Version mismatch**: `Middleware::Version` compares `X-Inertia-Version` request header against
|
|
125
|
-
`Hanami.app["inertia.config"].version` on GET only; mismatch → `409` + `X-Inertia-Location` (empty body), so the
|
|
126
|
-
client does a full browser visit and picks up new assets.
|
|
127
|
-
- **Redirects**: rewrite `301/302` → `303` when the original method was PUT/PATCH/DELETE, so the browser doesn't
|
|
128
|
-
resubmit the body on the client-side follow-up GET. External-origin redirects on an Inertia request become
|
|
129
|
-
`409 + X-Inertia-Location` instead of a normal redirect (SPA can't follow cross-origin redirects via XHR).
|
|
130
|
-
- **Partial reloads**: `X-Inertia-Partial-Component` must match the component about to render, else partial mode is
|
|
131
|
-
ignored. `X-Inertia-Partial-Data` (only) / `X-Inertia-Partial-Except` (except) are comma-separated dot-paths.
|
|
132
|
-
`AlwaysProp` bypasses filtering; `Optional`/`Defer` props are excluded unless explicitly requested; `Once` props
|
|
133
|
-
are excluded once already sent (tracked via `X-Inertia-Reset` / an except-once header) — port inertia-rage's
|
|
134
|
-
`ProtocolBuilder` (~180 lines, already ActiveSupport-free) rather than inertia-rails' more Rails-idiomatic version.
|
|
135
|
-
- **Shared props**: `inertia_share(**hash, &block)` macro accumulates into an instance-level hash, block form
|
|
136
|
-
`instance_exec`'d against the action at render time, merged (shallow, no need to reimplement `deep_merge!` unless
|
|
137
|
-
a real use case demands it — start simple).
|
|
138
|
-
|
|
139
|
-
## Phased roadmap
|
|
140
|
-
|
|
141
|
-
**Phase 0 — scaffolding & spec baseline**
|
|
142
|
-
- Fill in gemspec (summary, homepage, dependencies: none required at runtime besides Ruby stdlib `json`; dev deps:
|
|
143
|
-
`hanami`, `hanami-controller`, `hanami-view`, `rack-test`, `rspec`).
|
|
144
|
-
- Set up a `spec/dummy_app` (minimal Hanami 3 app) for integration specs, matching how inertia-rails/inertia-rage
|
|
145
|
-
test against real dummy apps rather than mocks.
|
|
146
|
-
|
|
147
|
-
**Phase 1 — MVP protocol (no SSR, no generators)**
|
|
148
|
-
- `Configuration` + provider registration.
|
|
149
|
-
- `Props` wrappers + `PropEvaluator` + `ProtocolBuilder` (ported from inertia-rage, adapted naming).
|
|
150
|
-
- `RequestContext` header parsing.
|
|
151
|
-
- `Renderer` + `Action` module (`inertia_render`, `inertia_share`, `#auto_render?` override).
|
|
152
|
-
- `Middleware::Version`, `Middleware::Redirects`.
|
|
153
|
-
- `Helper#inertia_root` + example layout template.
|
|
154
|
-
- ~~Manual end-to-end test: dummy app renders a component, partial reload works, version-mismatch 409 works.~~ —
|
|
155
|
-
**Verified**: `spec/inertia_hanami/integration_spec.rb` exercises all three against the dummy app (both
|
|
156
|
-
middlewares now registered via `config.middleware.use` in `spec/dummy_app/config/app.rb`).
|
|
157
|
-
|
|
158
|
-
**Phase 2 — DX & polish**
|
|
159
|
-
- Install generator (scaffolds provider file, layout, adds `@inertiajs/*` guidance to package.json, sample page).
|
|
160
|
-
- Asset-version integration: derive `Configuration#version` automatically from `hanami-assets`' `assets.json` digest
|
|
161
|
-
when not explicitly set.
|
|
162
|
-
- RSpec testing helpers (`have_props`, `have_exact_props`, `have_no_prop`, `be_inertia_response`,
|
|
163
|
-
`render_component`, partial-reload request helpers).
|
|
164
|
-
- `flash`/`errors` prop wiring (Hanami session integration) analogous to inertia-rails' `always_include_errors_hash`.
|
|
165
|
-
|
|
166
|
-
**Phase 3 — SSR (optional, follow inertia-rails' design)**
|
|
167
|
-
- `SSRRenderer`: POST `page.to_json` to a configurable `ssr_url` (Node process), expects `{head:, body:}` JSON,
|
|
168
|
-
render into the layout in place of the CSR div, cache by content digest, fall back to CSR on error
|
|
169
|
-
(`ssr_raise_on_error` config toggle). No process-supervision plugin needed initially (unlike inertia-rails' Puma
|
|
170
|
-
plugin) — document running the Node SSR server as a separate process.
|
|
171
|
-
|
|
172
|
-
**Phase 4 — protocol completeness / parity audit**
|
|
173
|
-
- ~~Encrypted history (`encryptHistory`/`clearHistory` session flags).~~ — **Done**: envelope
|
|
174
|
-
plumbing (`Renderer`/`Action#inertia_render` kwargs) already existed; added the sticky
|
|
175
|
-
mechanism — `Configuration#encrypt_history` global default, class-level `encrypt_history`
|
|
176
|
-
macro (inherited down subclasses), instance-level `encrypt_history`/`clear_history`
|
|
177
|
-
overrides, all resolved in `Action::InstanceMethods#inertia_history_encrypted?` /
|
|
178
|
-
`#inertia_history_cleared?`. See `spec/inertia_hanami/action_spec.rb`'s "encrypted history"
|
|
179
|
-
block and `spec/inertia_hanami/configuration_spec.rb`.
|
|
180
|
-
- `Once`/scroll/infinite-scroll props if there's demand.
|
|
181
|
-
- CSRF: confirm Hanami/Rack session middleware already covers the `X-XSRF-TOKEN` ↔ cookie handshake Inertia's
|
|
182
|
-
client expects; add a thin bridge only if a gap is found — don't hand-roll CSRF from scratch like inertia-rage did.
|
|
183
|
-
|
|
184
|
-
## Open questions to resolve empirically against a real Hanami 3.0 app (docs were incomplete on these)
|
|
185
|
-
|
|
186
|
-
1. ~~Exact default layout file path/naming convention in Hanami 3.0~~ — **Resolved**: confirmed
|
|
187
|
-
`app/templates/layouts/app.html.erb` (default layout name `"app"`) against `hanami-cli`'s app generator and
|
|
188
|
-
`hanami-view`'s config; see "Target Hanami integration points" above.
|
|
189
|
-
2. Whether a provider can push onto `config.middleware` at boot time, or whether middleware registration must live
|
|
190
|
-
in `config/app.rb` directly (affects whether the gem can self-register middleware via an install generator vs.
|
|
191
|
-
requiring a manual `config.middleware.use InertiaHanami::Middleware::Version` line).
|
|
192
|
-
3. Per-route middleware/`use` block scoping semantics — needed if we want an opt-in per-route Inertia mode rather
|
|
193
|
-
than app-wide.
|