react_on_rails_pro 16.3.0.rc.1 → 16.3.0.rc.2

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: 9bcbae8e9b968c6c6b8b9f707f9c7595015c56af77c29e3b0c069063469bd812
4
- data.tar.gz: a084d5851b315254056a147320f70c14a2052fe5c4dee0244171d0281ae75053
3
+ metadata.gz: cc236969b444c2c9f738559fd9a3e950c99ad2270916493938cf41fc336ba8bb
4
+ data.tar.gz: 2d11cd0f177d4a970c3304b9a039a9e4a9b8b0d4f5bff14c701f18e30636aa7a
5
5
  SHA512:
6
- metadata.gz: 0a5a0c698d58a49260e31acd91ac9cc8d7135229e838dd890df0aa415bec027a39db2afaee1257218fecf0e85c82c468b9d37bd92b5a27abbbd78bc16ce2500f
7
- data.tar.gz: 520c471a7c2bbd168664f2d719d1ca3e8dd1e8d028d8bc2b8ebadccd1fe633cf6bdfa3e9bb4adca916d351ecf22f42ddc58db00fe6976353913700ed16ecc393
6
+ metadata.gz: e7bd44d3915dc10bcfb2c26b46c20400e617273f666ab556e038ad336a6fc041cb783c30bf2d10cce509712cf6c6708fc3fdceb5af16c8d523ca28bd2ee184c7
7
+ data.tar.gz: f750769c29e546b39798de80bf16caa6adf1f707ed329d791cd56f38b8c6806afe8485a0be5e16adb245ffaf7c81d5d8aee2fcc502c2b0c5ff436ce636602637
data/CHANGELOG.md CHANGED
@@ -25,6 +25,7 @@ Changes since the last non-beta release.
25
25
 
26
26
  ### Added
27
27
 
28
+ - **Multiple License Plan Types**: License validation now supports multiple plan types beyond "paid": `startup`, `nonprofit`, `education`, `oss`, and `partner`. Non-paid plan types are displayed in the license validation success message (e.g., "License validated successfully (startup license)."). Includes thread-safe caching for plan type retrieval via `LicenseValidator.license_plan`. [PR 2334](https://github.com/shakacode/react_on_rails/pull/2334) by [justin808](https://github.com/justin808).
28
29
  - **Node Renderer Master/Worker Exports**: Added public `master` and `worker` exports to `react-on-rails-pro-node-renderer` package, allowing users to import from `react-on-rails-pro-node-renderer/master` and `react-on-rails-pro-node-renderer/worker`. [PR 2326](https://github.com/shakacode/react_on_rails/pull/2326) by [justin808](https://github.com/justin808).
29
30
 
30
31
  ## [16.2.0] - 2026-01-14
data/CONTRIBUTING.md CHANGED
@@ -119,7 +119,7 @@ script/ci-changes-detector origin/master
119
119
  - Push Pro changes without testing locally first
120
120
  - Modify both Pro and main gem without running full tests
121
121
 
122
- For comprehensive CI documentation, see [`../docs/CI_OPTIMIZATION.md`](../docs/CI_OPTIMIZATION.md) in the repository root.
122
+ For comprehensive CI documentation, see [`../docs/contributor-info/ci-optimization.md`](../docs/contributor-info/ci-optimization.md) in the repository root.
123
123
 
124
124
  # IDE/Editor Setup
125
125
 
data/Gemfile.lock CHANGED
@@ -9,7 +9,7 @@ GIT
9
9
  PATH
10
10
  remote: ..
11
11
  specs:
12
- react_on_rails (16.3.0.rc.1)
12
+ react_on_rails (16.3.0.rc.2)
13
13
  addressable
14
14
  connection_pool
15
15
  execjs (~> 2.5)
@@ -20,7 +20,7 @@ PATH
20
20
  PATH
21
21
  remote: .
22
22
  specs:
23
- react_on_rails_pro (16.3.0.rc.1)
23
+ react_on_rails_pro (16.3.0.rc.2)
24
24
  addressable
25
25
  async (>= 2.6)
26
26
  connection_pool
@@ -29,7 +29,7 @@ PATH
29
29
  httpx (~> 1.5)
30
30
  jwt (~> 2.7)
31
31
  rainbow
32
- react_on_rails (= 16.3.0.rc.1)
32
+ react_on_rails (= 16.3.0.rc.2)
33
33
 
34
34
  GEM
35
35
  remote: https://rubygems.org/
data/docs/caching.md CHANGED
@@ -114,7 +114,7 @@ The reasons "why" and "why not" are the same as for basic Rails fragment caching
114
114
  ### Considerations for Determining Your Cache Key
115
115
 
116
116
  1. Consult the [Rails docs for cache keys](http://guides.rubyonrails.org/caching_with_rails.html#cache-keys) for help with cache key definitions.
117
- 2. If your React code depends on any values from the [Rails Context](https://github.com/shakacode/react_on_rails/blob/master/docs/core-concepts/render-functions-and-railscontext.md#rails-context), such as the `locale` or the URL `location`, then be sure to include such values in your cache key. In other words, if you are using some JavaScript such as `react-router` that depends on your URL, or on a call to `toLocalString(locale)`, then be sure to include such values in your cache key. To find the values that React on Rails uses, use some code like this:
117
+ 2. If your React code depends on any values from the [Rails Context](../../docs/core-concepts/render-functions-and-railscontext.md#rails-context), such as the `locale` or the URL `location`, then be sure to include such values in your cache key. In other words, if you are using some JavaScript such as `react-router` that depends on your URL, or on a call to `toLocalString(locale)`, then be sure to include such values in your cache key. To find the values that React on Rails uses, use some code like this:
118
118
 
119
119
  ```ruby
120
120
  the_rails_context = rails_context
data/docs/home-pro.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # React on Rails Pro
2
2
 
3
- Node rendering and caching performance enhancements for [React on Rails](https://github.com/shakacode/react_on_rails). Now supports React 18 with updates to React on Rails! Check the [React on Rails CHANGELOG.md](https://github.com/shakacode/react_on_rails/blob/master/CHANGELOG.md) for details and the updates to the [loadable-components instructions](https://github.com/shakacode/react_on_rails_pro/blob/master/docs/code-splitting-loadable-components.md).
3
+ Node rendering and caching performance enhancements for [React on Rails](https://github.com/shakacode/react_on_rails). Now supports React 18 with updates to React on Rails! Check the [React on Rails CHANGELOG.md](https://github.com/shakacode/react_on_rails/blob/master/CHANGELOG.md) for details and the updates to the [loadable-components instructions](./code-splitting-loadable-components.md).
4
4
 
5
5
  ## Getting Started
6
6
 
@@ -39,7 +39,7 @@ See [docs/caching](./caching.md) for more details.
39
39
 
40
40
  Suppose you detect that some library used in server-rendering is leaking state between calls to server render. In that case, you can set the `config.ssr_pre_hook_js` in your `config/initializers/react_on_rails_pro.rb` to run some JavaScript to clear the globally leaked state at the beginning of each call to server render.
41
41
 
42
- For more details, see [Rails Configuration](https://github.com/shakacode/react_on_rails/blob/master/docs/configuration/configuration.md).
42
+ For more details, see [Rails Configuration](../../docs/configuration/configuration.md).
43
43
 
44
44
  ### React On Rails Pro Node Renderer
45
45
 
data/docs/installation.md CHANGED
@@ -55,7 +55,7 @@ echo "your-license-token-here" > config/react_on_rails_pro_license.key
55
55
 
56
56
  ⚠️ **Security Warning**: Never commit your license token to version control. Add `config/react_on_rails_pro_license.key` to your `.gitignore`. For production, use environment variables or secure secret management systems (Rails credentials, Heroku config vars, AWS Secrets Manager, etc.).
57
57
 
58
- For complete license setup instructions, see [LICENSE_SETUP.md](../LICENSE_SETUP.md).
58
+ For complete license setup instructions, see [LICENSE_SETUP.md](https://github.com/shakacode/react_on_rails/blob/master/react_on_rails_pro/LICENSE_SETUP.md).
59
59
 
60
60
  ## Rails Configuration
61
61
 
@@ -89,3 +89,75 @@ And add this line to your `scripts` section of `package.json`
89
89
  ```
90
90
 
91
91
  `yarn start` will run the renderer.
92
+
93
+ ## Custom Fastify Configuration
94
+
95
+ For advanced use cases, you can customize the Fastify server instance by importing the `master` and `worker` modules directly. This is useful for:
96
+
97
+ - Adding custom routes (e.g., `/health` for container health checks)
98
+ - Registering Fastify plugins
99
+ - Adding custom hooks for logging or monitoring
100
+
101
+ ### Adding a Health Check Endpoint
102
+
103
+ When running the node-renderer in Docker or Kubernetes, you may need a `/health` endpoint for container health checks:
104
+
105
+ ```js
106
+ import masterRun from 'react-on-rails-pro-node-renderer/master';
107
+ import run, { configureFastify } from 'react-on-rails-pro-node-renderer/worker';
108
+ import cluster from 'cluster';
109
+
110
+ const config = {
111
+ // Your configuration options here
112
+ };
113
+
114
+ // Register a custom health check route
115
+ configureFastify((app) => {
116
+ app.get('/health', (request, reply) => {
117
+ reply.send({ status: 'ok' });
118
+ });
119
+ });
120
+
121
+ // The node-renderer uses Node.js cluster module to fork worker processes.
122
+ // The primary process manages workers; workers handle HTTP requests.
123
+ if (cluster.isPrimary) {
124
+ masterRun(config);
125
+ } else {
126
+ run(config);
127
+ }
128
+ ```
129
+
130
+ ### Registering Fastify Plugins
131
+
132
+ You can also register Fastify plugins. This example assumes you're using the same cluster setup pattern shown above:
133
+
134
+ ```js
135
+ // In the worker branch of your cluster setup (see example above)
136
+ import run, { configureFastify } from 'react-on-rails-pro-node-renderer/worker';
137
+ import cors from '@fastify/cors';
138
+
139
+ configureFastify((app) => {
140
+ // Register a plugin
141
+ app.register(cors, {
142
+ origin: true,
143
+ });
144
+ });
145
+
146
+ // Add request logging
147
+ configureFastify((app) => {
148
+ app.addHook('onRequest', (request, reply, done) => {
149
+ try {
150
+ console.log(`Request: ${request.method} ${request.url}`);
151
+ done();
152
+ } catch (err) {
153
+ done(err);
154
+ }
155
+ });
156
+ });
157
+ ```
158
+
159
+ > **Note:** The `configureFastify` function must be called before calling `run()`. Multiple callbacks can be registered and will execute in order. You can use `app.ready()` in your callback to ensure all plugins are loaded before performing operations that depend on them.
160
+
161
+ ### API Stability
162
+
163
+ The `./master` and `./worker` exports provide direct access to the node-renderer internals. While we strive to maintain backwards compatibility, these are considered advanced APIs. If you only need basic configuration, prefer using the standard `reactOnRailsProNodeRenderer` function with the configuration options documented above.
data/docs/updating.md CHANGED
@@ -179,7 +179,7 @@ echo "your-license-token-here" > config/react_on_rails_pro_license.key
179
179
 
180
180
  **Where to get your license token:** Contact [justin@shakacode.com](mailto:justin@shakacode.com) if you don't have your license token.
181
181
 
182
- For complete license setup instructions, see [LICENSE_SETUP.md](../LICENSE_SETUP.md).
182
+ For complete license setup instructions, see [LICENSE_SETUP.md](https://github.com/shakacode/react_on_rails/blob/master/react_on_rails_pro/LICENSE_SETUP.md).
183
183
 
184
184
  ### Verify Migration
185
185
 
@@ -10,6 +10,12 @@ module ReactOnRailsPro
10
10
  class LicenseValidator
11
11
  # Valid license plan types.
12
12
  # Must match VALID_PLANS in packages/react-on-rails-pro-node-renderer/src/shared/licenseValidator.ts
13
+ # - paid: Standard commercial license
14
+ # - startup: Complimentary for qualifying startups
15
+ # - nonprofit: Complimentary for non-profits
16
+ # - education: For educational institutions
17
+ # - oss: For open source projects
18
+ # - partner: Strategic partners
13
19
  VALID_PLANS = %w[paid startup nonprofit education oss partner].freeze
14
20
 
15
21
  # Plans that require attribution by default (complimentary licenses)
@@ -72,7 +78,7 @@ module ReactOnRailsPro
72
78
  end
73
79
 
74
80
  # Returns the license plan type if available
75
- # @return [String, nil] The plan type or nil if not available
81
+ # @return [String, nil] The plan type (e.g., "paid", "startup") or nil if not available
76
82
  def license_plan
77
83
  return @license_plan if defined?(@license_plan)
78
84
 
@@ -150,21 +156,17 @@ module ReactOnRailsPro
150
156
  # Determines the license expiration time from the decoded JWT
151
157
  # @return [Time, nil] The expiration time or nil if not available
152
158
  def determine_license_expiration
153
- license_string = load_license_string
154
- return nil unless license_string
155
-
156
- decoded_data = decode_license(license_string)
157
- return nil unless decoded_data
158
-
159
- exp = decoded_data["exp"]
160
- return nil unless exp
161
-
162
- exp_time = if exp.is_a?(Numeric)
163
- exp.to_i
164
- else
165
- Integer(exp)
166
- end
167
- Time.at(exp_time)
159
+ with_decoded_license do |decoded_data|
160
+ exp = decoded_data["exp"]
161
+ return nil unless exp
162
+
163
+ exp_time = if exp.is_a?(Numeric)
164
+ exp.to_i
165
+ else
166
+ Integer(exp)
167
+ end
168
+ Time.at(exp_time)
169
+ end
168
170
  rescue ArgumentError, TypeError
169
171
  nil
170
172
  end
@@ -184,19 +186,29 @@ module ReactOnRailsPro
184
186
  org.strip
185
187
  end
186
188
 
187
- # Determines the license plan from the decoded JWT
188
- # @return [String, nil] The plan type or nil if not available
189
+ # Determines the license plan type from the decoded JWT
190
+ # Returns nil for invalid/unknown plans - validation is handled by check_plan in license_status
191
+ # @return [String, nil] The plan type or nil if not available/invalid
189
192
  def determine_license_plan
193
+ with_decoded_license do |decoded_data|
194
+ plan = decoded_data["plan"]
195
+ return nil unless plan && VALID_PLANS.include?(plan)
196
+
197
+ plan
198
+ end
199
+ end
200
+
201
+ # Helper to load and decode license, yielding decoded data if successful
202
+ # @yield [Hash] The decoded license data
203
+ # @return [Object, nil] The block's return value or nil if license unavailable
204
+ def with_decoded_license
190
205
  license_string = load_license_string
191
206
  return nil unless license_string
192
207
 
193
208
  decoded_data = decode_license(license_string)
194
209
  return nil unless decoded_data
195
210
 
196
- plan = decoded_data["plan"]
197
- return nil unless plan.is_a?(String) && !plan.strip.empty?
198
-
199
- plan.strip
211
+ yield decoded_data
200
212
  end
201
213
 
202
214
  # Determines if attribution is required based on license data
@@ -258,7 +270,8 @@ module ReactOnRailsPro
258
270
 
259
271
  # Checks if the license plan is valid for production use
260
272
  # Licenses without a plan field are considered valid (backwards compatibility with old paid licenses)
261
- # Valid plans: paid, startup, nonprofit, education, oss, partner
273
+ # Plans in VALID_PLANS are valid; all other plans (e.g., "free") are invalid
274
+ # Note: Unknown plan types result in :invalid status, and license_plan returns nil
262
275
  # @return [Symbol] :valid or :invalid
263
276
  def check_plan(decoded_data)
264
277
  plan = decoded_data["plan"]
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReactOnRailsPro
4
- VERSION = "16.3.0.rc.1"
4
+ VERSION = "16.3.0.rc.2"
5
5
  PROTOCOL_VERSION = "2.0.0"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: react_on_rails_pro
3
3
  version: !ruby/object:Gem::Version
4
- version: 16.3.0.rc.1
4
+ version: 16.3.0.rc.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Gordon
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - '='
130
130
  - !ruby/object:Gem::Version
131
- version: 16.3.0.rc.1
131
+ version: 16.3.0.rc.2
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - '='
137
137
  - !ruby/object:Gem::Version
138
- version: 16.3.0.rc.1
138
+ version: 16.3.0.rc.2
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: bundler
141
141
  requirement: !ruby/object:Gem::Requirement