active_storage-async_variants 0.1.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.
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveStorage
4
+ module AsyncVariants
5
+ module VariantWithRecordExtension
6
+ def url(...)
7
+ if processed?
8
+ super
9
+ else
10
+ fallback_url(...)
11
+ end
12
+ end
13
+
14
+ def ready?
15
+ async_record&.state == "processed"
16
+ end
17
+
18
+ def processing?
19
+ async_record&.state == "processing"
20
+ end
21
+
22
+ def pending?
23
+ async_record.nil? || async_record.state == "pending"
24
+ end
25
+
26
+ def failed?
27
+ async_record&.state == "failed"
28
+ end
29
+
30
+ def error
31
+ async_record&.error
32
+ end
33
+
34
+ private
35
+
36
+ def processed?
37
+ async? ? ready? : super
38
+ end
39
+
40
+ def async?
41
+ variation.async_options[:fallback].present?
42
+ end
43
+
44
+ def async_record
45
+ blob.variant_records.find_by(variation_digest: variation.digest)
46
+ end
47
+
48
+ def fallback_url(...)
49
+ case variation.async_options[:fallback]
50
+ when :original
51
+ blob.url(...)
52
+ when :blank
53
+ nil
54
+ when Proc
55
+ variation.async_options[:fallback].call(blob)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveStorage
4
+ module AsyncVariants
5
+ module VariationExtension
6
+ ASYNC_KEYS = %i[fallback transformer max_retries].freeze
7
+
8
+ def initialize(transformations)
9
+ if transformations.is_a?(Hash)
10
+ @async_options = transformations.slice(*ASYNC_KEYS)
11
+ super(transformations.except(*ASYNC_KEYS))
12
+ else
13
+ @async_options = {}
14
+ super
15
+ end
16
+ end
17
+
18
+ def async_options
19
+ @async_options || {}
20
+ end
21
+
22
+ def default_to(defaults)
23
+ self.class.new(transformations.merge(@async_options).reverse_merge(defaults))
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveStorage
4
+ module AsyncVariants
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "async_variants/version"
4
+ require_relative "async_variants/transformer"
5
+ require_relative "async_variants/variation_extension"
6
+ require_relative "async_variants/variant_with_record_extension"
7
+ require_relative "async_variants/attachment_extension"
8
+ require_relative "async_variants/process_job"
9
+
10
+ module ActiveStorage
11
+ module AsyncVariants
12
+ class Engine < ::Rails::Engine
13
+ config.after_initialize do
14
+ ActiveStorage::Variation.prepend(
15
+ ActiveStorage::AsyncVariants::VariationExtension
16
+ )
17
+ ActiveStorage::VariantWithRecord.prepend(
18
+ ActiveStorage::AsyncVariants::VariantWithRecordExtension
19
+ )
20
+ ActiveStorage::Attachment.prepend(
21
+ ActiveStorage::AsyncVariants::AttachmentExtension
22
+ )
23
+ end
24
+ end
25
+
26
+ def self.callback_token_for(variant_record)
27
+ ActiveStorage.verifier.generate(variant_record.id, purpose: :async_variant_callback)
28
+ end
29
+
30
+ def self.callback_url_for(variant_record)
31
+ token = callback_token_for(variant_record)
32
+ Rails.application.routes.url_helpers.active_storage_async_variant_callback_url(
33
+ token: token,
34
+ **ActiveStorage::Current.url_options,
35
+ )
36
+ end
37
+ end
38
+ end
data/log/.gitkeep ADDED
File without changes
@@ -0,0 +1,6 @@
1
+ module ActiveStorage
2
+ module AsyncVariants
3
+ VERSION: String
4
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
5
+ end
6
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_storage-async_variants
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Micah Geisel
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 2026-03-04 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: activestorage
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '7.2'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '7.2'
26
+ email:
27
+ - micah@botandrose.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - ".github/workflows/ci.yml"
33
+ - ".ruby-gemset"
34
+ - ".ruby-version"
35
+ - Appraisals
36
+ - CHANGELOG.md
37
+ - CLAUDE.md
38
+ - LICENSE.txt
39
+ - README.md
40
+ - Rakefile
41
+ - app/controllers/active_storage/async_variants/callbacks_controller.rb
42
+ - config/routes.rb
43
+ - gemfiles/rails_7.2.gemfile
44
+ - gemfiles/rails_7.2.gemfile.lock
45
+ - gemfiles/rails_8.0.gemfile
46
+ - gemfiles/rails_8.0.gemfile.lock
47
+ - gemfiles/rails_8.1.gemfile
48
+ - gemfiles/rails_8.1.gemfile.lock
49
+ - lib/active_storage/async_variants.rb
50
+ - lib/active_storage/async_variants/attachment_extension.rb
51
+ - lib/active_storage/async_variants/process_job.rb
52
+ - lib/active_storage/async_variants/transformer.rb
53
+ - lib/active_storage/async_variants/variant_with_record_extension.rb
54
+ - lib/active_storage/async_variants/variation_extension.rb
55
+ - lib/active_storage/async_variants/version.rb
56
+ - log/.gitkeep
57
+ - sig/active_storage/async_variants.rbs
58
+ homepage: https://github.com/botandrose/active_storage-async_variants
59
+ licenses:
60
+ - MIT
61
+ metadata:
62
+ homepage_uri: https://github.com/botandrose/active_storage-async_variants
63
+ source_code_uri: https://github.com/botandrose/active_storage-async_variants
64
+ changelog_uri: https://github.com/botandrose/active_storage-async_variants/blob/master/CHANGELOG.md
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 3.3.0
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubygems_version: 3.6.2
80
+ specification_version: 4
81
+ summary: Async-safe variant processing with pluggable transformers for Active Storage.
82
+ test_files: []