class Capsium::Package::MergedView
The merged (overlay) view of a package’s content, per ARCHITECTURE.md section 5a. Shared by Package (validation) and Reactor (serving).
The content/ tree is always the implicit bottom layer; layers from storage.layers stack on top of it, bottom -> top in declaration order. Resolution scans from the TOP down and the first hit wins. Deletions are recorded as tombstones: a .capsium-tombstones JSON file in a writable layer listing content/-relative paths; a tombstoned path resolves to nil even when a lower layer (including a dependency’s content) holds the file, while a file reappearing in a layer ABOVE the tombstone is served again.
Composite packages (section 4a): dependency_views are
- dependency GUID,
MergedView -
pairs acting as read-only layers below
ALL own layers. A resource reference that is a URI of the form “<dependency-guid>/<path>” resolves explicitly against that dependency’s view; plain content paths fall through to the dependency layers in declaration order after all own layers miss.
With ‘exported_only: true` (the view a dependent package gets): layers whose visibility is “private” are hidden entirely, and a path resolves only when the manifest lists the resource as “exported”. extra_layers stack on top of ALL own layers (e.g. the reactor’s writable overlay, section 5a).
Constants
- CONTENT_PREFIX
- Layer
-
A single read layer: an absolute root directory mirroring the content/ tree, plus its parsed tombstone set.
- TOMBSTONE_FILE
Attributes
Array[[ String, MergedView ]]
Array[Layer]
String
Public Class Methods
(String package_path, storage: Storage storage, manifest: Manifest manifest, ?dependency_views: Array[[ String, MergedView ]] dependency_views, ?exported_only: bool exported_only, ?extra_layers: Array[Layer] extra_layers) → void
Source
# File lib/capsium/package/merged_view.rb, line 49 def initialize(package_path, storage:, manifest:, dependency_views: [], exported_only: false, extra_layers: []) @package_path = package_path @storage = storage @manifest = manifest @exported_only = exported_only @dependency_views = dependency_views @layers = build_layers + extra_layers end
Public Instance Methods
(String reference) → [ String, MergedView ]?
Source
# File lib/capsium/package/merged_view.rb, line 87 def dependency_pair_for(reference) @dependency_views .sort_by { |guid, _view| -guid.length } .find { |guid, _view| reference.start_with?("#{guid}/") } end
The [GUID, view] pair whose GUID prefixes the reference (longest GUID first, so nested GUIDs address the innermost dependency).
(String? reference) → String?
Source
# File lib/capsium/package/merged_view.rb, line 64 def resolve(reference) return unless reference.is_a?(String) if reference.include?("://") pair = dependency_pair_for(reference) return unless pair return pair[1].resolve(reference.delete_prefix("#{pair[0]}/")) end content_relative = content_relative(reference) return unless content_relative return if content_relative == TOMBSTONE_FILE result = resolve_own(content_relative) return if result == :tombstoned return result if result resolve_dependencies(reference) end
The absolute filesystem path serving a resource reference: a package-relative content path (“content/app.js”), or a dependency reference (“<dependency-guid>/content/app.js”). nil when no layer provides the path or it is tombstoned. Non-content paths never resolve through the view.