Skip to content

@makaio/preferences

User preference storage handlers for browser localStorage, Drizzle, and hybrid browser/database coordination.

┌─────────────────────────────────────────────────────────────┐
│ @makaio/services-core/preferences owns PreferencesSubjects │
│ preferences.get / preferences.set / preferences.delete / │
│ preferences.list │
└─────────────────────────────────────────────────────────────┘
┌────────────────────┐ ┌─────────────────┐ ┌──────────────────┐
│ BrowserHandler │ │ DrizzleHandler │ │ HybridHandler │
│ (localStorage) │ │ (SQLite) │ │ (local + Drizzle)│
└────────────────────┘ └─────────────────┘ └──────────────────┘
StorageCoordinator + ConflictResolvers

@makaio/preferences does not define the bus subjects. PreferencesSubjects and PreferencesNamespace are owned by @makaio/services-core/preferences; consumers and hosts that request or register preference handlers need that dependency.

interface PreferenceKey {
scope: string; // 'global' or projectId
surface?: 'ui' | 'app'; // SEAM: undefined = all (Phase 1)
context?: string; // SEAM: widget layout focus
viewport?: 'desktop' | 'tablet' | 'mobile'; // SEAM: unused in Phase 1
}
SubjectDescription
preferences.getFetch value by { key, category }
preferences.setStore { key, category, value }
preferences.deleteRemove a preference
preferences.listList preferences with optional filter
BackendEnvironmentSource of truth
BrowserHandlerBrowser — localStorage onlylocalStorage
DrizzleHandlerNode/Electron — SQLite via DrizzleDatabase
HybridHandlerHybrid app — localStorage plus Drizzle coordinationDatabase

HybridHandler uses StorageCoordinator to read from the Drizzle database as the durable source of truth, write through to both localStorage and the database, and reconcile legacy local entries through conflict resolution. localStorage remains a fast local cache and migration bridge; the DB owns persisted state. The coordinator and conflict resolver are the current sync seam for future multi-device coordination.

import { PreferencesSubjects } from '@makaio/services-core/preferences';
await bus.request(PreferencesSubjects.set, {
key: { scope: 'global' },
category: 'layout',
value: { sidebarWidth: 280 },
});
const { value } = await bus.request(PreferencesSubjects.get, {
key: { scope: 'global' },
category: 'layout',
});
EntryDescription
@makaio/preferencesNode barrel — all exports including Drizzle
@makaio/preferences/browserBrowser-safe — no Drizzle dependencies
@makaio/preferences/packageMakaioExtension manifest
  • surface, context, viewport key fields — prepared for Phase 2 use
  • StorageCoordinator + ConflictResolvers — local cache/database reconciliation and future sync seam