Documentation
¶
Overview ¶
Package module provides the minimal public PlatformKit module composition framework.
Example ¶
Example composes two modules through a shared port. The content module declares a required dependency on Notifier; the notifications module provides it. Compose validates the dependency and returns the modules in dependency order (provider before consumer).
// Validates: REQ-002.
// Per: ADR-0009.
// Discipline: C-14.
package main
import (
"fmt"
"github.com/septagon-oss/pk-core/pkg/module"
)
// Notifier is an example port: an interface one module provides and another
// consumes, without either module importing the other.
type Notifier interface {
Notify(message string) error
}
// Example composes two modules through a shared port. The content module
// declares a required dependency on Notifier; the notifications module provides
// it. Compose validates the dependency and returns the modules in dependency
// order (provider before consumer).
func main() {
notifications := module.NewBundle("example.notifications", []module.Entry{
{ID: "notifications", New: func() module.Composable {
return module.Must(
module.Metadata{ID: "notifications", Name: "Notifications"},
module.WithProvides(module.Provide[Notifier]("1.0.0")),
)
}},
}, []string{"notifications"})
content := module.NewBundle("example.content", []module.Entry{
{ID: "content", New: func() module.Composable {
return module.Must(
module.Metadata{ID: "content", Name: "Content"},
module.WithDependencies(module.RequiresPort[Notifier](module.PortSpec{
Version: "1.0.0",
Purpose: "notify subscribers on publish",
PreferredProvider: "notifications",
})),
)
}},
}, []string{"content"})
catalog := module.NewCatalog().Add(content).Add(notifications).MustBuild()
plan, err := module.Compose(catalog)
if err != nil {
fmt.Println("compose error:", err)
return
}
for _, m := range plan.Modules {
fmt.Println(m.Metadata().ID)
}
}
Output: notifications content
Index ¶
- Variables
- func MatchesVersion(producer PortVersion, constraint string) (bool, error)
- func Validate(modules []Composable) error
- func ValidatePortVersion(version PortVersion) error
- func ValidateVersionConstraint(constraint string) error
- type Bundle
- type Catalog
- type CatalogBuilder
- type Composable
- type Constructor
- type Dependency
- type DependencyCategory
- type Entry
- type Metadata
- type Module
- type Option
- type Plan
- type Port
- type PortSpec
- type PortVersion
- type StaticBundle
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrUnknownModule = errors.New("unknown module")
ErrUnknownModule is returned when a module ID is not cataloged.
Functions ¶
func MatchesVersion ¶
func MatchesVersion(producer PortVersion, constraint string) (bool, error)
MatchesVersion reports whether a producer's version satisfies a dependency constraint. Empty constraints and "*" match any valid producer version.
func Validate ¶
func Validate(modules []Composable) error
Validate checks that required dependencies are provided by the selected module set.
func ValidatePortVersion ¶
func ValidatePortVersion(version PortVersion) error
ValidatePortVersion reports whether a provided port version is syntactically valid. Producer versions are mandatory. Pre-release and build metadata are accepted but ignored for compatibility comparisons; port versions represent API shape, not release channel.
func ValidateVersionConstraint ¶
ValidateVersionConstraint reports whether a dependency version constraint is syntactically valid.
Types ¶
type Catalog ¶
type Catalog struct {
// contains filtered or unexported fields
}
Catalog is an immutable lookup surface for composed modules.
func (*Catalog) BuildModule ¶
func (c *Catalog) BuildModule(id string) (Composable, error)
BuildModule constructs a module by ID.
type CatalogBuilder ¶
type CatalogBuilder struct {
// contains filtered or unexported fields
}
CatalogBuilder composes Bundles into a Catalog.
func (*CatalogBuilder) Add ¶
func (b *CatalogBuilder) Add(bundle Bundle) *CatalogBuilder
Add appends a Bundle.
func (*CatalogBuilder) AddAll ¶
func (b *CatalogBuilder) AddAll(bundles ...Bundle) *CatalogBuilder
AddAll appends multiple Bundles.
func (*CatalogBuilder) Build ¶
func (b *CatalogBuilder) Build() (*Catalog, error)
Build resolves the catalog.
func (*CatalogBuilder) MustBuild ¶
func (b *CatalogBuilder) MustBuild() *Catalog
MustBuild resolves the catalog or panics.
Panics if Build returns an error (for example, a bundle with an empty name, an entry with an empty ID or nil constructor, or a duplicate module ID). Use Build to handle these conditions as errors.
type Composable ¶
type Composable interface {
Metadata() Metadata
Dependencies() []Dependency
Provides() []Port
Providers() []any
Invocations() []any
}
Composable is the minimal read-only contract for a PlatformKit module.
Providers and Invocations are intentionally typed as any so the OSS seed does not force a dependency injection implementation. Adapters can translate this contract to Fx, Wire, Dig, or a custom container.
func Sort ¶
func Sort(modules []Composable) ([]Composable, error)
Sort returns modules in dependency order.
type Dependency ¶
type Dependency struct {
Port Port `json:"port"`
Required bool `json:"required"`
Purpose string `json:"purpose,omitempty"`
Category DependencyCategory `json:"category,omitempty"`
SubCategory string `json:"sub_category,omitempty"`
PreferredProvider string `json:"preferred_provider,omitempty"`
FallbackProviders []string `json:"fallback_providers,omitempty"`
}
Dependency declares that a module consumes a port.
func OptionalPort ¶
func OptionalPort[T any](spec PortSpec) Dependency
OptionalPort declares a typed, optional dependency on interface T.
func RequiresPort ¶
func RequiresPort[T any](spec PortSpec) Dependency
RequiresPort declares a typed, required dependency on interface T.
type DependencyCategory ¶
type DependencyCategory string
DependencyCategory defines the broad kind of port dependency a module has.
const ( // DependencyCategoryInfrastructure covers platform infrastructure ports. DependencyCategoryInfrastructure DependencyCategory = "infrastructure" // DependencyCategoryBusiness covers business-domain ports. DependencyCategoryBusiness DependencyCategory = "business" // DependencyCategoryUI covers user-interface ports. DependencyCategoryUI DependencyCategory = "ui" // DependencyCategorySecurity covers security and authorization ports. DependencyCategorySecurity DependencyCategory = "security" // DependencyCategoryMonitoring covers observability and monitoring ports. DependencyCategoryMonitoring DependencyCategory = "monitoring" // DependencyCategoryData covers data and persistence ports. DependencyCategoryData DependencyCategory = "data" // DependencyCategoryUnknown is the default when no category is declared. DependencyCategoryUnknown DependencyCategory = "unknown" )
Recognized dependency categories.
type Entry ¶
type Entry struct {
ID string
New Constructor
}
Entry is one module contribution to a Bundle.
type Module ¶
type Module struct {
// contains filtered or unexported fields
}
Module is the concrete base module. Pro and downstream modules can embed it and add their own fields or methods while still satisfying Composable:
type BillingModule struct {
module.Module
StripeAccount string
}
func Must ¶
Must constructs a Module and panics on invalid metadata.
Panics if New returns an error (for example, metadata with an empty ID or an ID containing whitespace). Use New to handle invalid metadata as an error.
func (*Module) Dependencies ¶
func (m *Module) Dependencies() []Dependency
Dependencies returns a copy of the module's declared port dependencies.
func (*Module) Invocations ¶
Invocations returns a copy of the module's dependency-injection invocation values.
type Option ¶
type Option func(*Module)
Option configures a Module.
func WithDependencies ¶
func WithDependencies(deps ...Dependency) Option
WithDependencies appends dependency declarations.
func WithInvocations ¶
WithInvocations appends dependency-injection invocation values.
func WithProviders ¶
WithProviders appends dependency-injection provider values.
func WithProvides ¶
WithProvides appends provided port declarations.
type Plan ¶
type Plan struct {
Modules []Composable
Providers []any
Invocations []any
}
Plan is the dependency-ordered result of composing modules from a catalog.
type Port ¶
type Port struct {
// Name is the stable package-qualified Go interface name.
Name string
// Version is interpreted by context: provided ports use a concrete
// producer version, dependency ports use a version constraint.
Version string
}
Port names a typed contract that one module provides and another module consumes. Name is derived from a Go interface type by PortOf.
type PortSpec ¶
type PortSpec struct {
Required bool
Purpose string
Version string
Category DependencyCategory
SubCategory string
PreferredProvider string
FallbackProviders []string
}
PortSpec is the human-authored part of a dependency declaration.
type PortVersion ¶
type PortVersion string
PortVersion is the producer-side version for a provided port.
type StaticBundle ¶
type StaticBundle struct {
// contains filtered or unexported fields
}
StaticBundle is a simple Bundle implementation.
func NewBundle ¶
func NewBundle(name string, entries []Entry, defaults []string) StaticBundle
NewBundle creates a StaticBundle.
func (StaticBundle) Defaults ¶
func (b StaticBundle) Defaults() []string
Defaults returns a copy of the bundle's default module IDs.
func (StaticBundle) Entries ¶
func (b StaticBundle) Entries() []Entry
Entries returns a copy of the bundle's module entries.