import type { ServerConfig, ServerConfigStreamEvent } from "@t3tools/contracts";import * as Option from "effect/Option"; export interface ServerConfigProjection { readonly config: ServerConfig; readonly latestEvent: ServerConfigStreamEvent; readonly source: "cache" | "live";} /** * Cached config keeps the provider and model catalog available across reconnects. * Published themes are current machine state, so a cache could restore themes * that the machine no longer publishes. Replay sends themes as a separate event. */export function withoutEnvironmentThemes(config: ServerConfig): ServerConfig { if (config.environmentThemes === undefined) return config; const { environmentThemes: _ephemeral, ...rest } = config; return rest;} export function applyServerConfigProjection( current: Option.Option<ServerConfigProjection>, event: ServerConfigStreamEvent,): Option.Option<ServerConfigProjection> { switch (event.type) { case "snapshot": { // Wire snapshots never contain published themes. Keep the previous set // until a capable server sends its authoritative theme event. A legacy // server cannot send a later removal, so a downgrade must clear the set. const carried = event.config.environment.capabilities.environmentThemes === true && Option.isSome(current) ? current.value.config.environmentThemes : undefined; return Option.some({ config: carried === undefined ? event.config : { ...event.config, environmentThemes: carried }, latestEvent: event, source: "live" as const, }); } case "keybindingsUpdated": return Option.map(current, (projection) => ({ config: { ...projection.config, keybindings: event.payload.keybindings, issues: event.payload.issues, }, latestEvent: event, source: "live", })); case "providerStatuses": return Option.map(current, (projection) => ({ config: { ...projection.config, providers: event.payload.providers, }, latestEvent: event, source: "live", })); case "settingsUpdated": return Option.map(current, (projection) => ({ config: { ...projection.config, settings: event.payload.settings, }, latestEvent: event, source: "live", })); case "environmentThemesUpdated": return Option.map(current, (projection) => ({ config: { ...projection.config, environmentThemes: event.payload.themes.length > 0 ? event.payload.themes : undefined, }, latestEvent: event, source: "live", })); }}
import type { ServerConfig, ServerConfigStreamEvent } from "@t3tools/contracts";
import * as Option from "effect/Option";
export interface ServerConfigProjection {
readonly config: ServerConfig;
readonly latestEvent: ServerConfigStreamEvent;
readonly source: "cache" | "live";
}
/**
* Cached config keeps the provider and model catalog available across reconnects.
* Published themes are current machine state, so a cache could restore themes
* that the machine no longer publishes. Replay sends themes as a separate event.
*/
export function withoutEnvironmentThemes(config: ServerConfig): ServerConfig {
if (config.environmentThemes === undefined) return config;
const { environmentThemes: _ephemeral, ...rest } = config;
return rest;
}
export function applyServerConfigProjection(
current: Option.Option<ServerConfigProjection>,
event: ServerConfigStreamEvent,
): Option.Option<ServerConfigProjection> {
switch (event.type) {
case "snapshot": {
// Wire snapshots never contain published themes. Keep the previous set
// until a capable server sends its authoritative theme event. A legacy
// server cannot send a later removal, so a downgrade must clear the set.
const carried =
event.config.environment.capabilities.environmentThemes === true && Option.isSome(current)
? current.value.config.environmentThemes
: undefined;
return Option.some({
config:
carried === undefined ? event.config : { ...event.config, environmentThemes: carried },
latestEvent: event,
source: "live" as const,
});
}
case "keybindingsUpdated":
return Option.map(current, (projection) => ({
config: {
...projection.config,
keybindings: event.payload.keybindings,
issues: event.payload.issues,
},
latestEvent: event,
source: "live",
}));
case "providerStatuses":
return Option.map(current, (projection) => ({
config: {
...projection.config,
providers: event.payload.providers,
},
latestEvent: event,
source: "live",
}));
case "settingsUpdated":
return Option.map(current, (projection) => ({
config: {
...projection.config,
settings: event.payload.settings,
},
latestEvent: event,
source: "live",
}));
case "environmentThemesUpdated":
return Option.map(current, (projection) => ({
config: {
...projection.config,
environmentThemes: event.payload.themes.length > 0 ? event.payload.themes : undefined,
},
latestEvent: event,
source: "live",
}));
}
}