You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
3.1 KiB
96 lines
3.1 KiB
import {
|
|
createActivePrefs,
|
|
createPrefsStorageBridge,
|
|
type ActivePrefs,
|
|
type EnginePrefsOptions,
|
|
type PrefsIntentStorage,
|
|
type PrefsStorageBridge,
|
|
type PrefsStorageOp
|
|
} from '$prefs';
|
|
import type { AppServiceFactory } from '../services.ts';
|
|
|
|
/**
|
|
* Options for `defineActivePrefs`. A thin alias of `EnginePrefsOptions`
|
|
* — exported here so callers can `import { type DefineActivePrefsOptions }
|
|
* from '$active-app'` without reaching into `$prefs`.
|
|
*/
|
|
export type DefineActivePrefsOptions = EnginePrefsOptions;
|
|
|
|
/**
|
|
* Options for `defineActivePrefsWithStorage`. Adds a `PrefsIntentStorage`
|
|
* port and an optional error reporter on top of the base prefs config.
|
|
*/
|
|
export interface DefineActivePrefsWithStorageOptions extends DefineActivePrefsOptions {
|
|
readonly storage: PrefsIntentStorage;
|
|
readonly onError?: (error: unknown, op: PrefsStorageOp) => void;
|
|
}
|
|
|
|
/**
|
|
* `defineActivePrefs(options)` produces a service factory for the
|
|
* `prefs` slot. Adds the runtime to the App schema as
|
|
* `App.prefs: ActivePrefs`, where downstream service factories
|
|
* (`defineActiveLang`, `defineActiveFormat`, `defineActiveFrontend`)
|
|
* read capability sources via the helpers in `$prefs/sources`.
|
|
*
|
|
* No core dependencies: the engine is pure data — capabilities,
|
|
* environment and intent are passed in by the caller. Environment
|
|
* detection lives in `$prefs/adapters/*` and is invoked by the
|
|
* application's bootstrap code, not by this factory.
|
|
*
|
|
* `initMode: 'immediate'` because consumer factories ask for `prefs`
|
|
* via `serviceDependencies` at construction time; deferring the build
|
|
* would make the dependency graph order-sensitive.
|
|
*/
|
|
export function defineActivePrefs(
|
|
options: DefineActivePrefsOptions
|
|
): AppServiceFactory<'prefs', readonly [], readonly [], ActivePrefs> {
|
|
return {
|
|
name: 'prefs',
|
|
coreDependencies: [],
|
|
initMode: 'immediate',
|
|
create(): ActivePrefs {
|
|
return createActivePrefs(options);
|
|
},
|
|
dispose(instance) {
|
|
instance.dispose();
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* `defineActivePrefsWithStorage(options)` is the storage-bundled variant
|
|
* of `defineActivePrefs`. Bootstraps the engine and immediately attaches
|
|
* a `PrefsStorageBridge` so persisted intent loads on hydrate and every
|
|
* subsequent commit is saved back. Bridge teardown runs before the
|
|
* engine disposes.
|
|
*
|
|
* Use this when the application has a `PrefsIntentStorage` ready to
|
|
* inject (typically a thin adapter over `arts/storage`). Apps that wire
|
|
* persistence by hand can stay on `defineActivePrefs(...)` and call
|
|
* `createPrefsStorageBridge(...)` themselves.
|
|
*/
|
|
export function defineActivePrefsWithStorage(
|
|
options: DefineActivePrefsWithStorageOptions
|
|
): AppServiceFactory<'prefs', readonly [], readonly [], ActivePrefs> {
|
|
let bridge: PrefsStorageBridge | undefined;
|
|
return {
|
|
name: 'prefs',
|
|
coreDependencies: [],
|
|
initMode: 'immediate',
|
|
create(): ActivePrefs {
|
|
const prefs = createActivePrefs(options);
|
|
bridge = createPrefsStorageBridge({
|
|
engine: prefs,
|
|
storage: options.storage,
|
|
onError: options.onError
|
|
});
|
|
return prefs;
|
|
},
|
|
dispose(instance) {
|
|
bridge?.dispose();
|
|
bridge = undefined;
|
|
instance.dispose();
|
|
}
|
|
};
|
|
}
|