Ports And Adapters
Ports And Adapters
Section titled “Ports And Adapters”rim uses outbound ports so the application layer can request external work without owning concrete implementations.
rim-ports currently defines:
StorageIoFileWatcherFilePicker
These are trait contracts only. They describe what the application needs, not how the host provides it.
Adapters
Section titled “Adapters”rim-infra-storage: async file I/O, workspace file listing, previews, undo persistence, swap persistence, session persistencerim-infra-file-watcher: file and workspace watch integrationrim-infra-input: terminal input capture and action emissionrim-infra-ui: rendering and terminal session management
flowchart LR Application["rim-application"] --> Ports["rim-ports traits"] Storage["rim-infra-storage"] --> Application Storage --> Domain["rim-domain"] Storage --> Ports Watcher["rim-infra-file-watcher"] --> Application Watcher --> Domain Watcher --> Ports UI["rim-infra-ui"] --> Application UI --> Domain Input["rim-infra-input"] --> Application App["rim-app"] --> Picker["host file picker"]Dependency Direction
Section titled “Dependency Direction”Adapters may depend on application/domain types because they serialize or render those types. The reverse is not allowed.
Allowed:
- adapter implements a port
- adapter emits
AppAction - adapter serializes domain/application DTOs
Not allowed:
- domain calling adapter code directly
- adapter mutating editor state without an application action
- application depending on adapter-specific worker internals
Why SwapEditOp Still Lives In Application
Section titled “Why SwapEditOp Still Lives In Application”Swap replay is currently an application-facing integration contract used by storage orchestration. It is not editor domain state, so it should not be forced into rim-domain. It can remain in rim-application until a narrower shared contract emerges.
Anti-Patterns
Section titled “Anti-Patterns”- adding filesystem semantics to
rim-ports - making UI rendering the source of truth for editor state
- hiding long-running worker behavior behind untyped callbacks