Settings Client
Settings Client protocol schemas
SettingsClient — reactive consumer contract for runtime settings.
Background. Phase 0 introduced the cascade scope (env > global > tenant > user > default) and made SettingsService.get() resolve
across the chain. Consumers (e.g. EmailServicePlugin, BrandingPlugin)
still pull values once at boot, which means saved changes never take
effect without a process restart.
This module defines the contract that fixes that:
const mail = ctx.settings.bind('mail', MailSettingsSchema); mail.current.smtp_host; // current effective value const off = mail.onChange(() => rebuild());
service.set('mail', 'smtp_host', '…') // ↳ fires settings:changed // → handler runs → transport rebuilt
Design rules:
-
Spec-only. This package emits types and Zod shapes. No runtime wiring (event bus, in-memory cache) lives here — that is
@objectstack/service-settings's job. Keeping the contract pure lets non-Node consumers (RN, edge workers) re-implement it. -
Snapshot semantics.
currentis an immutable snapshot of the namespace at the moment of the last refresh. After a change event fires, the next read ofcurrentreturns the new snapshot — old references stay stable (good for React useSyncExternalStore). -
No fetching here. A
SettingsClientdoes not know how to fetch itself; it is constructed by an authority (the service) that owns the persistence layer. That keeps cycles out of the dependency graph and lets us mock the client trivially in tests.
Source: packages/spec/src/system/settings-client.zod.ts
TypeScript Usage
import { SettingsChangeEventSchema } from '@objectstack/spec/system';
import type { SettingsChangeEvent } from '@objectstack/spec/system';
// Validate data
const result = SettingsChangeEventSchema.parse(data);SettingsChangeEvent
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| namespace | string | ✅ | Settings namespace, e.g. "mail" |
| key | string | ✅ | Specifier key, e.g. "smtp_host" |
| scope | Enum<'global' | 'tenant' | 'user'> | ✅ | Scope of the mutated row |
| action | Enum<'set' | 'reset'> | ✅ | Mutation kind |
| at | string | ✅ | ISO 8601 mutation timestamp |