react-email-rails 0.12.0 → 0.12.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e2dc04e0c361e5517d66cf3a60a274b090bc5978b82ee4a77c07758ac8ca82e7
4
- data.tar.gz: 027c7e6c6e4510621b6738c271f273a1a89a248e6de59772bc0af6fec7eebe4d
3
+ metadata.gz: 281158df961cccec48c34e03628715fda9a9c9cf16bbda4cae3097f380498a48
4
+ data.tar.gz: 68d882e14c9a5ed7281b5e1bb39a046e7ecb77314b25667cb27a289509aac319
5
5
  SHA512:
6
- metadata.gz: b044fc510c92a914031d4932586b12f2a16c306fee35f4cb4088f22093910456b3a8e3fe4a1909d1e8a67ba10a6235462f4531858a6f575e3516ef8bea20e260
7
- data.tar.gz: d30686390cf1c1d435a24ec640d3a5873cf7137e211c67e6e316a660c3ffa67ae6c78787b90075676ddab90ded4282b2db6730195120ff954c919fd58a3610f3
6
+ metadata.gz: 7a679b532deae816d2337e38810077045b85a38d0e0e86089d516ba70d8e9060a06b4c9e9af5a8fa4a7aaa310f101c2817c0f246e559f97c1baaf829f19db91c
7
+ data.tar.gz: 7117f2c68aacaa3a4683d2272384a8ee5171d3684c3ad2a7b809bb833e7b85b4a19df738de66de3c45ce234d7e87a78537db3d1c8b24c733fcb25b26b8fa3d60
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.12.1
4
+
5
+ - Export `CamelMailer` and `CamelMessage` TypeScript types, plus a `Register` module augmentation (`propKeys: "camel"`) so apps that camelize props can type the injected `mailer` / `message` shapes without a local mapped type. Default `Mailer` / `Message` stay snake_case.
6
+ - Timeouts that already received a partial response line no longer suggest a gem/npm version mismatch. The renderer drains stdout before deciding the process was silent.
7
+
3
8
  ## 0.12.0
4
9
 
5
10
  - **Breaking:** Remove `config.render_mode`. There is one renderer: a long-lived Node child per Ruby process, speaking newline-delimited JSON. Delete `config.render_mode = :persistent` from initializers. Set `config.render_process_max_requests = 1` to recycle the child after every email.
data/README.md CHANGED
@@ -334,6 +334,8 @@ type WelcomeProps = {
334
334
  }
335
335
  ```
336
336
 
337
+ The table shows the default snake_case keys. Keys follow `config.prop_transformer` just like your own props, so a camelize transformer yields `mailerName` / `replyTo` at runtime. Augment `Register` once so `Mailer` / `Message` match, or alias `CamelMailer` / `CamelMessage` — see [Prop Transformation](#prop-transformation).
338
+
337
339
  | Prop | Example |
338
340
  |------|---------|
339
341
  | `mailer.mailer_name` | `"account_mailer"` |
@@ -343,9 +345,7 @@ type WelcomeProps = {
343
345
  | `message.cc`, `message.bcc` | `["…"]` or `null` |
344
346
  | `message.from`, `message.reply_to` | `["app@example.com"]` |
345
347
 
346
- Context is merged before prop serialization, so keys follow `config.prop_transformer` just like your own props. The exported TypeScript types describe the default (untransformed) shape.
347
-
348
- Per-mail and shared props win on conflict, so a prop named `mailer` or `message` overrides the injected context. When props come from a serializer, the context is merged in as long as `as_json` returns a hash; collections, arrays, and other non-object values pass through unchanged so their top-level shape is preserved.
348
+ Context is merged before prop serialization. Per-mail and shared props win on conflict, so a prop named `mailer` or `message` overrides the injected context. When props come from a serializer, the context is merged in as long as `as_json` returns a hash; collections, arrays, and other non-object values pass through unchanged so their top-level shape is preserved.
349
349
 
350
350
  ### Prop Serialization
351
351
 
@@ -435,9 +435,7 @@ end
435
435
 
436
436
  ### Prop Transformation
437
437
 
438
- Use `prop_transformer` to change props after `as_json` and before they reach React. The default is a no-op, matching [inertia-rails](https://inertia-rails.dev/guide/configuration#prop_transformer).
439
-
440
- To work with `snake_case` in Ruby and `camelCase` in components:
438
+ Use `prop_transformer` to change props after `as_json` and before they reach React. To work with `snake_case` in Ruby and `camelCase` in components:
441
439
 
442
440
  ```ruby
443
441
  ReactEmailRails.configure do |config|
@@ -447,6 +445,29 @@ ReactEmailRails.configure do |config|
447
445
  end
448
446
  ```
449
447
 
448
+ The transformer is arbitrary, so TypeScript cannot infer it. The default `Mailer` and `Message` types stay snake_case (`mailer_name`, `reply_to`). App-authored props (`expiresMinutes`, and so on) stay hand-typed in the app.
449
+
450
+ If you camelize in Ruby, augment `Register` once so `import type { Mailer, Message }` matches runtime — the same "configure once" idea as the initializer:
451
+
452
+ ```ts
453
+ // e.g. react-email-rails.d.ts
454
+ import "react-email-rails"
455
+
456
+ declare module "react-email-rails" {
457
+ interface Register {
458
+ propKeys: "camel"
459
+ }
460
+ }
461
+ ```
462
+
463
+ The `import "react-email-rails"` (or an `export {}`) makes the file a module so TypeScript *augments* the package. Without it, a script-style `.d.ts` replaces the module and you lose the rest of the package's types.
464
+
465
+ If you do not want a `.d.ts`, alias the camel types at the import. `CamelMailer` and `CamelMessage` are always camel, regardless of `Register`:
466
+
467
+ ```ts
468
+ import type { CamelMailer as Mailer, CamelMessage as Message } from "react-email-rails"
469
+ ```
470
+
450
471
  The transformer receives one hash at a time: the root props object, or each object in a top-level collection. Nested hashes inside a single object are left to the transformer — `deep_transform_keys` walks those.
451
472
 
452
473
  ### Render Process
@@ -112,9 +112,16 @@ class ReactEmailRails::Renderer::Child
112
112
 
113
113
  remaining = deadline - monotonic_time
114
114
  if remaining <= 0 || IO.select([@stdout], nil, nil, remaining).nil?
115
- silent = line.empty? && @stdout_buffer.empty?
115
+ drain_stdout_nonblock
116
+ if (buffered_line = consume_buffered_response_line)
117
+ line << buffered_line
118
+ return line
119
+ end
120
+
121
+ line << @stdout_buffer
122
+ @stdout_buffer.clear
116
123
  stop
117
- raise(Timeout::Error, unmatched_package_message) if silent
124
+ raise(Timeout::Error, unmatched_package_message) if line.empty?
118
125
 
119
126
  raise(Timeout::Error)
120
127
  end
@@ -134,6 +141,12 @@ class ReactEmailRails::Renderer::Child
134
141
  "no response received; gem and npm package react-email-rails must both be #{ReactEmailRails::VERSION}"
135
142
  end
136
143
 
144
+ def drain_stdout_nonblock
145
+ loop { @stdout_buffer << @stdout.read_nonblock(16 * 1024) }
146
+ rescue IO::WaitReadable, IOError, Errno::EAGAIN, Errno::EINTR
147
+ nil
148
+ end
149
+
137
150
  def consume_buffered_response_line
138
151
  separator = @stdout_buffer.index("\n")
139
152
  return unless separator
@@ -1,3 +1,3 @@
1
1
  module ReactEmailRails
2
- VERSION = "0.12.0"
2
+ VERSION = "0.12.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: react-email-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Supertape