turbostreamer 1.9.0 → 1.11.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 +4 -4
- data/README.md +31 -10
- data/lib/turbostreamer/dependency_tracker.rb +0 -2
- data/lib/turbostreamer/errors.rb +0 -2
- data/lib/turbostreamer/handler.rb +3 -6
- data/lib/turbostreamer/key_formatter.rb +22 -26
- data/lib/turbostreamer/railtie.rb +15 -5
- data/lib/turbostreamer/template.rb +1 -1
- data/lib/turbostreamer/version.rb +1 -1
- data/lib/turbostreamer.rb +15 -7
- metadata +63 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28af7502575ff95a77ab4771bd22fd1010c265f76a246b187333ccbfd8dc0832
|
4
|
+
data.tar.gz: 3814e0e465cecc5f568fc8c7c91eb949835d03c150d7d1f52c7080f75473828d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 817908e5623d3d2e0a3ff5cb4593ebf06f454ce1f1b3417b92b6f45d521dd50b8c2fe1a45358eb34e10e5cf8d39c93ab10c3652e7e09ba526bac4bc2ddcecc66
|
7
|
+
data.tar.gz: c214d24143ffd1e67e237afff5312e5087ea3afba1f3e33b08b71be475757857886b2691c69a2564c8dbe1220ec7597585ab1c893a5926d9af5429a7b4814662
|
data/README.md
CHANGED
@@ -1,17 +1,23 @@
|
|
1
|
-
# TurboStreamer
|
1
|
+
# TurboStreamer
|
2
2
|
|
3
|
-
|
4
|
-
hash structures. This is particularly helpful when the generation process is
|
5
|
-
fraught with conditionals and loops.
|
3
|
+
[](https://github.com/malomalo/turbostreamer/actions?query=workflow%3ACI)
|
6
4
|
|
5
|
+
[](http://badge.fury.io/rb/turbostreamer)
|
6
|
+
[](http://badge.fury.io/rb/turbostreamer)
|
7
|
+
|
8
|
+
TurboStreamer gives you a simple DSL like jBuilder for generating JSON that
|
9
|
+
streams directly to a String or IO object.
|
7
10
|
|
8
11
|
[Jbuilder](https://github.com/rails/jbuilder) builds a Hash as it renders the
|
9
12
|
template and once complete converts the Hash to JSON. TurboStreamer on the other
|
10
13
|
hand writes directly to the output as it is rendering the template. Because of
|
11
14
|
this some of the magic cannot be done and requires a little more verboseness.
|
12
15
|
|
13
|
-
|
14
|
-
|
16
|
+
Because no time is spent creating a hash caching is also fast. No time is spent
|
17
|
+
marshaling and unmarshaling from the cache, instead the string is cached and
|
18
|
+
directly inserted into the stream skipping any unmarshaling.
|
19
|
+
|
20
|
+
## Examples
|
15
21
|
|
16
22
|
``` ruby
|
17
23
|
# app/views/message/show.json.streamer
|
@@ -31,7 +37,7 @@ json.object! do
|
|
31
37
|
if current_user.admin?
|
32
38
|
json.visitors calculate_visitors(@message)
|
33
39
|
end
|
34
|
-
|
40
|
+
|
35
41
|
json.tags do
|
36
42
|
json.array! do
|
37
43
|
@message.tags.each { |tag| json.child! tag }
|
@@ -66,7 +72,7 @@ This will build the following structure:
|
|
66
72
|
"visitors": 15,
|
67
73
|
|
68
74
|
"tags": ['public'],
|
69
|
-
|
75
|
+
|
70
76
|
"comments": [
|
71
77
|
{ "content": "Hello everyone!", "created_at": "2011-10-29T20:45:28-05:00" },
|
72
78
|
{ "content": "To you my good sir!", "created_at": "2011-10-29T20:47:28-05:00" }
|
@@ -151,7 +157,7 @@ json.object! do
|
|
151
157
|
json.url url_for(@message.creator, format: :json)
|
152
158
|
end
|
153
159
|
end
|
154
|
-
|
160
|
+
|
155
161
|
if current_user.admin?
|
156
162
|
json.visitors calculate_visitors(@message)
|
157
163
|
end
|
@@ -299,7 +305,8 @@ TurboStreamer.encode(encoder: TurboStreamer::WankelEncoder)
|
|
299
305
|
TurboStreamer.encode(encoder: MyEncoder)
|
300
306
|
```
|
301
307
|
|
302
|
-
|
308
|
+
Setting the default encoder and options
|
309
|
+
---------------------------------------
|
303
310
|
If you need explicitly set the default:
|
304
311
|
|
305
312
|
```ruby
|
@@ -339,6 +346,20 @@ All backends must have the following functions:
|
|
339
346
|
- `inject(string)` Inject a (usually cached) string into the output; instering any delimiters as needed.
|
340
347
|
- `capture(&block)` Capture the output of the block (w/o any delimiters)
|
341
348
|
|
349
|
+
Benchmark
|
350
|
+
---------
|
351
|
+
`gnuplot` is required to run benchmark, to install:
|
352
|
+
- `brew install gnuplot` (MacOS)
|
353
|
+
|
354
|
+
`yajl` is required to install a development dependency [`wankel`](https://github.com/malomalo/wankel), to install:
|
355
|
+
- `brew install yajl` (MacOS)
|
356
|
+
|
357
|
+
To run benchmark: `bundle exec rake performance`
|
358
|
+
|
359
|
+
This will produce 2 graph images on in folders
|
360
|
+
- `performance/dirk`
|
361
|
+
- `performance/rolftimmermans`
|
362
|
+
|
342
363
|
Special Thanks & Contributors
|
343
364
|
-----------------------------
|
344
365
|
|
data/lib/turbostreamer/errors.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require "turbostreamer"
|
2
2
|
require "active_support/core_ext"
|
3
|
-
# This module makes TurboStreamer work with Rails using the template handler API.
|
4
3
|
|
4
|
+
# This module makes TurboStreamer work with Rails using the template handler
|
5
|
+
# API.
|
5
6
|
class TurboStreamer
|
6
7
|
class Handler
|
7
8
|
|
@@ -12,11 +13,7 @@ class TurboStreamer
|
|
12
13
|
true
|
13
14
|
end
|
14
15
|
|
15
|
-
|
16
|
-
# source can be a required param and
|
17
|
-
# `source = template.source if source.nil?` can be removed
|
18
|
-
def self.call(template, source=nil)
|
19
|
-
source = template.source if source.nil?
|
16
|
+
def self.call(template, source)
|
20
17
|
# this juggling is required to keep line numbers right in the error
|
21
18
|
%{__already_defined = defined?(json); json||=TurboStreamer::Template.new(self, output_buffer: output_buffer || ActionView::OutputBuffer.new); #{source}
|
22
19
|
json.target! unless (__already_defined && __already_defined != "method")}
|
@@ -1,33 +1,29 @@
|
|
1
|
-
|
1
|
+
class TurboStreamer::KeyFormatter
|
2
|
+
def initialize(*args)
|
3
|
+
@format = {}
|
4
|
+
@cache = {}
|
2
5
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
@format = {}
|
7
|
-
@cache = {}
|
8
|
-
|
9
|
-
options = args.extract_options!
|
10
|
-
args.each do |name|
|
11
|
-
@format[name] = []
|
12
|
-
end
|
13
|
-
options.each do |name, paramaters|
|
14
|
-
@format[name] = paramaters
|
15
|
-
end
|
6
|
+
options = args.extract_options!
|
7
|
+
args.each do |name|
|
8
|
+
@format[name] = []
|
16
9
|
end
|
17
|
-
|
18
|
-
|
19
|
-
@cache = {}
|
10
|
+
options.each do |name, paramaters|
|
11
|
+
@format[name] = paramaters
|
20
12
|
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize_copy(original)
|
16
|
+
@cache = {}
|
17
|
+
end
|
21
18
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
19
|
+
def format(key)
|
20
|
+
@cache[key] ||= @format.inject(key.to_s) do |result, args|
|
21
|
+
func, args = args
|
22
|
+
if ::Proc === func
|
23
|
+
func.call result, *args
|
24
|
+
else
|
25
|
+
result.send func, *args
|
30
26
|
end
|
31
27
|
end
|
32
28
|
end
|
33
|
-
end
|
29
|
+
end
|
@@ -1,15 +1,25 @@
|
|
1
1
|
require 'rails/railtie'
|
2
|
-
require 'turbostreamer/handler'
|
3
|
-
require 'turbostreamer/template'
|
4
|
-
|
5
|
-
require File.expand_path('../../../ext/actionview/buffer', __FILE__)
|
6
|
-
require File.expand_path('../../../ext/actionview/streaming_template_renderer', __FILE__)
|
7
2
|
|
8
3
|
class TurboStreamer
|
9
4
|
class Railtie < ::Rails::Railtie
|
10
5
|
initializer :turbostreamer do
|
11
6
|
ActiveSupport.on_load :action_view do
|
7
|
+
# Require turbostreamer in here so it's only loaded if needed
|
8
|
+
require 'turbostreamer'
|
9
|
+
require File.expand_path('../../../ext/actionview/buffer', __FILE__)
|
10
|
+
require File.expand_path('../../../ext/actionview/streaming_template_renderer', __FILE__)
|
11
|
+
|
12
|
+
# Register Turbostreamer with Rails
|
12
13
|
ActionView::Template.register_template_handler :streamer, TurboStreamer::Handler
|
14
|
+
|
15
|
+
# Setup the default for oj to be rails mode by default unless options
|
16
|
+
# have already been set
|
17
|
+
if TurboStreamer.default_encoder_for(:json).name == 'TurboStreamer::OjEncoder'
|
18
|
+
if !TurboStreamer.has_default_encoder_options?(:oj)
|
19
|
+
TurboStreamer.set_default_encoder_options(:oj, mode: :rails)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
13
23
|
require 'turbostreamer/dependency_tracker'
|
14
24
|
end
|
15
25
|
end
|
@@ -215,7 +215,7 @@ class TurboStreamer::Template < TurboStreamer
|
|
215
215
|
if @context.respond_to?(:cache_fragment_name)
|
216
216
|
# Current compatibility, fragment_name_with_digest is private again and cache_fragment_name
|
217
217
|
# should be used instead.
|
218
|
-
@context.cache_fragment_name(key, options)
|
218
|
+
@context.cache_fragment_name(key, **options)
|
219
219
|
elsif @context.respond_to?(:fragment_name_with_digest)
|
220
220
|
# Backwards compatibility for period of time when fragment_name_with_digest was made public.
|
221
221
|
@context.fragment_name_with_digest(key)
|
data/lib/turbostreamer.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
require 'stringio'
|
2
|
-
require 'turbostreamer/key_formatter'
|
3
|
-
require 'turbostreamer/errors'
|
4
2
|
|
5
3
|
class TurboStreamer
|
6
4
|
|
5
|
+
autoload :Handler, 'turbostreamer/handler'
|
6
|
+
autoload :Template, 'turbostreamer/template'
|
7
|
+
autoload :KeyFormatter, 'turbostreamer/key_formatter'
|
8
|
+
autoload :Errors, 'turbostreamer/errors'
|
9
|
+
|
7
10
|
BLANK = ::Object.new
|
8
11
|
|
9
12
|
ENCODERS = {
|
@@ -228,18 +231,23 @@ class TurboStreamer
|
|
228
231
|
@@key_formatter = formatter
|
229
232
|
end
|
230
233
|
|
231
|
-
def self.set_default_encoder(mime, encoder, default_options=
|
232
|
-
if encoder.is_a?(Symbol)
|
233
|
-
|
234
|
+
def self.set_default_encoder(mime, encoder, default_options=nil)
|
235
|
+
@@default_encoders[mime] = if encoder.is_a?(Symbol)
|
236
|
+
get_encoder(mime, encoder)
|
234
237
|
else
|
235
|
-
|
238
|
+
encoder
|
236
239
|
end
|
237
|
-
|
240
|
+
|
241
|
+
@@encoder_options[encoder] = default_options if default_options
|
238
242
|
end
|
239
243
|
|
240
244
|
def self.set_default_encoder_options(encoder, options)
|
241
245
|
@@encoder_options[encoder] = options
|
242
246
|
end
|
247
|
+
|
248
|
+
def self.has_default_encoder_options?(encoder)
|
249
|
+
@@encoder_options.has_key?(encoder)
|
250
|
+
end
|
243
251
|
|
244
252
|
def self.get_encoder(mime, key)
|
245
253
|
require "turbostreamer/encoders/#{key}"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbostreamer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Bracy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest-reporters
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: oj
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -192,7 +206,51 @@ dependencies:
|
|
192
206
|
- - ">="
|
193
207
|
- !ruby/object:Gem::Version
|
194
208
|
version: '0'
|
195
|
-
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: appraisal
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - "~>"
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '2.0'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - "~>"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '2.0'
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: railties
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - ">="
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: '0'
|
237
|
+
- !ruby/object:Gem::Dependency
|
238
|
+
name: multi_json
|
239
|
+
requirement: !ruby/object:Gem::Requirement
|
240
|
+
requirements:
|
241
|
+
- - ">="
|
242
|
+
- !ruby/object:Gem::Version
|
243
|
+
version: '0'
|
244
|
+
type: :development
|
245
|
+
prerelease: false
|
246
|
+
version_requirements: !ruby/object:Gem::Requirement
|
247
|
+
requirements:
|
248
|
+
- - ">="
|
249
|
+
- !ruby/object:Gem::Version
|
250
|
+
version: '0'
|
251
|
+
description: |2
|
252
|
+
TurboStreamer is a JBuilder-like DSL for building JSON that streams directly
|
253
|
+
to a string or IO
|
196
254
|
email:
|
197
255
|
- jonbracy@gmail.com
|
198
256
|
executables: []
|
@@ -227,14 +285,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
227
285
|
requirements:
|
228
286
|
- - ">="
|
229
287
|
- !ruby/object:Gem::Version
|
230
|
-
version: '
|
288
|
+
version: '3.0'
|
231
289
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
232
290
|
requirements:
|
233
291
|
- - ">="
|
234
292
|
- !ruby/object:Gem::Version
|
235
293
|
version: '0'
|
236
294
|
requirements: []
|
237
|
-
rubygems_version: 3.
|
295
|
+
rubygems_version: 3.5.4
|
238
296
|
signing_key:
|
239
297
|
specification_version: 4
|
240
298
|
summary: Stream JSON via a Builder-style DSL
|