humid 0.0.6 → 0.2.0

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: b8422854ba8184e3afc75af501ec45002304538e9f756ea3ee3bdd58b15d98de
4
- data.tar.gz: 8e8025cba53a2ed0e54aecb85701bcb65a7d39798f241ef4e5d3aeea391367aa
3
+ metadata.gz: 73079cacc72320a7c7d439d5cc443a42221a9e177dda5f25712c9898212f533a
4
+ data.tar.gz: f06abbe52e2e566a415d7982cac6c6313d158e1f47f2ec142179226f55d7cd63
5
5
  SHA512:
6
- metadata.gz: 404f369b35a24b2b313bf2a5d572746b1d4262df0b5ee4988f69540a878502045d046279714432d77b367366e98031818f6c3f3c26747f67e916581335b4004f
7
- data.tar.gz: 38feb90293fd0340155314e6300e5a3ff70a8ee5f2d2e7fb081c0bf89ea8b7826a7297d52b15888d05f447ff64738da454cc4ede07ff9a152236ae7318fd5380
6
+ metadata.gz: ce807ac8725f2054eaa15f00ecd2ec7532b5d720145f9078d211966fd3b5c81f06e282a9511778fa1ecfdcc4af028dd109ae950c14d6a9c4cb1f2c78d64bba14
7
+ data.tar.gz: 903b52f1aebf08c3f90d606f5e1eca7656aa04bc988d1342f863cf9a915acdc52b94d440d2f6f50c68f3d8e34f58d400c669dd7afc6f75688aad9104203e592c
data/README.md CHANGED
@@ -33,14 +33,16 @@ Add an initializer to configure
33
33
 
34
34
  ```ruby
35
35
  Humid.configure do |config|
36
- # Path to your build file located in `app/assets/build/`. You should use a
36
+ # Path to your build file located in `app/assets/builds/`. You should use a
37
37
  # separate build apart from your `application.js`.
38
+ #
38
39
  # Required
39
- config.application_path = "app/assets/build/server_rendering.js"
40
+ config.application_path = Rails.root.join('app', 'assets', 'builds', 'server_rendering.js')
40
41
 
41
42
  # Path to your source map file
43
+ #
42
44
  # Optional
43
- config.source_map_path = "app/assets/build/server_rendering.js.map"
45
+ config.source_map_path = Rails.root.join('app', 'assets', 'builds', 'server_rendering.js.map')
44
46
 
45
47
  # Raise errors if JS rendering failed. If false, the error will be
46
48
  # logged out to Rails log and Humid.render will return an empty string
@@ -52,8 +54,8 @@ Humid.configure do |config|
52
54
  # `console.log` and friends (`warn`, `error`) are delegated to
53
55
  # the respective logger levels on the ruby side.
54
56
  #
55
- # Defaults to `Logger.new(STDOUT)`
56
- config.logger = Rails.logger
57
+ # Defaults to `nil`
58
+ config.logger = Rails.env.development? ? Rails.logger : nil
57
59
 
58
60
  # Options passed to mini_racer.
59
61
  #
@@ -64,14 +66,27 @@ Humid.configure do |config|
64
66
  }
65
67
  end
66
68
 
67
- # Common development options
68
- if Rails.env.development? || Rails.env.test?
69
+ # Capybara defines its own puma config which is set up to run a single puma process
70
+ # with a thread pool. This ensures that a context gets created on that process.
71
+ if Rails.env.test?
69
72
  # Use single_threaded mode for Spring and other forked envs.
70
73
  MiniRacer::Platform.set_flags! :single_threaded
74
+ Humid.create_context
75
+ end
76
+ ```
77
+
78
+ Then add to your `config/puma.rb`
71
79
 
72
- # If you're using Puma in single mode:
80
+ ```
81
+ workers ENV.fetch("WEB_CONCURRENCY") { 1 }
82
+
83
+ on_worker_boot do
73
84
  Humid.create_context
74
85
  end
86
+
87
+ on_worker_shutdown do
88
+ Humid.dispose
89
+ end
75
90
  ```
76
91
 
77
92
  If you'd like support for source map support, you will need to
@@ -108,9 +123,32 @@ The following functions are **not** available in the mini_racer environment
108
123
  `console.log` and friends (`info`, `error`, `warn`) are delegated to the
109
124
  respective methods on the configured logger.
110
125
 
126
+ All arguments are passed through — MiniRacer converts JS objects to Ruby
127
+ hashes and arrays automatically. A `log_formatter` proc controls how these
128
+ arguments are formatted into a single string for the logger:
129
+
130
+ ```ruby
131
+ Humid.configure do |config|
132
+ config.logger = Rails.logger
133
+
134
+ config.log_formatter = proc { |level, message, *rest|
135
+ parts = [message]
136
+ parts += rest.map { |a| a.is_a?(String) ? a : JSON.pretty_generate(a) }
137
+ parts.join("\n")
138
+ }
139
+ end
140
+ ```
141
+
142
+ The formatter receives `(level, message, *rest)` where:
143
+ - `level` — the log level as a symbol (`:debug`, `:info`, `:warn`, `:error`)
144
+ - `message` — the first argument passed to `console.log/info/warn/error`
145
+ - `rest` — any additional arguments (objects come through as Ruby hashes/arrays)
146
+
147
+ The default formatter simply returns `message` unchanged.
148
+
111
149
  ## Usage
112
150
 
113
- In your entry file, e.g, `server_rendering.js`, pass your HTML render function
151
+ In your entry file, e.g, `server_rendering.js`, pass your HTML render function
114
152
  to `setHumidRenderer`. There is no need to require the function.
115
153
 
116
154
  ```javascript
@@ -128,7 +166,7 @@ setHumidRenderer((json) => {
128
166
  And finally call `render` from ERB.
129
167
 
130
168
  ```ruby
131
- <%= Humid.render(initial_state) %>
169
+ <%= Humid.render(initial_state).html_safe %>
132
170
  ```
133
171
 
134
172
  Instrumentation is included:
@@ -140,7 +178,8 @@ Completed 200 OK in 14ms (Views: 0.2ms | Humid SSR: 11.0ms | ActiveRecord: 2.7ms
140
178
  ### Puma
141
179
 
142
180
  `mini_racer` is thread safe, but not fork safe. To use with web servers that
143
- employ forking, use `Humid.create_context` only on forked processes.
181
+ employ forking, use `Humid.create_context` only on forked processes. On
182
+ production, There should be no context created on the master process.
144
183
 
145
184
  ```ruby
146
185
  # Puma
@@ -155,7 +194,7 @@ end
155
194
 
156
195
  ### Server-side libraries that detect node.js envs.
157
196
  You may need webpacker to create aliases for server friendly libraries that can
158
- not detect the `mini_racer` environment. For example, in your `webpack.config.js`.
197
+ not detect the `mini_racer` environment. For example, in `webpack.config.js`.
159
198
 
160
199
  ```diff
161
200
  ...
@@ -180,19 +219,17 @@ every call.
180
219
  This provides better isolation, but as it is still a shared context, polluting
181
220
  `global` is still possible. Be careful of modifying `global` in your code.
182
221
 
183
- ### Polyfills
222
+ ### Missing browser APIs
184
223
 
185
- Polyfills will fail when using in the `mini_racer` environment because of missing
186
- browser APIs. Account for this by moving the `require` to `componentDidMount`
187
- in your component.
224
+ Polyfills and some libraries that depend on browser APIs will fail in the
225
+ `mini_racer` environment because of missing browser APIs. Account for this by
226
+ moving the `require` to `useEffect` in your component.
188
227
 
189
228
  ```
190
- componentDidMount() {
191
- const dialogPolyfill = require('dialog-polyfill').default
192
- dialogPolyfill.registerDialog(this.dialog.current)
193
- this.dialog.current.open = this.props.open
194
- this.dialog.current.showModal()
195
- }
229
+ useEffect(() => {
230
+ const svgPanZoom = require('svg-pan-zoom')
231
+ //...
232
+ }, [])
196
233
  ```
197
234
 
198
235
  ## Contributing
@@ -201,23 +238,28 @@ Please see [CONTRIBUTING.md](/CONTRIBUTING.md).
201
238
 
202
239
  ## License
203
240
 
204
- Humid is Copyright © 2021-2021 Johny Ho.
241
+ Humid is Copyright © 2021-2024 Johny Ho.
205
242
  It is free software, and may be redistributed under the terms specified in the
206
243
  [LICENSE](/LICENSE.md) file.
207
244
 
245
+ <!-- START /templates/footer.md -->
208
246
  ## About thoughtbot
209
247
 
210
- ![thoughtbot](https://thoughtbot.com/brand_assets/93:44.svg)
248
+ ![thoughtbot](https://thoughtbot.com/thoughtbot-logo-for-readmes.svg)
211
249
 
212
- Humid is maintained and funded by thoughtbot, inc.
250
+ This repo is maintained and funded by thoughtbot, inc.
213
251
  The names and logos for thoughtbot are trademarks of thoughtbot, inc.
214
252
 
215
253
  We love open source software!
216
- See [our other projects][community] or
217
- [hire us][hire] to design, develop, and grow your product.
254
+ See [our other projects][community].
255
+ We are [available for hire][hire].
218
256
 
219
257
  [community]: https://thoughtbot.com/community?utm_source=github
220
- [hire]: https://thoughtbot.com?utm_source=github
258
+ [hire]: https://thoughtbot.com/hire-us?utm_source=github
259
+
260
+
261
+ <!-- END /templates/footer.md -->
262
+
221
263
  [mini_racer]: https://github.com/rubyjs/mini_racer
222
264
  [vue_ssr]: https://ssr.vuejs.org/
223
265
  [sample]: ./webpack.config.js
@@ -1,4 +1,4 @@
1
- module Humid
1
+ class Humid
2
2
  module ControllerRuntime
3
3
  extend ActiveSupport::Concern
4
4
 
@@ -1,4 +1,4 @@
1
- module Humid
1
+ class Humid
2
2
  class LogSubscriber < ActiveSupport::LogSubscriber
3
3
  thread_cattr_accessor :humid_runtime
4
4
 
data/lib/humid/version.rb CHANGED
@@ -1,3 +1,3 @@
1
- module Humid
2
- VERSION = "0.0.6".freeze
1
+ class Humid
2
+ VERSION = "0.2.0".freeze
3
3
  end
data/lib/humid.rb CHANGED
@@ -6,106 +6,106 @@ require "humid/log_subscriber"
6
6
  require "humid/controller_runtime"
7
7
  require "humid/version"
8
8
 
9
- module Humid
10
- extend self
11
- include ActiveSupport::Configurable
9
+ class Humid
10
+ @@context = nil
12
11
 
13
12
  class RenderError < StandardError
14
13
  end
15
14
 
16
15
  class FileNotFound < StandardError
17
16
  end
17
+
18
+ class_attribute :config
19
+
20
+ self.config = ActiveSupport::OrderedOptions.new.merge({
21
+ raise_render_errors: true,
22
+ context_options: {},
23
+ log_formatter: proc { |_level, message, *_rest| message },
24
+ })
25
+
26
+ class << self
27
+ def configure
28
+ yield config
29
+ end
18
30
 
19
- @@context = nil
20
-
21
- config_accessor :application_path
22
- config_accessor :source_map_path
23
-
24
- config_accessor :raise_render_errors do
25
- true
26
- end
31
+ def remove_functions
32
+ <<~JS
33
+ delete this.setTimeout;
34
+ delete this.setInterval;
35
+ delete this.clearTimeout;
36
+ delete this.clearInterval;
37
+ delete this.setImmediate;
38
+ delete this.clearImmediate;
39
+ JS
40
+ end
27
41
 
28
- config_accessor :logger do
29
- Logger.new($stdout)
30
- end
42
+ def logger
43
+ config.logger
44
+ end
31
45
 
32
- config_accessor :context_options do
33
- {}
34
- end
46
+ def renderer
47
+ <<~JS
48
+ var __renderer;
49
+ function setHumidRenderer(fn) {
50
+ __renderer = fn;
51
+ }
52
+ JS
53
+ end
35
54
 
36
- def remove_functions
37
- <<~JS
38
- delete this.setTimeout;
39
- delete this.setInterval;
40
- delete this.clearTimeout;
41
- delete this.clearInterval;
42
- delete this.setImmediate;
43
- delete this.clearImmediate;
44
- JS
45
- end
55
+ def context
56
+ @@context
57
+ end
46
58
 
47
- def logger
48
- config.logger
49
- end
59
+ def dispose
60
+ if @@context
61
+ @@context.dispose
62
+ @@context = nil
63
+ end
64
+ end
50
65
 
51
- def renderer
52
- <<~JS
53
- var __renderer;
54
- function setHumidRenderer(fn) {
55
- __renderer = fn;
56
- }
57
- JS
58
- end
66
+ def create_context
67
+ ctx = MiniRacer::Context.new(**config.context_options)
59
68
 
60
- def context
61
- @@context
62
- end
69
+ if logger
70
+ fmt = config.log_formatter || proc { |_level, message, *_rest| message }
71
+ ctx.attach("console.log", proc { |*args| logger.debug(fmt.call(:debug, *args)) })
72
+ ctx.attach("console.info", proc { |*args| logger.info(fmt.call(:info, *args)) })
73
+ ctx.attach("console.error", proc { |*args| logger.error(fmt.call(:error, *args)) })
74
+ ctx.attach("console.warn", proc { |*args| logger.warn(fmt.call(:warn, *args)) })
75
+ end
63
76
 
64
- def dispose
65
- if @@context
66
- @@context.dispose
67
- @@context = nil
68
- end
69
- end
77
+ js = ""
78
+ js << remove_functions
79
+ js << renderer
80
+ ctx.eval(js)
70
81
 
71
- def create_context
72
- ctx = MiniRacer::Context.new(**config.context_options)
73
- ctx.attach("console.log", proc { |err| logger.debug(err.to_s) })
74
- ctx.attach("console.info", proc { |err| logger.info(err.to_s) })
75
- ctx.attach("console.error", proc { |err| logger.error(err.to_s) })
76
- ctx.attach("console.warn", proc { |err| logger.warn(err.to_s) })
82
+ source_path = config.application_path
83
+ map_path = config.source_map_path
77
84
 
78
- js = ""
79
- js << remove_functions
80
- js << renderer
81
- ctx.eval(js)
85
+ if map_path
86
+ ctx.attach("readSourceMap", proc { File.read(map_path) })
87
+ end
82
88
 
83
- source_path = config.application_path
84
- map_path = config.source_map_path
89
+ filename = File.basename(source_path.to_s)
90
+ @@current_filename = filename
91
+ ctx.eval(File.read(source_path), filename: filename)
85
92
 
86
- if map_path
87
- ctx.attach("readSourceMap", proc { File.read(map_path) })
93
+ @@context = ctx
88
94
  end
89
95
 
90
- filename = File.basename(source_path.to_s)
91
- @@current_filename = filename
92
- ctx.eval(File.read(source_path), filename: filename)
93
-
94
- @@context = ctx
95
- end
96
-
97
- def render(*args)
98
- ActiveSupport::Notifications.instrument("render.humid") do
99
- context.call("__renderer", *args)
100
- rescue MiniRacer::RuntimeError => e
101
- message = ([e.message] + e.backtrace.filter { |x| x.starts_with? "JavaScript" }).join("\n")
102
- render_error = Humid::RenderError.new(message)
103
-
104
- if config.raise_render_errors
105
- raise render_error
106
- else
107
- config.logger.error(render_error.inspect)
108
- ""
96
+ def render(*args)
97
+ ActiveSupport::Notifications.instrument("render.humid") do
98
+ context.call("__renderer", *args)
99
+ rescue MiniRacer::RuntimeError => e
100
+ message = ([e.message] + e.backtrace.filter { |x| x.starts_with? "JavaScript" }).join("\n")
101
+ render_error = Humid::RenderError.new(message)
102
+
103
+ if config.raise_render_errors
104
+ raise render_error
105
+ else
106
+ config.logger.error(render_error.inspect)
107
+ ""
108
+ end
109
109
  end
110
110
  end
111
111
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: humid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johny Ho
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-07-13 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: mini_racer
@@ -28,16 +27,16 @@ dependencies:
28
27
  name: activesupport
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
- - - ">="
30
+ - - "~>"
32
31
  - !ruby/object:Gem::Version
33
- version: '7.0'
32
+ version: '8.0'
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
- - - ">="
37
+ - - "~>"
39
38
  - !ruby/object:Gem::Version
40
- version: '7.0'
39
+ version: '8.0'
41
40
  description: Javascript SSR rendering for Rails
42
41
  email: jho406@gmail.com
43
42
  executables: []
@@ -53,7 +52,6 @@ homepage: https://github.com/thoughtbot/humid/
53
52
  licenses:
54
53
  - MIT
55
54
  metadata: {}
56
- post_install_message:
57
55
  rdoc_options: []
58
56
  require_paths:
59
57
  - lib
@@ -68,8 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
66
  - !ruby/object:Gem::Version
69
67
  version: '0'
70
68
  requirements: []
71
- rubygems_version: 3.4.6
72
- signing_key:
69
+ rubygems_version: 3.6.9
73
70
  specification_version: 4
74
71
  summary: Javascript SSR rendering for Rails
75
72
  test_files: []