Providers and persistence

Where a namespace gets its values from, and which of them survive a restart.

Data providers

A namespace and the code that fills it. Lazy by default: nothing loads until something reads or subscribes below it.

store.registerDataProvider({
  namespace: 'services',
  unloadAfter: 30_000,        // unload when nothing has watched for 30s
  provider: {
    async load(store) {
      store.set('$/services/list', await fetchServices());
    },
    unload(store) {
      store.delete('$/services/list');
    },
  },
});

Schemas and persistence

store.registerSchema({
  path: '$/config/port',
  validate: (v) => (typeof v === 'number' ? null : 'expected a number'),
  initial: 8080,
});

store.registerPersistence({
  id: 'ui',
  paths: ['$/ui/', '$/layout/surfaces/'],   // a trailing slash means the subtree
  read: () => JSON.parse(readFileSync(path, 'utf8')),
  write: (entries) => writeFileSync(path, JSON.stringify(entries)),
  debounceMs: 500,
});

await store.hydrate();   // once, at boot

Schemas are optional and dynamic paths stay legal either way - the point is to catch a wrong write where it happens, not to make the store typed.


Back to top

MIT licensed. Pre-1.0 - the surface is still moving.