simple_json 0.1.0 → 1.0.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: a56e99e174ee5d2165009b5f97816af1dd98b339a8374cfdb2adc6ee60d0def3
4
- data.tar.gz: 8dd4dafd8bc2cbaf05e6f54b86397917270ff971f03a041b85c6832b2061c294
3
+ metadata.gz: 9a291f4db8583e29927c04cd48fc264d352cef336473a1557f47c312fe12d79f
4
+ data.tar.gz: ada55b0635efe7edb401ba408fec5a2bb61b6e0c6bbd63e3e519ef6cef183e62
5
5
  SHA512:
6
- metadata.gz: 1735930768817f1ed0d1bb22771e084ee782573e8c32d1386bb38862f4b8d2cff3dfa0c982873bf5b6a04d1d4ab0590c4031e1af3dbd9d2819b0bb15e4b32205
7
- data.tar.gz: f4f8f62d99abcf3a0534dcc54830f2d93aa8bcb1b70ebaecea8fc83ba0c7bdc95afc9ccfe42a4b36d4b4774a5512e4da5d14c49cab4d4ae5d48cdbe687a5de36
6
+ metadata.gz: a00c58cb111dd69b6df8fb318f4b4f17419decffb5df83d8317d213710aeb705c049e234e33d6bf135b0a5a11bb6f354a13c2873670cb1aec87c687a4914c913
7
+ data.tar.gz: 87c14d778121b155790859c492789a2ff6253fb34f96b82c575adcc44e0afd0ac38f2b7b6389ad72ffb56bdcdb4641240aacd5a47dde67429afedd347cd7910f
@@ -6,8 +6,8 @@ jobs:
6
6
  build:
7
7
  strategy:
8
8
  matrix:
9
- ruby: ['3.2', '3.3', '3.4']
10
- rails: ["7.1", "7.2", "8.0"]
9
+ ruby: ['3.2', '3.3', '3.4', "4.0"]
10
+ rails: ["7.1", "7.2", "8.0", "8.1"]
11
11
 
12
12
  runs-on: ubuntu-latest
13
13
 
data/.gitignore CHANGED
@@ -9,3 +9,5 @@ gemfiles/*.lock
9
9
  /spec/reports/
10
10
  /tmp/
11
11
  /test/dummy_app/log/*
12
+ /test/dummy_app/tmp/*
13
+ /vendor/bundle
data/CHANGELOG.md ADDED
@@ -0,0 +1,35 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
5
+
6
+ ## [Unreleased]
7
+
8
+ ## [1.0.0] - 2026-01-28
9
+ ### Breaking
10
+ - Templates are no longer executed by invoking lambdas directly; they are compiled into methods.
11
+
12
+ ### Changed
13
+ - Cache template methods by code hash to reduce Ruby method cache invalidation.
14
+ - Use a renderer subclass that includes helpers instead of extending instances.
15
+
16
+ ### Fixed
17
+ - Rename the config key `cache_enabled` to `template_cache_enabled`.
18
+ - Add `/vendor/bundle` to `.gitignore`.
19
+
20
+ ## [0.1.0] - 2025-09-10
21
+ ### Changed
22
+ - Default JSON serializer switched from Oj to ActiveSupport::JSON to better align with Rails defaults.
23
+ - Development dependencies refreshed and benchmark script fixed for the latest Ruby/Rails stacks.
24
+ - README formatting and examples improved for clarity.
25
+
26
+ ### Fixed
27
+ - Resolved `MissingTemplate` errors introduced by the Rails 8 upgrade.
28
+ - Added coverage for rendering when template/action names differ to avoid regressions.
29
+
30
+ ## [0.0.0] - 2021-11-02
31
+ ### Added
32
+ - Initial SimpleJson renderer, templates (`.simple_json.rb` lambdas), and `SimpleJson::SimpleJsonRenderable` integration.
33
+ - Template caching toggle and configurable template paths.
34
+ - Rails generator hooks and dummy app scaffolding for getting started.
35
+ - Migration helpers for comparing SimpleJson output against existing Jbuilder views.
data/README.md CHANGED
@@ -53,7 +53,7 @@ This project is built on work of [jb](https://github.com/amatsuda/jb).
53
53
 
54
54
  ## Template Syntax
55
55
 
56
- SimpleJson templates are simply lambda objects that return data(Hashes or Arrays) for json.
56
+ SimpleJson templates should be written in Ruby lambda format. The template code is converted into a method and then invoked to produce data (Hashes or Arrays) for JSON.
57
57
 
58
58
  ```ruby
59
59
  -> {
@@ -176,110 +176,80 @@ Rails.application.config.generators.simple_json false
176
176
 
177
177
  Here're the results of a benchmark (which you can find [here](https://github.com/aktsk/simple_json/blob/master/test/dummy_app/app/controllers/benchmarks_controller.rb) in this repo) rendering a collection to JSON.
178
178
 
179
- ### RAILS_ENV=development
180
-
181
179
  ```
182
180
  % ./bin/benchmark.sh
183
181
 
184
- * Rendering 10 partials via render_partial
185
- Warming up --------------------------------------
186
- jb 257.000 i/100ms
187
- jbuilder 108.000 i/100ms
188
- simple_json 2.039k i/100ms
189
- Calculating -------------------------------------
190
- jb 2.611k (± 7.1%) i/s - 13.107k in 5.046110s
191
- jbuilder 1.084k (± 3.5%) i/s - 5.508k in 5.088845s
192
- simple_json 20.725k (± 4.4%) i/s - 103.989k in 5.026914s
193
-
194
- Comparison:
195
- simple_json: 20725.5 i/s
196
- jb: 2610.5 i/s - 7.94x (± 0.00) slower
197
- jbuilder: 1083.8 i/s - 19.12x (± 0.00) slower
198
-
199
-
200
- * Rendering 100 partials via render_partial
201
- Warming up --------------------------------------
202
- jb 88.000 i/100ms
203
- jbuilder 14.000 i/100ms
204
- simple_json 290.000 i/100ms
205
- Calculating -------------------------------------
206
- jb 928.202 (± 5.0%) i/s - 4.664k in 5.037314s
207
- jbuilder 137.980 (± 6.5%) i/s - 700.000 in 5.094658s
208
- simple_json 2.931k (± 5.2%) i/s - 14.790k in 5.060707s
209
-
210
- Comparison:
211
- simple_json: 2931.1 i/s
212
- jb: 928.2 i/s - 3.16x (± 0.00) slower
213
- jbuilder: 138.0 i/s - 21.24x (± 0.00) slower
214
-
215
-
216
- * Rendering 1000 partials via render_partial
217
- Warming up --------------------------------------
218
- jb 11.000 i/100ms
219
- jbuilder 1.000 i/100ms
220
- simple_json 29.000 i/100ms
221
- Calculating -------------------------------------
222
- jb 106.150 (± 5.7%) i/s - 539.000 in 5.094255s
223
- jbuilder 13.012 (± 7.7%) i/s - 65.000 in 5.054016s
224
- simple_json 271.683 (± 5.2%) i/s - 1.363k in 5.030646s
225
-
226
- Comparison:
227
- simple_json: 271.7 i/s
228
- jb: 106.1 i/s - 2.56x (± 0.00) slower
229
- jbuilder: 13.0 i/s - 20.88x (± 0.00) slower
230
- ```
231
-
232
- ### RAILS_ENV=production
233
-
234
- ```
235
- % RAILS_ENV=production ./bin/benchmark.sh
182
+ SimpleJson Benchmark
183
+ ruby: 4.0.1
184
+ rails: 8.1.1
185
+ json: 2.15.2
186
+ oj: 3.16.11
187
+ ----------------------
236
188
 
237
- * Rendering 10 partials via render_partial
189
+ * Rendering 10 partials via render_to_string
190
+ ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [arm64-darwin24]
238
191
  Warming up --------------------------------------
239
- jb 246.000 i/100ms
240
- jbuilder 97.000 i/100ms
241
- simple_json 1.957k i/100ms
192
+ jb 23.000 i/100ms
193
+ jbuilder 30.000 i/100ms
194
+ simple_json(oj) 40.000 i/100ms
195
+ simple_json(AS::json)
196
+ 46.000 i/100ms
242
197
  Calculating -------------------------------------
243
- jb 2.611k 4.1%) i/s - 13.038k in 5.002304s
244
- jbuilder 972.031 (± 4.7%) i/s - 4.850k in 5.001200s
245
- simple_json 20.383k (± 3.8%) i/s - 101.764k in 4.999989s
198
+ jb 298.51823.4%) i/s (3.35 ms/i) - 1.426k in 5.019370s
199
+ jbuilder 255.925 (± 4.3%) i/s (3.91 ms/i) - 1.290k in 5.052973s
200
+ simple_json(oj) 270.192 (± 3.7%) i/s (3.70 ms/i) - 1.360k in 5.039635s
201
+ simple_json(AS::json)
202
+ 297.476 (±10.1%) i/s (3.36 ms/i) - 1.518k in 5.145803s
246
203
 
247
204
  Comparison:
248
- simple_json: 20382.8 i/s
249
- jb: 2611.3 i/s - 7.81x (± 0.00) slower
250
- jbuilder: 972.0 i/s - 20.97x (± 0.00) slower
205
+ jb: 298.5 i/s
206
+ simple_json(AS::json): 297.5 i/s - same-ish: difference falls within error
207
+ simple_json(oj): 270.2 i/s - same-ish: difference falls within error
208
+ jbuilder: 255.9 i/s - same-ish: difference falls within error
251
209
 
252
210
 
253
- * Rendering 100 partials via render_partial
211
+ * Rendering 100 partials via render_to_string
212
+ ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [arm64-darwin24]
254
213
  Warming up --------------------------------------
255
- jb 90.000 i/100ms
256
- jbuilder 11.000 i/100ms
257
- simple_json 280.000 i/100ms
214
+ jb 19.000 i/100ms
215
+ jbuilder 14.000 i/100ms
216
+ simple_json(oj) 15.000 i/100ms
217
+ simple_json(AS::json)
218
+ 26.000 i/100ms
258
219
  Calculating -------------------------------------
259
- jb 883.446 4.8%) i/s - 4.410k in 5.003438s
260
- jbuilder 119.932 8.3%) i/s - 605.000 in 5.085382s
261
- simple_json 2.886k4.2%) i/s - 14.560k in 5.054327s
220
+ jb 186.051 12.9%) i/s (5.37 ms/i) - 912.000 in 5.075117s
221
+ jbuilder 144.279 2.1%) i/s (6.93 ms/i) - 728.000 in 5.048538s
222
+ simple_json(oj) 159.2541.9%) i/s (6.28 ms/i) - 810.000 in 5.088178s
223
+ simple_json(AS::json)
224
+ 249.690 (± 6.0%) i/s (4.00 ms/i) - 1.248k in 5.017042s
262
225
 
263
226
  Comparison:
264
- simple_json: 2885.7 i/s
265
- jb: 883.4 i/s - 3.27x (± 0.00) slower
266
- jbuilder: 119.9 i/s - 24.06x (± 0.00) slower
227
+ simple_json(AS::json): 249.7 i/s
228
+ jb: 186.1 i/s - 1.34x slower
229
+ simple_json(oj): 159.3 i/s - 1.57x slower
230
+ jbuilder: 144.3 i/s - 1.73x slower
267
231
 
268
232
 
269
- * Rendering 1000 partials via render_partial
233
+ * Rendering 1000 partials via render_to_string
234
+ ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [arm64-darwin24]
270
235
  Warming up --------------------------------------
271
- jb 12.000 i/100ms
272
- jbuilder 1.000 i/100ms
273
- simple_json 32.000 i/100ms
236
+ jb 4.000 i/100ms
237
+ jbuilder 2.000 i/100ms
238
+ simple_json(oj) 2.000 i/100ms
239
+ simple_json(AS::json)
240
+ 10.000 i/100ms
274
241
  Calculating -------------------------------------
275
- jb 124.627 4.8%) i/s - 624.000 in 5.018515s
276
- jbuilder 12.710 7.9%) i/s - 64.000 in 5.073018s
277
- simple_json 314.896 3.2%) i/s - 1.600k in 5.086509s
242
+ jb 48.691 2.1%) i/s (20.54 ms/i) - 244.000 in 5.013815s
243
+ jbuilder 27.930 3.6%) i/s (35.80 ms/i) - 140.000 in 5.016897s
244
+ simple_json(oj) 29.083 6.9%) i/s (34.38 ms/i) - 146.000 in 5.039076s
245
+ simple_json(AS::json)
246
+ 99.792 (± 7.0%) i/s (10.02 ms/i) - 500.000 in 5.037716s
278
247
 
279
248
  Comparison:
280
- simple_json: 314.9 i/s
281
- jb: 124.6 i/s - 2.53x (± 0.00) slower
282
- jbuilder: 12.7 i/s - 24.78x (± 0.00) slower
249
+ simple_json(AS::json): 99.8 i/s
250
+ jb: 48.7 i/s - 2.05x slower
251
+ simple_json(oj): 29.1 i/s - 3.43x slower
252
+ jbuilder: 27.9 i/s - 3.57x slower
283
253
  ```
284
254
 
285
255
  ## Migrating from Jbuilder
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec path: '../'
6
+
7
+ gem 'jbuilder'
8
+ gem 'rails', '~> 8.1.0'
9
+ gem 'selenium-webdriver'
@@ -54,9 +54,7 @@ module SimpleJson
54
54
  end
55
55
 
56
56
  def simple_renderer
57
- @simple_renderer ||= SimpleJsonRenderer.new(self).tap do |r|
58
- r.extend(_helpers) if respond_to?(:_helpers)
59
- end
57
+ @simple_renderer ||= self.class.simple_json_renderer_class.new(self)
60
58
  end
61
59
 
62
60
  def render_json_template(template_name, **_options)
@@ -68,6 +66,14 @@ module SimpleJson
68
66
  if SimpleJson.template_cache_enabled? && !SimpleJsonRenderer.templates_loaded?
69
67
  SimpleJsonRenderer.load_all_templates!
70
68
  end
69
+
70
+ def self.simple_json_renderer_class
71
+ @simple_json_renderer_class ||= begin
72
+ klass = Class.new(SimpleJsonRenderer)
73
+ klass.include(_helpers) if method_defined?(:_helpers)
74
+ klass
75
+ end
76
+ end
71
77
  end
72
78
 
73
79
  def template_path
@@ -20,7 +20,7 @@ module SimpleJson
20
20
  template_files = Rails.root.glob("#{path}/**/*.simple_json.rb")
21
21
  template_files.each do |file_path|
22
22
  template_path = file_path.relative_path_from(Rails.root.join(path)).to_path.delete_suffix('.simple_json.rb')
23
- @renderers[template_path] = SimpleJsonTemplate.new(file_path.to_path).renderer
23
+ define_template_method(template_path, file_path.to_path)
24
24
  end
25
25
  end
26
26
  @templates_loaded = true
@@ -29,7 +29,7 @@ module SimpleJson
29
29
  def load_template(template_path)
30
30
  if SimpleJson.template_cache_enabled?
31
31
  load_all_templates! unless templates_loaded?
32
- renderers[template_path]
32
+ render_methods[template_path]
33
33
  else
34
34
  load_template_from_file(template_path)
35
35
  end
@@ -38,18 +38,36 @@ module SimpleJson
38
38
  def load_template_from_file(template_path)
39
39
  SimpleJson.template_paths.each do |path|
40
40
  file_path = Rails.root.join("#{path}/#{template_path}.simple_json.rb").to_path
41
- return SimpleJsonTemplate.new(file_path).renderer if File.exist?(file_path)
41
+
42
+ return define_template_method(template_path, file_path) if File.exist?(file_path)
42
43
  end
43
44
 
44
45
  nil
45
46
  end
46
47
 
47
- def renderers
48
- @renderers ||= {}
48
+ def define_template_method(template_path, file_path)
49
+ template = SimpleJsonTemplate.new(file_path)
50
+ code_hash = template.code.hash
51
+
52
+ render_methods[template_path] = render_methods_cache.fetch(code_hash) do
53
+ @template_num ||= 0
54
+ @template_num += 1
55
+ method_name = :"template_#{@template_num}"
56
+ template.define_to_class(self, method_name)
57
+ render_methods_cache[code_hash] = method_name
58
+ end
59
+ end
60
+
61
+ def render_methods
62
+ @render_methods ||= {}
63
+ end
64
+
65
+ def render_methods_cache
66
+ @render_methods_cache ||= {}
49
67
  end
50
68
 
51
69
  def clear_renderers
52
- @renderers = {}
70
+ @render_methods = {}
53
71
  @templates_loaded = false
54
72
  end
55
73
  end
@@ -60,7 +78,7 @@ module SimpleJson
60
78
  end
61
79
 
62
80
  def renderer(template_path)
63
- renderers[template_path] || self.class.load_template(template_path).tap do |renderer|
81
+ renderers[template_path] || SimpleJson::SimpleJsonRenderer.load_template(template_path).tap do |renderer|
64
82
  renderers[template_path] = renderer
65
83
  end
66
84
  end
@@ -70,10 +88,11 @@ module SimpleJson
70
88
  end
71
89
 
72
90
  def render(template_name, **params)
91
+ method_name = renderer(template_name)
73
92
  if !params.empty?
74
- instance_exec(**params, &renderer(template_name))
93
+ send(method_name, **params)
75
94
  else
76
- instance_exec(&renderer(template_name))
95
+ send(method_name)
77
96
  end
78
97
  end
79
98
 
@@ -7,8 +7,11 @@ module SimpleJson
7
7
  @source = File.read(path)
8
8
  end
9
9
 
10
- def renderer
11
- @renderer ||= eval(code, TOPLEVEL_BINDING, @path) # rubocop:disable Security/Eval
10
+ def define_to_class(klass, method_name)
11
+ method_string = to_method_string(method_name)
12
+ klass.class_eval(method_string, @path)
13
+
14
+ method_name
12
15
  end
13
16
 
14
17
  def code
@@ -22,5 +25,27 @@ module SimpleJson
22
25
 
23
26
  "-> { #{source} }"
24
27
  end
28
+
29
+ def method_string_from_lambda(source, method_name)
30
+ pattern = %r{
31
+ \A(?<prefix>(?:\s*\#.*\n|\s+)*)
32
+ ->\s*
33
+ (?:\((?<params_p>.*?)\)|(?<params_n>[^\{ ]*?))
34
+ \s*(?:\{(?<body>.*)\}|do(?<body>.*)end)
35
+ (?<suffix>(?:\s*\#.*|\s+)*)\z
36
+ }mx
37
+
38
+ match = source.match(pattern)
39
+ raise :parse_error unless match
40
+
41
+ params = (match[:params_p] || match[:params_n] || "").strip
42
+ arg_part = params.empty? ? "" : "(#{params})"
43
+
44
+ "#{match[:prefix]}def #{method_name}#{arg_part};#{match[:body]};end#{match[:suffix]}"
45
+ end
46
+
47
+ def to_method_string(method_name)
48
+ method_string_from_lambda(code, method_name)
49
+ end
25
50
  end
26
51
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleJson
4
- VERSION = '0.1.0'
4
+ VERSION = '1.0.0'
5
5
  end
data/lib/simple_json.rb CHANGED
@@ -11,7 +11,7 @@ require 'simple_json/simple_json_renderer_for_migration'
11
11
 
12
12
  module SimpleJson
13
13
  @config = {
14
- cache_enabled: false,
14
+ template_cache_enabled: false,
15
15
  template_paths: ['app/views'],
16
16
  cache_key_prefix: 'simple_json/views',
17
17
  default_json_module: ActiveSupport::JSON
data/simple_json.gemspec CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency 'action_args'
26
26
  spec.add_development_dependency 'bundler'
27
27
  spec.add_development_dependency 'debug'
28
- spec.add_development_dependency 'rails', '~> 8.0'
28
+ spec.add_development_dependency 'rails', '>= 7.1'
29
29
  spec.add_development_dependency 'rake'
30
30
  spec.add_development_dependency 'selenium-webdriver'
31
31
  spec.add_development_dependency 'test-unit-rails'
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_json
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jingyuan Zhao
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-09-10 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: oj
@@ -70,16 +69,16 @@ dependencies:
70
69
  name: rails
71
70
  requirement: !ruby/object:Gem::Requirement
72
71
  requirements:
73
- - - "~>"
72
+ - - ">="
74
73
  - !ruby/object:Gem::Version
75
- version: '8.0'
74
+ version: '7.1'
76
75
  type: :development
77
76
  prerelease: false
78
77
  version_requirements: !ruby/object:Gem::Requirement
79
78
  requirements:
80
- - - "~>"
79
+ - - ">="
81
80
  - !ruby/object:Gem::Version
82
- version: '8.0'
81
+ version: '7.1'
83
82
  - !ruby/object:Gem::Dependency
84
83
  name: rake
85
84
  requirement: !ruby/object:Gem::Requirement
@@ -145,6 +144,7 @@ extra_rdoc_files: []
145
144
  files:
146
145
  - ".github/workflows/main.yml"
147
146
  - ".gitignore"
147
+ - CHANGELOG.md
148
148
  - Gemfile
149
149
  - LICENSE.txt
150
150
  - README.md
@@ -156,6 +156,7 @@ files:
156
156
  - gemfiles/rails_7.1.gemfile
157
157
  - gemfiles/rails_7.2.gemfile
158
158
  - gemfiles/rails_8.0.gemfile
159
+ - gemfiles/rails_8.1.gemfile
159
160
  - gemfiles/rails_edge.gemfile
160
161
  - lib/generators/rails/scaffold_controller_generator.rb
161
162
  - lib/generators/rails/simple_json_generator.rb
@@ -174,7 +175,6 @@ homepage: https://github.com/aktsk/simple_json
174
175
  licenses:
175
176
  - MIT
176
177
  metadata: {}
177
- post_install_message:
178
178
  rdoc_options: []
179
179
  require_paths:
180
180
  - lib
@@ -189,8 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
189
  - !ruby/object:Gem::Version
190
190
  version: '0'
191
191
  requirements: []
192
- rubygems_version: 3.5.11
193
- signing_key:
192
+ rubygems_version: 4.0.3
194
193
  specification_version: 4
195
194
  summary: Faster and simpler Jbuilder alternative
196
195
  test_files: []