On this page
Overview
Loads and updates schema-defined app preferences through native storage with a narrow browser fallback.
- Artifact
PreferenceStore.js· esm - Classification
public first party - Availability
Browser/native hybrid - Normalization
Complete values and operation context retained; the default adapter recognizes only exact missing preferences namespace/matching method or existing Android unsupported capability before selecting existing app-scoped localStorage. Single operations retry once after disposal/cancellation checks; partial-service and genuine failures reject unchanged. An advertised rejected batch is never retried serially, and its original rejection is preserved before later local operations.
Import and lifecycle
import * as module from '/node_modules/arcane-os/runtime/arcane/modules/PreferenceStore.js';
Construction validates schema and initializes mutable defaults only. Explicit adapters retain their behavior. setAll uses one optional adapter setMany call for every selected value when advertised; adapters without setMany retain complete ordered serial writes under one queued operation. The default Android/no-bridge route selects existing app-scoped localStorage. A native route changes to that same local adapter only after ANDROID_CAPABILITY_UNSUPPORTED or an exact absent preferences namespace/matching method. Single operations retry once after disposal and cancellation checks; a late absence result cannot start a cancelled local write. A rejected advertised batch preserves its original rejection before subsequent local operations. No data migration occurs.
Application-facing behavior: Event/error constants, default PreferenceStore, re-exported Preference/schema; load/set/setAll/reset APIs, required adapter get/set/delete plus optional setMany, state-free EventTarget/on compatibility, and dispose().
Protocol and host implementation
Arcane.preferences or app-scoped localStorage + per-realm globalThis.arcaneEvents authority This detail does not widen the application-facing API or grant authority.
Exports, signatures, parameters, and results
| Binding | Form | Declaration or signature | Parameter syntax |
|---|---|---|---|
PREFERENCE_STORE_ERROR_CODES | variable · value | variable PREFERENCE_STORE_ERROR_CODES | — |
PREFERENCE_STORE_EVENT_TYPES | variable · value | variable PREFERENCE_STORE_EVENT_TYPES | — |
default | default · class | class PreferenceStore extends EventTarget | — |
Preference | re-export | Preference | — |
preferenceSchema | re-export | preferenceSchema | — |
| Member | Kind | Exact public declaration | Parameter syntax |
|---|---|---|---|
PreferenceStore.constructor | constructor | constructor({namespace='arcane',schema=[],adapter=null}={}) | {namespace='arcane',schema=[],adapter=null}={} |
PreferenceStore.addEventListener | method | addEventListener(type,listener,options) | type,listener,options |
PreferenceStore.removeEventListener | method | removeEventListener(type,listener,options) | type,listener,options |
PreferenceStore.on | method | on(type,listener,options) | type,listener,options |
PreferenceStore.dispatchEvent | method | dispatchEvent(value) | value |
PreferenceStore.defaults | method | defaults() | — |
PreferenceStore.storageKey | method | storageKey(key) | key |
PreferenceStore.definition | method | definition(key) | key |
PreferenceStore.load | async method | async load(options={}) | options={} |
PreferenceStore.set | async method | async set(key,value,options={}) | key,value,options={} |
PreferenceStore.setAll | async method | async setAll(values={},options={}) | values={},options={} |
PreferenceStore.reset | async method | async reset(options={}) | options={} |
PreferenceStore.emit | method | emit(type,detail={}) | type,detail={} |
PreferenceStore.dispose | method | dispose() | — |
PreferenceStore.destroy | method | destroy() | — |
Parameter meanings and results
new PreferenceStore({namespace='arcane',schema=[],adapter?}); adapters require get(key,context), set(key,value,context), and delete(key,context), and may expose setMany(entries,context). Complete values and {operationId,signal} context are retained. defaults(), storageKey(), definition(); load() resolves a mutable complete values snapshot; set(key,value) resolves the schema-normalized value; setAll(values,options) and reset() resolve mutable complete snapshots without batch-count caps or freezing. Also re-exports Preference and preferenceSchema.
Events, side effects, and errors
Source-literal CustomEvent dispatches
No source-literal CustomEvent dispatch is part of this artifact.
Lifecycle and event flow
- preference-load with {values}
- preference-change with {values,key,value}
- preference-reset with {values}
Direct coded failures
This artifact directly assigns no stable coded failure.
Exported Error subclasses
This artifact exports no Error subclass.
Documented failure behavior
- RangeError for unknown key.
- Optional namespace absence requires code:'METHOD_NOT_ALLOWED', reason:'core-namespace-unavailable', namespace:'preferences', and the exact method:'preferences.<current operation>'. Partial/read-only services, older unmarked errors, permission, persistence, transport and cancellation failures remain errors.
- A dispatched setMany rejection never retries as serial writes. Exact absence selects local storage only for later operations while preserving that batch rejection.
Availability and capabilities
Browser/native hybrid. Complete values and operation context retained; the default adapter recognizes only exact missing preferences namespace/matching method or existing Android unsupported capability before selecting existing app-scoped localStorage. Single operations retry once after disposal/cancellation checks; partial-service and genuine failures reject unchanged. An advertised rejected batch is never retried serially, and its original rejection is preserved before later local operations.
Non-Android native get uses preferences.read; set/delete and optional atomic setMany use preferences.write. Android and browser localStorage need no preference capability, while application scoping may resolve capability-free app.current.
Contract example
import PreferenceStore from '/node_modules/arcane-os/runtime/arcane/modules/PreferenceStore.js';
const data = new Map();
const adapter = {
async get(key){return {found:data.has(key),value:data.get(key)}},
async set(key,value){data.set(key,value)},
async delete(key){data.delete(key)}
};
const store = new PreferenceStore({
namespace:'demo',
schema:[{key:'enabled',type:'boolean',defaultValue:false}],
adapter
});
await store.set('enabled', true);
console.log(await store.load());