react_on_rails 16.2.0.beta.3 → 16.2.0.beta.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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/CLAUDE.md +59 -0
  4. data/CONTRIBUTING.md +48 -0
  5. data/Gemfile.development_dependencies +1 -0
  6. data/Gemfile.lock +25 -2
  7. data/SWITCHING_CI_CONFIGS.md +55 -6
  8. data/Steepfile +51 -0
  9. data/bin/ci-rerun-failures +34 -11
  10. data/bin/ci-run-failed-specs +25 -1
  11. data/bin/ci-switch-config +254 -32
  12. data/bin/lefthook/check-trailing-newlines +2 -12
  13. data/bin/lefthook/eslint-lint +0 -10
  14. data/bin/lefthook/prettier-format +0 -10
  15. data/bin/lefthook/ruby-autofix +1 -5
  16. data/lib/react_on_rails/configuration.rb +56 -12
  17. data/lib/react_on_rails/controller.rb +3 -3
  18. data/lib/react_on_rails/doctor.rb +4 -2
  19. data/lib/react_on_rails/helper.rb +3 -3
  20. data/lib/react_on_rails/pro_helper.rb +2 -44
  21. data/lib/react_on_rails/react_component/render_options.rb +7 -7
  22. data/lib/react_on_rails/utils.rb +40 -0
  23. data/lib/react_on_rails/version.rb +1 -1
  24. data/react_on_rails_pro/CHANGELOG.md +135 -29
  25. data/react_on_rails_pro/Gemfile.development_dependencies +1 -0
  26. data/react_on_rails_pro/Gemfile.lock +6 -3
  27. data/react_on_rails_pro/README.md +559 -38
  28. data/react_on_rails_pro/docs/installation.md +40 -22
  29. data/react_on_rails_pro/docs/node-renderer/basics.md +26 -19
  30. data/react_on_rails_pro/docs/node-renderer/js-configuration.md +24 -22
  31. data/react_on_rails_pro/docs/node-renderer/troubleshooting.md +2 -0
  32. data/react_on_rails_pro/lib/react_on_rails_pro/version.rb +1 -1
  33. data/react_on_rails_pro/package.json +1 -1
  34. data/react_on_rails_pro/packages/node-renderer/src/master/restartWorkers.ts +39 -17
  35. data/react_on_rails_pro/packages/node-renderer/src/master.ts +15 -4
  36. data/react_on_rails_pro/packages/node-renderer/src/shared/configBuilder.ts +44 -5
  37. data/react_on_rails_pro/packages/node-renderer/src/shared/utils.ts +4 -2
  38. data/react_on_rails_pro/packages/node-renderer/src/worker/handleGracefulShutdown.ts +49 -0
  39. data/react_on_rails_pro/packages/node-renderer/src/worker/vm.ts +3 -3
  40. data/react_on_rails_pro/packages/node-renderer/src/worker.ts +5 -2
  41. data/react_on_rails_pro/packages/node-renderer/tests/helper.ts +8 -8
  42. data/react_on_rails_pro/packages/node-renderer/tests/testingNodeRendererConfigs.js +1 -1
  43. data/react_on_rails_pro/packages/node-renderer/tests/worker.test.ts +19 -19
  44. data/react_on_rails_pro/rakelib/rbs.rake +47 -0
  45. data/react_on_rails_pro/sig/react_on_rails_pro/cache.rbs +13 -0
  46. data/react_on_rails_pro/sig/react_on_rails_pro/configuration.rbs +100 -0
  47. data/react_on_rails_pro/sig/react_on_rails_pro/error.rbs +4 -0
  48. data/react_on_rails_pro/sig/react_on_rails_pro/utils.rbs +7 -0
  49. data/react_on_rails_pro/sig/react_on_rails_pro.rbs +5 -0
  50. data/react_on_rails_pro/spec/dummy/Gemfile.lock +6 -3
  51. data/react_on_rails_pro/spec/dummy/client/node-renderer.js +1 -1
  52. data/react_on_rails_pro/spec/dummy/spec/system/integration_spec.rb +16 -17
  53. data/sig/react_on_rails/controller.rbs +1 -1
  54. data/sig/react_on_rails/error.rbs +4 -0
  55. data/sig/react_on_rails/helper.rbs +2 -2
  56. data/sig/react_on_rails/json_parse_error.rbs +10 -0
  57. data/sig/react_on_rails/prerender_error.rbs +21 -0
  58. data/sig/react_on_rails/smart_error.rbs +28 -0
  59. data/sig/react_on_rails.rbs +3 -24
  60. metadata +14 -3
  61. data/lib/react_on_rails/pro_utils.rb +0 -37
@@ -0,0 +1,49 @@
1
+ import cluster from 'cluster';
2
+ import { FastifyInstance } from './types';
3
+ import { SHUTDOWN_WORKER_MESSAGE } from '../shared/utils';
4
+ import log from '../shared/log';
5
+
6
+ const handleGracefulShutdown = (app: FastifyInstance) => {
7
+ const { worker } = cluster;
8
+ if (!worker) {
9
+ log.error('handleGracefulShutdown is called on master, expected to call it on worker only');
10
+ return;
11
+ }
12
+
13
+ let activeRequestsCount = 0;
14
+ let isShuttingDown = false;
15
+
16
+ process.on('message', (msg) => {
17
+ if (msg === SHUTDOWN_WORKER_MESSAGE) {
18
+ log.debug('Worker #%d received graceful shutdown message', worker.id);
19
+ isShuttingDown = true;
20
+ if (activeRequestsCount === 0) {
21
+ log.debug('Worker #%d has no active requests, killing the worker', worker.id);
22
+ worker.destroy();
23
+ } else {
24
+ log.debug(
25
+ 'Worker #%d has "%d" active requests, disconnecting the worker',
26
+ worker.id,
27
+ activeRequestsCount,
28
+ );
29
+ worker.disconnect();
30
+ }
31
+ }
32
+ });
33
+
34
+ app.addHook('onRequest', (_req, _reply, done) => {
35
+ activeRequestsCount += 1;
36
+ done();
37
+ });
38
+
39
+ app.addHook('onResponse', (_req, _reply, done) => {
40
+ activeRequestsCount -= 1;
41
+ if (isShuttingDown && activeRequestsCount === 0) {
42
+ log.debug('Worker #%d served all active requests and going to be killed', worker.id);
43
+ worker.destroy();
44
+ }
45
+ done();
46
+ });
47
+ };
48
+
49
+ export default handleGracefulShutdown;
@@ -112,7 +112,7 @@ export async function runInVM(
112
112
  filePath: string,
113
113
  vmCluster?: typeof cluster,
114
114
  ): Promise<RenderResult> {
115
- const { bundlePath } = getConfig();
115
+ const { serverBundleCachePath } = getConfig();
116
116
 
117
117
  try {
118
118
  // Wait for VM creation if it's in progress
@@ -137,7 +137,7 @@ export async function runInVM(
137
137
  const workerId = vmCluster?.worker?.id;
138
138
  log.debug(`worker ${workerId ? `${workerId} ` : ''}received render request for bundle ${filePath} with code
139
139
  ${smartTrim(renderingRequest)}`);
140
- const debugOutputPathCode = path.join(bundlePath, 'code.js');
140
+ const debugOutputPathCode = path.join(serverBundleCachePath, 'code.js');
141
141
  log.debug(`Full code executed written to: ${debugOutputPathCode}`);
142
142
  await writeFileAsync(debugOutputPathCode, renderingRequest);
143
143
  }
@@ -165,7 +165,7 @@ ${smartTrim(renderingRequest)}`);
165
165
  if (log.level === 'debug') {
166
166
  log.debug(`result from JS:
167
167
  ${smartTrim(result)}`);
168
- const debugOutputPathResult = path.join(bundlePath, 'result.json');
168
+ const debugOutputPathResult = path.join(serverBundleCachePath, 'result.json');
169
169
  log.debug(`Wrote result to file: ${debugOutputPathResult}`);
170
170
  await writeFileAsync(debugOutputPathResult, result);
171
171
  }
@@ -17,6 +17,7 @@ import type { FastifyInstance, FastifyReply, FastifyRequest } from './worker/typ
17
17
  import checkProtocolVersion from './worker/checkProtocolVersionHandler';
18
18
  import authenticate from './worker/authHandler';
19
19
  import { handleRenderRequest, type ProvidedNewBundle } from './worker/handleRenderRequest';
20
+ import handleGracefulShutdown from './worker/handleGracefulShutdown';
20
21
  import {
21
22
  errorResponseResult,
22
23
  formatExceptionMessage,
@@ -117,7 +118,7 @@ export default function run(config: Partial<Config>) {
117
118
  // getConfig():
118
119
  buildConfig(config);
119
120
 
120
- const { bundlePath, logHttpLevel, port, fastifyServerOptions, workersCount } = getConfig();
121
+ const { serverBundleCachePath, logHttpLevel, port, fastifyServerOptions, workersCount } = getConfig();
121
122
 
122
123
  const app = fastify({
123
124
  http2: useHttp2 as true,
@@ -127,6 +128,8 @@ export default function run(config: Partial<Config>) {
127
128
  ...fastifyServerOptions,
128
129
  });
129
130
 
131
+ handleGracefulShutdown(app);
132
+
130
133
  // We shouldn't have unhandled errors here, but just in case
131
134
  app.addHook('onError', (req, res, err, done) => {
132
135
  // Not errorReporter.error so that integrations can decide how to log the errors.
@@ -148,7 +151,7 @@ export default function run(config: Partial<Config>) {
148
151
  fileSize: Infinity,
149
152
  },
150
153
  onFile: async (part) => {
151
- const destinationPath = path.join(bundlePath, 'uploads', part.filename);
154
+ const destinationPath = path.join(serverBundleCachePath, 'uploads', part.filename);
152
155
  // TODO: inline here
153
156
  await saveMultipartFile(part, destinationPath);
154
157
  // eslint-disable-next-line no-param-reassign
@@ -35,23 +35,23 @@ export function getOtherFixtureAsset() {
35
35
  return path.resolve(__dirname, `./fixtures/${ASSET_UPLOAD_OTHER_FILE}`);
36
36
  }
37
37
 
38
- export function bundlePath(testName: string) {
38
+ export function serverBundleCachePath(testName: string) {
39
39
  return path.resolve(__dirname, 'tmp', testName);
40
40
  }
41
41
 
42
42
  export function setConfig(testName: string) {
43
43
  buildConfig({
44
- bundlePath: bundlePath(testName),
44
+ serverBundleCachePath: serverBundleCachePath(testName),
45
45
  });
46
46
  }
47
47
 
48
48
  export function vmBundlePath(testName: string) {
49
- return path.resolve(bundlePath(testName), `${BUNDLE_TIMESTAMP}`, `${BUNDLE_TIMESTAMP}.js`);
49
+ return path.resolve(serverBundleCachePath(testName), `${BUNDLE_TIMESTAMP}`, `${BUNDLE_TIMESTAMP}.js`);
50
50
  }
51
51
 
52
52
  export function vmSecondaryBundlePath(testName: string) {
53
53
  return path.resolve(
54
- bundlePath(testName),
54
+ serverBundleCachePath(testName),
55
55
  `${SECONDARY_BUNDLE_TIMESTAMP}`,
56
56
  `${SECONDARY_BUNDLE_TIMESTAMP}.js`,
57
57
  );
@@ -76,7 +76,7 @@ export function secondaryLockfilePath(testName: string) {
76
76
  }
77
77
 
78
78
  export function uploadedBundleDir(testName: string) {
79
- return path.resolve(bundlePath(testName), 'uploads');
79
+ return path.resolve(serverBundleCachePath(testName), 'uploads');
80
80
  }
81
81
 
82
82
  export function uploadedBundlePath(testName: string) {
@@ -96,11 +96,11 @@ export function uploadedAssetOtherPath(testName: string) {
96
96
  }
97
97
 
98
98
  export function assetPath(testName: string, bundleTimestamp: string) {
99
- return path.resolve(bundlePath(testName), bundleTimestamp, ASSET_UPLOAD_FILE);
99
+ return path.resolve(serverBundleCachePath(testName), bundleTimestamp, ASSET_UPLOAD_FILE);
100
100
  }
101
101
 
102
102
  export function assetPathOther(testName: string, bundleTimestamp: string) {
103
- return path.resolve(bundlePath(testName), bundleTimestamp, ASSET_UPLOAD_OTHER_FILE);
103
+ return path.resolve(serverBundleCachePath(testName), bundleTimestamp, ASSET_UPLOAD_OTHER_FILE);
104
104
  }
105
105
 
106
106
  export async function createUploadedBundle(testName: string) {
@@ -129,7 +129,7 @@ export async function createAsset(testName: string, bundleTimestamp: string) {
129
129
  }
130
130
 
131
131
  export async function resetForTest(testName: string) {
132
- await fsExtra.emptyDir(bundlePath(testName));
132
+ await fsExtra.emptyDir(serverBundleCachePath(testName));
133
133
  resetVM();
134
134
  setConfig(testName);
135
135
  }
@@ -8,7 +8,7 @@ if (fs.existsSync(BUNDLE_PATH)) {
8
8
 
9
9
  const config = {
10
10
  // This is the default but avoids searching for the Rails root
11
- bundlePath: BUNDLE_PATH,
11
+ serverBundleCachePath: BUNDLE_PATH,
12
12
  port: env.RENDERER_PORT || 3800, // Listen at RENDERER_PORT env value or default port 3800
13
13
  logLevel: env.RENDERER_LOG_LEVEL || 'info',
14
14
 
@@ -15,14 +15,14 @@ import {
15
15
  getFixtureAsset,
16
16
  getOtherFixtureAsset,
17
17
  createAsset,
18
- bundlePath,
18
+ serverBundleCachePath,
19
19
  assetPath,
20
20
  assetPathOther,
21
21
  } from './helper';
22
22
 
23
23
  const testName = 'worker';
24
24
  const createVmBundleForTest = () => createVmBundle(testName);
25
- const bundlePathForTest = () => bundlePath(testName);
25
+ const serverBundleCachePathForTest = () => serverBundleCachePath(testName);
26
26
 
27
27
  const gemVersion = packageJson.version;
28
28
  const { protocolVersion } = packageJson;
@@ -41,7 +41,7 @@ describe('worker', () => {
41
41
 
42
42
  test('POST /bundles/:bundleTimestamp/render/:renderRequestDigest when bundle is provided and did not yet exist', async () => {
43
43
  const app = worker({
44
- bundlePath: bundlePathForTest(),
44
+ serverBundleCachePath: serverBundleCachePathForTest(),
45
45
  });
46
46
 
47
47
  const form = formAutoContent({
@@ -69,7 +69,7 @@ describe('worker', () => {
69
69
 
70
70
  test('POST /bundles/:bundleTimestamp/render/:renderRequestDigest', async () => {
71
71
  const app = worker({
72
- bundlePath: bundlePathForTest(),
72
+ serverBundleCachePath: serverBundleCachePathForTest(),
73
73
  });
74
74
 
75
75
  const form = formAutoContent({
@@ -105,7 +105,7 @@ describe('worker', () => {
105
105
  await createVmBundleForTest();
106
106
 
107
107
  const app = worker({
108
- bundlePath: bundlePathForTest(),
108
+ serverBundleCachePath: serverBundleCachePathForTest(),
109
109
  password: 'password',
110
110
  });
111
111
 
@@ -132,7 +132,7 @@ describe('worker', () => {
132
132
  await createVmBundleForTest();
133
133
 
134
134
  const app = worker({
135
- bundlePath: bundlePathForTest(),
135
+ serverBundleCachePath: serverBundleCachePathForTest(),
136
136
  password: 'password',
137
137
  });
138
138
 
@@ -159,7 +159,7 @@ describe('worker', () => {
159
159
  await createVmBundleForTest();
160
160
 
161
161
  const app = worker({
162
- bundlePath: bundlePathForTest(),
162
+ serverBundleCachePath: serverBundleCachePathForTest(),
163
163
  password: 'my_password',
164
164
  });
165
165
 
@@ -187,7 +187,7 @@ describe('worker', () => {
187
187
  await createVmBundleForTest();
188
188
 
189
189
  const app = worker({
190
- bundlePath: bundlePathForTest(),
190
+ serverBundleCachePath: serverBundleCachePathForTest(),
191
191
  });
192
192
 
193
193
  const res = await app
@@ -211,7 +211,7 @@ describe('worker', () => {
211
211
  await createAsset(testName, bundleHash);
212
212
 
213
213
  const app = worker({
214
- bundlePath: bundlePathForTest(),
214
+ serverBundleCachePath: serverBundleCachePathForTest(),
215
215
  password: 'my_password',
216
216
  });
217
217
 
@@ -237,7 +237,7 @@ describe('worker', () => {
237
237
  await createAsset(testName, bundleHash);
238
238
 
239
239
  const app = worker({
240
- bundlePath: bundlePathForTest(),
240
+ serverBundleCachePath: serverBundleCachePathForTest(),
241
241
  password: 'my_password',
242
242
  });
243
243
 
@@ -261,7 +261,7 @@ describe('worker', () => {
261
261
  test('post /asset-exists requires targetBundles (protocol version 2.0.0)', async () => {
262
262
  await createAsset(testName, String(BUNDLE_TIMESTAMP));
263
263
  const app = worker({
264
- bundlePath: bundlePathForTest(),
264
+ serverBundleCachePath: serverBundleCachePathForTest(),
265
265
  password: 'my_password',
266
266
  });
267
267
 
@@ -283,7 +283,7 @@ describe('worker', () => {
283
283
  const bundleHash = 'some-bundle-hash';
284
284
 
285
285
  const app = worker({
286
- bundlePath: bundlePathForTest(),
286
+ serverBundleCachePath: serverBundleCachePathForTest(),
287
287
  password: 'my_password',
288
288
  });
289
289
 
@@ -307,7 +307,7 @@ describe('worker', () => {
307
307
  const bundleHashOther = 'some-other-bundle-hash';
308
308
 
309
309
  const app = worker({
310
- bundlePath: bundlePathForTest(),
310
+ serverBundleCachePath: serverBundleCachePathForTest(),
311
311
  password: 'my_password',
312
312
  });
313
313
 
@@ -334,7 +334,7 @@ describe('worker', () => {
334
334
  await createVmBundleForTest();
335
335
 
336
336
  const app = worker({
337
- bundlePath: bundlePathForTest(),
337
+ serverBundleCachePath: serverBundleCachePathForTest(),
338
338
  });
339
339
 
340
340
  const res = await app
@@ -355,7 +355,7 @@ describe('worker', () => {
355
355
  await createVmBundleForTest();
356
356
 
357
357
  const app = worker({
358
- bundlePath: bundlePathForTest(),
358
+ serverBundleCachePath: serverBundleCachePathForTest(),
359
359
  });
360
360
 
361
361
  const res = await app
@@ -379,7 +379,7 @@ describe('worker', () => {
379
379
  await createVmBundleForTest();
380
380
 
381
381
  const app = worker({
382
- bundlePath: bundlePathForTest(),
382
+ serverBundleCachePath: serverBundleCachePathForTest(),
383
383
  });
384
384
 
385
385
  const res = await app
@@ -400,7 +400,7 @@ describe('worker', () => {
400
400
  await createVmBundleForTest();
401
401
 
402
402
  const app = worker({
403
- bundlePath: bundlePathForTest(),
403
+ serverBundleCachePath: serverBundleCachePathForTest(),
404
404
  });
405
405
 
406
406
  // If package version is 4.0.0, this tests that 4.0.0.rc.1 gets normalized to 4.0.0-rc.1
@@ -426,7 +426,7 @@ describe('worker', () => {
426
426
  await createVmBundleForTest();
427
427
 
428
428
  const app = worker({
429
- bundlePath: bundlePathForTest(),
429
+ serverBundleCachePath: serverBundleCachePathForTest(),
430
430
  });
431
431
 
432
432
  const gemVersionUpperCase = packageJson.version.toUpperCase();
@@ -449,7 +449,7 @@ describe('worker', () => {
449
449
  await createVmBundleForTest();
450
450
 
451
451
  const app = worker({
452
- bundlePath: bundlePathForTest(),
452
+ serverBundleCachePath: serverBundleCachePathForTest(),
453
453
  });
454
454
 
455
455
  const gemVersionWithWhitespace = ` ${packageJson.version} `;
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+ require "timeout"
5
+
6
+ # NOTE: Pro package does not include Steep tasks (:steep, :all) as it does not
7
+ # use Steep type checker. Only RBS validation is performed.
8
+ # rubocop:disable Metrics/BlockLength
9
+ namespace :rbs do
10
+ desc "Validate RBS type signatures"
11
+ task :validate do
12
+ require "rbs"
13
+ require "rbs/cli"
14
+
15
+ puts "Validating RBS type signatures..."
16
+
17
+ # Use Open3 for better error handling - captures stdout, stderr, and exit status separately
18
+ # This allows us to distinguish between actual validation errors and warnings
19
+ # Note: Must use bundle exec even though rake runs in bundle context because
20
+ # spawned shell commands via Open3.capture3() do NOT inherit bundle context
21
+ # Wrap in Timeout to prevent hung processes in CI environments (60 second timeout)
22
+ stdout, stderr, status = Timeout.timeout(60) do
23
+ Open3.capture3("bundle exec rbs -I sig validate")
24
+ end
25
+
26
+ if status.success?
27
+ puts "✓ RBS validation passed"
28
+ else
29
+ puts "✗ RBS validation failed"
30
+ puts stdout unless stdout.empty?
31
+ warn stderr unless stderr.empty?
32
+ exit 1
33
+ end
34
+ end
35
+
36
+ desc "Check RBS type signatures (alias for validate)"
37
+ task check: :validate
38
+
39
+ desc "List all RBS files"
40
+ task :list do
41
+ sig_files = Dir.glob("sig/**/*.rbs")
42
+ puts "RBS type signature files:"
43
+ sig_files.each { |f| puts " #{f}" }
44
+ puts "\nTotal: #{sig_files.count} files"
45
+ end
46
+ end
47
+ # rubocop:enable Metrics/BlockLength
@@ -0,0 +1,13 @@
1
+ module ReactOnRailsPro
2
+ class Cache
3
+ def self.fetch_react_component: (String component_name, Hash[Symbol, untyped] options) { () -> untyped } -> untyped
4
+
5
+ def self.use_cache?: (Hash[Symbol, untyped] options) -> bool
6
+
7
+ def self.base_cache_key: (String type, ?prerender: bool?) -> Array[String]
8
+
9
+ def self.dependencies_cache_key: () -> String?
10
+
11
+ def self.react_component_cache_key: (String component_name, Hash[Symbol, untyped] options) -> Array[untyped]
12
+ end
13
+ end
@@ -0,0 +1,100 @@
1
+ module ReactOnRailsPro
2
+ class Configuration
3
+ DEFAULT_RENDERER_URL: String
4
+ DEFAULT_RENDERER_METHOD: String
5
+ DEFAULT_RENDERER_FALLBACK_EXEC_JS: bool
6
+ DEFAULT_RENDERER_HTTP_POOL_SIZE: Integer
7
+ DEFAULT_RENDERER_HTTP_POOL_TIMEOUT: Integer
8
+ DEFAULT_RENDERER_HTTP_POOL_WARN_TIMEOUT: Float
9
+ DEFAULT_SSR_TIMEOUT: Integer
10
+ DEFAULT_PRERENDER_CACHING: bool
11
+ DEFAULT_TRACING: bool
12
+ DEFAULT_DEPENDENCY_GLOBS: Array[String]
13
+ DEFAULT_EXCLUDED_DEPENDENCY_GLOBS: Array[String]
14
+ DEFAULT_REMOTE_BUNDLE_CACHE_ADAPTER: nil
15
+ DEFAULT_RENDERER_REQUEST_RETRY_LIMIT: Integer
16
+ DEFAULT_THROW_JS_ERRORS: bool
17
+ DEFAULT_RENDERING_RETURNS_PROMISES: bool
18
+ DEFAULT_PROFILE_SERVER_RENDERING_JS_CODE: bool
19
+ DEFAULT_RAISE_NON_SHELL_SERVER_RENDERING_ERRORS: bool
20
+ DEFAULT_ENABLE_RSC_SUPPORT: bool
21
+ DEFAULT_RSC_PAYLOAD_GENERATION_URL_PATH: String
22
+ DEFAULT_RSC_BUNDLE_JS_FILE: String
23
+ DEFAULT_REACT_CLIENT_MANIFEST_FILE: String
24
+ DEFAULT_REACT_SERVER_CLIENT_MANIFEST_FILE: String
25
+
26
+ attr_accessor renderer_url: String?
27
+ attr_accessor renderer_password: String?
28
+ attr_accessor tracing: bool?
29
+ attr_accessor server_renderer: String?
30
+ attr_accessor renderer_use_fallback_exec_js: bool?
31
+ attr_accessor prerender_caching: bool?
32
+ attr_accessor renderer_http_pool_size: Integer?
33
+ attr_accessor renderer_http_pool_timeout: Integer?
34
+ attr_accessor renderer_http_pool_warn_timeout: Float?
35
+ attr_accessor dependency_globs: Array[String]?
36
+ attr_accessor excluded_dependency_globs: Array[String]?
37
+ attr_accessor rendering_returns_promises: bool?
38
+ attr_accessor remote_bundle_cache_adapter: Module?
39
+ attr_accessor ssr_pre_hook_js: String?
40
+ attr_accessor assets_to_copy: Array[String]?
41
+ attr_accessor renderer_request_retry_limit: Integer?
42
+ attr_accessor throw_js_errors: bool?
43
+ attr_accessor ssr_timeout: Integer?
44
+ attr_accessor profile_server_rendering_js_code: bool?
45
+ attr_accessor raise_non_shell_server_rendering_errors: bool?
46
+ attr_accessor enable_rsc_support: bool?
47
+ attr_accessor rsc_payload_generation_url_path: String?
48
+ attr_accessor rsc_bundle_js_file: String?
49
+ attr_accessor react_client_manifest_file: String?
50
+ attr_accessor react_server_client_manifest_file: String?
51
+
52
+ def initialize: (
53
+ ?renderer_url: String?,
54
+ ?renderer_password: String?,
55
+ ?server_renderer: String?,
56
+ ?renderer_use_fallback_exec_js: bool?,
57
+ ?prerender_caching: bool?,
58
+ ?renderer_http_pool_size: Integer?,
59
+ ?renderer_http_pool_timeout: Integer?,
60
+ ?renderer_http_pool_warn_timeout: Float?,
61
+ ?tracing: bool?,
62
+ ?dependency_globs: Array[String]?,
63
+ ?excluded_dependency_globs: Array[String]?,
64
+ ?rendering_returns_promises: bool?,
65
+ ?remote_bundle_cache_adapter: Module?,
66
+ ?ssr_pre_hook_js: String?,
67
+ ?assets_to_copy: Array[String]?,
68
+ ?renderer_request_retry_limit: Integer?,
69
+ ?throw_js_errors: bool?,
70
+ ?ssr_timeout: Integer?,
71
+ ?profile_server_rendering_js_code: bool?,
72
+ ?raise_non_shell_server_rendering_errors: bool?,
73
+ ?enable_rsc_support: bool?,
74
+ ?rsc_payload_generation_url_path: String?,
75
+ ?rsc_bundle_js_file: String?,
76
+ ?react_client_manifest_file: String?,
77
+ ?react_server_client_manifest_file: String?
78
+ ) -> void
79
+
80
+ def setup_config_values: () -> void
81
+
82
+ def check_react_on_rails_support_for_rsc: () -> void
83
+
84
+ def setup_execjs_profiler_if_needed: () -> void
85
+
86
+ def node_renderer?: () -> bool
87
+
88
+ private
89
+
90
+ def setup_assets_to_copy: () -> void
91
+
92
+ def configure_default_url_if_not_provided: () -> void
93
+
94
+ def validate_url: () -> void
95
+
96
+ def validate_remote_bundle_cache_adapter: () -> void
97
+
98
+ def setup_renderer_password: () -> void
99
+ end
100
+ end
@@ -0,0 +1,4 @@
1
+ module ReactOnRailsPro
2
+ class Error < StandardError
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ module ReactOnRailsPro
2
+ module Utils
3
+ def self.bundle_js_file_path: (String bundle_name) -> String
4
+
5
+ def self.running_on_windows?: () -> bool
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module ReactOnRailsPro
2
+ def self.configure: () { (Configuration) -> void } -> void
3
+
4
+ def self.configuration: () -> Configuration
5
+ end
@@ -9,7 +9,7 @@ GIT
9
9
  PATH
10
10
  remote: ../../..
11
11
  specs:
12
- react_on_rails (16.2.0.beta.3)
12
+ react_on_rails (16.2.0.beta.4)
13
13
  addressable
14
14
  connection_pool
15
15
  execjs (~> 2.5)
@@ -20,14 +20,14 @@ PATH
20
20
  PATH
21
21
  remote: ../..
22
22
  specs:
23
- react_on_rails_pro (16.2.0.beta.3)
23
+ react_on_rails_pro (16.2.0.beta.4)
24
24
  addressable
25
25
  connection_pool
26
26
  execjs (~> 2.9)
27
27
  httpx (~> 1.5)
28
28
  jwt (~> 2.7)
29
29
  rainbow
30
- react_on_rails (= 16.2.0.beta.3)
30
+ react_on_rails (= 16.2.0.beta.4)
31
31
 
32
32
  GEM
33
33
  remote: https://rubygems.org/
@@ -327,6 +327,8 @@ GEM
327
327
  rb-fsevent (0.11.2)
328
328
  rb-inotify (0.11.1)
329
329
  ffi (~> 1.0)
330
+ rbs (3.9.5)
331
+ logger
330
332
  rdoc (6.12.0)
331
333
  psych (>= 4.0.0)
332
334
  redis (5.4.0)
@@ -524,6 +526,7 @@ DEPENDENCIES
524
526
  pry-theme
525
527
  puma (~> 6)
526
528
  rails (~> 7.1)
529
+ rbs
527
530
  react_on_rails!
528
531
  react_on_rails_pro!
529
532
  redis
@@ -29,7 +29,7 @@ require('@shakacode-tools/react-on-rails-pro-node-renderer/integrations/sentry')
29
29
 
30
30
  const config = {
31
31
  // This is the default but avoids searching for the Rails root
32
- bundlePath: path.resolve(__dirname, '../.node-renderer-bundles'),
32
+ serverBundleCachePath: path.resolve(__dirname, '../.node-renderer-bundles'),
33
33
  port: env.RENDERER_PORT || 3800, // Listen at RENDERER_PORT env value or default port 3800
34
34
  logLevel: env.RENDERER_LOG_LEVEL || 'info',
35
35