lazy_chain 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 490f13aa3fc5619f80736a1e222dff5a98f7ae36264d828e27c5bc322fdd7e04
4
+ data.tar.gz: a06fe7509586c68ec26b9ec3d31c5313bd9391cb9e076cb62a50ad154fdfccfe
5
+ SHA512:
6
+ metadata.gz: 69ee1ffcf8236e402b4b36dc9fe20c7664ccda22d984052f241445b3039fafbf9c6e09c9c84526b29d9c15f897c6b057ca6c7802f25bdc23dd9591653c29a12b
7
+ data.tar.gz: f9a684c1721e42005310b22f2300fa56ba0ab00e27359941557140d8688c779a50e3f336e69753f4743903bb7b6919be8705dcc051b7c7d2c56bd0a346f7aac8
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright Andy Cohen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # LazyChain :chains:
2
+
3
+ **Render every page immediately, even if your code is slow.**
4
+
5
+ > ⚠️ **Not usable yet.** `0.0.1` reserves the gem name and ships an empty engine — installing it does nothing. The API described below is the direction, not a promise, and it will change before `1.0`. Watch the repo if you want to know when it's real.
6
+
7
+ ## The problem
8
+
9
+ Every mature Rails app has a page like this:
10
+
11
+ ```erb
12
+ <td><%= number_to_currency estimate.pricing.all.total_amount %></td>
13
+ <td><%= number_to_currency estimate.pricing.all.margin_amount %></td>
14
+ <td><%= number_to_currency estimate.pricing.all.tax_amount %></td>
15
+ ```
16
+
17
+ Three innocent-looking method calls. Each one walks a tree of associations, and each one takes 800ms. The page takes nine seconds to paint, and the user stares at a blank screen the whole time — including the header, the navigation, and the twenty other values that were ready instantly.
18
+
19
+ You know how to fix it. Memoize it, denormalize it, precompute it in a background job, rewrite it as one heroic SQL query. All of that is real work, and all of it is work you were not planning to do this week.
20
+
21
+ ## The idea
22
+
23
+ The page is not slow. A handful of method calls on the page are slow. LazyChain lets you say which ones, and gets them out of the critical path:
24
+
25
+ ```erb
26
+ <td><%= lazy_chain estimate, "pricing.all.total_amount" %></td>
27
+ <td><%= lazy_chain estimate, "pricing.all.margin_amount" %></td>
28
+ <td><%= lazy_chain estimate, "pricing.all.tax_amount" %></td>
29
+ ```
30
+
31
+ The page renders now. Each deferred value arrives on its own, as soon as it's ready, in the spot where it belongs. All you need to do is opt-in to the provided route concern and use the view helper. Everything else is magic :magic_wand:.
32
+
33
+ ```ruby
34
+ resources :estimates, concerns: %i[lazy_chain]
35
+ ```
36
+
37
+ That's the whole pitch. No new service objects, no background job infrastructure, no cache to invalidate by hand, no JavaScript to write. You point at the slow call and move on with your day.
38
+
39
+ ## What you get
40
+
41
+ - **A one-line change at the call site.** Wrap the expensive call. Delete the wrapper later when you get around to making it fast. Nothing else in your app needs to know.
42
+ - **Nine seconds becomes nine parallel requests.** The browser fetches deferred values concurrently, so the slowest one sets your page time — not the sum of all of them.
43
+ - **Values that show up where they belong.** Each one lands in its own slot in the markup. No spinners bolted onto the layout, no reflow, no partial rewrites.
44
+ - **Below-the-fold work that never happens.** Values further down the page aren't computed until the user scrolls to them.
45
+ - **Safe by construction.** Method chains are signed automatically, and signatures are validated before execution.
46
+ - **Turbo-native and boring.** Standard Turbo Frames, standard Rails caching, standard controllers. Nothing you'd be surprised to find in a `curl`.
47
+
48
+ ## What it isn't
49
+
50
+ LazyChain is not a performance fix — it's a way to stop paying for one up front. The slow method is still slow, and it will still be slow after you install this. What changes is that your user isn't waiting on it to see the rest of the page.
51
+
52
+ If a value is slow *and* the user is blocked on reading it, make it fast. If it's slow and merely nice to have on screen eventually — which describes an enormous number of totals, rollups, and derived figures in real applications — defer it.
53
+
54
+ ## Installation
55
+
56
+ ```ruby
57
+ gem "lazy_chain"
58
+ ```
59
+
60
+ ```bash
61
+ $ bundle install
62
+ ```
63
+
64
+ Requires Rails 8.1+ and Turbo.
65
+
66
+ ## Status & roadmap
67
+
68
+ LazyChain is being extracted from a production estimating application, where it defers several hundred pricing rollups across the app and has been in daily use by a real sales team.
69
+
70
+ The extraction is in progress. Coming before the first usable release:
71
+
72
+ - [ ] The `lazy_chain` view helper and its underlying view object
73
+ - [ ] The controller and routing concern that resolve a deferred chain
74
+ - [ ] Signed method chains, verified before anything is called
75
+ - [ ] A pluggable cache strategy, so a computed value is computed once
76
+ - [ ] Pluggable formatting, with sensible defaults
77
+ - [ ] Test helpers for making deferred values behave in system specs
78
+ - [ ] Documentation worth the name
79
+
80
+ ## Contributing
81
+
82
+ Not yet — there's nothing to contribute to. Once the extraction lands, issues and pull requests are welcome. Until then, if the pitch above describes a page in your app, open an issue and tell me about it. That's genuinely useful.
83
+
84
+ ## License
85
+
86
+ Released under the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ require "bundler/gem_tasks"
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Rails.application.routes.draw do
2
+ end
@@ -0,0 +1,4 @@
1
+ module LazyChain
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module LazyChain
2
+ VERSION = "0.0.1"
3
+ end
data/lib/lazy_chain.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "lazy_chain/version"
2
+ require "lazy_chain/engine"
3
+
4
+ module LazyChain
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :lazy_chain do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lazy_chain
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andy Cohen
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rails
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: 8.1.3.1
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 8.1.3.1
26
+ description: |-
27
+ Most slow Rails pages are not slow -- a handful of method calls on them are. LazyChain lets you
28
+ mark those calls in your templates and moves them off the critical path. The page renders right
29
+ away, and each deferred value loads on its own in a Turbo Frame as soon as it is ready. Values
30
+ below the fold are never computed at all unless the user scrolls to them. No background job
31
+ infrastructure, no cache to invalidate by hand, and no JavaScript to write -- just standard
32
+ Turbo Frames and standard Rails caching.
33
+ email:
34
+ - outlawandy@gmail.com
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - MIT-LICENSE
40
+ - README.md
41
+ - Rakefile
42
+ - config/routes.rb
43
+ - lib/lazy_chain.rb
44
+ - lib/lazy_chain/engine.rb
45
+ - lib/lazy_chain/version.rb
46
+ - lib/tasks/lazy_chain_tasks.rake
47
+ homepage: https://github.com/OutlawAndy/lazy_chain
48
+ licenses:
49
+ - MIT
50
+ metadata:
51
+ source_code_uri: https://github.com/OutlawAndy/lazy_chain
52
+ changelog_uri: https://github.com/OutlawAndy/lazy_chain/blob/main/CHANGELOG.md
53
+ bug_tracker_uri: https://github.com/OutlawAndy/lazy_chain/issues
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 3.2.0
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubygems_version: 4.0.16
69
+ specification_version: 4
70
+ summary: Defer expensive method calls into Turbo Frames so every page renders immediately.
71
+ test_files: []