Skip to content

Commit 1bcfc88

Browse files
cursor[bot]cursoragentjuliusmarminge
authored
Adopt idiomatic Effect APIs in generator and decider (#2581)
Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Julius Marminge <juliusmarminge@users.noreply.github.com> Co-authored-by: Julius Marminge <julius0216@outlook.com>
1 parent 2ba5807 commit 1bcfc88

2 files changed

Lines changed: 45 additions & 59 deletions

File tree

apps/server/src/orchestration/decider.ts

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type {
33
OrchestrationEvent,
44
OrchestrationReadModel,
55
} from "@t3tools/contracts";
6-
import { Effect } from "effect";
6+
import { DateTime, Effect } from "effect";
77

88
import { OrchestrationCommandInvariantError } from "./Errors.ts";
99
import {
@@ -17,17 +17,7 @@ import {
1717
} from "./commandInvariants.ts";
1818
import { projectEvent } from "./projector.ts";
1919

20-
const nowIso = () => new Date().toISOString();
21-
const defaultMetadata: Omit<OrchestrationEvent, "sequence" | "type" | "payload"> = {
22-
eventId: crypto.randomUUID() as OrchestrationEvent["eventId"],
23-
aggregateKind: "thread",
24-
aggregateId: "" as OrchestrationEvent["aggregateId"],
25-
occurredAt: nowIso(),
26-
commandId: null,
27-
causationEventId: null,
28-
correlationId: null,
29-
metadata: {},
30-
};
20+
const currentIso = DateTime.now.pipe(Effect.map(DateTime.formatIso));
3121

3222
function withEventBase(
3323
input: Pick<OrchestrationCommand, "commandId"> & {
@@ -38,12 +28,12 @@ function withEventBase(
3828
},
3929
): Omit<OrchestrationEvent, "sequence" | "type" | "payload"> {
4030
return {
41-
...defaultMetadata,
4231
eventId: crypto.randomUUID() as OrchestrationEvent["eventId"],
4332
aggregateKind: input.aggregateKind,
4433
aggregateId: input.aggregateId,
4534
occurredAt: input.occurredAt,
4635
commandId: input.commandId,
36+
causationEventId: null,
4737
correlationId: input.commandId,
4838
metadata: input.metadata ?? {},
4939
};
@@ -126,7 +116,7 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand"
126116
command,
127117
projectId: command.projectId,
128118
});
129-
const occurredAt = nowIso();
119+
const occurredAt = yield* currentIso;
130120
return {
131121
...withEventBase({
132122
aggregateKind: "project",
@@ -183,7 +173,7 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand"
183173
});
184174
}
185175

186-
const occurredAt = nowIso();
176+
const occurredAt = yield* currentIso;
187177
return {
188178
...withEventBase({
189179
aggregateKind: "project",
@@ -239,7 +229,7 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand"
239229
command,
240230
threadId: command.threadId,
241231
});
242-
const occurredAt = nowIso();
232+
const occurredAt = yield* currentIso;
243233
return {
244234
...withEventBase({
245235
aggregateKind: "thread",
@@ -261,7 +251,7 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand"
261251
command,
262252
threadId: command.threadId,
263253
});
264-
const occurredAt = nowIso();
254+
const occurredAt = yield* currentIso;
265255
return {
266256
...withEventBase({
267257
aggregateKind: "thread",
@@ -284,7 +274,7 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand"
284274
command,
285275
threadId: command.threadId,
286276
});
287-
const occurredAt = nowIso();
277+
const occurredAt = yield* currentIso;
288278
return {
289279
...withEventBase({
290280
aggregateKind: "thread",
@@ -306,7 +296,7 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand"
306296
command,
307297
threadId: command.threadId,
308298
});
309-
const occurredAt = nowIso();
299+
const occurredAt = yield* currentIso;
310300
return {
311301
...withEventBase({
312302
aggregateKind: "thread",
@@ -334,7 +324,7 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand"
334324
command,
335325
threadId: command.threadId,
336326
});
337-
const occurredAt = nowIso();
327+
const occurredAt = yield* currentIso;
338328
return {
339329
...withEventBase({
340330
aggregateKind: "thread",
@@ -357,7 +347,7 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand"
357347
command,
358348
threadId: command.threadId,
359349
});
360-
const occurredAt = nowIso();
350+
const occurredAt = yield* currentIso;
361351
return {
362352
...withEventBase({
363353
aggregateKind: "thread",

packages/effect-codex-app-server/scripts/generate.ts

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
44
import * as NodeServices from "@effect/platform-node/NodeServices";
55
import { make as makeJsonSchemaGenerator } from "@effect/openapi-generator/JsonSchemaGenerator";
66
import { Effect, FileSystem, Layer, Logger, Path, Schema } from "effect";
7+
import {
8+
FetchHttpClient,
9+
HttpClient,
10+
HttpClientRequest,
11+
HttpClientResponse,
12+
} from "effect/unstable/http";
713
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
814

915
const UPSTREAM_REF = "be75785504ff152fa6333e380a2d50642f42fba0";
@@ -21,6 +27,13 @@ const GithubContentEntries = Schema.Array(
2127
);
2228
type GithubContentEntry = (typeof GithubContentEntries.Type)[number];
2329

30+
const JsonSchemaDocument = Schema.StructWithRest(
31+
Schema.Struct({
32+
definitions: Schema.optionalKey(Schema.Record(Schema.String, Schema.Json)),
33+
}),
34+
[Schema.Record(Schema.String, Schema.Json)],
35+
);
36+
2437
interface GeneratedPaths {
2538
readonly generatedDir: string;
2639
readonly schemaOutputPath: string;
@@ -143,40 +156,19 @@ const ensureGeneratedDir = Effect.fn("ensureGeneratedDir")(function* () {
143156
});
144157

145158
const fetchText = Effect.fn("fetchText")(function* (url: string) {
146-
const response = yield* Effect.tryPromise({
147-
try: () =>
148-
fetch(url, {
149-
headers: {
150-
"user-agent": USER_AGENT,
151-
},
152-
}),
153-
catch: (cause) =>
154-
new GeneratorError({
155-
detail: `Failed to fetch ${url}`,
156-
cause,
157-
}),
158-
});
159-
160-
if (!response.ok) {
161-
const detail = yield* Effect.tryPromise({
162-
try: () => response.text(),
163-
catch: () => "",
164-
});
165-
return yield* Effect.fail(
166-
new GeneratorError({
167-
detail: `Failed to download ${url}: ${response.status} ${detail}`,
168-
}),
169-
);
170-
}
171-
172-
return yield* Effect.tryPromise({
173-
try: () => response.text(),
174-
catch: (cause) =>
175-
new GeneratorError({
176-
detail: `Failed to read response body for ${url}`,
177-
cause,
178-
}),
179-
});
159+
return yield* HttpClientRequest.get(url).pipe(
160+
HttpClientRequest.setHeader("user-agent", USER_AGENT),
161+
HttpClient.execute,
162+
Effect.flatMap(HttpClientResponse.filterStatusOk),
163+
Effect.flatMap((okResponse) => okResponse.text),
164+
Effect.mapError(
165+
(cause) =>
166+
new GeneratorError({
167+
detail: `Failed to fetch ${url}`,
168+
cause,
169+
}),
170+
),
171+
);
180172
});
181173

182174
const fetchDirectoryEntries = Effect.fn("fetchDirectoryEntries")(function* (path: string) {
@@ -548,9 +540,7 @@ const generateFiles = Effect.fn("generateFiles")(function* () {
548540

549541
for (const file of jsonSchemaFiles) {
550542
const raw = yield* fetchText(file.downloadUrl);
551-
const parsed = JSON.parse(raw) as {
552-
readonly definitions?: Record<string, typeof Schema.Json.Type>;
553-
} & Record<string, typeof Schema.Json.Type>;
543+
const parsed = yield* Schema.decodeEffect(Schema.fromJsonString(JsonSchemaDocument))(raw);
554544
const localDefinitionNames = new Map(
555545
Object.keys(parsed.definitions ?? {}).map((definitionName) => [
556546
definitionName,
@@ -767,6 +757,12 @@ const generateFiles = Effect.fn("generateFiles")(function* () {
767757

768758
generateFiles().pipe(
769759
Effect.scoped,
770-
Effect.provide(Layer.mergeAll(Logger.layer([Logger.consolePretty()]), NodeServices.layer)),
760+
Effect.provide(
761+
Layer.mergeAll(
762+
Logger.layer([Logger.consolePretty()]),
763+
NodeServices.layer,
764+
FetchHttpClient.layer,
765+
),
766+
),
771767
NodeRuntime.runMain,
772768
);

0 commit comments

Comments
 (0)