@weasel-js/prefs 0.0.0-stage → 1.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +29 -2
- package/dist/index.d.ts +153 -0
- package/dist/index.js +637 -0
- package/dist/index.js.map +1 -0
- package/dist/react.d.ts +20 -0
- package/dist/react.js +34 -0
- package/dist/react.js.map +1 -0
- package/dist/store-CNFnA_3c.d.ts +572 -0
- package/package.json +58 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 orochi235
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,30 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @weasel-js/prefs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A preferences schema — groups of typed leaves with names, defaults and
|
|
4
|
+
rendering hints — and a store that keeps values for it.
|
|
5
|
+
|
|
6
|
+
```ts
|
|
7
|
+
const store = await openPrefs(SCHEMA, { storage: indexedDbAdapter, prefix: 'myapp.prefs.' });
|
|
8
|
+
store.get('view.gridVisible');
|
|
9
|
+
store.set('view.gridVisible', false);
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
One record per leaf. A leaf with no record follows its schema default. Reads
|
|
13
|
+
repair stored values that no longer fit the schema without writing them back.
|
|
14
|
+
`migrations[i]` takes stored records from version `i` to `i + 1`.
|
|
15
|
+
`openPrefsSync` opens from an adapter that reads synchronously, such as
|
|
16
|
+
`localStorageAdapter`, with no `await`.
|
|
17
|
+
|
|
18
|
+
`usePref(store, path)` and `usePrefsValues(store)` bind it to React. They
|
|
19
|
+
live in `@weasel-js/prefs/react`, so the main entry never loads React.
|
|
20
|
+
`usePrefsValues` returns the pieces `@weasel-js/ui`'s `PrefsForm` takes.
|
|
21
|
+
|
|
22
|
+
## Ranges
|
|
23
|
+
|
|
24
|
+
A number leaf's range is one scale: the low end is the least of what its label
|
|
25
|
+
names and the high end the most. Do not give zero a second meaning such as
|
|
26
|
+
"no limit" or "automatic" — on a slider it reads as the least, and the form
|
|
27
|
+
draws it there. Put an unlimited setting at the end of the range it is nearest:
|
|
28
|
+
a 0–100% limit is off at 100, and a scale with no such end takes `endless`,
|
|
29
|
+
which adds a stop one step past the range that stores `Infinity` and reads the
|
|
30
|
+
leaf's `infinity` word.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { P as PrefLeaf, a as PrefGroup, b as PrefSection, c as PrefNumber, d as PrefObject, e as PrefsStore, f as PrefKind } from './store-CNFnA_3c.js';
|
|
2
|
+
export { B as BuiltinPref, g as PREF_KINDS, h as PrefAction, i as PrefActionContext, j as PrefActionControl, k as PrefAlias, l as PrefAtPath, m as PrefBase, n as PrefBoolean, o as PrefBooleanControl, p as PrefBooleanEncoding, q as PrefChange, r as PrefColor, s as PrefCustom, t as PrefEnum, u as PrefEnumBase, v as PrefEnumControl, w as PrefEnumEncoding, x as PrefField, y as PrefGroupAs, z as PrefLabel, A as PrefList, C as PrefMap, D as PrefNumberControl, E as PrefNumberUnit, F as PrefPaint, G as PrefPair, H as PrefPath, I as PrefSectionAs, J as PrefSeparator, K as PrefString, L as PrefStringControl, M as PrefUnion, N as PrefValueAt, O as PrefValueOf, Q as isBuiltinPref, R as pairRowsOf, S as prefAliasTarget, T as prefAliasedLeaf, U as prefGroupIsPage, V as prefUnit, W as prefVariantDefault, X as prefVariantOf } from './store-CNFnA_3c.js';
|
|
3
|
+
import { StorageAdapter, SyncStorageAdapter } from '@weasel-js/storage';
|
|
4
|
+
import '@weasel-js/quantity';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A number leaf's bounds in the unit it is displayed in.
|
|
8
|
+
*
|
|
9
|
+
* Only what the leaf declares converts: an omitted bound has no stored
|
|
10
|
+
* counterpart to put through the conversion, and its fallback — 0..100 for a
|
|
11
|
+
* slider's track, a step of 1 — is a display-space number already. `min` and
|
|
12
|
+
* `max` are points, so they convert the way the value does; `step` is a
|
|
13
|
+
* distance, and a unit with an offset maps zero somewhere else, so converting
|
|
14
|
+
* it as a point would scale it wrong. A decreasing conversion swaps which end
|
|
15
|
+
* is the lower one.
|
|
16
|
+
*/
|
|
17
|
+
declare function prefDisplayBounds(p: PrefNumber): {
|
|
18
|
+
min?: number;
|
|
19
|
+
max?: number;
|
|
20
|
+
step: number;
|
|
21
|
+
};
|
|
22
|
+
/** Distinguishes a leaf from a group or a section while walking a schema tree. */
|
|
23
|
+
declare function isPrefLeaf(node: PrefLeaf | PrefGroup | PrefSection): node is PrefLeaf;
|
|
24
|
+
/** Whether a leaf has a value to store: an `action` is a button and holds none, an `alias` shows another leaf's,
|
|
25
|
+
* and a `label` and a `separator` are text and a rule. */
|
|
26
|
+
declare function prefHoldsValue(leaf: PrefLeaf): boolean;
|
|
27
|
+
/** Distinguishes a section, whose key adds nothing to a path, from a group, whose key is a segment. */
|
|
28
|
+
declare function isPrefSection(node: PrefLeaf | PrefGroup | PrefSection): node is PrefSection;
|
|
29
|
+
/**
|
|
30
|
+
* Every leaf under a section's `members` or an object leaf's `children`, in
|
|
31
|
+
* schema order, by its own key: the sections between contribute nothing.
|
|
32
|
+
*/
|
|
33
|
+
declare function prefSectionLeaves(members: PrefSection['members']): [key: string, leaf: PrefLeaf][];
|
|
34
|
+
/**
|
|
35
|
+
* The leaf whose value lives at `path`, as the schema's own shape builds
|
|
36
|
+
* paths: a segment per key under a {@link PrefGroup}, the leaf's own key
|
|
37
|
+
* under a {@link PrefSection}. `undefined` for a path that names a group, a
|
|
38
|
+
* field inside an `object` leaf, or nothing.
|
|
39
|
+
*/
|
|
40
|
+
declare function prefLeafAt(schema: PrefGroup | PrefSection, path: string): PrefLeaf | undefined;
|
|
41
|
+
/** Get the value at a dotted path inside a nested value tree. Returns
|
|
42
|
+
* `undefined` when a segment is missing or hits a non-object. */
|
|
43
|
+
declare function prefValueAtPath(values: unknown, path: string): unknown;
|
|
44
|
+
/**
|
|
45
|
+
* Recursively drop `hidden` leaves (unless `showHidden`), an object leaf's
|
|
46
|
+
* hidden fields among them, pruning groups
|
|
47
|
+
* that end up empty (unless `keepEmpty`). Returns null when the entire
|
|
48
|
+
* subtree is pruned.
|
|
49
|
+
*/
|
|
50
|
+
declare function visiblePrefSubtree<T extends PrefLeaf | PrefGroup>(node: T, showHidden: boolean, keepEmpty?: boolean): T | null;
|
|
51
|
+
/** The record holding the schema version the stored values were written at.
|
|
52
|
+
* Reserved: no top-level schema key may take its name. */
|
|
53
|
+
declare const VERSION_RECORD = "$version";
|
|
54
|
+
/** Every leaf under `schema`, by dotted path, in schema order. A group's key
|
|
55
|
+
* is a segment; {@link prefSectionLeaves} is the walk for a section. */
|
|
56
|
+
declare function prefLeaves(schema: PrefGroup): Map<string, PrefLeaf>;
|
|
57
|
+
/** Each of `schema`'s leaves that `tree` holds a value for, as a path and
|
|
58
|
+
* that value — the inverse of building a tree from per-leaf records. */
|
|
59
|
+
declare function flattenPrefValues(schema: PrefGroup, tree: unknown): [string, unknown][];
|
|
60
|
+
/**
|
|
61
|
+
* Drop every leaf that does not answer to `query`, pruning groups left empty.
|
|
62
|
+
* A group whose own name matches keeps all of its leaves — a reader who typed
|
|
63
|
+
* the group's name is asking for the group, not for leaves repeating it.
|
|
64
|
+
*
|
|
65
|
+
* An empty or whitespace query matches everything, so a cleared field restores
|
|
66
|
+
* the tree rather than emptying it.
|
|
67
|
+
*
|
|
68
|
+
* An alias answers as the row it draws: its target's name and description
|
|
69
|
+
* where it gives none. `leafAt` finds that target, and defaults to looking in
|
|
70
|
+
* `node`; pass one over the whole schema when `node` is a part of it.
|
|
71
|
+
*/
|
|
72
|
+
declare function filterPrefSubtree<T extends PrefLeaf | PrefGroup>(node: T, query: string, path?: string, leafAt?: (path: string) => PrefLeaf | undefined): T | null;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The object a write to one field of an `object` leaf starts from: `held` itself where it is one. Where it is
|
|
76
|
+
* not, the write has to make a whole object, so it starts from the scalar lifted by the leaf's `fromScalar`, else
|
|
77
|
+
* from the leaf's `default`: one field on its own is a stroke with a width and no paint.
|
|
78
|
+
*/
|
|
79
|
+
declare function prefObjectBase(pref: PrefObject, held: unknown): Record<string, unknown>;
|
|
80
|
+
/** The object an `object` leaf holds after one of its fields is set: {@link prefObjectBase} with `key` at
|
|
81
|
+
* `value`, or without the key for `undefined`. */
|
|
82
|
+
declare function prefObjectWithField(pref: PrefObject, held: unknown, key: string, value: unknown): Record<string, unknown>;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* `leaf` as a named type: the same leaf carrying `name` in its `type` field.
|
|
86
|
+
* Declared once beside the code that reads its value and used wherever a
|
|
87
|
+
* schema wants one, spread with what that place sets for itself
|
|
88
|
+
* (`{ ...GradientStop, name: 'First stop' }`), or as a list's or a map's
|
|
89
|
+
* `item`. `name` is the identifier the type is exported under, which a schema
|
|
90
|
+
* editor prints in place of the leaf's literal.
|
|
91
|
+
*/
|
|
92
|
+
declare function prefType<L extends PrefLeaf>(name: string, leaf: L): L & {
|
|
93
|
+
type: string;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/** Takes stored values from one version to the next: rename, transform or
|
|
97
|
+
* delete entries in `records`, keyed by leaf path. It sees the values, not
|
|
98
|
+
* the stamps they are stored under, and only those at its own version. */
|
|
99
|
+
type PrefsMigration = (records: Map<string, unknown>) => void;
|
|
100
|
+
|
|
101
|
+
/** Decides what a stored value reads as for one kind of leaf: the value to
|
|
102
|
+
* read, or `undefined` for "invalid, read the default". */
|
|
103
|
+
type PrefValidator = (stored: unknown, leaf: PrefLeaf) => unknown;
|
|
104
|
+
/** What `stored` reads as for `leaf`. Never writes anything back: a schema
|
|
105
|
+
* rolled back finds the original still in storage. */
|
|
106
|
+
declare function repairPrefValue(leaf: PrefLeaf, stored: unknown, validators?: Readonly<Record<string, PrefValidator>>): unknown;
|
|
107
|
+
|
|
108
|
+
/** Options for `openPrefs` and `openPrefsSync`. */
|
|
109
|
+
interface PrefsOptions {
|
|
110
|
+
storage: StorageAdapter;
|
|
111
|
+
/** Prepended to every record's key: `'myapp.prefs.'`. */
|
|
112
|
+
prefix: string;
|
|
113
|
+
/** `migrations[i]` takes stored records from version `i` to `i + 1`. The
|
|
114
|
+
* current version is `migrations.length`. */
|
|
115
|
+
migrations?: readonly PrefsMigration[];
|
|
116
|
+
/** Validators for app-defined kinds, keyed by `kind`. One given for a
|
|
117
|
+
* built-in kind replaces that kind's own rule. */
|
|
118
|
+
validators?: Readonly<Record<string, PrefValidator>>;
|
|
119
|
+
}
|
|
120
|
+
/** Load every stored value for `schema`, migrate it, and return the store. */
|
|
121
|
+
declare function openPrefs<S extends PrefGroup>(schema: S, options: PrefsOptions): Promise<PrefsStore<S>>;
|
|
122
|
+
/** `openPrefs` for an adapter that reads synchronously: the store is ready
|
|
123
|
+
* on return, so values can be read before anything renders. */
|
|
124
|
+
declare function openPrefsSync<S extends PrefGroup>(schema: S, options: PrefsOptions & {
|
|
125
|
+
storage: SyncStorageAdapter;
|
|
126
|
+
}): PrefsStore<S>;
|
|
127
|
+
|
|
128
|
+
/** What a surface has to know about a kind before it can lay its control out. */
|
|
129
|
+
interface PrefKindTraits {
|
|
130
|
+
/** Its value is made of other leaves' values: too much for one control on a
|
|
131
|
+
* line, so a bar opens it in a popover and a compact panel in a dialog. */
|
|
132
|
+
compound: boolean;
|
|
133
|
+
/** Its control is several controls, or a button. A row drawn as a `<label>`
|
|
134
|
+
* would hand a click on its text to the first of them. */
|
|
135
|
+
several: boolean;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* The traits of every built-in kind. A `Record` over {@link PrefKind}, so a
|
|
139
|
+
* kind added to the union does not compile until it says what it is here:
|
|
140
|
+
* a plain set of kind names lets a new one through to draw inline in a
|
|
141
|
+
* `<label>`, on a bar's line, and with no dialog row.
|
|
142
|
+
*/
|
|
143
|
+
declare const PREF_KIND_TRAITS: Record<PrefKind, PrefKindTraits>;
|
|
144
|
+
/** Whether a leaf's value is made of other leaves' values. An app-defined kind is not: its renderer is one control. */
|
|
145
|
+
declare function prefIsCompound(leaf: {
|
|
146
|
+
kind: string;
|
|
147
|
+
}): boolean;
|
|
148
|
+
/** Whether a leaf's control is several controls or a button. */
|
|
149
|
+
declare function prefDrawsSeveral(leaf: {
|
|
150
|
+
kind: string;
|
|
151
|
+
}): boolean;
|
|
152
|
+
|
|
153
|
+
export { PREF_KIND_TRAITS, PrefGroup, PrefKind, type PrefKindTraits, PrefLeaf, PrefNumber, PrefObject, PrefSection, type PrefValidator, type PrefsMigration, type PrefsOptions, PrefsStore, VERSION_RECORD, filterPrefSubtree, flattenPrefValues, isPrefLeaf, isPrefSection, openPrefs, openPrefsSync, prefDisplayBounds, prefDrawsSeveral, prefHoldsValue, prefIsCompound, prefLeafAt, prefLeaves, prefObjectBase, prefObjectWithField, prefSectionLeaves, prefType, prefValueAtPath, repairPrefValue, visiblePrefSubtree };
|