Class: ReactOnRailsPro::RendererArtifact
- Inherits:
-
Object
- Object
- ReactOnRailsPro::RendererArtifact
- Defined in:
- lib/react_on_rails_pro/renderer_artifact.rb
Overview
Immutable description of one renderer bundle and the flat companion files that must be staged beside it. The ID is safe to use as a cache directory name and changes whenever any runtime-visible byte or destination changes.
Defined Under Namespace
Classes: Identity, InlineCompanion
Constant Summary collapse
- ID_PREFIX =
"rorp-v2"- ROLE_CODES =
{ server: "s", rsc: "r" }.freeze
- ID_PATTERN =
/\Arorp-v2-[sr]-[0-9a-f]{64}\z/- SAFE_COMPANION_NAME_PATTERN =
%r{\A(?!\.{1,2}\z)[^/\\:\x00-\x1f\x7f]+\z}
Instance Attribute Summary collapse
-
#bundle ⇒ Object
readonly
Returns the value of attribute bundle.
-
#bundle_body ⇒ Object
readonly
Returns the value of attribute bundle_body.
-
#companion_bodies ⇒ Object
readonly
Returns the value of attribute companion_bodies.
-
#companions ⇒ Object
readonly
Returns the value of attribute companions.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#role ⇒ Object
readonly
Returns the value of attribute role.
Class Method Summary collapse
- .role_from_id(value) ⇒ Object
- .safe_companion_name?(value) ⇒ Boolean
- .versioned_id?(value) ⇒ Boolean
Instance Method Summary collapse
-
#initialize(role:, bundle:, companions:, bundle_body: nil, companion_bodies: nil) ⇒ RendererArtifact
constructor
A new instance of RendererArtifact.
-
#with_materialized_files(bundle_name: File.basename(bundle.to_s)) ⇒ Object
Materializes only this value object's captured bytes and removes them as soon as the synchronous consumer returns.
Constructor Details
#initialize(role:, bundle:, companions:, bundle_body: nil, companion_bodies: nil) ⇒ RendererArtifact
Returns a new instance of RendererArtifact.
57 58 59 60 61 62 63 64 65 |
# File 'lib/react_on_rails_pro/renderer_artifact.rb', line 57 def initialize(role:, bundle:, companions:, bundle_body: nil, companion_bodies: nil) @role = role.to_sym @bundle = Pathname.new(bundle.to_s) @bundle_body = capture_body(bundle_body || File.binread(@bundle)) @companions = normalize_companions(companions) @companion_bodies = capture_companion_bodies(companion_bodies) @id = build_id.freeze freeze end |
Instance Attribute Details
#bundle ⇒ Object (readonly)
Returns the value of attribute bundle.
55 56 57 |
# File 'lib/react_on_rails_pro/renderer_artifact.rb', line 55 def bundle @bundle end |
#bundle_body ⇒ Object (readonly)
Returns the value of attribute bundle_body.
55 56 57 |
# File 'lib/react_on_rails_pro/renderer_artifact.rb', line 55 def bundle_body @bundle_body end |
#companion_bodies ⇒ Object (readonly)
Returns the value of attribute companion_bodies.
55 56 57 |
# File 'lib/react_on_rails_pro/renderer_artifact.rb', line 55 def companion_bodies @companion_bodies end |
#companions ⇒ Object (readonly)
Returns the value of attribute companions.
55 56 57 |
# File 'lib/react_on_rails_pro/renderer_artifact.rb', line 55 def companions @companions end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
55 56 57 |
# File 'lib/react_on_rails_pro/renderer_artifact.rb', line 55 def id @id end |
#role ⇒ Object (readonly)
Returns the value of attribute role.
55 56 57 |
# File 'lib/react_on_rails_pro/renderer_artifact.rb', line 55 def role @role end |
Class Method Details
.role_from_id(value) ⇒ Object
71 72 73 74 75 76 |
# File 'lib/react_on_rails_pro/renderer_artifact.rb', line 71 def self.role_from_id(value) match = ID_PATTERN.match(value.to_s) return nil unless match ROLE_CODES.key(value.to_s.delete_prefix("#{ID_PREFIX}-").slice(0)) end |
.safe_companion_name?(value) ⇒ Boolean
78 79 80 81 |
# File 'lib/react_on_rails_pro/renderer_artifact.rb', line 78 def self.safe_companion_name?(value) name = value.to_s.dup.force_encoding(Encoding::UTF_8) name.valid_encoding? && SAFE_COMPANION_NAME_PATTERN.match?(name) end |
.versioned_id?(value) ⇒ Boolean
67 68 69 |
# File 'lib/react_on_rails_pro/renderer_artifact.rb', line 67 def self.versioned_id?(value) ID_PATTERN.match?(value.to_s) end |
Instance Method Details
#with_materialized_files(bundle_name: File.basename(bundle.to_s)) ⇒ Object
Materializes only this value object's captured bytes and removes them as
soon as the synchronous consumer returns. This lets path-based adapter
APIs and tarball composition use the exact bytes bound into id without
retaining large snapshots in a process-wide cache.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/react_on_rails_pro/renderer_artifact.rb', line 87 def with_materialized_files(bundle_name: File.basename(bundle.to_s)) bundle_name = bundle_name.to_s conflicting_name = companion_bodies.each_key.find { |basename| basename.casecmp?(bundle_name) } if conflicting_name raise ArgumentError, "Renderer companion name #{conflicting_name.inspect} conflicts with bundle filename " \ "#{bundle_name.inspect}" end Dir.mktmpdir("rorp-artifact-") do |directory| bundle_path = File.join(directory, bundle_name) File.binwrite(bundle_path, bundle_body) materialized_companions = companion_bodies.to_h do |basename, body| path = File.join(directory, basename) File.binwrite(path, body) [basename, Pathname.new(path)] end.freeze yield Pathname.new(bundle_path), materialized_companions end end |