annotation
API reference for @effx/compiler/annotation
annotation.ts overview
Exports Grouped by Category
- utils
- ArgsCodec (type alias)
- DefinitionLift (interface)
- ImplementOptions (interface)
- Implementation (interface)
- LiftDefinitionEntry (interface)
- LiftImplementation (interface)
- LiftRecognition (type alias)
- LiftRecognitionError (type alias)
- LiftRecognitionErrorSchema
- LiftRegistry (interface)
- LiftSite (interface)
- ReadArgs (type alias)
- ReadContext (interface)
- Resolved (type alias)
- argsSchemaOf
- dataOf
- decodeSchemaOf
- decoderOf
- definitionDiagnostics
- definitionProblemDiagnostics
- definitionsOf
- extension
- implement
- liftRegistryOf
- schemaOfPlan
utils
ArgsCodec (type alias)
The decode Schema of a definition: lowered args in, what read receives out.
Signature
type ArgsCodec<D extends DefinitionData = DefinitionData> = Schema.Codec<ReadArgs<D>, Annotation["args"]>DefinitionLift (interface)
A definition-owned compiler lift (spec 0019 §5, S1): inert rule DATA validated as LiftRules, and the
optional recognizer the core invokes only at this definition's registered effect key. Both are
compiler-side; neither enters runtime Definition data, the IR, or LiftInput.
Signature
export interface DefinitionLift<D extends DefinitionData = DefinitionData> {
readonly rules?: ReadonlyArray<LiftRule>
readonly recognize?: (site: LiftSite<D>) => Result.Result<ReadArgs<D>, LiftRecognitionError>
}ImplementOptions (interface)
Signature
export interface ImplementOptions<Read, D extends DefinitionData = DefinitionData> {
/** Explanations owned by this implementation, collected by extension(). */
readonly diagnosticEntries?: ReadonlyArray<DiagnosticEntry>
/** IR analyses that belong to this annotation (diagnostics only). */
readonly analyze?: Analysis | ReadonlyArray<Analysis>
/** A free generator over the IR: new generated files, never a rewrite of source (spec 0020 §6). */
readonly write?: Generator
/** Source→IR. Omitted: the default declarative `Extension` node (spec 0020 §2.3), added by the framework. */
readonly read?: (args: Read, at: ReadContext) => Contribution
/** A framework guard run before the duplicate check (e.g. `Http.Group`'s declaration-kind check). */
readonly before?: (annotation: { readonly name: string }, declaration: Declaration) => Diagnostic | undefined
/** Duplicate-annotation diagnostic for `cardinality: "one"`; defaults to `EFFX2402`. */
readonly duplicate?: (subject: string, annotation: string) => Diagnostic
/** Diagnostic for an operation-target annotation on a declaration that is not an operation. */
readonly notOperation?: (annotation: { readonly name: string }, declaration: Declaration) => Diagnostic
/**
* What malformed arguments contribute. Default `"report"`: the `EFFX1102` diagnostic. `"ignore"`: nothing,
* for an assertion annotation whose arguments another interpreter already decodes and reports
* (`@Errors`/`@Requirements` are decoded and reported by the operation they sit on).
*/
readonly malformed?: "report" | "ignore"
/**
* The definition-owned compiler lift seam (spec 0019 §5, S1). Omitted: the framework's default
* recognizer lowers the site's term by `definition.plan` and decodes with the definition's own codec.
*/
readonly lift?: DefinitionLift<D>
}Implementation (interface)
Signature
export interface Implementation<D extends DefinitionData = DefinitionData> {
readonly definition: D
readonly diagnosticEntries?: ReadonlyArray<DiagnosticEntry>
readonly interpreter: Interpreter
readonly analyses: ReadonlyArray<Analysis>
readonly generators: ReadonlyArray<Generator>
/**
* The erased definition-owned lift hook (spec 0019 §5, S1). Erased because `Implementation<D>` must
* stay assignable to `Implementation` for `extension()`; the site carries the definition itself and the
* result is validated by the definition's own decode, so the type-level erasure never changes what a
* recognizer receives or returns.
*/
readonly lift?: LiftImplementation
}LiftDefinitionEntry (interface)
One entry the lift registry carries per definition (spec 0019 §5, S1): the definition value itself, its aggregate rule data and its recognizer.
Signature
export interface LiftDefinitionEntry {
readonly definition: DefinitionData
readonly rules: ReadonlyArray<LiftRule>
readonly recognize: LiftRecognition | undefined
}LiftImplementation (interface)
The erased per-definition lift hook an implement() built from its DefinitionLift<D>.
Signature
export interface LiftImplementation {
readonly rules: ReadonlyArray<LiftRule>
readonly recognize: LiftRecognition | undefined
}LiftRecognition (type alias)
The recognizer at the erased registry boundary. The returned arguments stay unknown here and are re-typed through the selected definition's cached codec, which is derived from definition.plan once per registry; the site carries the definition rather than a duplicate plan.
Signature
type LiftRecognition = (site: LiftSite<DefinitionData>) => Result.Result<unknown, LiftRecognitionError>LiftRecognitionError (type alias)
Signature
type LiftRecognitionError = typeof LiftRecognitionErrorSchema.TypeLiftRecognitionErrorSchema
The closed failure a recognizer returns instead of arguments (spec 0019 §5, S1): one tag plus the construct that names the site's neutral form. Schema-derived data only: never a thrown value, never application payload.
Signature
declare const LiftRecognitionErrorSchema: Schema.TaggedStruct<"Unsupported", { readonly construct: Schema.String }>LiftRegistry (interface)
The registry lift(model, input, registry) consumes: per-definition entries and the shared rules.
Signature
export interface LiftRegistry {
/** Entries by annotation name, in implementation order; the first implementation of a name wins. */
readonly definitions: ReadonlyMap<string, LiftDefinitionEntry>
/** Definition-owned rule data, in implementation order, behind the input's own rules. */
readonly rules: ReadonlyArray<LiftRule>
/** The derived lowered-args codec of each definition, derived ONCE per registry (never per endpoint). */
readonly codecs: ReadonlyMap<string, ArgsCodec>
}LiftSite (interface)
The neutral data the core hands a recognizer (spec 0019 §5, S1). Pure and synchronous; built per invocation from data the analyzed model already recorded. The definition owns the lowering plan; the codec is derived once per registry from that plan, and the site carries the definition rather than a copy.
Signature
export interface LiftSite<D extends DefinitionData = DefinitionData> {
readonly definition: D
readonly schema: ArgsCodec<D>
/** The term the frontend lowered for the annotation's argument list. */
readonly value: Term
/** `<group>.<endpoint key>`, as users write the site. */
readonly subject: string
/** Source range of the `.annotate` step. */
readonly range: SourceRange
readonly names: Readonly<Record<string, SymbolRef>>
readonly emptyInput: SchemaRef | undefined
readonly project: ProjectResolution
}ReadArgs (type alias)
The decoded argument tuple of a definition.
Signature
type ReadArgs<D> = D extends { readonly Args?: infer Input }
? Resolved<ReadParameters<Exclude<Input, undefined>>>
: neverReadContext (interface)
What read receives besides the decoded arguments.
Signature
export interface ReadContext {
/** The lowered annotation `args` were decoded from; its `definition` is the definition's own export. */
readonly annotation: Annotation
readonly declaration: Declaration
readonly ctx: InterpretContext
}Resolved (type alias)
Resolves the runtime's Read markers to the real decoded types, so read receives exactly what the
derived Schema decodes (no second type declaration).
Signature
type Resolved<T> = T extends JsonValue
? T // marker-free JSON (also: the recursive `JsonValue` itself must not be mapped over)
: T extends SchemaMarker
? typeof SchemaArg.Type
: T extends RootSymbolMarker
? typeof RootSymbol.Type
: T extends SymbolMarker
? typeof SymbolArg.Type
: T extends CapabilityMarker
? typeof capabilityValue.Type
: T extends ReadonlyArray<unknown>
? { readonly [I in keyof T]: Resolved<T[I]> }
: T extends object
? { readonly [K in keyof T]: Resolved<T[K]> }
: TargsSchemaOf
Schema.Tuple(items) for fixed arguments, Schema.TupleWithRest / Schema.Array for variadic ones.
Signature
declare const argsSchemaOf: (plan: ArgsPlan) => Schema.TopdataOf
The typed reader of the declarative node the default read writes (spec 0020 §2.3): the decoded
arguments definition recorded on operationId, decoded again against decodeSchemaOf(definition).
None when the operation has no such node or its data no longer decodes (see declarativeOf).
Pure: analyses and generators call it on the normalized IR.
Signature
declare const dataOf: <D extends DefinitionData>(
definition: D,
ir: ApplicationIR,
operationId: StableId.StableId
) => Option.Option<ReadArgs<D>>decodeSchemaOf
The derived decode Schema, typed as decoding the lowered args of an annotation into what read
receives. Also what callers outside an interpreter decode with (the Http.Group / operation-argument
pre-pass).
Signature
declare const decodeSchemaOf: <D extends DefinitionData>(definition: D) => ArgsCodec<D>decoderOf
Decodes an annotation's lowered arguments against decodeSchemaOf(definition). Also how an
interpreter reads a SIBLING annotation (@Query reads @Errors) with the same typed result as read.
Signature
declare const decoderOf: <D extends DefinitionData>(
definition: D
) => (annotation: Annotation, declaration: Declaration) => Result.Result<ReadArgs<D>, Diagnostic>definitionDiagnostics
Definition-level errors: EFFX1302 (a name outside the grammar, or declared by two definitions),
EFFX1301 (an A.fromSchema node the frontend cannot lower, collected by define) and EFFX1304
(two definitions share one effect.key id: the key is the runtime identity of the annotation, so the
second would overwrite the first on the same endpoint). The other half of EFFX1304, a key id that is
not a literal in source, belongs to the lift (spec 0019): nothing here reads source.
Signature
declare const definitionDiagnostics: (extensions: ReadonlyArray<Extension>) => ReadonlyArray<Diagnostic>definitionProblemDiagnostics
The diagnostics a runtime definition collected at build time (EFFX1301), with canonical severity
restored. The one place this projection exists: the forward pipeline and the lift both call it.
Signature
declare const definitionProblemDiagnostics: (definition: DefinitionData) => ReadonlyArray<Diagnostic>definitionsOf
Plan and target of every definition the extensions declare, by annotation name (frontend input).
Signature
declare const definitionsOf: (extensions: ReadonlyArray<Extension>) => ReadonlyMap<string, DefinitionEntry>extension
An Extension whose interpreters are derived from its implementations. A definition with an effect
clause also gets its default endpoint fragment and the analysis that reports an argument the fragment
cannot print (spec 0020 §6), both in implementation order.
Signature
declare const extension: (
name: string,
implementations: ReadonlyArray<Implementation>,
rest?: Partial<Pick<Extension, "analyses" | "generators" | "expand" | "diagnosticEntries">>
) => Extensionimplement
Binds the compiler half to a definition value. The framework owns the repeated guards (target,
cardinality) and the decode; read sees only typed, decoded arguments.
Signature
declare const implement: <D extends DefinitionData>(
definition: D,
options?: ImplementOptions<ReadArgs<D>, D>
) => Implementation<D>liftRegistryOf
The lift registry of the SELECTED extensions (spec 0019 §5, S1): one entry per definition that declares
a compiler lift, keyed by annotation name, and the definition-owned rule data in implementation order.
There is no second registry convention: duplicate definition names and duplicate effect keys stay
reported by definitionDiagnostics(extensions), which the pipeline already runs, and a name only
appears once here (first implementation in extension order).
Signature
declare const liftRegistryOf: (extensions: ReadonlyArray<Extension>) => LiftRegistryschemaOfPlan
Signature
declare const schemaOfPlan: (plan: Plan) => Schema.Top