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 +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +27 -6
- data/lib/react_email_rails/renderer/child.rb +15 -2
- data/lib/react_email_rails/version.rb +1 -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: 281158df961cccec48c34e03628715fda9a9c9cf16bbda4cae3097f380498a48
|
|
4
|
+
data.tar.gz: 68d882e14c9a5ed7281b5e1bb39a046e7ecb77314b25667cb27a289509aac319
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
|
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
|