mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-02 22:41:01 +02:00
Use Effect fn for config service helpers
This commit is contained in:
parent
3890a598b5
commit
6ba4cf3b32
2 changed files with 193 additions and 177 deletions
|
|
@ -1942,6 +1942,27 @@ Notes:
|
||||||
- `cd ts && bun run lint`
|
- `cd ts && bun run lint`
|
||||||
- `git diff --check`
|
- `git diff --check`
|
||||||
|
|
||||||
|
### 2026-06-04: Config Service Effect.fn Helper Slice
|
||||||
|
|
||||||
|
- Status: migrated and package-verified.
|
||||||
|
- Completed:
|
||||||
|
- `ts/packages/flow/src/config/service.ts` now defines its reusable
|
||||||
|
generator helpers with `Effect.fn` or `Effect.fnUntraced` instead of
|
||||||
|
arrow functions returning `Effect.gen`.
|
||||||
|
- `consumeOnceEffect` uses `Effect.fnUntraced`; persistence, push, read,
|
||||||
|
put/delete, close, and run helpers use named `Effect.fn` wrappers.
|
||||||
|
- Existing persistence read/write catch/logging behavior is preserved through
|
||||||
|
`Effect.fn` post-processing functions.
|
||||||
|
- The focused scan for config-service helper `=> Effect.gen` patterns is
|
||||||
|
clean.
|
||||||
|
- Verification:
|
||||||
|
- `cd ts/packages/flow && bunx --bun vitest run src/__tests__/config-service.test.ts`
|
||||||
|
- `cd ts && bun run check:tsgo`
|
||||||
|
- `cd ts && bun run build`
|
||||||
|
- `cd ts && bun run test`
|
||||||
|
- `cd ts && bun run lint`
|
||||||
|
- `git diff --check`
|
||||||
|
|
||||||
## Subagent Findings To Preserve
|
## Subagent Findings To Preserve
|
||||||
|
|
||||||
- MCP/workbench:
|
- MCP/workbench:
|
||||||
|
|
@ -2067,9 +2088,9 @@ Notes:
|
||||||
- Gateway dispatcher static service registries, streaming membership, and
|
- Gateway dispatcher static service registries, streaming membership, and
|
||||||
scoped requestor cache now use Effect `HashMap`/`HashSet`; gateway
|
scoped requestor cache now use Effect `HashMap`/`HashSet`; gateway
|
||||||
term-bearing service membership sets now use Effect `HashSet` too.
|
term-bearing service membership sets now use Effect `HashSet` too.
|
||||||
- FlowManager and KnowledgeCore `() => Effect.gen(...)` factories are
|
- FlowManager, KnowledgeCore, and ConfigService `() => Effect.gen(...)`
|
||||||
normalized to `Effect.fn` / `Effect.fnUntraced`. Config and Librarian
|
factories are normalized to `Effect.fn` / `Effect.fnUntraced`. Librarian
|
||||||
helper factories still need focused follow-up slices.
|
helper factories still need a focused follow-up slice.
|
||||||
- ConfigService and KnowledgeCore operation dispatch now use `effect/Match`
|
- ConfigService and KnowledgeCore operation dispatch now use `effect/Match`
|
||||||
with `Match.exhaustive`; FlowManager and Librarian operation dispatch now
|
with `Match.exhaustive`; FlowManager and Librarian operation dispatch now
|
||||||
use `effect/Match` with runtime-preserving `Match.orElse` fallbacks.
|
use `effect/Match` with runtime-preserving `Match.orElse` fallbacks.
|
||||||
|
|
|
||||||
|
|
@ -313,11 +313,8 @@ const updateHandles = (
|
||||||
pushProducer: handles.pushProducer === undefined ? state.pushProducer : handles.pushProducer,
|
pushProducer: handles.pushProducer === undefined ? state.pushProducer : handles.pushProducer,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const persistStateEffect = (
|
const persistStateEffect = Effect.fn("ConfigService.persistState")(
|
||||||
persistPath: string | null,
|
function* (persistPath: string | null, state: ConfigServiceState) {
|
||||||
state: ConfigServiceState,
|
|
||||||
): Effect.Effect<void> =>
|
|
||||||
Effect.gen(function* () {
|
|
||||||
if (persistPath === null) return;
|
if (persistPath === null) return;
|
||||||
const payload = {
|
const payload = {
|
||||||
version: state.version,
|
version: state.version,
|
||||||
|
|
@ -332,16 +329,18 @@ const persistStateEffect = (
|
||||||
try: () => writeTextFile(persistPath, json),
|
try: () => writeTextFile(persistPath, json),
|
||||||
catch: (cause) => configServiceError("persist-write", cause),
|
catch: (cause) => configServiceError("persist-write", cause),
|
||||||
});
|
});
|
||||||
}).pipe(
|
},
|
||||||
|
(effect) =>
|
||||||
|
effect.pipe(
|
||||||
Effect.catch((err) =>
|
Effect.catch((err) =>
|
||||||
Effect.logError("[ConfigService] Failed to persist config", {error: err.message}),
|
Effect.logError("[ConfigService] Failed to persist config", {error: err.message}),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const pushConfigWithStateEffect = (
|
const pushConfigWithStateEffect = Effect.fn("ConfigService.pushConfigWithState")(function* (
|
||||||
state: ConfigServiceState,
|
state: ConfigServiceState,
|
||||||
): Effect.Effect<void, ConfigServiceError> =>
|
) {
|
||||||
Effect.gen(function* () {
|
|
||||||
const pushProducer = state.pushProducer;
|
const pushProducer = state.pushProducer;
|
||||||
if (pushProducer === null) return;
|
if (pushProducer === null) return;
|
||||||
|
|
||||||
|
|
@ -357,10 +356,8 @@ const pushConfigWithStateEffect = (
|
||||||
yield* Effect.log(`[ConfigService] Pushed configuration version ${state.version}`);
|
yield* Effect.log(`[ConfigService] Pushed configuration version ${state.version}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
const readPersistedConfigEffect = (
|
const readPersistedConfigEffect = Effect.fn("ConfigService.readPersistedConfig")(
|
||||||
persistPath: string,
|
function* (persistPath: string) {
|
||||||
): Effect.Effect<PersistedConfig | null> =>
|
|
||||||
Effect.gen(function* () {
|
|
||||||
const raw = yield* Effect.tryPromise({
|
const raw = yield* Effect.tryPromise({
|
||||||
try: () => readTextFile(persistPath),
|
try: () => readTextFile(persistPath),
|
||||||
catch: (cause) => configServiceError("persist-read", cause),
|
catch: (cause) => configServiceError("persist-read", cause),
|
||||||
|
|
@ -368,12 +365,15 @@ const readPersistedConfigEffect = (
|
||||||
return yield* S.decodeUnknownEffect(PersistedConfigJsonSchema)(raw).pipe(
|
return yield* S.decodeUnknownEffect(PersistedConfigJsonSchema)(raw).pipe(
|
||||||
Effect.mapError((cause) => configServiceError("persist-decode", cause)),
|
Effect.mapError((cause) => configServiceError("persist-decode", cause)),
|
||||||
);
|
);
|
||||||
}).pipe(
|
},
|
||||||
|
(effect) =>
|
||||||
|
effect.pipe(
|
||||||
Effect.catch(() =>
|
Effect.catch(() =>
|
||||||
Effect.log("[ConfigService] No persisted config found, starting fresh").pipe(
|
Effect.log("[ConfigService] No persisted config found, starting fresh").pipe(
|
||||||
Effect.flatMap(() => Effect.succeed<PersistedConfig | null>(null)),
|
Effect.flatMap(() => Effect.succeed<PersistedConfig | null>(null)),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleGetWithState = (
|
const handleGetWithState = (
|
||||||
|
|
@ -515,12 +515,11 @@ const applyDeleteStringKeys = (
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePutEffect = (
|
const handlePutEffect = Effect.fn("ConfigService.handlePut")(function* (
|
||||||
stateRef: SynchronizedRef.SynchronizedRef<ConfigServiceState>,
|
stateRef: SynchronizedRef.SynchronizedRef<ConfigServiceState>,
|
||||||
persistPath: string | null,
|
persistPath: string | null,
|
||||||
request: ConfigRequest,
|
request: ConfigRequest,
|
||||||
): Effect.Effect<ConfigResponse, ConfigServiceError> =>
|
) {
|
||||||
Effect.gen(function* () {
|
|
||||||
const values = configValues(request);
|
const values = configValues(request);
|
||||||
if (values.length === 0) return yield* configServiceError("put", "Put requires config values");
|
if (values.length === 0) return yield* configServiceError("put", "Put requires config values");
|
||||||
|
|
||||||
|
|
@ -531,12 +530,11 @@ const handlePutEffect = (
|
||||||
return {version: next.version};
|
return {version: next.version};
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleDeleteEffect = (
|
const handleDeleteEffect = Effect.fn("ConfigService.handleDelete")(function* (
|
||||||
stateRef: SynchronizedRef.SynchronizedRef<ConfigServiceState>,
|
stateRef: SynchronizedRef.SynchronizedRef<ConfigServiceState>,
|
||||||
persistPath: string | null,
|
persistPath: string | null,
|
||||||
request: ConfigRequest,
|
request: ConfigRequest,
|
||||||
): Effect.Effect<ConfigResponse, ConfigServiceError> =>
|
) {
|
||||||
Effect.gen(function* () {
|
|
||||||
const workspace = workspaceFor(request);
|
const workspace = workspaceFor(request);
|
||||||
const keysByObject = objectKeys(request);
|
const keysByObject = objectKeys(request);
|
||||||
|
|
||||||
|
|
@ -639,10 +637,9 @@ const handleConfigDumpWithState = (
|
||||||
config: configDumpForState(state, workspaceFor(request)),
|
config: configDumpForState(state, workspaceFor(request)),
|
||||||
});
|
});
|
||||||
|
|
||||||
const closeConfigResourcesEffect = (
|
const closeConfigResourcesEffect = Effect.fn("ConfigService.closeResources")(function* (
|
||||||
stateRef: SynchronizedRef.SynchronizedRef<ConfigServiceState>,
|
stateRef: SynchronizedRef.SynchronizedRef<ConfigServiceState>,
|
||||||
): Effect.Effect<void, ConfigServiceError> =>
|
) {
|
||||||
Effect.gen(function* () {
|
|
||||||
const state = yield* SynchronizedRef.get(stateRef);
|
const state = yield* SynchronizedRef.get(stateRef);
|
||||||
|
|
||||||
const consumer = state.consumer;
|
const consumer = state.consumer;
|
||||||
|
|
@ -674,10 +671,9 @@ const closeConfigResourcesEffect = (
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const consumeOnceEffect = (
|
const consumeOnceEffect = Effect.fnUntraced(function* (
|
||||||
service: ConfigService,
|
service: ConfigService,
|
||||||
): Effect.Effect<void, ConfigServiceError> =>
|
) {
|
||||||
Effect.gen(function* () {
|
|
||||||
const state = yield* SynchronizedRef.get(service.state);
|
const state = yield* SynchronizedRef.get(service.state);
|
||||||
const consumer = state.consumer;
|
const consumer = state.consumer;
|
||||||
if (consumer === null) {
|
if (consumer === null) {
|
||||||
|
|
@ -697,10 +693,9 @@ const consumeOnceEffect = (
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const runConfigServiceEffect = (
|
const runConfigServiceEffect = Effect.fn("ConfigService.run")(function* (
|
||||||
service: ConfigService,
|
service: ConfigService,
|
||||||
): Effect.Effect<void, ConfigServiceError> =>
|
) {
|
||||||
Effect.gen(function* () {
|
|
||||||
yield* service.loadFromDiskEffect;
|
yield* service.loadFromDiskEffect;
|
||||||
|
|
||||||
const responseProducer = yield* Effect.tryPromise({
|
const responseProducer = yield* Effect.tryPromise({
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue