world-manager/docs/provider-architecture-design.md
2026-06-01 20:50:52 -05:00

5.7 KiB

Provider Architecture Design

World Manager should treat Minecraft libraries as sources of content units that can be discovered, inspected, cached, displayed, materialized, exported, and eventually copied between sources. Bedrock local folders, Bedrock iOS devices, Java local folders, and possible future platforms should be cohesive provider modules behind one engine contract.

Goals

  • Keep provider-specific knowledge inside provider modules.
  • Give the UI a uniform model for equivalent concepts: name, edition, kind, source, icon, dates, size, availability, progress, and actions.
  • Preserve variable metadata for platform details that do not translate across editions.
  • Allow scan workflows to stream events instead of forcing every provider into the same fixed stages.
  • Keep connected-device and remote-like sources free to throttle work more aggressively than local filesystem sources.

Shape

Platforms/Bedrock
  BedrockLocalFolderProvider
  BedrockIOSDeviceProvider
  BedrockContentScanner
  BedrockMetadataReader
  BedrockExporter
  BedrockMaterializer

Platforms/Java
  JavaLocalFolderProvider
  JavaContentScanner
  JavaMetadataReader
  JavaExporter
  JavaMaterializer

Engine
  ProviderRegistry
  SourceEngine
  Scan orchestration
  Cache/snapshot persistence
  Generic indexing/search/projection
  Generic action dispatch

UI
  Generic source and item surfaces
  Provider/edition-specific detail sections

Core Concepts

Provider

A provider is the unit that knows a platform and access method. A provider can represent an edition/access pairing such as Bedrock local folder, Bedrock iOS device, or Java local folder.

protocol MinecraftPlatformProvider: Sendable {
    var id: PlatformProviderID { get }
    var displayName: String { get }

    func accessDescriptor(for source: MinecraftSource) -> SourceAccessDescriptor
    func accessStatus(for source: MinecraftSource) async -> SourceAccessStatus
    func capabilities(for source: MinecraftSource) async -> SourceCapabilities

    func scan(_ request: ProviderScanRequest) -> AsyncThrowingStream<ProviderEvent, Error>
    func materialize(_ unit: MinecraftContentItem, in source: MinecraftSource) async throws -> URL
    func export(_ unit: MinecraftContentItem, in source: MinecraftSource, request: ExportRequest) async throws -> URL
}

The current SourceAccessMethod is already close to this role. The refactor should evolve it rather than replace the whole source system at once.

Content Unit

The engine should pass around an edition-aware content unit with a strong common surface and boxed platform metadata.

struct MinecraftContentItem {
    let id: URL
    let folderURL: URL
    let folderName: String
    let sourceEdition: MinecraftEdition
    let contentKind: MinecraftContentKind
    let platformType: MinecraftPlatformContentType
    let collectionRootURL: URL

    var displayName: String
    var iconURL: URL?
    var modifiedDate: Date?
    var sizeBytes: Int64?
    var capabilities: ContentItemCapabilities
    var platformMetadata: PlatformContentMetadata
}

The model can retain compatibility shims during migration, but new code should prefer edition, kind, capabilities, and boxed metadata over Bedrock-only fields.

Metadata

Generic UI should avoid flattening provider metadata. Platform details should be boxed and rendered by edition/provider-aware detail sections.

enum PlatformContentMetadata: Hashable, Sendable, Codable {
    case bedrock(BedrockContentMetadata)
    case java(JavaContentMetadata)
    case none
}

Access Status

Availability should be richer than local-vs-device.

enum SourceAccessMode: String, Hashable, Sendable, Codable {
    case localFileSystem
    case securityScopedLocalFolder
    case usbDevice
    case networkDevice
    case archive
    case unknown
}

struct SourceAccessStatus: Hashable, Sendable, Codable {
    var availability: SourceAvailability
    var mode: SourceAccessMode
    var displayName: String
    var iconSystemName: String
    var statusText: String?
    var warningText: String?
}

Event-Driven Scanning

Providers should be able to stream discoveries, metadata, progress, and warnings.

enum ProviderEvent: Sendable {
    case accessStatusChanged(SourceAccessStatus)
    case stageUpdated(WorkStage)
    case discovered(MinecraftContentItem)
    case inspected(MinecraftContentItem)
    case warning(ProviderWarning)
}

The engine consumes events, updates source state, updates indexes, persists snapshots, and exposes UI-ready projections.

Responsibilities

Engine Owns

  • Provider registration/routing.
  • Source lifecycle and persistence.
  • Scan task ownership, cancellation, and worker limits.
  • Cache and snapshot persistence hooks.
  • Generic item search, sorting, counts, and projections.
  • Generic action dispatch and user-facing error normalization.

Provider Owns

  • Access method details.
  • Discovery layout and content markers.
  • Metadata parsing.
  • Platform relationships.
  • Materialization.
  • Export formats.
  • Provider-specific progress stages and warnings.
  • Provider-specific detail metadata.

Current Fit

Existing app pieces already map to this design:

  • SourceAccessMethod: provider-like boundary.
  • SourceAccessCoordinator: provider registry/router.
  • SourceLibrary: engine/orchestrator.
  • MinecraftSource: source session and persisted model.
  • SourcePersistenceStore: persistence.
  • SourceContentIndexer: generic indexing plus Bedrock-specific relationship logic that should be split.
  • ContentItemActionService and ContentPackageExporter: action/export layer that should become capability/provider aware.

The main mismatch is that shared models and UI currently carry Bedrock-specific types and fields directly.