universal_renderer 0.4.2 → 0.4.4

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: a5fa544d66ff988bec74e5bb3219bc9fef83bfd4b4049559478134b138c73ade
4
- data.tar.gz: 159dfc977add1ede83e0dc3e3c37332556c1e0b0b127a0cc8a47923f676e1e49
3
+ metadata.gz: 40fcb0b84e6de636246a3b1d47e128d511bc0246b6a871fa2250a30907463987
4
+ data.tar.gz: 53b3200c0b02084ee00a534cbbc22513b9d616ff32ab9fcc98075a161495b1fd
5
5
  SHA512:
6
- metadata.gz: fafcf155308586b524e8b2a158add8cdc4b80a012c9cdcf9d35d38c2e2d5d9f204c99407430a7dfb65143a7f4f2d8838788a3e7d6741c9140688d6175baf3b73
7
- data.tar.gz: 8f952d4175fcf095e2aeb04fcf3e2d6d67a804e86613ad2a2a605623eef62e14249de60d639a1019396fa50b4761609bb67cc6b5efd86eec6508eba938278d64
6
+ metadata.gz: 5e028737cb85c1e220e26afe9491e0b8f49e922cd7bf16af335ab0016fbed1b870eebd93d36e25503a70646a1f0c895b11f3f6d4840d452f70e02912eecc09d2
7
+ data.tar.gz: 1c7d4b8708c07f631f7b43998a9d8083ca67737869557f4b26ef153a9911c9d2d28cab81e10824c5573912fc04507a7361080564105d0637ee217a26405bd9db
data/README.md CHANGED
@@ -12,22 +12,12 @@ UniversalRenderer helps you forward rendering requests to external SSR services,
12
12
 
13
13
  ## Features
14
14
 
15
- - **Static and streaming SSR** support
15
+ - **Streaming SSR** support
16
16
  - **Configurable SSR server endpoint** and timeouts
17
17
  - **Simple API** for passing data between Rails and your SSR service
18
18
  - **Automatic fallback** to client-side rendering if SSR fails
19
19
  - **View helpers** for easy integration into your layouts
20
20
 
21
- ## Requirements
22
-
23
- > **Heads-up ⚠️**  The JavaScript side of UniversalRenderer is **Bun-native**.
24
- >
25
- > • You **must** run the SSR server with **Bun ≥ 1.2**.
26
- >
27
- > • The exported helpers call Bun's built-in HTTP router and `Response` implementation; they **will not boot under Node, Deno, or Cloudflare Workers**.
28
- >
29
- > • The Ruby gem is runtime-agnostic and continues to work on every platform – only the SSR service requires Bun.
30
-
31
21
  ## Installation
32
22
 
33
23
  1. Add to your Gemfile:
@@ -61,9 +51,28 @@ end
61
51
 
62
52
  After installation, you can pass data to your SSR service using `add_prop` in your controllers:
63
53
 
54
+ ### SSR Modes
55
+
56
+ UniversalRenderer supports two SSR modes:
57
+
58
+ 1. **Standard SSR** (default): Fetches complete HTML from the SSR service before rendering
59
+ 2. **Streaming SSR**: Streams HTML content as it's generated (requires ActionController::Live)
60
+
61
+ ```ruby
62
+ # Standard SSR (recommended for most use cases)
63
+ enable_ssr
64
+
65
+ # Streaming SSR (only use if you need fast TTFB)
66
+ enable_ssr streaming: true
67
+ ```
68
+
64
69
  ```ruby
65
70
  class ProductsController < ApplicationController
66
- enable_ssr # enables SSR controller-wide
71
+ # Enable basic SSR (recommended for most use cases)
72
+ enable_ssr
73
+
74
+ # Or enable SSR with streaming (only if you need real-time rendering)
75
+ # enable_ssr streaming: true
67
76
 
68
77
  def show
69
78
  @product = Product.find(params[:id])
@@ -93,13 +102,13 @@ end
93
102
  ```erb
94
103
  <%# "ssr/index" %>
95
104
 
96
- <%# Inject SSR snippets using the provided helpers. When streaming is enabled
97
- these render HTML placeholders (<!-- SSR_HEAD --> / <!-- SSR_BODY -->);
98
- otherwise they output the sanitised HTML returned by the SSR service. %>
105
+ <%# Inject SSR snippets using the provided helpers %>
106
+ <%# When streaming is enabled these render HTML placeholders %>
107
+ <%# Otherwise they output the sanitised HTML returned by the SSR service %>
99
108
 
100
- <head>
109
+ <%= content_for :head do %>
101
110
  <%= ssr_head %>
102
- </head>
111
+ <% end %>
103
112
 
104
113
  <div id="root">
105
114
  <%= ssr_body %>
@@ -145,7 +154,7 @@ To set up the SSR server for your Rails application:
145
154
  query_data.forEach(({ key, data }) => queryClient.setQueryData(key, data));
146
155
  const state = dehydrate(queryClient);
147
156
 
148
- const jsx = sheet.collectStyles(
157
+ const app = sheet.collectStyles(
149
158
  <HelmetProvider context={helmetContext}>
150
159
  <Metadata url={url} />
151
160
  <QueryClientProvider client={queryClient}>
@@ -157,7 +166,7 @@ To set up the SSR server for your Rails application:
157
166
  </HelmetProvider>,
158
167
  );
159
168
 
160
- return { jsx, helmetContext, sheet, queryClient };
169
+ return { app, helmetContext, sheet, queryClient };
161
170
  }
162
171
  ```
163
172
 
@@ -198,18 +207,10 @@ To set up the SSR server for your Rails application:
198
207
  import { head, transform } from "@/ssr/utils";
199
208
  import { renderToString } from "react-dom/server.node";
200
209
  import { createServer } from "universal-renderer";
201
- import { createServer as createViteServer } from "vite";
202
-
203
- const vite = await createViteServer({
204
- server: { middlewareMode: true },
205
- appType: "custom",
206
- });
207
-
208
- await createServer({
209
- port: 3001,
210
- middleware: vite.middlewares,
211
210
 
211
+ const app = await createServer({
212
212
  setup: (await import("@/ssr/setup")).default,
213
+
213
214
  render: ({ app, helmet, sheet }) => {
214
215
  const root = renderToString(app);
215
216
  const styles = sheet.getStyleTags();
@@ -218,11 +219,14 @@ To set up the SSR server for your Rails application:
218
219
  body: `${root}\n${styles}`,
219
220
  };
220
221
  },
222
+
221
223
  cleanup: ({ sheet, queryClient }) => {
222
224
  sheet?.seal();
223
225
  queryClient?.clear();
224
226
  },
225
227
  });
228
+
229
+ app.listen(3001);
226
230
  ```
227
231
 
228
232
  5. Build the SSR bundle:
@@ -8,9 +8,13 @@ module UniversalRenderer
8
8
  response,
9
9
  stream_uri
10
10
  )
11
+ success = false
12
+
11
13
  http_client.request(http_post_request) do |node_res|
12
14
  if node_res.is_a?(Net::HTTPSuccess)
13
15
  node_res.read_body { |chunk| response.stream.write(chunk) }
16
+
17
+ success = true
14
18
  else
15
19
  Rails.logger.error(
16
20
  "SSR stream server at #{stream_uri} responded with #{node_res.code} #{node_res.message}."
@@ -19,18 +23,18 @@ module UniversalRenderer
19
23
  # Close stream without forwarding error to allow fallback to client rendering
20
24
  response.stream.close unless response.stream.closed?
21
25
 
22
- false
26
+ success = false
23
27
  end
24
28
  rescue StandardError => e
25
29
  Rails.logger.error(
26
30
  "Error during SSR data transfer or stream writing from #{stream_uri}: #{e.class.name} - #{e.message}"
27
31
  )
28
- false
32
+ success = false
29
33
  ensure
30
34
  response.stream.close unless response.stream.closed?
31
35
  end
32
36
 
33
- true
37
+ success
34
38
  end
35
39
  end
36
40
  end
@@ -3,11 +3,16 @@ module UniversalRenderer
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- include ActionController::Live
7
6
  helper UniversalRenderer::SSR::Helpers
8
7
  before_action :initialize_props
9
8
  end
10
9
 
10
+ module Streaming
11
+ extend ActiveSupport::Concern
12
+
13
+ included { include ActionController::Live }
14
+ end
15
+
11
16
  class_methods do
12
17
  def enable_ssr(options = {})
13
18
  class_attribute :enable_ssr, instance_writer: false
@@ -15,6 +20,8 @@ module UniversalRenderer
15
20
 
16
21
  class_attribute :ssr_streaming_preference, instance_writer: false
17
22
  self.ssr_streaming_preference = options[:streaming]
23
+
24
+ include UniversalRenderer::Renderable::Streaming if options[:streaming]
18
25
  end
19
26
  end
20
27
 
@@ -1,3 +1,3 @@
1
1
  module UniversalRenderer
2
- VERSION = "0.4.2".freeze
2
+ VERSION = "0.4.4".freeze
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: universal_renderer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - thaske
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-05-23 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: loofah
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '7.1'
33
33
  - - "<"
34
34
  - !ruby/object:Gem::Version
35
- version: '8.0'
35
+ version: '9.0'
36
36
  type: :runtime
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,7 +42,7 @@ dependencies:
42
42
  version: '7.1'
43
43
  - - "<"
44
44
  - !ruby/object:Gem::Version
45
- version: '8.0'
45
+ version: '9.0'
46
46
  description: Provides helper methods and configuration to forward rendering requests
47
47
  from a Rails app to an external SSR server and return the response.
48
48
  email:
@@ -93,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
93
  - !ruby/object:Gem::Version
94
94
  version: '0'
95
95
  requirements: []
96
- rubygems_version: 3.6.2
96
+ rubygems_version: 3.6.9
97
97
  specification_version: 4
98
98
  summary: Facilitates Server-Side Rendering (SSR) in Rails applications.
99
99
  test_files: []