phlex-reactive 0.4.0 → 0.4.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 +21 -0
- data/lib/phlex/reactive/streamable.rb +5 -2
- data/lib/phlex/reactive/version.rb +1 -1
- data/lib/phlex/reactive.rb +25 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 786d397de0be7e32424c73079906cdf8d32d0325727d06027025d888693754e6
|
|
4
|
+
data.tar.gz: b080f12ff8c8f4271066993548f9c951278fe2dacabf9b7d21c2113704f58da4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 316b9b2094490dd5045d1362276a8f31ba4deee96df08e6614dc9db8f62a2ceb822f5a474d2204dcb65f7ed1bb27b3c99303f14a180a336c2d5bc3d21c3bf31a
|
|
7
|
+
data.tar.gz: f54ecfe74e977b3d4a399cd004071792a3a7245636d1c82f19441b0240fb2d24d32bb072a3ae863a9e04efcab5a31182560628237f72bf77ff73ac387592e4c4
|
data/CHANGELOG.md
CHANGED
|
@@ -72,6 +72,27 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
72
72
|
|
|
73
73
|
### Fixed
|
|
74
74
|
|
|
75
|
+
- **0.4.0 regression: re-renders lost the `request`, crashing `form_authenticity_token`
|
|
76
|
+
and other request-dependent helpers (#42).** The 0.4.0 render-path perf rework
|
|
77
|
+
built the cached off-request view context from a bare
|
|
78
|
+
`ActionController::Base.new.view_context`, whose controller has `request == nil`.
|
|
79
|
+
Any reactive component whose `view_template` calls `form_authenticity_token`,
|
|
80
|
+
`protect_against_forgery?`, or a host-aware URL helper (all of which read
|
|
81
|
+
`request.env`) then raised `NoMethodError: undefined method 'env' for nil` on
|
|
82
|
+
**every** re-render — through the action endpoint AND on broadcasts — so any app
|
|
83
|
+
with a reactive component rendering a Rails CSRF form could not adopt 0.4.0. Fixed
|
|
84
|
+
by building the cached view context through a request-bound controller
|
|
85
|
+
(`Phlex::Reactive.request_bound_view_context`), replicating exactly what
|
|
86
|
+
`ActionController::Renderer#render` does to set up its mock request: an
|
|
87
|
+
`ActionDispatch::Request` whose host is derived from the routes'
|
|
88
|
+
`default_url_options`. The 0.4.0 `render_in` speedup is kept — the request is set
|
|
89
|
+
up once when the per-thread context is built (not per render), and steady-state
|
|
90
|
+
render throughput/allocations are unchanged (retained-per-render stays 0). Covered
|
|
91
|
+
at the request level (a reactive `save` re-rendering a CSRF form returns 200, not
|
|
92
|
+
500), the broadcast level (the form component broadcasts without crashing), and the
|
|
93
|
+
unit level (a request is present on the cached context; host-aware `*_url` helpers
|
|
94
|
+
resolve when the renderer carries routes).
|
|
95
|
+
|
|
75
96
|
- **Multipart path silently dropped an explicit nested-hash / array param (#39).**
|
|
76
97
|
When an action declared a `:file` param alongside an explicit nested (hash/array)
|
|
77
98
|
param, the nested param was dropped on the multipart path while the JSON path
|
|
@@ -83,7 +83,10 @@ module Phlex
|
|
|
83
83
|
|
|
84
84
|
# Turbo::Streams::TagBuilder needs a real VIEW CONTEXT (it calls
|
|
85
85
|
# `.formats` on it), not a controller class. Build one off-request from
|
|
86
|
-
# the configured renderer controller
|
|
86
|
+
# the configured renderer controller, bound to a real request so
|
|
87
|
+
# request-dependent helpers (form_authenticity_token, host-aware URL
|
|
88
|
+
# helpers) work during a re-render/broadcast (issue #42). Memoized PER
|
|
89
|
+
# THREAD — building a
|
|
87
90
|
# view context instantiates the renderer controller and assembles its
|
|
88
91
|
# whole helper module set, so doing it per render/broadcast was the
|
|
89
92
|
# hottest server-side allocation in the action round trip. The builder
|
|
@@ -260,7 +263,7 @@ module Phlex
|
|
|
260
263
|
cached = store[self]
|
|
261
264
|
|
|
262
265
|
unless cached && cached.renderer.equal?(current) && cached.generation == generation
|
|
263
|
-
view_context = current
|
|
266
|
+
view_context = Phlex::Reactive.request_bound_view_context(current)
|
|
264
267
|
cached = ThreadViewContext.new(
|
|
265
268
|
view_context,
|
|
266
269
|
::Turbo::Streams::TagBuilder.new(view_context),
|
data/lib/phlex/reactive.rb
CHANGED
|
@@ -78,6 +78,30 @@ module Phlex
|
|
|
78
78
|
@renderer ||= defined?(::ActionController::Base) ? ::ActionController::Base : nil
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
+
# Build an off-request view context whose controller has a REAL `request`.
|
|
82
|
+
#
|
|
83
|
+
# A bare `controller.new.view_context` (the naive off-request context) has
|
|
84
|
+
# `request == nil`, so any request-dependent helper raises
|
|
85
|
+
# `undefined method 'env' for nil` — form_authenticity_token,
|
|
86
|
+
# protect_against_forgery?, and host-aware URL helpers all read
|
|
87
|
+
# `request.env` (issue #42). We replicate exactly what
|
|
88
|
+
# ActionController::Renderer#render does to set up its mock request — build
|
|
89
|
+
# an ActionDispatch::Request from the renderer's env (which derives the host
|
|
90
|
+
# from the routes' default_url_options), bind the routes, and attach it —
|
|
91
|
+
# then return the controller's view context instead of rendering a template.
|
|
92
|
+
# The result keeps the 0.4.0 render_in speedup (no renderer.render
|
|
93
|
+
# machinery) while restoring the request those helpers need.
|
|
94
|
+
def request_bound_view_context(controller_class)
|
|
95
|
+
ar_renderer = controller_class.renderer
|
|
96
|
+
request = ::ActionDispatch::Request.new(ar_renderer.send(:env_for_request))
|
|
97
|
+
request.routes = controller_class._routes
|
|
98
|
+
|
|
99
|
+
instance = controller_class.new
|
|
100
|
+
instance.set_request!(request)
|
|
101
|
+
instance.set_response!(controller_class.make_response!(request))
|
|
102
|
+
instance.view_context
|
|
103
|
+
end
|
|
104
|
+
|
|
81
105
|
# DOM id of the host-app container a Response#flash appends into.
|
|
82
106
|
# Default "flash"; override to match your layout's flash region.
|
|
83
107
|
def flash_target
|
|
@@ -136,7 +160,7 @@ module Phlex
|
|
|
136
160
|
generation = off_request_view_context_generation
|
|
137
161
|
|
|
138
162
|
unless cache && cache[:renderer].equal?(current) && cache[:generation] == generation
|
|
139
|
-
view_context = current
|
|
163
|
+
view_context = request_bound_view_context(current)
|
|
140
164
|
cache = {
|
|
141
165
|
view_context: view_context,
|
|
142
166
|
builder: ::Turbo::Streams::TagBuilder.new(view_context),
|