@@ -49,11 +49,33 @@ import { fromLenientJson } from "@t3tools/shared/schemaJson";
4949import { applyServerSettingsPatch } from "@t3tools/shared/serverSettings" ;
5050import { ServerSecretStoreLive } from "./auth/Layers/ServerSecretStore.ts" ;
5151import { ServerSecretStore } from "./auth/Services/ServerSecretStore.ts" ;
52- const decodeServerSettings = Schema . decodeEffect ( ServerSettings ) ;
52+ const encodeServerSettingsSync = Schema . encodeSync ( ServerSettings ) ;
53+ const decodeServerSettings = Schema . decodeUnknownEffect ( ServerSettings ) ;
5354
5455const textEncoder = new TextEncoder ( ) ;
5556const textDecoder = new TextDecoder ( ) ;
5657
58+ function settingsInputForDecode ( settings : ServerSettings ) : unknown {
59+ return {
60+ ...settings ,
61+ automaticGitFetchInterval : Duration . toMillis ( settings . automaticGitFetchInterval ) ,
62+ } ;
63+ }
64+
65+ const normalizeServerSettings = (
66+ settings : ServerSettings ,
67+ ) : Effect . Effect < ServerSettings , ServerSettingsError > =>
68+ decodeServerSettings ( settingsInputForDecode ( settings ) ) . pipe (
69+ Effect . mapError (
70+ ( cause ) =>
71+ new ServerSettingsError ( {
72+ settingsPath : "<memory>" ,
73+ detail : `failed to normalize server settings: ${ SchemaIssue . makeFormatterDefault ( ) ( cause . issue ) } ` ,
74+ cause,
75+ } ) ,
76+ ) ,
77+ ) ;
78+
5779function providerEnvironmentSecretName ( input : {
5880 readonly instanceId : string ;
5981 readonly name : string ;
@@ -117,28 +139,19 @@ export class ServerSettingsService extends Context.Service<
117139 Layer . effect (
118140 ServerSettingsService ,
119141 Effect . gen ( function * ( ) {
120- const currentSettingsRef = yield * Ref . make < ServerSettings > (
142+ const initialSettings = yield * normalizeServerSettings (
121143 deepMerge ( DEFAULT_SERVER_SETTINGS , overrides ) ,
122144 ) ;
145+ const currentSettingsRef = yield * Ref . make < ServerSettings > ( initialSettings ) ;
123146
124147 return {
125148 start : Effect . void ,
126149 ready : Effect . void ,
127150 getSettings : Ref . get ( currentSettingsRef ) ,
128151 updateSettings : ( patch ) =>
129152 Ref . get ( currentSettingsRef ) . pipe (
130- Effect . flatMap ( ( currentSettings ) =>
131- decodeServerSettings ( applyServerSettingsPatch ( currentSettings , patch ) ) . pipe (
132- Effect . mapError (
133- ( cause ) =>
134- new ServerSettingsError ( {
135- settingsPath : "<memory>" ,
136- detail : `failed to normalize server settings: ${ SchemaIssue . makeFormatterDefault ( ) ( cause . issue ) } ` ,
137- cause,
138- } ) ,
139- ) ,
140- ) ,
141- ) ,
153+ Effect . map ( ( currentSettings ) => applyServerSettingsPatch ( currentSettings , patch ) ) ,
154+ Effect . flatMap ( normalizeServerSettings ) ,
142155 Effect . tap ( ( nextSettings ) => Ref . set ( currentSettingsRef , nextSettings ) ) ,
143156 ) ,
144157 streamChanges : Stream . empty ,
@@ -200,7 +213,10 @@ function fallbackTextGenerationProvider(settings: ServerSettings): ServerSetting
200213}
201214
202215// Values under these keys are compared as a whole — never stripped field-by-field.
203- const ATOMIC_SETTINGS_KEYS : ReadonlySet < string > = new Set ( [ "textGenerationModelSelection" ] ) ;
216+ const ATOMIC_SETTINGS_KEYS : ReadonlySet < string > = new Set ( [
217+ "automaticGitFetchInterval" ,
218+ "textGenerationModelSelection" ,
219+ ] ) ;
204220
205221function stripDefaultServerSettings ( current : unknown , defaults : unknown ) : unknown | undefined {
206222 if ( Array . isArray ( current ) || Array . isArray ( defaults ) ) {
@@ -431,7 +447,9 @@ const makeServerSettings = Effect.gen(function* () {
431447 } ) ;
432448
433449 const writeSettingsAtomically = ( settings : ServerSettings ) => {
434- const sparseSettings = stripDefaultServerSettings ( settings , DEFAULT_SERVER_SETTINGS ) ?? { } ;
450+ const encodedSettings = encodeServerSettingsSync ( settings ) ;
451+ const encodedDefaults = encodeServerSettingsSync ( DEFAULT_SERVER_SETTINGS ) ;
452+ const sparseSettings = stripDefaultServerSettings ( encodedSettings , encodedDefaults ) ?? { } ;
435453
436454 return writeFileStringAtomically ( {
437455 filePath : settingsPath ,
@@ -533,16 +551,7 @@ const makeServerSettings = Effect.gen(function* () {
533551 current ,
534552 applyServerSettingsPatch ( current , patch ) ,
535553 ) ;
536- const next = yield * decodeServerSettings ( nextPersisted ) . pipe (
537- Effect . mapError (
538- ( cause ) =>
539- new ServerSettingsError ( {
540- settingsPath : "<memory>" ,
541- detail : `failed to normalize server settings: ${ SchemaIssue . makeFormatterDefault ( ) ( cause . issue ) } ` ,
542- cause,
543- } ) ,
544- ) ,
545- ) ;
554+ const next = yield * normalizeServerSettings ( nextPersisted ) ;
546555 yield * writeSettingsAtomically ( next ) ;
547556 yield * Cache . set ( settingsCache , cacheKey , next ) ;
548557 yield * emitChange ( next ) ;
0 commit comments