mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-04 10:52:27 +02:00
Remove native classes from TS runtime
This commit is contained in:
parent
952daf325d
commit
dca2786828
79 changed files with 7622 additions and 6703 deletions
|
|
@ -8,7 +8,6 @@ import { Effect } from "effect";
|
|||
import * as S from "effect/Schema";
|
||||
import type { Spec } from "./types.js";
|
||||
import type { SpecRuntimeRequirements } from "./types.js";
|
||||
import type { PubSubBackend } from "../backend/types.js";
|
||||
import type { Flow, FlowDefinition } from "../processor/flow.js";
|
||||
import { type MessageHandler } from "../messaging/consumer.js";
|
||||
import {
|
||||
|
|
@ -24,64 +23,71 @@ import {
|
|||
|
||||
const isTooManyRequestsError = S.is(TooManyRequestsError);
|
||||
|
||||
export class ConsumerSpec<T, E = never, R = never> implements Spec<R> {
|
||||
public readonly name: string;
|
||||
private readonly handler: EffectMessageHandler<T, E, R>;
|
||||
private readonly concurrency: number;
|
||||
declare const ConsumerSpecType: unique symbol;
|
||||
|
||||
constructor(
|
||||
name: string,
|
||||
handler: EffectMessageHandler<T, E, R>,
|
||||
concurrency = 1,
|
||||
export interface ConsumerSpec<T, E = never, R = never> extends Spec<R> {
|
||||
readonly [ConsumerSpecType]?: {
|
||||
readonly message: T;
|
||||
readonly error: E;
|
||||
};
|
||||
readonly addEffect: (
|
||||
flow: Flow<R>,
|
||||
definition: FlowDefinition,
|
||||
) => Effect.Effect<void, PubSubError, SpecRuntimeRequirements | R>;
|
||||
}
|
||||
|
||||
export function makeConsumerSpec<T, E = never, R = never>(
|
||||
name: string,
|
||||
handler: EffectMessageHandler<T, E, R>,
|
||||
concurrency = 1,
|
||||
): ConsumerSpec<T, E, R> {
|
||||
const addEffect = Effect.fn("ConsumerSpec.addEffect")(function* (
|
||||
flow: Flow<R>,
|
||||
definition: FlowDefinition,
|
||||
) {
|
||||
this.name = name;
|
||||
this.handler = handler;
|
||||
this.concurrency = concurrency;
|
||||
}
|
||||
|
||||
static fromPromise<T>(
|
||||
name: string,
|
||||
handler: MessageHandler<T>,
|
||||
concurrency = 1,
|
||||
): ConsumerSpec<T, TooManyRequestsError | MessagingHandlerError> {
|
||||
return new ConsumerSpec<T, TooManyRequestsError | MessagingHandlerError>(
|
||||
name,
|
||||
(message, properties, flow) =>
|
||||
Effect.tryPromise({
|
||||
try: () => handler(message, properties, flow),
|
||||
catch: (error) =>
|
||||
isTooManyRequestsError(error)
|
||||
? error
|
||||
: messagingHandlerError(name, `${flow.id}-${flow.name}-${name}`, error),
|
||||
}),
|
||||
concurrency,
|
||||
);
|
||||
}
|
||||
|
||||
addEffect(flow: Flow<R>, definition: FlowDefinition) {
|
||||
const spec = this;
|
||||
return Effect.gen(function* () {
|
||||
const topic = definition.topics?.[spec.name] ?? spec.name;
|
||||
const topic = definition.topics?.[name] ?? name;
|
||||
const factory = yield* ConsumerFactory;
|
||||
const consumer = yield* factory.run<T, E, R>(
|
||||
{
|
||||
topic,
|
||||
subscription: `${flow.processorId}-${flow.name}-${spec.name}`,
|
||||
handler: spec.handler,
|
||||
concurrency: spec.concurrency,
|
||||
subscription: `${flow.processorId}-${flow.name}-${name}`,
|
||||
handler,
|
||||
concurrency,
|
||||
},
|
||||
{ id: flow.processorId, name: flow.name, flow },
|
||||
);
|
||||
flow.registerConsumer(spec.name, consumer);
|
||||
});
|
||||
}
|
||||
flow.registerConsumer(name, consumer);
|
||||
});
|
||||
|
||||
async add(flow: Flow, pubsub: PubSubBackend, definition: FlowDefinition): Promise<void> {
|
||||
const effect = this.addEffect(flow, definition) as Effect.Effect<
|
||||
void,
|
||||
PubSubError,
|
||||
SpecRuntimeRequirements
|
||||
>;
|
||||
await flow.runInCompatibilityScope(effect, pubsub);
|
||||
}
|
||||
return {
|
||||
name,
|
||||
addEffect,
|
||||
add: async (flow, pubsub, definition) => {
|
||||
const effect = addEffect(flow as Flow<R>, definition) as Effect.Effect<
|
||||
void,
|
||||
PubSubError,
|
||||
SpecRuntimeRequirements
|
||||
>;
|
||||
await flow.runInCompatibilityScope(effect, pubsub);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function makeConsumerSpecFromPromise<T>(
|
||||
name: string,
|
||||
handler: MessageHandler<T>,
|
||||
concurrency = 1,
|
||||
): ConsumerSpec<T, TooManyRequestsError | MessagingHandlerError> {
|
||||
return makeConsumerSpec<T, TooManyRequestsError | MessagingHandlerError>(
|
||||
name,
|
||||
(message, properties, flow) =>
|
||||
Effect.tryPromise({
|
||||
try: () => handler(message, properties, flow),
|
||||
catch: (error) =>
|
||||
isTooManyRequestsError(error)
|
||||
? error
|
||||
: messagingHandlerError(name, `${flow.id}-${flow.name}-${name}`, error),
|
||||
}),
|
||||
concurrency,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
export type { Spec, SpecRuntimeError, SpecRuntimeRequirements } from "./types.js";
|
||||
export { ConsumerSpec } from "./consumer-spec.js";
|
||||
export { ProducerSpec } from "./producer-spec.js";
|
||||
export { ParameterSpec } from "./parameter-spec.js";
|
||||
export { RequestResponseSpec } from "./request-response-spec.js";
|
||||
export { makeConsumerSpec, makeConsumerSpecFromPromise, type ConsumerSpec } from "./consumer-spec.js";
|
||||
export { makeProducerSpec, type ProducerSpec } from "./producer-spec.js";
|
||||
export { makeParameterSpec, type ParameterSpec } from "./parameter-spec.js";
|
||||
export { makeRequestResponseSpec, type RequestResponseSpec } from "./request-response-spec.js";
|
||||
|
|
|
|||
|
|
@ -6,25 +6,22 @@
|
|||
|
||||
import { Effect } from "effect";
|
||||
import type { Spec } from "./types.js";
|
||||
import type { PubSubBackend } from "../backend/types.js";
|
||||
import type { Flow, FlowDefinition } from "../processor/flow.js";
|
||||
|
||||
export class ParameterSpec implements Spec {
|
||||
public readonly name: string;
|
||||
export interface ParameterSpec extends Spec {}
|
||||
|
||||
constructor(name: string) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
addEffect(flow: Flow, definition: FlowDefinition) {
|
||||
const spec = this;
|
||||
return Effect.sync(() => {
|
||||
const value = definition.parameters?.[spec.name];
|
||||
flow.setParameter(spec.name, value);
|
||||
export function makeParameterSpec(name: string): ParameterSpec {
|
||||
const addEffect = (flow: Flow, definition: FlowDefinition) =>
|
||||
Effect.sync(() => {
|
||||
const value = definition.parameters?.[name];
|
||||
flow.setParameter(name, value);
|
||||
});
|
||||
}
|
||||
|
||||
async add(flow: Flow, _pubsub: PubSubBackend, definition: FlowDefinition): Promise<void> {
|
||||
await Effect.runPromise(this.addEffect(flow, definition));
|
||||
}
|
||||
return {
|
||||
name,
|
||||
addEffect,
|
||||
add: async (flow, _pubsub, definition) => {
|
||||
await Effect.runPromise(addEffect(flow, definition));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,31 +6,34 @@
|
|||
|
||||
import { Effect } from "effect";
|
||||
import type { Spec } from "./types.js";
|
||||
import type { PubSubBackend } from "../backend/types.js";
|
||||
import type { Flow, FlowDefinition } from "../processor/flow.js";
|
||||
import {
|
||||
ProducerFactory,
|
||||
type EffectProducer,
|
||||
} from "../messaging/runtime.js";
|
||||
|
||||
export class ProducerSpec<T> implements Spec {
|
||||
public readonly name: string;
|
||||
declare const ProducerSpecType: unique symbol;
|
||||
|
||||
constructor(name: string) {
|
||||
this.name = name;
|
||||
}
|
||||
export interface ProducerSpec<T> extends Spec {
|
||||
readonly [ProducerSpecType]?: (_: T) => T;
|
||||
}
|
||||
|
||||
addEffect(flow: Flow, definition: FlowDefinition) {
|
||||
const spec = this;
|
||||
return Effect.gen(function* () {
|
||||
const topic = definition.topics?.[spec.name] ?? spec.name;
|
||||
export function makeProducerSpec<T>(name: string): ProducerSpec<T> {
|
||||
const addEffect = Effect.fn("ProducerSpec.addEffect")(function* (
|
||||
flow: Flow,
|
||||
definition: FlowDefinition,
|
||||
) {
|
||||
const topic = definition.topics?.[name] ?? name;
|
||||
const factory = yield* ProducerFactory;
|
||||
const producer = yield* factory.make<T>({ topic });
|
||||
flow.registerProducer(spec.name, producer as EffectProducer<unknown>);
|
||||
});
|
||||
}
|
||||
flow.registerProducer(name, producer as EffectProducer<unknown>);
|
||||
});
|
||||
|
||||
async add(flow: Flow, pubsub: PubSubBackend, definition: FlowDefinition): Promise<void> {
|
||||
await flow.runInCompatibilityScope(this.addEffect(flow, definition), pubsub);
|
||||
}
|
||||
return {
|
||||
name,
|
||||
addEffect,
|
||||
add: async (flow, pubsub, definition) => {
|
||||
await flow.runInCompatibilityScope(addEffect(flow, definition), pubsub);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,44 +9,46 @@
|
|||
|
||||
import { Effect } from "effect";
|
||||
import type { Spec } from "./types.js";
|
||||
import type { PubSubBackend } from "../backend/types.js";
|
||||
import type { Flow, FlowDefinition } from "../processor/flow.js";
|
||||
import {
|
||||
RequestResponseFactory,
|
||||
type EffectRequestResponse,
|
||||
} from "../messaging/runtime.js";
|
||||
|
||||
export class RequestResponseSpec<TReq, TRes> implements Spec {
|
||||
public readonly name: string;
|
||||
private readonly requestTopicName: string;
|
||||
private readonly responseTopicName: string;
|
||||
declare const RequestResponseSpecType: unique symbol;
|
||||
|
||||
constructor(
|
||||
name: string,
|
||||
requestTopicName: string,
|
||||
responseTopicName: string,
|
||||
export interface RequestResponseSpec<TReq, TRes> extends Spec {
|
||||
readonly [RequestResponseSpecType]?: {
|
||||
readonly request: TReq;
|
||||
readonly response: TRes;
|
||||
};
|
||||
}
|
||||
|
||||
export function makeRequestResponseSpec<TReq, TRes>(
|
||||
name: string,
|
||||
requestTopicName: string,
|
||||
responseTopicName: string,
|
||||
): RequestResponseSpec<TReq, TRes> {
|
||||
const addEffect = Effect.fn("RequestResponseSpec.addEffect")(function* (
|
||||
flow: Flow,
|
||||
definition: FlowDefinition,
|
||||
) {
|
||||
this.name = name;
|
||||
this.requestTopicName = requestTopicName;
|
||||
this.responseTopicName = responseTopicName;
|
||||
}
|
||||
|
||||
addEffect(flow: Flow, definition: FlowDefinition) {
|
||||
const spec = this;
|
||||
return Effect.gen(function* () {
|
||||
const requestTopic = definition.topics?.[spec.requestTopicName] ?? spec.requestTopicName;
|
||||
const responseTopic = definition.topics?.[spec.responseTopicName] ?? spec.responseTopicName;
|
||||
const requestTopic = definition.topics?.[requestTopicName] ?? requestTopicName;
|
||||
const responseTopic = definition.topics?.[responseTopicName] ?? responseTopicName;
|
||||
const factory = yield* RequestResponseFactory;
|
||||
const requestor = yield* factory.make<TReq, TRes>({
|
||||
requestTopic,
|
||||
responseTopic,
|
||||
subscription: `${flow.processorId}-${flow.name}-${spec.name}`,
|
||||
subscription: `${flow.processorId}-${flow.name}-${name}`,
|
||||
});
|
||||
flow.registerRequestor(spec.name, requestor as EffectRequestResponse<unknown, unknown>);
|
||||
});
|
||||
}
|
||||
flow.registerRequestor(name, requestor as EffectRequestResponse<unknown, unknown>);
|
||||
});
|
||||
|
||||
async add(flow: Flow, pubsub: PubSubBackend, definition: FlowDefinition): Promise<void> {
|
||||
await flow.runInCompatibilityScope(this.addEffect(flow, definition), pubsub);
|
||||
}
|
||||
return {
|
||||
name,
|
||||
addEffect,
|
||||
add: async (flow, pubsub, definition) => {
|
||||
await flow.runInCompatibilityScope(addEffect(flow, definition), pubsub);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue