@sinequa/atomic

User settings

Per-user preferences stored on the server, with a shape you extend yourself — and the difference between save and patch.

User settings are a free-form object the server keeps per user. The library knows about three keys and lets you add whatever else your application needs.

the four calls
await client.api.userSettings.get();          // load
await client.api.userSettings.patch(changes); // merge, and get the new state back
await client.api.userSettings.save(settings); // replace wholesale
await client.api.userSettings.reset();        // empty them

patch unless you mean to replace

This is the distinction that matters:

SendsReturnsUse it for
patch(partial)Only your keysThe merged settingsAlmost always
save(settings)The whole objectvoidA settings screen that owns the entire object

save replaces. A view that saves its own slice — a sidebar remembering its width — wipes every other setting on the way. And it returns nothing, so you cannot tell what the state became.

Typing your own settings

UserSettings is { language?, skipCount?, email? } & Record<string, any>, so extra keys are accepted. Declare your own shape and pass it as the generic:

A typed settings store
src/settings.ts
import { createAtomicClient } from "@sinequa/atomic";
import type { UserSettings } from "@sinequa/atomic";

const client = createAtomicClient({
  app: "<your-app>",
  backendUrl: "https://<your-sinequa-server>",
});

await client.initializeConfig();
await client.auth.login();

/** Your application's settings, on top of the ones the library declares. */
type MySettings = UserSettings & {
  resultsPerPage?: number;
  savedSearches?: { name: string; text: string }[];
  sidebarWidth?: number;
};

// Load once at start-up; they change rarely and every read is a round trip.
let settings = await client.api.userSettings.get<MySettings>();

/** Merge one change. Never `save` from a view that owns only part of the object. */
export async function update(change: Partial<MySettings>) {
  settings = await client.api.userSettings.patch<MySettings>(change);
  return settings;
}

export async function addSavedSearch(name: string, text: string) {
  // Read-modify-write on an array: patch merges keys, it does not append to arrays.
  const saved = [...(settings.savedSearches ?? []), { name, text }];
  return update({ savedSearches: saved });
}

export function pageSize() {
  return settings.resultsPerPage ?? 10;
}

UserSettingsKeys is a small convenience: it autocompletes the known keys without rejecting your own, using the StringWithAutocomplete trick.

Pitfalls

What's next

On this page