mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-01 17:39:39 +02:00
Add schema-backed parameter spec accessors
This commit is contained in:
parent
b51dc33786
commit
abb6f3aed0
6 changed files with 187 additions and 38 deletions
|
|
@ -5,10 +5,14 @@
|
|||
*/
|
||||
|
||||
import { Context, Effect, Exit, Layer, ManagedRuntime, Scope } from "effect";
|
||||
import * as O from "effect/Option";
|
||||
import * as S from "effect/Schema";
|
||||
import type { PubSubBackend } from "../backend/types.js";
|
||||
import { makePubSubService } from "../backend/pubsub.js";
|
||||
import {
|
||||
flowParameterDecodeError,
|
||||
flowResourceNotFoundError,
|
||||
type FlowParameterDecodeError,
|
||||
type FlowResourceNotFoundError,
|
||||
type PubSubError,
|
||||
} from "../errors.js";
|
||||
|
|
@ -25,6 +29,7 @@ import {
|
|||
makeRequestResponseFactoryService,
|
||||
} from "../messaging/runtime.js";
|
||||
import { loadMessagingRuntimeConfig } from "../runtime/messaging-config.js";
|
||||
import type { ParameterSpec } from "../spec/parameter-spec.js";
|
||||
import type { Spec, SpecRuntimeRequirements } from "../spec/types.js";
|
||||
|
||||
export interface FlowDefinition {
|
||||
|
|
@ -57,6 +62,8 @@ export interface FlowRequestor<TReq, TRes> {
|
|||
readonly stop: () => Promise<void>;
|
||||
}
|
||||
|
||||
type FlowParameterError = FlowResourceNotFoundError | FlowParameterDecodeError;
|
||||
|
||||
export function makeFlow<Requirements = never>(
|
||||
name: string,
|
||||
processorId: string,
|
||||
|
|
@ -97,6 +104,60 @@ export function makeFlow<Requirements = never>(
|
|||
};
|
||||
};
|
||||
|
||||
const getParameterEffect = (parameterName: string): Effect.Effect<unknown, FlowResourceNotFoundError> => {
|
||||
const value = parameters.get(parameterName);
|
||||
return value === undefined
|
||||
? Effect.fail(flowResourceNotFoundError(name, "parameter", parameterName))
|
||||
: Effect.succeed(value);
|
||||
};
|
||||
|
||||
const getParameter = (parameterName: string): unknown => {
|
||||
const value = parameters.get(parameterName);
|
||||
if (value === undefined) throw flowResourceNotFoundError(name, "parameter", parameterName);
|
||||
return value;
|
||||
};
|
||||
|
||||
const decodeParameterEffect = <T>(
|
||||
spec: ParameterSpec<T>,
|
||||
value: unknown,
|
||||
): Effect.Effect<T, FlowParameterDecodeError> =>
|
||||
S.decodeUnknownEffect(spec.schema)(value).pipe(
|
||||
Effect.mapError((error) => flowParameterDecodeError(name, spec.name, error)),
|
||||
);
|
||||
|
||||
const decodeParameter = <T>(spec: ParameterSpec<T>, value: unknown): T => {
|
||||
const decoded = S.decodeUnknownOption(spec.schema)(value);
|
||||
if (O.isSome(decoded)) return decoded.value;
|
||||
throw flowParameterDecodeError(name, spec.name, "Parameter value does not match schema");
|
||||
};
|
||||
|
||||
function parameterEffect<T>(
|
||||
parameterSpec: ParameterSpec<T>,
|
||||
): Effect.Effect<T, FlowParameterError>;
|
||||
function parameterEffect(
|
||||
parameterName: string,
|
||||
): Effect.Effect<unknown, FlowResourceNotFoundError>;
|
||||
function parameterEffect<T>(
|
||||
parameter: string | ParameterSpec<T>,
|
||||
): Effect.Effect<unknown, FlowParameterError> {
|
||||
if (typeof parameter === "string") {
|
||||
return getParameterEffect(parameter);
|
||||
}
|
||||
return getParameterEffect(parameter.name).pipe(
|
||||
Effect.flatMap((value) => decodeParameterEffect(parameter, value)),
|
||||
);
|
||||
}
|
||||
|
||||
function parameter<T>(parameterSpec: ParameterSpec<T>): T;
|
||||
function parameter(parameterName: string): unknown;
|
||||
function parameter<T>(parameter: string | ParameterSpec<T>): unknown {
|
||||
const value = getParameter(typeof parameter === "string" ? parameter : parameter.name);
|
||||
if (typeof parameter === "string") {
|
||||
return value;
|
||||
}
|
||||
return decodeParameter(parameter, value);
|
||||
}
|
||||
|
||||
const flow = {
|
||||
name,
|
||||
processorId,
|
||||
|
|
@ -198,12 +259,7 @@ export function makeFlow<Requirements = never>(
|
|||
? Effect.fail(flowResourceNotFoundError(name, "requestor", requestorName))
|
||||
: Effect.succeed(rr as EffectRequestResponse<TReq, TRes>);
|
||||
},
|
||||
parameterEffect<T>(parameterName: string): Effect.Effect<T, FlowResourceNotFoundError> {
|
||||
const v = parameters.get(parameterName);
|
||||
return v === undefined
|
||||
? Effect.fail(flowResourceNotFoundError(name, "parameter", parameterName))
|
||||
: Effect.succeed(v as T);
|
||||
},
|
||||
parameterEffect,
|
||||
producer<T>(producerName: string): FlowProducer<T> {
|
||||
const p = producers.get(producerName);
|
||||
if (p === undefined) throw flowResourceNotFoundError(name, "producer", producerName);
|
||||
|
|
@ -234,11 +290,7 @@ export function makeFlow<Requirements = never>(
|
|||
stop: () => compatibilityRuntime.runPromise(rr.stop),
|
||||
};
|
||||
},
|
||||
parameter<T>(parameterName: string): T {
|
||||
const v = parameters.get(parameterName);
|
||||
if (v === undefined) throw flowResourceNotFoundError(name, "parameter", parameterName);
|
||||
return v as T;
|
||||
},
|
||||
parameter,
|
||||
};
|
||||
|
||||
return flow;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue