Use Effect fn for base processor helpers

This commit is contained in:
elpresidank 2026-06-04 07:34:14 -05:00
parent 4032d15d96
commit 1a29bdef9d
8 changed files with 316 additions and 193 deletions

View file

@ -7,16 +7,28 @@
import { Effect, type Context } from "effect";
import * as S from "effect/Schema";
import type { PubSubBackend } from "../backend/types.js";
import type { Spec } from "./types.js";
import type { SpecRuntimeRequirements } from "./types.js";
import type { Flow, FlowDefinition } from "../processor/flow.js";
import type { PubSubError } from "../errors.js";
declare const ParameterSpecType: unique symbol;
const UnknownParameterSchema: S.Codec<unknown, unknown> = S.Unknown;
export interface ParameterSpec<T = unknown> extends Spec {
export interface ParameterSpec<T = unknown> {
readonly [ParameterSpecType]?: (_: T) => T;
readonly name: string;
readonly schema: S.Codec<T, unknown>;
readonly addEffect: <Requirements = never>(
flow: Flow<Requirements>,
definition: FlowDefinition,
) => Effect.Effect<void, PubSubError, SpecRuntimeRequirements | Requirements>;
readonly add: <Requirements = never>(
flow: Flow<Requirements>,
pubsub: PubSubBackend,
definition: FlowDefinition,
context: Context.Context<Requirements>,
) => Promise<void>;
}
export function makeParameterSpec(name: string): ParameterSpec<unknown>;
@ -29,7 +41,7 @@ export function makeParameterSpec<T>(
schema?: S.Codec<T, unknown>,
) {
const parameterSchema = schema ?? UnknownParameterSchema;
const addEffect = (flow: Flow, definition: FlowDefinition) =>
const addEffect = <Requirements = never>(flow: Flow<Requirements>, definition: FlowDefinition) =>
Effect.sync(() => {
const value = definition.parameters?.[name];
flow.setParameter(name, value);
@ -39,11 +51,11 @@ export function makeParameterSpec<T>(
name,
schema: parameterSchema,
addEffect,
add: (
flow: Flow,
add: <Requirements = never>(
flow: Flow<Requirements>,
pubsub: PubSubBackend,
definition: FlowDefinition,
context: Context.Context<never>,
context: Context.Context<Requirements>,
) =>
flow.runInCompatibilityScope(addEffect(flow, definition), pubsub, context),
};

View file

@ -4,12 +4,14 @@
* Python reference: trustgraph-base/trustgraph/base/producer_spec.py
*/
import { Effect } from "effect";
import type { Spec } from "./types.js";
import { Effect, type Context } from "effect";
import type { SpecRuntimeRequirements } from "./types.js";
import type { Flow, FlowDefinition } from "../processor/flow.js";
import type { PubSubBackend } from "../backend/types.js";
import {
flowResourceNotFoundError,
type FlowResourceNotFoundError,
type PubSubError,
} from "../errors.js";
import {
type EffectProducer,
@ -18,8 +20,19 @@ import {
declare const ProducerSpecType: unique symbol;
export interface ProducerSpec<T> extends Spec {
export interface ProducerSpec<T> {
readonly [ProducerSpecType]?: (_: T) => T;
readonly name: string;
readonly addEffect: <Requirements = never>(
flow: Flow<Requirements>,
definition: FlowDefinition,
) => Effect.Effect<void, PubSubError, SpecRuntimeRequirements | Requirements>;
readonly add: <Requirements = never>(
flow: Flow<Requirements>,
pubsub: PubSubBackend,
definition: FlowDefinition,
context: Context.Context<Requirements>,
) => Promise<void>;
readonly producerEffect: <Requirements = never>(
flow: Flow<Requirements>,
) => Effect.Effect<EffectProducer<T>, FlowResourceNotFoundError>;
@ -55,8 +68,8 @@ export function makeProducerSpec<T>(name: string): ProducerSpec<T> {
: Effect.succeed(producer);
};
const addEffect = Effect.fn("ProducerSpec.addEffect")(function* (
flow: Flow,
const addEffect = Effect.fn("ProducerSpec.addEffect")(function* <Requirements = never>(
flow: Flow<Requirements>,
definition: FlowDefinition,
) {
const topic = definition.topics?.[name] ?? name;

View file

@ -7,12 +7,14 @@
* Python reference: trustgraph-base/trustgraph/base/prompt_client_spec.py
*/
import { Effect } from "effect";
import type { Spec } from "./types.js";
import { Effect, type Context } from "effect";
import type { SpecRuntimeRequirements } from "./types.js";
import type { Flow, FlowDefinition } from "../processor/flow.js";
import type { PubSubBackend } from "../backend/types.js";
import {
flowResourceNotFoundError,
type FlowResourceNotFoundError,
type PubSubError,
} from "../errors.js";
import {
type EffectRequestResponse,
@ -21,11 +23,22 @@ import {
declare const RequestResponseSpecType: unique symbol;
export interface RequestResponseSpec<TReq, TRes> extends Spec {
export interface RequestResponseSpec<TReq, TRes> {
readonly [RequestResponseSpecType]?: {
readonly request: TReq;
readonly response: TRes;
};
readonly name: string;
readonly addEffect: <Requirements = never>(
flow: Flow<Requirements>,
definition: FlowDefinition,
) => Effect.Effect<void, PubSubError, SpecRuntimeRequirements | Requirements>;
readonly add: <Requirements = never>(
flow: Flow<Requirements>,
pubsub: PubSubBackend,
definition: FlowDefinition,
context: Context.Context<Requirements>,
) => Promise<void>;
readonly requestorEffect: <Requirements = never>(
flow: Flow<Requirements>,
) => Effect.Effect<EffectRequestResponse<TReq, TRes>, FlowResourceNotFoundError>;
@ -65,8 +78,8 @@ export function makeRequestResponseSpec<TReq, TRes>(
: Effect.succeed(requestor);
};
const addEffect = Effect.fn("RequestResponseSpec.addEffect")(function* (
flow: Flow,
const addEffect = Effect.fn("RequestResponseSpec.addEffect")(function* <Requirements = never>(
flow: Flow<Requirements>,
definition: FlowDefinition,
) {
const requestTopic = definition.topics?.[requestTopicName] ?? requestTopicName;