runtime

package
v0.12.0-a.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 6, 2026 License: MIT Imports: 35 Imported by: 0

Documentation

Overview

Package runtime is the execution engine linked into every compiled factory binary.

Owns:

  • DAG construction (implicit deps via reference; explicit via @depends-on)
  • Plan computation: refresh + drift + change detection + replace-because chains
  • Apply execution: parallelism cap (default 10), per-resource state writes, apply error UX
  • State model (snapshots, content-addressed, encrypted at rest)
  • Action semantics (triggered with @trigger; 'always' literal; @lock; @timeout)

Companion packages:

  • pkg/sdk/state - Backend contract that provider libraries implement
  • pkg/state/local and pkg/state/s3 - the filesystem and S3 backends
  • pkg/runner - the factory CLI that invokes runtime entry points

Index

Constants

View Source
const DefaultParallelism = 10

DefaultParallelism is the in-flight cap apply uses when no explicit value is given on the Executor or in the plan file.

View Source
const PlanFormatVersion = 2
View Source
const TriggerAlways = "always"

TriggerAlways is the literal an action uses to opt into running every time, regardless of stored state.

Variables

View Source
var ErrEvalNotFound = errors.New("not found")

ErrEvalNotFound is returned by Eval when an address or field cannot be resolved in the current scope. Plan callers may treat it as "known after apply"; apply re-evaluates against the live scope and surfaces a real failure when the reference truly is invalid.

View Source
var ErrInstanceGone = errors.New("instance no longer in iterable")

ErrInstanceGone is returned by ensureCompositeScope when a per- instance composite scope is requested for a key that the boundary's `@for-each` iterable no longer yields. Plan-time seeding of prior state treats this as a signal to skip rather than fail; orphan destroy steps for the missing instance still emit through the usual orphan path.

View Source
var ErrInterrupted = errors.New("apply: interrupted")

ErrInterrupted is returned by ApplyPlanV2 when the executor's Drain channel was closed before all steps could be dispatched. The returned snapshot still reflects every step that completed before the drain, so re-plan plus apply will pick up the remainder.

View Source
var ErrNotFound = errors.New("resource not found")

ErrNotFound is returned by a resource's Read method when the resource is absent in the cloud. The runtime treats it as a request to recreate.

Functions

func AcquireStateLock added in v0.11.0

func AcquireStateLock(
	ctx context.Context,
	store state.Backend,
) (func(error) error, error)

func ApplyBindings added in v0.6.0

func ApplyBindings(ctx *EvalContext, binds []lang.EachBinding)

ApplyBindings copies a constraint's iteration bindings onto the context so @each and any chained level name resolve during the element's evaluation.

func Changed

func Changed[T any](prior, current T) bool

Changed reports whether a field differs between its prior and current value. It compares by value, so a pointer field compares what it points at, and a state round trip that re-decodes an equal value is not a false positive.

func CompositeInputNames added in v0.8.0

func CompositeInputNames(n *Node) map[string]bool

CompositeInputNames returns the input names declared by a composite boundary.

func CoreFunctionSigs added in v0.6.0

func CoreFunctionSigs() map[string]typecheck.FuncSig

CoreFunctionSigs returns each @core function's signature, keyed by name, for compile-time existence, arity, and type checking.

func Decode

func Decode(v any, inputs map[string]any) error

Decode fills v's exported fields from the inputs map using `ub` struct tags. A field's key is the tag's name, or the kebab-cased field name when the tag has no name (or no tag at all). String values like "30s" decode into time.Duration fields. v must be a non-nil pointer to a struct.

func DirectParent

func DirectParent(addr string) string

DirectParent returns addr's parent state-ref segment path, or the empty string for a root segment. Unlike templateAddress, DirectParent preserves `['key']` segments so the result names a per-instance composite call site when one is present.

func DotPathString added in v0.6.0

func DotPathString(p *lang.DotPath) string

dotPathString renders a dotted reference back to its source form. Named segments are joined with `.`; indexed segments preserve the `['<key>']` form when the index is a string literal, and otherwise collapse to `[...]` so the path stays readable.

func EncodePlanV2

func EncodePlanV2(plan PlanFileV2) ([]byte, error)

EncodePlanV2 encodes a validated version 2 plan body.

func Eval

func Eval(e lang.Expr, ctx *EvalContext) (any, error)

Eval reduces a parsed expression to a Go value. Supported are literals, bare identifiers (as their name string); array and object literals (recursive); and the `input.X[.Y...]` address form.

func RefAddress added in v0.6.0

func RefAddress(p *lang.DotPath) string

func Refs

func Refs(e lang.Expr) []string

Refs returns the addresses an expression depends on, in source order with duplicates removed. Each returned address is the canonical form of another node: input.name, resource.name, data-source.name, or action.name. Field segments past the node address and @each.X bindings are skipped.

func RootSensitiveOutputs added in v0.8.0

func RootSensitiveOutputs(
	body syntax.FactoryBody,
	libs map[string]*Library,
	dag *DAG,
) map[string]bool

RootSensitiveOutputs reports root output names whose values must be masked.

func SameEntryRef added in v0.8.0

func SameEntryRef(a, b EntryRef) bool

func ScopeRef added in v0.6.0

func ScopeRef(ref, callSite string) string

scopeRef rewrites a reference into a composite internal address. `resource.inner` under call site `resource.outer` becomes `resource.outer/resource.inner`; every segment keeps its own kind root, so resource, data-source, and action refs all join the same way. Input refs and unsupported kinds pass through unchanged so toposort skips them. An empty callSite means the ref is already in its target scope (a top-level boundary's body refs, or a no-op when walking up past the outermost scope) and the ref returns unchanged.

func SealPlanV2

func SealPlanV2(plan PlanFileV2, enc encrypt.Encrypter) ([]byte, error)

SealPlanV2 encrypts a validated version 2 plan in the shared envelope.

func SplitInstanceAddress

func SplitInstanceAddress(addr string) (template, key string)

SplitInstanceAddress separates a `<template>['<key>']` address into its template part and the instance key. Non-instance addresses return unchanged with an empty key.

func UnknownRefAddress added in v0.8.0

func UnknownRefAddress(p *lang.DotPath, nodes map[string]*Node, scope string) string

Types

type ActionPlanOperation

type ActionPlanOperation struct {
	Decision Decision             `json:"decision"`
	Desired  *PlannedActionTarget `json:"desired,omitempty"`
	Prior    *ActionStatePayload  `json:"prior,omitempty"`
}

func (ActionPlanOperation) Validate

func (o ActionPlanOperation) Validate() error

type ActionRegistration

type ActionRegistration interface {
	NewReceiver() any
	Run(ctx context.Context, receiver, cfg any) (any, error)
	OutputType() reflect.Type
}

ActionRegistration is the type-erased registration for actions.

func MakeAction

func MakeAction[T, Out, Config any, PT actionPtr[T, Out, Config]]() ActionRegistration

MakeAction produces an ActionRegistration that wraps a TypedAction[Out, Config] implemented by *T.

func MakeActionWith

func MakeActionWith[T, Out, Config any, PT actionPtr[T, Out, Config]](
	construct func() *T,
) ActionRegistration

MakeActionWith is the variant of MakeAction that captures external state through the constructor.

type ActionStatePayload

type ActionStatePayload = state.ActionStatePayload

type AnyInputField

type AnyInputField[In any] interface {
	// contains filtered or unexported methods
}

AnyInputField retains the input root type while erasing the field value type.

type AnyOutputField

type AnyOutputField[Out any] interface {
	// contains filtered or unexported methods
}

AnyOutputField retains the output root type while erasing the field value type.

type ApplyError

type ApplyError struct {
	Address        string
	Kind           NodeKind
	Decision       Decision
	Alias          string
	LibraryPath    string
	Elapsed        time.Duration
	Err            error
	SkippedCount   int
	SucceededCount int
}

ApplyError is the structured failure value the apply scheduler returns when a step's CRUD or action call reports an error. The original error is available via Unwrap so callers can use errors.Is and errors.As; the runner uses the structured fields to print a multi line report that names the failing address, its decision and library, the elapsed time, and the counts of steps that were skipped or completed alongside it.

func (*ApplyError) Error

func (e *ApplyError) Error() string

func (*ApplyError) Unwrap

func (e *ApplyError) Unwrap() error

type ApplyEvent

type ApplyEvent struct {
	Address string
	Kind    NodeKind

	// Composite marks an event for a composite call site (a boundary).
	// A boundary's Kind is its own resource/data/action kind, so this
	// is what tells a boundary apart from a leaf of that kind.
	Composite bool

	Decision Decision
	Stage    ApplyStage
	Time     time.Time
	Elapsed  time.Duration
	Err      error
}

ApplyEvent is one observation the scheduler hands to the optional Executor.Events channel during a run. The renderer in the runner consumes these to print live per-step progress on stderr or to emit one JSON object per event under --json.

type ApplyFailure added in v0.11.0

type ApplyFailure struct {
	Stage ApplyFailureStage
	Cause error
}

func AsApplyFailure added in v0.11.0

func AsApplyFailure(err error) (*ApplyFailure, bool)

func NewApplyFailure added in v0.11.0

func NewApplyFailure(stage ApplyFailureStage, cause error) *ApplyFailure

func (*ApplyFailure) Error added in v0.11.0

func (e *ApplyFailure) Error() string

func (*ApplyFailure) Unwrap added in v0.11.0

func (e *ApplyFailure) Unwrap() error

type ApplyFailureStage added in v0.11.0

type ApplyFailureStage string
const (
	ApplyFailureSetup    ApplyFailureStage = "setup"
	ApplyFailureExecute  ApplyFailureStage = "execute"
	ApplyFailureFinalize ApplyFailureStage = "finalize"
)

type ApplyStage

type ApplyStage string

ApplyStage tags one moment in a step's apply lifecycle.

const (
	// StageStart fires when the scheduler hands the step to a worker.
	StageStart ApplyStage = "start"
	// StageDone fires when the worker reports a successful result.
	StageDone ApplyStage = "done"
	// StageFail fires when the worker returns an error. Apply will
	// halt further dispatch but already-running siblings still emit
	// their own done or fail events.
	StageFail ApplyStage = "fail"
)

type Binding

type Binding = state.CanonicalBinding

type CompositePlanOperation

type CompositePlanOperation struct {
	Decision Decision                `json:"decision"`
	Desired  *PlannedCompositeTarget `json:"desired,omitempty"`
	Prior    *CompositeStatePayload  `json:"prior,omitempty"`
}

func (CompositePlanOperation) Validate

func (o CompositePlanOperation) Validate(category NodeKind) error

type CompositeStatePayload

type CompositeStatePayload = state.CompositeStatePayload

type CompositeType

type CompositeType struct {
	Name                 string
	Kind                 NodeKind
	SyntaxBody           *syntax.FactoryBody
	AssetSetID           string
	Libraries            map[string]*Library
	LibraryBindings      map[string]string
	LibraryConfigSchemas map[string]LibraryConfigSchema
}

CompositeType registers a UB-implemented type under a library. SyntaxBody is the grammar-first body used by graph extraction.

Libraries is the resolved import table for this composite's body, keyed by the alias declared in the body's `imports:` block. The runtime looks up composite-internal nodes against this table, not the stack root's, so a composite can be reused without the caller importing every library it transitively uses. A nil Libraries uses the executor's root Libraries table. LibraryBindings declares aliases by canonical path for LibraryCatalog to resolve. A composite may supply either Libraries or LibraryBindings.

type ConfigurationRecord

type ConfigurationRecord = state.ConfigurationRecord

type DAG

type DAG struct {
	Nodes map[string]*Node
	Edges map[string][]string
}

DAG is a stack's runtime dependency graph: every addressable node indexed by its address, and the list of node addresses each one depends on, collected from references in the body and from any `@depends-on` meta key.

func BuildSyntaxDAG added in v0.8.0

func BuildSyntaxDAG(body syntax.FactoryBody, libs map[string]*Library) *DAG

BuildSyntaxDAG builds the dependency graph from a typed factory or composite body.

func (*DAG) TopologicalOrder

func (g *DAG) TopologicalOrder() ([]string, error)

TopologicalOrder returns the DAG's nodes in dependency order: every node appears after the nodes it references. Edges to non-node addresses such as `input.X` are skipped, since input refs are bound from stack values and do not block execution. Returns an error naming the involved addresses when the graph contains a cycle.

func (*DAG) UnderForEachComposite added in v0.6.0

func (g *DAG) UnderForEachComposite(n *Node) bool

UnderForEachComposite reports whether any composite call site in n's ancestry is itself a `@for-each` template.

type DataSourcePlanOperation

type DataSourcePlanOperation struct {
	Decision        Decision                 `json:"decision"`
	Desired         *PlannedDataSourceTarget `json:"desired,omitempty"`
	Prior           *DataSourceStatePayload  `json:"prior,omitempty"`
	ObservedOutputs *EncodedValue            `json:"observed-outputs,omitempty"`
}

func (DataSourcePlanOperation) Validate

func (o DataSourcePlanOperation) Validate() error

type DataSourceRegistration

type DataSourceRegistration interface {
	NewReceiver() any
	Read(ctx context.Context, receiver, cfg any) (any, error)
	OutputType() reflect.Type
}

DataSourceRegistration is the type-erased registration for data sources.

func MakeDataSource

func MakeDataSource[T, Out, Config any, PT dataSourcePtr[T, Out, Config]]() DataSourceRegistration

MakeDataSource produces a DataSourceRegistration that wraps a TypedDataSource[Out, Config] implemented by *T.

func MakeDataSourceWith

func MakeDataSourceWith[T, Out, Config any, PT dataSourcePtr[T, Out, Config]](
	construct func() *T,
) DataSourceRegistration

MakeDataSourceWith is the variant of MakeDataSource that captures external state through the constructor.

type DataSourceStatePayload

type DataSourceStatePayload = state.DataSourceStatePayload

type Decision

type Decision string

Decision tags one node's planned action.

const (
	DecisionCreate  Decision = "create"
	DecisionUpdate  Decision = "update"
	DecisionReplace Decision = "replace"
	DecisionDestroy Decision = "destroy"
	DecisionNoOp    Decision = "no-op"
	DecisionRerun   Decision = "rerun"
	DecisionSkip    Decision = "skip"
	DecisionRead    Decision = "read"
	DecisionEval    Decision = "eval"
)

type DriftRule

type DriftRule[Out any] struct {
	// contains filtered or unexported fields
}

DriftRule selects replacement from a change to one observed output field.

func ReplaceOnDrift

func ReplaceOnDrift[Out, Value any](
	field OutputDescriptor[Out, Value],
	equal func(recorded, observed Value) bool,
) DriftRule[Out]

ReplaceOnDrift replaces a resource when one recorded and observed output differs.

type EncodedValue

type EncodedValue = encodedvalue.Value

func AbsentValue

func AbsentValue() EncodedValue

func BooleanValue

func BooleanValue(v bool) EncodedValue

func DecodeEncodedValue

func DecodeEncodedValue(data []byte) (EncodedValue, error)

func IntegerValue

func IntegerValue(v int64) EncodedValue

func ListValue

func ListValue(items []EncodedValue) (EncodedValue, error)

func MapValue

func MapValue(entries map[string]EncodedValue) (EncodedValue, error)

func NullValue

func NullValue() EncodedValue

func NumberValue

func NumberValue(v float64) (EncodedValue, error)

func ObjectValue

func ObjectValue(fields map[string]EncodedValue) (EncodedValue, error)

func PendingEncodedValue

func PendingEncodedValue(refs []string) (EncodedValue, error)

func StringValue

func StringValue(v string) EncodedValue

type EncodedValueKind

type EncodedValueKind = encodedvalue.Kind

type EntryMoveMode added in v0.8.0

type EntryMoveMode int
const (
	EntryMoveStrict EntryMoveMode = iota
	EntryMoveIdempotent
)

type EntryMoveResult added in v0.8.0

type EntryMoveResult struct {
	From EntryRef
	To   EntryRef
}

func ApplyEntryMovesV2

func ApplyEntryMovesV2(
	snapshot *state.SnapshotV2,
	dag *DAG,
	libraries map[string]*Library,
	specs []EntryMoveSpec,
	mode EntryMoveMode,
) (*state.SnapshotV2, []EntryMoveResult, error)

type EntryMoveSpec added in v0.8.0

type EntryMoveSpec struct {
	From EntryRef
	To   EntryRef
}

type EntryRef added in v0.8.0

type EntryRef = stateref.EntryRef

func EntryRefFromNode added in v0.8.0

func EntryRefFromNode(n *Node) (EntryRef, bool)

func ParseEntryRef added in v0.8.0

func ParseEntryRef(s string) (EntryRef, error)

type EvalContext

type EvalContext struct {
	Inputs     map[string]any
	Resources  map[string]any
	Data       map[string]any
	Actions    map[string]any
	Libraries  map[string]*Library
	Bindings   map[string]any
	Assets     *asset.Set
	AssetCache *asset.Cache

	// Each holds named iteration bindings, @each for a @for-each body
	// and declared names like @rule for a chained constraint form,
	// each a key/value record read as @name.key and @name.value.
	Each map[string]lang.EachValue

	// MissingAsNull makes path navigation yield null instead of
	// ErrEvalNotFound, or a hard error, when a key is absent or a parent
	// is itself null. The constraint checkers set it so a predicate over
	// an unset optional input, including a nested one, reduces to a
	// boolean rather than collapsing the whole expression to null or
	// failing on a null parent. Navigating into a non-null scalar is
	// still an error. It stays false everywhere else, because the planner
	// relies on ErrEvalNotFound to detect forward references to upstreams
	// that have not run yet.
	MissingAsNull bool
	// contains filtered or unexported fields
}

EvalContext supplies the values that addresses resolve against. Inputs is the validated `inputs:` map after stack file values and missing values read from `UB_INPUT_*` env vars. Resources, Data, and Actions hold the outputs of nodes that have already executed, indexed by their source address path. Libraries is the import table the scope's `<alias>.<func>(...)` calls resolve against; nil disables library-qualified calls. Bindings holds comprehension-bound names, which resolve as bare values and as dot-path roots ahead of the reserved roots; validation keeps the names distinct across nesting.

func NewEvalContext added in v0.7.0

func NewEvalContext(f *lang.File) *EvalContext

NewEvalContext returns an EvalContext whose local.<name> references resolve against f's locals: block. Callers fill the remaining fields for their scope. A nil file, or one without locals, yields a context where any local reference reports the local as not declared.

func NewEvalContextFromLocals added in v0.8.0

func NewEvalContextFromLocals(exprs map[string]lang.Expr) *EvalContext

NewEvalContextFromLocals returns an EvalContext whose local.<name> references resolve against exprs. Callers fill the remaining fields for their scope.

type ExecResult

type ExecResult struct {
	Outputs    map[string]any
	Actions    map[string]any
	Data       map[string]any
	WrittenRev string
}

ExecResult contains evaluated outputs, action and data values, and the revision written by apply.

type Executor

type Executor struct {
	DAG            *DAG
	Libraries      map[string]*Library
	LibraryCatalog *LibraryCatalog
	Inputs         map[string]any

	AssetCatalog   *asset.Catalog
	AssetCache     *asset.Cache
	RootAssetSetID string

	// SyntaxSource is the typed factory body for grammar-first callers.
	SyntaxSource *syntax.FactoryBody

	Store   state.Backend
	Factory state.FactoryInfo

	// PlanBackend describes the state provider recorded in a version 2 plan.
	PlanBackend *StateRefV2

	// Parallelism caps the number of in-flight resource, data-source, and
	// action steps during ApplyPlanV2. Zero or negative uses the saved
	// plan's limit, or DefaultParallelism when no limit was recorded.
	Parallelism int

	// Destroy makes PlanV2 remove recorded entries using their saved
	// bindings and configurations, without evaluating root outputs.
	Destroy bool

	// Drain, when non-nil, lets the caller ask the scheduler to stop
	// dispatching new steps without canceling the apply context. The
	// runner closes this channel on SIGINT so in-flight CRUD calls
	// finish and their state writes commit; SIGTERM cancels the
	// context directly. A nil channel disables the drain signal.
	Drain <-chan struct{}

	// Events, when non-nil, receives one ApplyEvent per step stage
	// during ApplyPlanV2: start when the scheduler hands the step to a
	// worker, done or fail when the worker returns. The caller owns
	// the channel and is responsible for sizing the buffer and
	// closing it after ApplyPlanV2 returns. A nil channel disables
	// event emission.
	Events chan<- ApplyEvent
	// contains filtered or unexported fields
}

Executor owns the factory graph, libraries, inputs, and state backend. PlanV2 computes a saved plan, ApplyPlanV2 executes its reviewed decisions, and RefreshV2 records current resource observations.

func (*Executor) ApplyPlanV2

func (e *Executor) ApplyPlanV2(
	ctx context.Context, plan *PlanFileV2,
) (_ *ExecResult, err error)

ApplyPlanV2 executes the reviewed decisions against the recorded state revision.

func (*Executor) CheckLibraryConfigs added in v0.8.0

func (e *Executor) CheckLibraryConfigs() error

CheckLibraryConfigs reports Go leaves whose import alias needs a config but has no library-configs entry in its scope.

func (*Executor) PlanV2

func (e *Executor) PlanV2(ctx context.Context) (*PlanFileV2, error)

func (*Executor) RefreshV2

func (e *Executor) RefreshV2(ctx context.Context) (result *RefreshResult, err error)

RefreshV2 updates recorded resource observations under the stack state lock.

func (*Executor) ValidateCompositeConstraints added in v0.11.0

func (e *Executor) ValidateCompositeConstraints() error

ValidateCompositeConstraints checks every composite whose call arguments can be evaluated from factory inputs without reading resources or state.

type FactoryRef

type FactoryRef struct {
	Name            string `json:"name"`
	Version         string `json:"version"`
	ContentRevision string `json:"content-revision"`
}

FactoryRef identifies the stack a plan was computed against.

type FunctionType

type FunctionType struct {
	Name        string
	Description string
	ArgCount    int
	Variadic    bool
	Func        func(args []any) (any, error)
}

FunctionType registers a callable function under a Go library. Functions take pre-evaluated argument values and return a single value or an error. They run inline during expression evaluation and have no DAG node or state of their own.

ArgCount and Variadic declare the argument count the compiler enforces at each call site: a non-variadic function takes exactly ArgCount arguments, a variadic one takes ArgCount or more. A call's argument count is fixed in the source, so this check is compile-time only and the function body may assume it already holds.

func MakeFunc added in v0.6.0

func MakeFunc(name, description string, fn any) FunctionType

MakeFunc adapts a plain typed Go function into a FunctionType, the way text/template adapts a FuncMap entry. fn may take any number of parameters, variadic included, and must return (value, error); each parameter must be a type the evaluator's values convert to exactly: bool, int64, float64, string, any, []byte, or a slice or string-keyed map of the ordinary value types. Evaluated arguments convert to the parameter types on the way in and the result converts back to evaluator values on the way out, so the implementation stays plain typed Go and the argument count cannot disagree with the declaration.

MakeFunc panics on a fn that does not fit. Registration runs when a factory binary starts and when a library's own tests construct it; the compiler rejects the same signatures from source, so a malformed registration fails the importing factory's compile first.

type IdentityMigrationFunc

type IdentityMigrationFunc func(
	oldVersion int,
	resource ResourceMigrationState,
	priorStableID *string,
) (*string, error)

IdentityMigrationFunc migrates an identity derived from older resource values.

type IdentityRecord

type IdentityRecord = state.IdentityRecord

IdentityRecord is the persisted resource identity record.

type IdentityScope

type IdentityScope string

IdentityScope states whether configuration is part of a resource's logical address.

const (
	// IdentityConfiguration makes the selected library configuration part of identity.
	IdentityConfiguration IdentityScope = "configuration"
	// IdentityGlobal permits a resource identity to remain valid across configurations.
	IdentityGlobal IdentityScope = "global"
)

type InputDescriptor

type InputDescriptor[In, Value any] struct {
	// contains filtered or unexported fields
}

InputDescriptor identifies one field in a resource input struct.

func InputField

func InputField[In, Value any](
	selectField func(*In) *Value,
) InputDescriptor[In, Value]

InputField declares a field selected from a resource input struct.

type InputRule

type InputRule[In any] struct {
	// contains filtered or unexported fields
}

InputRule gives one input field custom semantic equality.

func EqualBy

func EqualBy[In, Value any](
	field InputDescriptor[In, Value],
	equal func(Value, Value) bool,
) InputRule[In]

EqualBy declares semantic equality for one input field.

type InputSemantics

type InputSemantics[In any] struct {
	Rules []InputRule[In]
}

InputSemantics contains the typed equality rules for resource inputs.

type Library

type Library struct {
	Name          string
	LibraryPath   string
	Description   string
	Configuration cfg.Registration
	Actions       map[string]ActionRegistration
	Resources     map[string]ResourceRegistration
	DataSources   map[string]DataSourceRegistration
	// Composites are kept in one map per kind, mirroring the
	// Resources / DataSources / Actions Go-type maps. resource,
	// data-source, and action are distinct namespaces, so a library may
	// declare resource.foo and data-source.foo as separate composites.
	ResourceComposites map[string]*CompositeType
	DataComposites     map[string]*CompositeType
	ActionComposites   map[string]*CompositeType
	Functions          map[string]FunctionType
	// Schema carries the library's resource, data source, and action
	// output field sets. Populated by the dev CLI from a fetched Go
	// library's source for compile-time reference checking; nil at
	// runtime since the generated binary does not need it.
	Schema *LibrarySchema

	// Constraints holds each Go type's cross-field constraints in the
	// embeddable spec form, keyed by "<kind>.<type>" (e.g. "resource.vpc")
	// since resource, data-source, and action are distinct namespaces. codegen
	// sets it in the generated main.go from the constraints goschema
	// derived from the library's source; the plan checks a node against
	// Constraints[node.Kind + "." + node.Type]. UB composites carry their
	// own constraints in their bodies, so this stays empty for UB libraries.
	Constraints map[string][]lang.ConstraintSpec

	// Defaults holds each Go type's declared input defaults, keyed by
	// "<kind>.<type>" like Constraints and set the same way by codegen.
	// The runtime fills a Value default into a body's inputs wherever a
	// field is left out, before constraints, triggers, and decode read
	// them; an Optional marker fills nothing.
	Defaults map[string][]lang.DefaultSpec
}

Library is the registration record a library exports for its types, actions, and data sources. Go libraries supply Resources, Actions, and DataSources via the generic helpers (`MakeResource` and friends); UB libraries compiled by `unobin compile` contribute Composites with typed syntax bodies. The compiler links each imported library's record and aggregates it under the alias the calling source assigned to the import.

func LibraryWithPath added in v0.8.0

func LibraryWithPath(lib *Library, libraryPath string) *Library

LibraryWithPath records the resolved import path on a library registration.

func (*Library) AddComposite

func (l *Library) AddComposite(ct *CompositeType)

AddComposite stores ct in the map for its kind, creating the map on first use.

func (*Library) Composite

func (l *Library) Composite(kind NodeKind, name string) *CompositeType

Composite returns the composite of the given kind and name, or nil when the library has none. resource, data-source, and action are independent namespaces, so the kind selects which map to consult.

type LibraryCatalog

type LibraryCatalog struct {
	// contains filtered or unexported fields
}

LibraryCatalog owns the library instances shared by a factory's import aliases.

func NewLibraryCatalog

func NewLibraryCatalog(registrations []LibraryRegistration) (*LibraryCatalog, error)

func (*LibraryCatalog) Libraries

func (c *LibraryCatalog) Libraries(bindings map[string]string) (map[string]*Library, error)

type LibraryConfigSchema added in v0.10.0

type LibraryConfigSchema struct {
	Path        string
	Identity    string
	Fields      []typecheck.ObjectField
	Defaults    []lang.DefaultSpec
	Constraints []lang.ConstraintSpec
	Digest      string
	Empty       bool
}

func LibraryConfigSchemaFromLibrary added in v0.10.0

func LibraryConfigSchemaFromLibrary(
	path string,
	lib *Library,
) (LibraryConfigSchema, bool, error)

func LibraryConfigSchemaFromLibrarySchema added in v0.10.0

func LibraryConfigSchemaFromLibrarySchema(
	path string,
	schema *LibrarySchema,
) (LibraryConfigSchema, bool)

func LibraryConfigSchemaFromView added in v0.10.0

func LibraryConfigSchemaFromView(path string, view cfg.LibraryConfigView) LibraryConfigSchema

func (LibraryConfigSchema) LangSchema added in v0.10.0

func (LibraryConfigSchema) TypecheckType added in v0.10.0

func (s LibraryConfigSchema) TypecheckType() typecheck.Type

type LibraryConfigurationPlanOperation

type LibraryConfigurationPlanOperation struct {
	Decision Decision             `json:"decision"`
	Inputs   EncodedValue         `json:"inputs"`
	Result   PlannedConfiguration `json:"result"`
}

func (LibraryConfigurationPlanOperation) Validate

type LibraryRegistration

type LibraryRegistration struct {
	LibraryPath string
	New         func() *Library
}

LibraryRegistration declares one implementation for a canonical library path.

type LibrarySchema

type LibrarySchema struct {
	Resources   map[string]*TypeSchema
	DataSources map[string]*TypeSchema
	Actions     map[string]*TypeSchema
	// Functions maps each function name the library exports to its
	// declared signature. The implementations live in the compiled Go
	// and cannot run at compile time, but the signature lets the
	// reference checker reject a call to an unknown function or one
	// given the wrong number of arguments, and the inferrer check each
	// argument's type and use the result type. A function registered
	// without declared types reads as all-Unknown, which counts
	// arguments but checks no types.
	Functions map[string]typecheck.FuncSig

	// Configuration describes the fields of the library's Configuration
	// struct, keyed by kebab-case field name. Nil when the library
	// declares no configuration or when the struct behind the
	// ConfigurationType's New function cannot be read from source.
	// HasConfiguration distinguishes the two: it is true whenever the
	// library declares a configuration, readable or not, so checks can
	// tell "no configuration" from "fields unknowable".
	Configuration            map[string]typecheck.Type
	ConfigurationFields      []typecheck.ObjectField
	ConfigurationDefaults    []lang.DefaultSpec
	ConfigurationConstraints []lang.ConstraintSpec
	ConfigurationIdentity    string
	ConfigurationDigest      string
	ConfigurationEmpty       bool
	HasConfiguration         bool
}

LibrarySchema describes a Go library's registered resource, data source, and action types as the dev CLI sees them at compile time. Each entry is keyed by the type's kebab-case name (the same name used in factory source).

func (*LibrarySchema) ForType added in v0.6.0

func (s *LibrarySchema) ForType(kind NodeKind, typ string) *TypeSchema

ForType returns the schema for a node kind's type, or nil when the kind is not a resource, data source, or action or the type is absent.

type MissingLibraryConfig added in v0.8.0

type MissingLibraryConfig struct {
	Address string
	Alias   string
}

MissingLibraryConfig identifies a leaf whose alias needs a config entry.

func MissingLibraryConfigs added in v0.8.0

func MissingLibraryConfigs(dag *DAG, libs map[string]*Library) []MissingLibraryConfig

MissingLibraryConfigs returns leaf aliases that need a library-configs entry.

type NoConfig added in v0.8.0

type NoConfig struct{}

NoConfig is the config parameter for libraries that declare no config.

type Node

type Node struct {
	Address              string
	Kind                 NodeKind
	Alias                string
	LibraryPath          string
	Type                 string
	Name                 string
	Body                 lang.Expr
	Composite            string
	CompositeSyntaxBody  *syntax.FactoryBody
	AssetSetID           string
	Libraries            map[string]*Library
	LibraryConfigSchemas map[string]LibraryConfigSchema

	ForEach lang.Expr

	// LockName is the value of a node body's `@lock:` field. Two nodes
	// sharing a non-empty LockName cannot run in parallel under apply's
	// scheduler, even on unrelated DAG branches. Empty means the node is
	// not under a named lock. It applies to any kind; since the
	// scheduler only runs nodes in parallel at apply, a lock has no
	// effect on a data source whose inputs are known and read at plan.
	LockName string

	// Timeout is the parsed value of a node body's `@timeout:` field: a
	// limit on how long the node's apply step may run. Zero means no
	// limit. On expiry the step's context is cancelled and the step
	// fails like any other apply error. Like @lock it only bites at
	// apply, so it does not bound a data source read at plan.
	Timeout time.Duration
}

Node is one addressable element of a stack: a single resource instance, data source, action, output, or composite call site. Address is the dotted form the language uses to reference the node from elsewhere, such as `resource.app`, `data-source.image`, `action.deploy`, or `output.cluster-arn`. Body is the source expression: an ObjectLit for resources, data sources, actions, and composites; any Expr for outputs.

A node inside a composite stores the call site address in Composite so the runtime evaluates its body against the composite's scope rather than the root. Its address looks like `resource.app/resource.inner`, with the call site as a prefix joined by a single `/`. For a composite that itself calls another composite the chain continues: `resource.outer/resource.inner/resource.leaf`, and each node's Composite names its direct enclosing call site.

CompositeSyntaxBody, AssetSetID, Libraries, and LibraryConfigSchemas are set only on a composite boundary (the call site node), and IsComposite reports that case. Libraries is the composite's resolved import table; the runtime resolves composite-internal node lookups against this map rather than the stack root's, so a composite can be reused without the caller importing every library it transitively uses.

func ExtractSyntaxNodes added in v0.8.0

func ExtractSyntaxNodes(body syntax.FactoryBody, libs map[string]*Library) []*Node

ExtractSyntaxNodes walks a typed factory or composite body and returns every addressable node in source order. The body is assumed to be validated.

func (*Node) IsComposite

func (n *Node) IsComposite() bool

IsComposite reports whether the node is a composite call site (a boundary) rather than a primitive leaf. A boundary has its own Kind (the call site's resource/data/action kind) just like a leaf; what sets it apart is the composite body populated only on boundaries.

type NodeKind

type NodeKind string

NodeKind tags a Node with its source block.

const (
	NodeResource      NodeKind = "resource"
	NodeDataSource    NodeKind = "data-source"
	NodeAction        NodeKind = "action"
	NodeOutput        NodeKind = "output"
	NodeLibraryConfig NodeKind = "library-config"
)
const NodeLibraryConfiguration NodeKind = "library-configuration"

type ObservationStatus

type ObservationStatus string
const (
	ObservationPresent ObservationStatus = "present"
	ObservationAbsent  ObservationStatus = "absent"
)

type OutputDescriptor

type OutputDescriptor[Out, Value any] struct {
	// contains filtered or unexported fields
}

OutputDescriptor identifies one field in a resource output struct.

func OutputField

func OutputField[Out, Value any](
	selectField func(Out) *Value,
) OutputDescriptor[Out, Value]

OutputField declares a field selected from a resource output struct.

type OutputPlanOperation

type OutputPlanOperation struct {
	Decision  Decision     `json:"decision"`
	Value     EncodedValue `json:"value"`
	Sensitive bool         `json:"sensitive"`
}

func (OutputPlanOperation) Validate

func (o OutputPlanOperation) Validate() error

type PanicError added in v0.6.0

type PanicError struct {
	Op      string
	Library string
	Value   any
	Stack   []byte
	Core    bool
}

PanicError reports that code the runtime called panicked. Every call into a library - a resource, action, data source, or function - is recovered at the boundary, so a defect there fails the step like any other error instead of crashing the process. A panic in unobin's own @core functions is recovered the same way but attributed to unobin rather than to a library.

Op names what was running when the panic happened. Library is the import alias to blame, filled in where the failing node is known and left empty when the runtime cannot place it. Value is whatever was passed to panic. Stack is the goroutine stack captured at the moment of recovery, kept for a verbose report.

func (*PanicError) Error added in v0.6.0

func (e *PanicError) Error() string

type PendingValue added in v0.6.0

type PendingValue struct {
	Refs []string
}

PendingValue represents an unresolved expression during planning. Its source addresses identify the values that must resolve before apply can pass concrete inputs to a provider.

type PlanFileV2

type PlanFileV2 struct {
	FormatVersion int                `json:"format-version"`
	Factory       FactoryRef         `json:"factory"`
	Stack         string             `json:"stack"`
	StateRevision string             `json:"state-revision"`
	GeneratedAt   time.Time          `json:"generated-at"`
	Inputs        EncodedValue       `json:"inputs"`
	Backend       *StateRefV2        `json:"backend,omitempty"`
	Parallelism   int                `json:"parallelism"`
	Mode          PlanMode           `json:"mode"`
	StateMoves    []PlannedEntryMove `json:"state-moves"`
	Steps         []PlanStepV2       `json:"steps"`
	Digest        string             `json:"digest"`
}

func DecodePlanV2

func DecodePlanV2(data []byte) (PlanFileV2, error)

DecodePlanV2 validates a version 2 plan body and its content digest.

func OpenPlanV2

func OpenPlanV2(
	b []byte,
	resolveEnc func(*StateRef) (encrypt.Encrypter, error),
) (PlanFileV2, error)

OpenPlanV2 decrypts an envelope and validates its version 2 plan body.

func (PlanFileV2) Validate

func (p PlanFileV2) Validate() error

type PlanMode

type PlanMode string
const (
	PlanApply   PlanMode = "apply"
	PlanDestroy PlanMode = "destroy"
)

type PlanStepV2

type PlanStepV2 struct {
	Address   string        `json:"address"`
	Kind      NodeKind      `json:"kind"`
	DependsOn []string      `json:"depends-on"`
	Operation StepOperation `json:"operation"`
}

func (PlanStepV2) Validate

func (s PlanStepV2) Validate() error

type PlannedActionTarget

type PlannedActionTarget struct {
	Binding              Binding              `json:"binding"`
	Inputs               EncodedValue         `json:"inputs"`
	Configuration        PlannedConfiguration `json:"configuration"`
	TriggerHash          string               `json:"trigger-hash"`
	SensitiveInputPaths  []string             `json:"sensitive-input-paths"`
	SensitiveOutputPaths []string             `json:"sensitive-output-paths"`
}

func (PlannedActionTarget) Validate

func (t PlannedActionTarget) Validate() error

type PlannedCompositeTarget

type PlannedCompositeTarget struct {
	Category             NodeKind     `json:"category"`
	Binding              Binding      `json:"binding"`
	Inputs               EncodedValue `json:"inputs"`
	SensitiveInputPaths  []string     `json:"sensitive-input-paths"`
	SensitiveOutputPaths []string     `json:"sensitive-output-paths"`
}

func (PlannedCompositeTarget) Validate

func (t PlannedCompositeTarget) Validate() error

type PlannedConfiguration

type PlannedConfiguration struct {
	Kind        PlannedConfigurationKind `json:"kind"`
	Record      *ConfigurationRecord     `json:"record,omitempty"`
	PendingRefs []string                 `json:"pending-refs,omitempty"`
}

func (PlannedConfiguration) Validate

func (c PlannedConfiguration) Validate() error

type PlannedConfigurationKind

type PlannedConfigurationKind string
const (
	PlannedConfigurationConcrete PlannedConfigurationKind = "concrete"
	PlannedConfigurationPending  PlannedConfigurationKind = "pending"
)

type PlannedDataSourceTarget

type PlannedDataSourceTarget struct {
	Binding              Binding              `json:"binding"`
	Inputs               EncodedValue         `json:"inputs"`
	Configuration        PlannedConfiguration `json:"configuration"`
	SensitiveInputPaths  []string             `json:"sensitive-input-paths"`
	SensitiveOutputPaths []string             `json:"sensitive-output-paths"`
}

func (PlannedDataSourceTarget) Validate

func (t PlannedDataSourceTarget) Validate() error

type PlannedEntryMove added in v0.8.0

type PlannedEntryMove struct {
	From string `json:"from"`
	To   string `json:"to"`
}

type PlannedResourceTarget

type PlannedResourceTarget struct {
	Binding              Binding              `json:"binding"`
	Inputs               EncodedValue         `json:"inputs"`
	Configuration        PlannedConfiguration `json:"configuration"`
	SensitiveInputPaths  []string             `json:"sensitive-input-paths"`
	SensitiveOutputPaths []string             `json:"sensitive-output-paths"`
}

func (PlannedResourceTarget) Validate

func (t PlannedResourceTarget) Validate() error

type Prior

type Prior[In, Out any] struct {
	Inputs   In
	Outputs  Out
	Observed Out
}

Prior is everything known before Update acts: the inputs the body evaluated to on the last apply, the outputs the resource returned then, and the reality a plan-time Read last saw. Compare current inputs against Inputs with Changed to decide what to reconcile, read Outputs for the prior handle (an id, an arn) the update acts against, and read Observed to patch from current reality rather than the recorded result when the two have drifted apart.

Inputs and Outputs are the recorded values after any required schema migration. Invalid recorded values fail before Update is called.

Observed is plan-time, not apply-time: apply does not re-Read before Update, so between plan and apply reality can move further. A resource that needs apply-time truth must Read itself.

type RefMatch added in v0.8.0

type RefMatch struct {
	Address  string
	Segments int
}

func RefMatchInScope added in v0.8.0

func RefMatchInScope(
	p *lang.DotPath,
	nodes map[string]*Node,
	scope string,
) (RefMatch, bool)

type RefreshResult

type RefreshResult struct {
	WrittenRev string
	Refreshed  int
	Dropped    int
}

RefreshResult reports observed resources, removed resources, and the saved revision.

type ReplacementRule

type ReplacementRule[In any] struct {
	// contains filtered or unexported fields
}

ReplacementRule selects replacement from a change to one input field.

func ReplaceWhen

func ReplaceWhen[In, Value any](
	field InputDescriptor[In, Value],
	predicate func(prior, desired Value) bool,
) ReplacementRule[In]

ReplaceWhen conditionally replaces a resource after one input field changes.

func ReplaceWhenChanged

func ReplaceWhenChanged[In, Value any](
	field InputDescriptor[In, Value],
) ReplacementRule[In]

ReplaceWhenChanged replaces a resource whenever one input field changes.

type ReplacementRules

type ReplacementRules[In, Out any] struct {
	Inputs []ReplacementRule[In]
	Drift  []DriftRule[Out]
}

ReplacementRules contains input-change and remote-drift replacement rules.

type ResourceDefinition

type ResourceDefinition[In, Out, Config any] struct {
	SchemaVersion  int
	Migrate        ResourceMigrationFunc
	Validate       ResourceValidateFunc[In, Config]
	InputSemantics InputSemantics[In]
	Identity       ResourceIdentity[In, Out]
	Replacement    ReplacementRules[In, Out]
}

ResourceDefinition declares a resource's schema, input semantics, identity, and replacement rules separately from its provider lifecycle methods.

type ResourceIdentity

type ResourceIdentity[In, Out any] struct {
	Version       int
	Scope         IdentityScope
	AddressInputs []AnyInputField[In]
	StableID      func(In, Out) (string, error)
	Migrate       IdentityMigrationFunc
}

ResourceIdentity declares how the runtime locates and identifies a resource.

type ResourceMigrationFunc

type ResourceMigrationFunc func(
	oldVersion int,
	prior ResourceMigrationState,
) (ResourceMigrationState, error)

ResourceMigrationFunc migrates one older resource schema version.

type ResourceMigrationState

type ResourceMigrationState struct {
	Inputs  EncodedValue
	Outputs EncodedValue
}

ResourceMigrationState contains the encoded resource values presented to a migration.

type ResourceObservation

type ResourceObservation struct {
	Status   ObservationStatus `json:"status"`
	Outputs  *EncodedValue     `json:"outputs,omitempty"`
	Identity *IdentityRecord   `json:"identity,omitempty"`
}

func (ResourceObservation) Validate

func (o ResourceObservation) Validate() error

type ResourcePlanOperation

type ResourcePlanOperation struct {
	Decision    Decision               `json:"decision"`
	Desired     *PlannedResourceTarget `json:"desired,omitempty"`
	Prior       *ResourceTarget        `json:"prior,omitempty"`
	Observation *ResourceObservation   `json:"observation,omitempty"`
	Reasons     []string               `json:"reasons"`
}

func (ResourcePlanOperation) Validate

func (o ResourcePlanOperation) Validate() error

type ResourceRegistration

type ResourceRegistration interface {
	// contains filtered or unexported methods
}

ResourceRegistration stores a validated definition and its typed provider operations. Library authors create registrations with MakeResource.

func MakeResource

func MakeResource[T, Out, Config any, PT resourcePtr[T, Out, Config]](
	definition ResourceDefinition[T, Out, Config],
) ResourceRegistration

MakeResource validates the definition and registers the lifecycle implemented by *T. Invalid definitions panic during registration. Each receiver starts as new(T) before the runtime decodes its inputs.

func MakeResourceWith

func MakeResourceWith[T, Out, Config any, PT resourcePtr[T, Out, Config]](
	definition ResourceDefinition[T, Out, Config],
	construct func() *T,
) ResourceRegistration

MakeResourceWith is the variant of MakeResource for callers that need each receiver to capture external state. The constructor runs once per instance the runtime needs; Decode then fills it from the inputs. Invalid definitions panic before the constructor can run.

type ResourceStatePayload

type ResourceStatePayload = state.ResourceStatePayload

type ResourceTarget

type ResourceTarget = state.ResourceTarget

type ResourceValidateFunc

type ResourceValidateFunc[In, Config any] func(context.Context, In, Config) error

ResourceValidateFunc validates concrete resource inputs and configuration.

type SensitiveValueRecord

type SensitiveValueRecord = state.SensitiveValueRecord

type StateRef

type StateRef = state.Ref

StateRef is an alias for state.Ref, the resolver reference that both the plan envelope and the state-snapshot envelope use to name a backend or encrypter. The type lives in pkg/sdk/state so a state backend can use it without importing runtime; the alias keeps the runtime spelling for the plan body and the resolver code.

type StateRefV2

type StateRefV2 struct {
	Name string       `json:"name"`
	Body EncodedValue `json:"body"`
}

func NewStateRefV2

func NewStateRefV2(name string, body map[string]any) (*StateRefV2, error)

NewStateRefV2 encodes concrete state-provider arguments for a saved plan.

func (StateRefV2) Validate

func (r StateRefV2) Validate() error

func (StateRefV2) Values

func (r StateRefV2) Values() (map[string]any, error)

Values returns a detached copy of the state-provider arguments.

type StateUnlockError added in v0.11.0

type StateUnlockError struct {
	Cause error
}

func (*StateUnlockError) Error added in v0.11.0

func (e *StateUnlockError) Error() string

type StepNode added in v0.7.0

type StepNode struct {
	Address     string   `json:"address"`
	Kind        NodeKind `json:"node-kind"`
	Composite   bool     `json:"composite,omitempty"`
	Decision    Decision `json:"decision"`
	DependsOn   []string `json:"depends-on,omitempty"`
	Category    string   `json:"category,omitempty"`
	ImportAlias string   `json:"import-alias,omitempty"`
	LibraryPath string   `json:"library-path,omitempty"`
	ExportKind  string   `json:"kind,omitempty"`
	Name        string   `json:"name,omitempty"`
	Parent      string   `json:"parent,omitempty"`
}

StepNode describes a plan step and its apply dependencies.

func PlanGraphV2

func PlanGraphV2(plan *PlanFileV2, dag *DAG) ([]StepNode, error)

PlanGraphV2 returns the dependencies used by the apply scheduler.

type StepOperation

type StepOperation struct {
	Kind                 StepOperationKind                  `json:"kind"`
	Resource             *ResourcePlanOperation             `json:"resource,omitempty"`
	Action               *ActionPlanOperation               `json:"action,omitempty"`
	DataSource           *DataSourcePlanOperation           `json:"data-source,omitempty"`
	LibraryConfiguration *LibraryConfigurationPlanOperation `json:"library-configuration,omitempty"`
	Composite            *CompositePlanOperation            `json:"composite,omitempty"`
	Output               *OutputPlanOperation               `json:"output,omitempty"`
}

func (StepOperation) Validate

func (o StepOperation) Validate(kind NodeKind) error

type StepOperationKind

type StepOperationKind string
const (
	StepResource             StepOperationKind = "resource"
	StepAction               StepOperationKind = "action"
	StepDataSource           StepOperationKind = "data-source"
	StepLibraryConfiguration StepOperationKind = "library-configuration"
	StepComposite            StepOperationKind = "composite"
	StepOutput               StepOperationKind = "output"
)

type TypeSchema

type TypeSchema struct {
	Inputs           map[string]typecheck.Type
	Outputs          map[string]typecheck.Type
	SensitiveInputs  []string
	SensitiveOutputs []string

	// Constraints holds the type's cross-field constraints, derived from
	// its Constraints method at compile time, in the embeddable string
	// form. A check parses them with lang.ParseSpecs and runs them through
	// lang.CheckConstraintEntries, the same path UB constraints take.
	Constraints []lang.ConstraintSpec

	// Defaults holds the type's declared input defaults, derived from
	// its Defaults method at compile time. A field with a Value default
	// is filled in when a body leaves it out; an Optional marker only
	// declares that absence is fine. Any other input is required.
	Defaults []lang.DefaultSpec
}

TypeSchema describes the input and output fields of one resource, data source, or action. Each map keys a kebab-case field name (the form factory source uses) to that field's semantic Type. Inputs lists the receiver type's exported fields; Outputs lists the output struct's. The walker that builds this schema (goschema) recursively expands named struct types so nested object fields can be type-checked too.

SensitiveInputs and SensitiveOutputs hold the kebab-case names of fields a library marked sensitive via a `ub:",sensitive"` struct tag. Both are top-level only; sensitivity does not descend into nested object fields.

type TypedAction

type TypedAction[Out, Config any] interface {
	Run(ctx context.Context, config Config) (Out, error)
}

TypedAction is the typed contract for actions. Out names the action's output struct.

type TypedDataSource

type TypedDataSource[Out, Config any] interface {
	Read(ctx context.Context, config Config) (Out, error)
}

TypedDataSource is the typed contract for read-only data sources.

type TypedResource

type TypedResource[In, Out, Config any] interface {
	Create(ctx context.Context, config Config) (Out, error)
	Read(ctx context.Context, config Config, prior Out) (Out, error)
	Update(ctx context.Context, config Config, prior Prior[In, Out]) (Out, error)
	Delete(ctx context.Context, config Config, prior Out) error
}

TypedResource is the typed contract a library author implements for one primitive resource type. In names the input struct, which is the method receiver; Out must be a pointer to an output struct (e.g. *VpcOutput) so a call without prior state passes nil. Config names the decoded library config type. Update receives a Prior bundling the last apply's inputs and outputs.

Source Files

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL