@weasel-js/prefs 1.9.3 → 1.10.0
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/README.md +17 -0
- package/dist/chunk-5KB3WBJZ.js +863 -0
- package/dist/chunk-5KB3WBJZ.js.map +1 -0
- package/dist/index.d.ts +351 -42
- package/dist/index.js +283 -338
- package/dist/index.js.map +1 -1
- package/dist/open-BEY-aOGe.d.ts +724 -0
- package/dist/react.d.ts +26 -2
- package/dist/react.js +66 -2
- package/dist/react.js.map +1 -1
- package/package.json +4 -3
- package/dist/store-BU2tRX5H.d.ts +0 -353
|
@@ -0,0 +1,724 @@
|
|
|
1
|
+
import { StorageAdapter, SyncStorageAdapter } from '@weasel-js/storage';
|
|
2
|
+
import { UnitEntry, UnitSystem, Unit, Display, InfinityText } from '@weasel-js/quantity';
|
|
3
|
+
|
|
4
|
+
/** What a condition can compare a leaf's value against. `null` stands for
|
|
5
|
+
* nothing held: a missing value as well as a stored `null`. */
|
|
6
|
+
type PrefConditionValue = string | number | boolean | null;
|
|
7
|
+
/**
|
|
8
|
+
* One leaf's value, tested. `path` is the full path the value is read and
|
|
9
|
+
* written at (`'windows.paging'`), a field of an `object` or `union` leaf
|
|
10
|
+
* included (`'stroke.width'`, `'fill.type'`). With `from: 'item'` the path is
|
|
11
|
+
* read from the entry the test's node is drawn in instead: the entry of the
|
|
12
|
+
* nearest list or map the node is the `item` of, or sits inside the item of.
|
|
13
|
+
* `{ from: 'item', path: 'mode' }` on a field of a list's item reads `mode`
|
|
14
|
+
* of the same entry, and an empty path is the entry itself. The value compared is the one
|
|
15
|
+
* the leaf's control shows, where an `encoding` stores another. With
|
|
16
|
+
* several operators it holds while all of them do, so
|
|
17
|
+
* `{ path: 'count', atLeast: 1, below: 10 }` is a range.
|
|
18
|
+
*
|
|
19
|
+
* With no operator it holds while the value is set, which by kind is:
|
|
20
|
+
* a `boolean` that is on; a `number` other than 0; a `string`, a `color`, a
|
|
21
|
+
* `field`, or an `enum`'s option that is not the empty string; a `paint`
|
|
22
|
+
* that is not `null`; a `list` with an entry; a `map` with a key; an
|
|
23
|
+
* `object` or a `union` holding a field. Nothing held is never set, and the
|
|
24
|
+
* value of an app-defined kind is set by whichever of those its shape is,
|
|
25
|
+
* else while it is truthy.
|
|
26
|
+
*/
|
|
27
|
+
interface PrefTest {
|
|
28
|
+
path: string;
|
|
29
|
+
/** Where `path` is read from: the entry the node is drawn in. Unset: the schema root. */
|
|
30
|
+
from?: 'item';
|
|
31
|
+
is?: PrefConditionValue;
|
|
32
|
+
isNot?: PrefConditionValue;
|
|
33
|
+
/** Holds while the value is any of these. */
|
|
34
|
+
in?: readonly PrefConditionValue[];
|
|
35
|
+
/** The ordering operators hold only for a number. */
|
|
36
|
+
above?: number;
|
|
37
|
+
below?: number;
|
|
38
|
+
atLeast?: number;
|
|
39
|
+
atMost?: number;
|
|
40
|
+
}
|
|
41
|
+
/** A condition a schema node holds in `showIf` or `enableIf`. An empty `all`
|
|
42
|
+
* holds and an empty `any` does not. */
|
|
43
|
+
type PrefCondition = PrefTest | {
|
|
44
|
+
all: readonly PrefCondition[];
|
|
45
|
+
} | {
|
|
46
|
+
any: readonly PrefCondition[];
|
|
47
|
+
} | {
|
|
48
|
+
not: PrefCondition;
|
|
49
|
+
};
|
|
50
|
+
/** Reads the value a test compares: at `path` from the schema root, or with `from`, from the entry being drawn. */
|
|
51
|
+
type PrefConditionReader = (path: string, from?: 'item') => unknown;
|
|
52
|
+
/** Whether `value` is a well-formed condition, all the way down. */
|
|
53
|
+
declare function isPrefCondition(value: unknown): value is PrefCondition;
|
|
54
|
+
/** Whether `condition` holds, given the value `read` finds at each path it names. */
|
|
55
|
+
declare function prefConditionHolds(condition: PrefCondition, read: PrefConditionReader): boolean;
|
|
56
|
+
/** Whether a node is drawn: its `showIf` holds, or it has none. A node
|
|
57
|
+
* answers for itself only; one inside a group that is not shown is not
|
|
58
|
+
* drawn either. */
|
|
59
|
+
declare function prefIsShown(node: {
|
|
60
|
+
showIf?: PrefCondition;
|
|
61
|
+
}, read: PrefConditionReader): boolean;
|
|
62
|
+
/** Whether a node's controls take input: its `enableIf` holds, or it has
|
|
63
|
+
* none. As {@link prefIsShown}, a node answers for itself only. */
|
|
64
|
+
declare function prefIsEnabled(node: {
|
|
65
|
+
enableIf?: PrefCondition;
|
|
66
|
+
}, read: PrefConditionReader): boolean;
|
|
67
|
+
/** Every path `condition` reads from the schema root, or with `from`, from the entry, once each, in the order met. */
|
|
68
|
+
declare function prefConditionPaths(condition: PrefCondition, from?: 'item'): string[];
|
|
69
|
+
/** Whether any test of `condition` reads from the entry, so that it has no answer until an entry is drawn. */
|
|
70
|
+
declare function prefConditionReadsItem(condition: PrefCondition): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* `condition` with every path it reads put through `move`, for following a
|
|
73
|
+
* key that was renamed or a leaf that moved. `move` is told where a path is
|
|
74
|
+
* read from, and what it hands back is read from there too. A condition none
|
|
75
|
+
* of whose paths change comes back as the object it was given, and so does
|
|
76
|
+
* each part of one.
|
|
77
|
+
*/
|
|
78
|
+
declare function mapPrefConditionPaths(condition: PrefCondition, move: (path: string, from?: 'item') => string): PrefCondition;
|
|
79
|
+
|
|
80
|
+
/** What a {@link PrefAction}'s `run` is told. */
|
|
81
|
+
interface PrefActionContext {
|
|
82
|
+
/** The path the action sits at on the surface drawing it. */
|
|
83
|
+
path: string;
|
|
84
|
+
}
|
|
85
|
+
/** How a schema-driven UI should present an action leaf. */
|
|
86
|
+
type PrefActionControl = 'button' | 'icon';
|
|
87
|
+
/**
|
|
88
|
+
* A leaf that holds no value: a button among the rows or in a bar. A store
|
|
89
|
+
* neither reads nor writes one, and its path is not a {@link PrefPath}.
|
|
90
|
+
*
|
|
91
|
+
* It fires one of two things. `action` names an action the host registered,
|
|
92
|
+
* by key, which keeps the leaf plain data: it survives JSON, so a layout
|
|
93
|
+
* holding it can be saved and exported. `run` is code the schema carries.
|
|
94
|
+
* A leaf with both fires `action`. While a promise `run` returned is
|
|
95
|
+
* pending, the button is disabled.
|
|
96
|
+
*/
|
|
97
|
+
interface PrefAction extends PrefBase<'action', undefined> {
|
|
98
|
+
/** The key of a registered action to fire: its id, or `id:variant` for one
|
|
99
|
+
* variant of a parametric action. The leaf's `name` and `icon` are what
|
|
100
|
+
* the button shows, over the registered action's own. */
|
|
101
|
+
action?: string;
|
|
102
|
+
/** What to call when no `action` is named. */
|
|
103
|
+
run?: (ctx: PrefActionContext) => void | Promise<void>;
|
|
104
|
+
/** The button's text. Default: the leaf's `name`. */
|
|
105
|
+
label?: string;
|
|
106
|
+
/** `button` reads its label; `icon` is the icon alone, with the label in
|
|
107
|
+
* its tooltip. Unset: a button in a row, an icon in a bar. */
|
|
108
|
+
control?: PrefActionControl;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* A second place for another leaf: its row draws that leaf's control and
|
|
113
|
+
* reads and writes that leaf's value, so one setting can sit on two pages.
|
|
114
|
+
* It holds no value of its own. A store neither reads nor writes one, and
|
|
115
|
+
* its path is not a {@link PrefPath}.
|
|
116
|
+
*
|
|
117
|
+
* `name` and `description` left empty are the target's.
|
|
118
|
+
*/
|
|
119
|
+
interface PrefAlias extends PrefBase<'alias', undefined> {
|
|
120
|
+
/** The leaf shown here, by the full path its value is read and written at (`'view.grid'`). */
|
|
121
|
+
of: string;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The leaf an alias stands for and the path its value lives at, following an
|
|
125
|
+
* alias of an alias to its end. `undefined` when a path along the way names
|
|
126
|
+
* no leaf, or the aliases lead back to one already passed.
|
|
127
|
+
*/
|
|
128
|
+
declare function prefAliasTarget(alias: PrefAlias, leafAt: (path: string) => PrefLeaf | undefined): {
|
|
129
|
+
path: string;
|
|
130
|
+
leaf: PrefLeaf;
|
|
131
|
+
} | undefined;
|
|
132
|
+
/**
|
|
133
|
+
* What an alias is called wherever one is drawn or named: its own name, else
|
|
134
|
+
* that of `target`, the leaf it shows, else `Alias` for one that shows
|
|
135
|
+
* nothing.
|
|
136
|
+
*/
|
|
137
|
+
declare function prefAliasName(alias: PrefAlias, target?: PrefLeaf): string;
|
|
138
|
+
/** A leaf drawn through an alias: the target, under the alias's own name and description where it gives them. */
|
|
139
|
+
declare function prefAliasedLeaf(alias: PrefAlias, target: PrefLeaf): PrefLeaf;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* A line of text among the rows, holding no value: `name` is the line and
|
|
143
|
+
* `description` the note under it. A store neither reads nor writes one, and
|
|
144
|
+
* its path is not a {@link PrefPath}.
|
|
145
|
+
*/
|
|
146
|
+
type PrefLabel = PrefBase<'label', undefined>;
|
|
147
|
+
/** A rule drawn between the rows, holding no value and drawing none of its own text. */
|
|
148
|
+
type PrefSeparator = PrefBase<'separator', undefined>;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* A leaf whose value is an array, every entry described by `item`.
|
|
152
|
+
*
|
|
153
|
+
* `item` is an ordinary leaf, built-in or app-defined, so a list of objects,
|
|
154
|
+
* of lists or of a custom kind is declared the way a list of numbers is, and
|
|
155
|
+
* each entry is validated and drawn as that leaf would be on its own. Its
|
|
156
|
+
* `default` is what a new entry starts as, and its `name` names one entry
|
|
157
|
+
* (`'Phase'` under a list named `'Phases'`).
|
|
158
|
+
*/
|
|
159
|
+
interface PrefList extends PrefBase<'list', readonly unknown[]> {
|
|
160
|
+
item: PrefLeaf;
|
|
161
|
+
/** A stored list shorter than this reads as the default, and a UI stops removing at it. */
|
|
162
|
+
minItems?: number;
|
|
163
|
+
/** A stored list longer than this reads cut to it, and a UI stops adding at it. */
|
|
164
|
+
maxItems?: number;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* A leaf whose value is an object keyed by strings nobody declared, every
|
|
169
|
+
* value described by `item`: the keyed counterpart of a {@link PrefList}.
|
|
170
|
+
* `item` is an ordinary leaf of any kind; its `default` is what a new entry
|
|
171
|
+
* starts as, and its `name` names one entry's value.
|
|
172
|
+
*/
|
|
173
|
+
interface PrefMap extends PrefBase<'map', Readonly<Record<string, unknown>>> {
|
|
174
|
+
item: PrefLeaf;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* A leaf whose value is one of several object shapes, told apart by the
|
|
179
|
+
* string its `tag` field holds: `{ type: 'linear', angle: 90 }` or
|
|
180
|
+
* `{ type: 'radial', radius: 1 }` under `tag: 'type'`.
|
|
181
|
+
*
|
|
182
|
+
* Each variant is an `object` leaf keyed by its tag value. Its `children`
|
|
183
|
+
* are the fields beside the tag, its `name` is what a person chooses, and
|
|
184
|
+
* its `default` (without the tag) is what the value becomes when they choose
|
|
185
|
+
* it. A stored value whose tag names no variant reads as the leaf's default.
|
|
186
|
+
*/
|
|
187
|
+
interface PrefUnion extends PrefBase<'union', unknown> {
|
|
188
|
+
tag: string;
|
|
189
|
+
variants: Record<string, PrefObject>;
|
|
190
|
+
}
|
|
191
|
+
/** The variant `value` is, or `undefined` when its tag names none. */
|
|
192
|
+
declare function prefVariantOf(leaf: PrefUnion, value: unknown): [key: string, variant: PrefObject] | undefined;
|
|
193
|
+
/** The value a union takes on switching to the variant at `key`: that variant's default, tagged. */
|
|
194
|
+
declare function prefVariantDefault(leaf: PrefUnion, key: string): Record<string, unknown>;
|
|
195
|
+
|
|
196
|
+
/** What both forms of a unit say about the text around the number. */
|
|
197
|
+
interface PrefUnitText {
|
|
198
|
+
/** Shown after the input, e.g. `'°'`. */
|
|
199
|
+
suffix?: string;
|
|
200
|
+
/** Suffixes a person may type, each mapped to the scale that turns a
|
|
201
|
+
* number in that unit into a display number: `{ mm: 0.1, cm: 1 }` for a
|
|
202
|
+
* field showing centimeters. A unit that disagrees with the display unit
|
|
203
|
+
* about zero carries an `offset` as well. */
|
|
204
|
+
accepts?: Readonly<Record<string, UnitEntry>>;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* A display unit as data, for a conversion that is linear: `stored = display * scale + offset`, the direction a
|
|
208
|
+
* `UnitEntry` runs toward its base, so `scale` is what one display unit is worth in stored units. Degrees shown
|
|
209
|
+
* over radians stored is `{ suffix: '°', scale: Math.PI / 180 }`, and `{ scale: 1 }` changes nothing. Being data,
|
|
210
|
+
* it is written to JSON, printed in a schema literal, and edited in `PrefSchemaEditor` like any other attribute.
|
|
211
|
+
*/
|
|
212
|
+
interface PrefLinearUnit extends PrefUnitText {
|
|
213
|
+
/** Stored units per display unit. Never 0. */
|
|
214
|
+
scale: number;
|
|
215
|
+
/** The stored value a display of 0 stands for. Absent is 0. */
|
|
216
|
+
offset?: number;
|
|
217
|
+
/** Decimal places the shown value is rounded to. Absent, the value shows unrounded and formats to two places.
|
|
218
|
+
* What is typed is stored unrounded either way. */
|
|
219
|
+
precision?: number;
|
|
220
|
+
}
|
|
221
|
+
/** A display unit as code, for a conversion that is not linear. It cannot be written to JSON or edited as data. */
|
|
222
|
+
interface PrefFunctionUnit extends PrefUnitText {
|
|
223
|
+
toDisplay: (stored: number) => number;
|
|
224
|
+
fromDisplay: (display: number) => number;
|
|
225
|
+
/** The stored value as display text, suffix included. */
|
|
226
|
+
format?: (stored: number) => string;
|
|
227
|
+
}
|
|
228
|
+
/** Display-unit conversion for number leaves whose stored value uses a
|
|
229
|
+
* canonical unit the user shouldn't see (e.g. radians stored, degrees
|
|
230
|
+
* shown). Read one through {@link resolvePrefUnit}, which answers for both forms. */
|
|
231
|
+
type PrefNumberUnit = PrefLinearUnit | PrefFunctionUnit;
|
|
232
|
+
/** A unit of either form as the functions that convert and format with it. */
|
|
233
|
+
interface ResolvedPrefUnit extends PrefFunctionUnit {
|
|
234
|
+
format: (stored: number) => string;
|
|
235
|
+
}
|
|
236
|
+
/** Whether `unit` is the data form, and so can be written out and edited. */
|
|
237
|
+
declare function isPrefLinearUnit(unit: PrefNumberUnit): unit is PrefLinearUnit;
|
|
238
|
+
/** How to convert and format with `unit`, whichever form it was written in. */
|
|
239
|
+
declare function resolvePrefUnit(unit: PrefNumberUnit): ResolvedPrefUnit;
|
|
240
|
+
/**
|
|
241
|
+
* A display unit built from a {@link UnitSystem}: values are stored in the
|
|
242
|
+
* system's base and shown in `display`, rounded to `precision` places when
|
|
243
|
+
* given, and every unit in the system is accepted as typed text. `suffix`
|
|
244
|
+
* defaults to the unit's name and is accepted too. Every unit of a system is
|
|
245
|
+
* linear, so what comes back is data.
|
|
246
|
+
*/
|
|
247
|
+
declare function prefUnit(system: UnitSystem, display: Unit, opts?: {
|
|
248
|
+
precision?: number;
|
|
249
|
+
suffix?: string;
|
|
250
|
+
}): PrefLinearUnit;
|
|
251
|
+
|
|
252
|
+
/** The value types a built-in pref leaf can hold. */
|
|
253
|
+
type PrefKind = 'number' | 'boolean' | 'string' | 'enum' | 'color' | 'paint' | 'object' | 'list' | 'map' | 'union' | 'field' | 'action' | 'alias' | 'label' | 'separator';
|
|
254
|
+
/** Leaves that share one row in a compact property UI, declared on the first
|
|
255
|
+
* of them. Purely presentational. */
|
|
256
|
+
interface PrefPair {
|
|
257
|
+
/** The other leaves on the row, by the full path their values are read and
|
|
258
|
+
* written at (`'pose.y'`, `'camera.type'`), in order. Each must follow the
|
|
259
|
+
* one before it among its siblings. */
|
|
260
|
+
with: string | readonly string[];
|
|
261
|
+
/** What the row reads. Default: the declaring leaf's `name`. */
|
|
262
|
+
label?: string;
|
|
263
|
+
}
|
|
264
|
+
/** The fields every leaf pref shares, keyed by its `kind` and typed by its stored value. */
|
|
265
|
+
interface PrefBase<K extends string, Value> {
|
|
266
|
+
kind: K;
|
|
267
|
+
/** Human-readable label. */
|
|
268
|
+
name: string;
|
|
269
|
+
/** Longer help text — shown in tooltips / a settings pane. */
|
|
270
|
+
description: string;
|
|
271
|
+
/** Fallback when nothing is persisted. */
|
|
272
|
+
default: Value;
|
|
273
|
+
/** Hide from a host app's settings UI by default. */
|
|
274
|
+
hidden?: boolean;
|
|
275
|
+
/** Drawn only while this holds. Presentational: the value stays stored
|
|
276
|
+
* and readable while the leaf is not drawn. */
|
|
277
|
+
showIf?: PrefCondition;
|
|
278
|
+
/** Drawn, and disabled while this does not hold. */
|
|
279
|
+
enableIf?: PrefCondition;
|
|
280
|
+
/** Nothing held where this leaf's value is read means `default`, because
|
|
281
|
+
* whoever reads the value takes it that way (`pose.rotation ?? 0`). A
|
|
282
|
+
* surface over sparse settings reads every leaf so already. One over a
|
|
283
|
+
* scene node, where a missing key otherwise means the node has no such
|
|
284
|
+
* property, shows the default only for a leaf that says this, and still
|
|
285
|
+
* writes nothing until an edit. */
|
|
286
|
+
absentIsDefault?: boolean;
|
|
287
|
+
/** Render full-width with no label row in schema-driven settings UIs
|
|
288
|
+
* (weasel-ui `PrefsForm` honors this for leaves whose control brings
|
|
289
|
+
* its own chrome). */
|
|
290
|
+
block?: boolean;
|
|
291
|
+
/** Glyph naming this leaf in a host UI's icon set (weasel-ui resolves it
|
|
292
|
+
* against `ICON_PATHS`). A plain string because this package ships no
|
|
293
|
+
* icon set and cannot depend on one. Read where a leaf's `name` has nowhere to go — a
|
|
294
|
+
* `pair`ed row is labeled by the pair, so its fields have only the glyph
|
|
295
|
+
* to tell them apart. */
|
|
296
|
+
icon?: string;
|
|
297
|
+
/** Puts this leaf and the ones it names on one row. */
|
|
298
|
+
pair?: PrefPair;
|
|
299
|
+
/** Shorter forms of `name`, longest first. A surface short of room for
|
|
300
|
+
* `name` — a strip of controls on one line, a segment in a `pair`ed row —
|
|
301
|
+
* shows the longest of them that fits. `name` stays the accessible name, so
|
|
302
|
+
* these abbreviate without costing anything. */
|
|
303
|
+
short?: readonly string[];
|
|
304
|
+
/** Never auto. A surface that lets a leaf be left for its owner to decide
|
|
305
|
+
* (weasel-ui `PrefsForm`'s `onAutoChange`, labkit's `ControlPanel`) gives
|
|
306
|
+
* this one no way to. */
|
|
307
|
+
manual?: boolean;
|
|
308
|
+
/** Starts auto, where it would start pinned at `default`. */
|
|
309
|
+
unpinned?: boolean;
|
|
310
|
+
/** What the leaf reads while it is auto, where its owner computes nothing
|
|
311
|
+
* for it. Unset, an auto leaf has no value. */
|
|
312
|
+
autoValue?: Value;
|
|
313
|
+
/** The name of the type this leaf was made from, set by `prefType`. A
|
|
314
|
+
* schema editor shows such a leaf as one closed thing and prints the name
|
|
315
|
+
* in place of its literal. */
|
|
316
|
+
type?: string;
|
|
317
|
+
}
|
|
318
|
+
/** How a schema-driven UI should present a number pref. */
|
|
319
|
+
type PrefNumberControl = 'input' | 'slider';
|
|
320
|
+
/** How a schema-driven UI should present a boolean pref. */
|
|
321
|
+
type PrefBooleanControl = 'checkbox' | 'switch' | 'toggle';
|
|
322
|
+
/** How a schema-driven UI should present a string pref. */
|
|
323
|
+
type PrefStringControl = 'input' | 'textarea';
|
|
324
|
+
/** How a schema-driven UI should present an enum pref. */
|
|
325
|
+
type PrefEnumControl = 'select' | 'radio' | 'toggle' | 'menu';
|
|
326
|
+
/** A numeric pref, optionally bounded and stepped, and optionally stored in a
|
|
327
|
+
* different unit from the one shown. */
|
|
328
|
+
interface PrefNumber extends PrefBase<'number', number> {
|
|
329
|
+
min?: number;
|
|
330
|
+
max?: number;
|
|
331
|
+
step?: number;
|
|
332
|
+
control?: PrefNumberControl;
|
|
333
|
+
/** How the value shows, speaks and reads back when typed — `compact()`
|
|
334
|
+
* reads `2.00M`. Presentation only: the stored value stays a number. */
|
|
335
|
+
display?: Display;
|
|
336
|
+
unit?: PrefNumberUnit;
|
|
337
|
+
/** Which end of a slider gets a stop for ±Infinity, one step beyond the range. */
|
|
338
|
+
endless?: 'min' | 'max' | 'both';
|
|
339
|
+
/** The word infinity shows as — `'never'`, `'uncapped'`. Default `∞`. */
|
|
340
|
+
infinity?: InfinityText;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Stored-value bridge for a boolean leaf whose field is not a boolean — the
|
|
344
|
+
* flag counterpart of {@link PrefEnumEncoding}. `TextStyle.fontStyle` is
|
|
345
|
+
* the case: it stores `'italic'`, and the control is an Italic toggle.
|
|
346
|
+
*/
|
|
347
|
+
interface PrefBooleanEncoding {
|
|
348
|
+
/** Whether `stored` reads as on. */
|
|
349
|
+
read: (stored: unknown, siblings: Record<string, unknown> | undefined) => boolean;
|
|
350
|
+
/** What to store for `on`. `undefined` removes the field. */
|
|
351
|
+
write: (on: boolean, siblings: Record<string, unknown> | undefined) => unknown;
|
|
352
|
+
}
|
|
353
|
+
/** An on/off pref. */
|
|
354
|
+
interface PrefBoolean extends PrefBase<'boolean', boolean> {
|
|
355
|
+
control?: PrefBooleanControl;
|
|
356
|
+
encoding?: PrefBooleanEncoding;
|
|
357
|
+
}
|
|
358
|
+
/** A free-text pref. */
|
|
359
|
+
interface PrefString extends PrefBase<'string', string> {
|
|
360
|
+
control?: PrefStringControl;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Stored-value bridge for an enum leaf whose value is not the option string —
|
|
364
|
+
* the counterpart of {@link PrefNumberUnit}, which does the same for a
|
|
365
|
+
* number stored in a canonical unit.
|
|
366
|
+
*
|
|
367
|
+
* A dash array is the case that needs it: `Stroke.dash` stores lengths, and
|
|
368
|
+
* the thing a person chooses is a style. The presets scale by the stroke's
|
|
369
|
+
* width, so both directions are given the object's other fields.
|
|
370
|
+
*/
|
|
371
|
+
interface PrefEnumEncoding<T extends string = string> {
|
|
372
|
+
/**
|
|
373
|
+
* The option `stored` reads as, or `undefined` for none — which a UI shows
|
|
374
|
+
* the way it shows a mixed selection, by selecting nothing.
|
|
375
|
+
*
|
|
376
|
+
* `siblings` is the object the leaf is a field of, or `undefined` when the
|
|
377
|
+
* node does not hold that object (and for a top-level leaf, which has none).
|
|
378
|
+
*/
|
|
379
|
+
read: (stored: unknown, siblings: Record<string, unknown> | undefined) => T | undefined;
|
|
380
|
+
/** What to store for `option`. `undefined` removes the field. */
|
|
381
|
+
write: (option: T, siblings: Record<string, unknown> | undefined) => unknown;
|
|
382
|
+
}
|
|
383
|
+
/** What every enum leaf carries; {@link PrefEnum} adds `clearable`. */
|
|
384
|
+
interface PrefEnumBase<T extends string = string> extends PrefBase<'enum', T | undefined> {
|
|
385
|
+
/** `short` holds shorter forms of `label`, longest first, for a segmented
|
|
386
|
+
* control too narrow for the full one — down to a capital or two. `icon`
|
|
387
|
+
* names a glyph in the host UI's set (weasel-ui resolves it against
|
|
388
|
+
* `ICON_PATHS`), drawn in place of any text form where it resolves. It is
|
|
389
|
+
* a plain string because this package ships no icon set and cannot
|
|
390
|
+
* depend on one. The full `label` stays the accessible name, so neither the abbreviation nor the glyph becomes the only thing naming
|
|
391
|
+
* the option.
|
|
392
|
+
*
|
|
393
|
+
* `disabled` marks an option a control reports but cannot author — the
|
|
394
|
+
* value a stored form reads as when it matches nothing offered. Dropping it
|
|
395
|
+
* from the list instead would leave the control selecting nothing and
|
|
396
|
+
* claiming the field is unset. */
|
|
397
|
+
options: readonly {
|
|
398
|
+
value: T;
|
|
399
|
+
label: string;
|
|
400
|
+
short?: readonly string[];
|
|
401
|
+
icon?: string;
|
|
402
|
+
disabled?: boolean;
|
|
403
|
+
}[];
|
|
404
|
+
control?: PrefEnumControl;
|
|
405
|
+
encoding?: PrefEnumEncoding<T>;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* A pref with a fixed set of labeled choices.
|
|
409
|
+
*
|
|
410
|
+
* `clearable` says the field may hold none of the options, and that absence
|
|
411
|
+
* is a state of its own rather than a missing value — a script that is
|
|
412
|
+
* neither super nor sub. A toggle control then lets the chosen segment be
|
|
413
|
+
* clicked off, which removes the field. Such a leaf's `default` is
|
|
414
|
+
* `undefined`: a missing value is the only stored form of cleared, so a
|
|
415
|
+
* default would bring an option back the moment the field was cleared.
|
|
416
|
+
*/
|
|
417
|
+
type PrefEnum<T extends string = string> = PrefEnumBase<T> & ({
|
|
418
|
+
clearable?: false;
|
|
419
|
+
} | {
|
|
420
|
+
clearable: true;
|
|
421
|
+
default: undefined;
|
|
422
|
+
});
|
|
423
|
+
/** A single color, stored as a hex string. For a value that may also be a
|
|
424
|
+
* gradient or a pattern, use {@link PrefPaint} instead. */
|
|
425
|
+
interface PrefColor extends PrefBase<'color', string> {
|
|
426
|
+
/** Value is `#rrggbb`, or `#rrggbbaa` when `alpha` is set (UIs then
|
|
427
|
+
* offer an opacity control). */
|
|
428
|
+
alpha?: boolean;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Open leaf: any node with a `kind` outside the built-ins. Schema-driven
|
|
432
|
+
* UIs dispatch it to an app-supplied renderer. Deliberately NOT
|
|
433
|
+
* index-signatured so concrete app interfaces stay assignable.
|
|
434
|
+
*/
|
|
435
|
+
type PrefCustom = PrefBase<string, unknown>;
|
|
436
|
+
/**
|
|
437
|
+
* A whole `Paint`, not a color inside one. Use it wherever the value is
|
|
438
|
+
* the tagged paint union — a solid color, a pattern, a gradient — rather
|
|
439
|
+
* than a hex string.
|
|
440
|
+
*
|
|
441
|
+
* Addressing `…fill.color` instead reads `undefined` off a gradient (so the
|
|
442
|
+
* control shows its default and claims the text is black) and writes a
|
|
443
|
+
* hybrid `{ fill: 'gradient', stops, color }` that the renderer's structural
|
|
444
|
+
* `'color' in paint` checks then paint flat solid. The union has to be
|
|
445
|
+
* edited as a union.
|
|
446
|
+
*/
|
|
447
|
+
interface PrefPaint extends PrefBase<'paint', unknown> {
|
|
448
|
+
/** Offer an opacity control alongside the color. */
|
|
449
|
+
alpha?: boolean;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* A leaf whose value is one object, with its own fields hanging off it as
|
|
453
|
+
* `children`; every edit commits the parent object whole. Sibling leaves
|
|
454
|
+
* addressing into the value (`data.stroke.width`, `data.stroke.cap`) would
|
|
455
|
+
* each write one field of a value they can only half see, and writing into
|
|
456
|
+
* something that is not an object yet corrupts it.
|
|
457
|
+
*
|
|
458
|
+
* `children` paths are relative to the object. They are ordinary leaves, so a
|
|
459
|
+
* field that is itself a union (a stroke's `paint`) declares the kind that
|
|
460
|
+
* edits that union. A child may also be a {@link PrefSection}, which
|
|
461
|
+
* organizes the fields under a heading without contributing to the path.
|
|
462
|
+
*/
|
|
463
|
+
interface PrefObject extends PrefBase<'object', unknown> {
|
|
464
|
+
children: Record<string, PrefLeaf | PrefSection>;
|
|
465
|
+
/**
|
|
466
|
+
* Lift a non-object value into the object form, for a consumer field that
|
|
467
|
+
* may also be held as a scalar. Called before a child edit is applied;
|
|
468
|
+
* without it a scalar-valued leaf shows its children empty, and an edit
|
|
469
|
+
* starts from the leaf's `default`.
|
|
470
|
+
*/
|
|
471
|
+
fromScalar?: (value: unknown) => Record<string, unknown>;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* A reference to another field of the same schema, held as the full path its
|
|
475
|
+
* value is read and written at (`'camera.type'`) — the currency fields refer
|
|
476
|
+
* to each other in. A surface offers the fields it draws as the choices.
|
|
477
|
+
*/
|
|
478
|
+
interface PrefField extends PrefBase<'field', string> {
|
|
479
|
+
/** Only fields of these kinds may be named. Default: any leaf. */
|
|
480
|
+
kinds?: readonly string[];
|
|
481
|
+
}
|
|
482
|
+
/** One built-in pref leaf. `PrefLeaf` widens this to include
|
|
483
|
+
* app-defined kinds. */
|
|
484
|
+
type BuiltinPref = PrefNumber | PrefBoolean | PrefString | PrefEnum | PrefColor | PrefPaint | PrefObject | PrefList | PrefMap | PrefUnion | PrefField | PrefAction | PrefAlias | PrefLabel | PrefSeparator;
|
|
485
|
+
/**
|
|
486
|
+
* The built-in kinds, as a table. A kind added to {@link PrefKind} is a
|
|
487
|
+
* compile error here, and from here it is one in every renderer's `never`
|
|
488
|
+
* guard.
|
|
489
|
+
*/
|
|
490
|
+
declare const PREF_KINDS: Record<PrefKind, true>;
|
|
491
|
+
/** Which row each pairing among `leaves` puts a path on: a `key` the row's
|
|
492
|
+
* members share (the declaring leaf's path) and the `label` it reads. A
|
|
493
|
+
* path no `pair` names is absent. `leaves` are given by the path each
|
|
494
|
+
* surface reads and writes them at, so references resolve in its terms. */
|
|
495
|
+
declare function pairRowsOf(leaves: Iterable<readonly [path: string, leaf: PrefLeaf]>): Map<string, {
|
|
496
|
+
key: string;
|
|
497
|
+
label: string;
|
|
498
|
+
}>;
|
|
499
|
+
/**
|
|
500
|
+
* Narrows a leaf to the built-in union, so a renderer's switch discriminates
|
|
501
|
+
* on {@link PrefKind} instead of the open `string` that
|
|
502
|
+
* {@link PrefCustom} widens `kind` to. An app-defined kind answers false
|
|
503
|
+
* and belongs to the renderer's custom-renderer path.
|
|
504
|
+
*/
|
|
505
|
+
declare function isBuiltinPref(leaf: PrefLeaf): leaf is BuiltinPref;
|
|
506
|
+
/** Built-in or app-defined leaf. */
|
|
507
|
+
type PrefLeaf = BuiltinPref | PrefCustom;
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* How a {@link PrefGroup} is drawn: `page` gets an entry in a form's rail and
|
|
511
|
+
* a pane of its own; `tab` shares a tab strip with the `tab` groups beside it;
|
|
512
|
+
* `panel` is a bordered, titled box; `section` is a heading over its rows;
|
|
513
|
+
* `fragment` draws nothing of its own, so its rows sit among its neighbors'
|
|
514
|
+
* as though they were written there. A fragment exists to hold things
|
|
515
|
+
* together: one key for their values to nest under, one node to move.
|
|
516
|
+
*/
|
|
517
|
+
type PrefGroupAs = 'page' | 'tab' | 'panel' | 'section' | 'fragment' | 'bar';
|
|
518
|
+
/** How a {@link PrefSection} is drawn. */
|
|
519
|
+
type PrefSectionAs = Exclude<PrefGroupAs, 'page'>;
|
|
520
|
+
/**
|
|
521
|
+
* A group whose key is a path segment: `view` > `gridDensity` is the leaf at
|
|
522
|
+
* `view.gridDensity`, and its value nests the same way. The shape of a
|
|
523
|
+
* preferences schema — what `openPrefs` stores, `PrefsForm` renders, and a
|
|
524
|
+
* tool declares its options as. A key holds no `.`.
|
|
525
|
+
*/
|
|
526
|
+
interface PrefGroup {
|
|
527
|
+
/** Heading for the group's rows. **Empty means no heading** — for a group
|
|
528
|
+
* that exists to organize, not to name: one whose children are themselves
|
|
529
|
+
* groups carrying the labels a reader needs. Give it a name whenever the
|
|
530
|
+
* name is the referent (a `Border` group over `Top` / `Right` / `Bottom`
|
|
531
|
+
* reads as nothing without it). */
|
|
532
|
+
name: string;
|
|
533
|
+
description?: string;
|
|
534
|
+
/** How the group is drawn. Unset, its depth decides: a top-level group is a
|
|
535
|
+
* `page`, and one inside another is a `section`. */
|
|
536
|
+
as?: PrefGroupAs;
|
|
537
|
+
/** Drawn, with everything under it, only while this holds. */
|
|
538
|
+
showIf?: PrefCondition;
|
|
539
|
+
/** Everything under it is disabled while this does not hold. */
|
|
540
|
+
enableIf?: PrefCondition;
|
|
541
|
+
children: Record<string, PrefLeaf | PrefGroup>;
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* A heading over leaves that adds nothing to their paths: each member is
|
|
545
|
+
* addressed by its own key alone, and the section's key only identifies the
|
|
546
|
+
* section. The shape of a node's property schema, where a leaf's key is the
|
|
547
|
+
* whole dotted node path (`pose.x`, `data.fill`), and of the headings inside
|
|
548
|
+
* a {@link PrefObject}, where a key is relative to the object.
|
|
549
|
+
*/
|
|
550
|
+
interface PrefSection {
|
|
551
|
+
/** Heading for the section's rows. Empty means no heading, as for a
|
|
552
|
+
* {@link PrefGroup}. */
|
|
553
|
+
name: string;
|
|
554
|
+
description?: string;
|
|
555
|
+
/** How the section is drawn, as a {@link PrefGroup}'s `as` — without
|
|
556
|
+
* `page`, since nothing that draws sections has a rail. Unset: a heading
|
|
557
|
+
* over its rows. */
|
|
558
|
+
as?: PrefSectionAs;
|
|
559
|
+
/** As a {@link PrefGroup}'s. */
|
|
560
|
+
showIf?: PrefCondition;
|
|
561
|
+
/** As a {@link PrefGroup}'s. */
|
|
562
|
+
enableIf?: PrefCondition;
|
|
563
|
+
members: Record<string, PrefLeaf | PrefSection>;
|
|
564
|
+
}
|
|
565
|
+
/** Whether a top-level group gets a page of its own, and not a place on the page of the root's own leaves. */
|
|
566
|
+
declare function prefGroupIsPage(group: PrefGroup): boolean;
|
|
567
|
+
|
|
568
|
+
type Join<A extends string, B extends string> = A extends '' ? B : `${A}.${B}`;
|
|
569
|
+
/** Every value's dotted path in a `PrefGroup` schema, where a group's key is a
|
|
570
|
+
* segment; an `object` leaf is one path, its fields are not, and an `action`,
|
|
571
|
+
* `alias`, `label`, or `separator` leaf, holding no value, has none. A `PrefSection`
|
|
572
|
+
* has no such paths: each of its leaves is addressed by its own key. */
|
|
573
|
+
type PrefPath<G, Prefix extends string = ''> = G extends {
|
|
574
|
+
children: infer C;
|
|
575
|
+
} ? string extends keyof C ? Join<Prefix, string> : {
|
|
576
|
+
[K in keyof C & string]: C[K] extends {
|
|
577
|
+
kind: string;
|
|
578
|
+
} ? C[K] extends {
|
|
579
|
+
kind: 'action' | 'alias' | 'label' | 'separator';
|
|
580
|
+
} ? never : Join<Prefix, K> : C[K] extends {
|
|
581
|
+
children: Record<string, unknown>;
|
|
582
|
+
} ? PrefPath<C[K], Join<Prefix, K>> : never;
|
|
583
|
+
}[keyof C & string] : never;
|
|
584
|
+
/** The leaf at `P`. */
|
|
585
|
+
type PrefAtPath<G, P extends string> = G extends {
|
|
586
|
+
children: infer C;
|
|
587
|
+
} ? P extends `${infer H}.${infer Rest}` ? H extends keyof C ? C[H] extends {
|
|
588
|
+
kind: string;
|
|
589
|
+
} ? never : PrefAtPath<C[H], Rest> : never : P extends keyof C ? C[P] extends {
|
|
590
|
+
kind: string;
|
|
591
|
+
} ? C[P] : never : never : never;
|
|
592
|
+
type AllOf<U> = (U extends unknown ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
|
|
593
|
+
/** The fields an `object` leaf's `children` describe, sections folded in. Each is optional: an object may omit any. */
|
|
594
|
+
type PrefFieldsOf<C> = {
|
|
595
|
+
[K in keyof C as C[K] extends {
|
|
596
|
+
kind: string;
|
|
597
|
+
} ? K : never]?: PrefValueOf<C[K]>;
|
|
598
|
+
} & AllOf<{
|
|
599
|
+
[K in keyof C]: C[K] extends {
|
|
600
|
+
members: infer M;
|
|
601
|
+
} ? PrefFieldsOf<M> : never;
|
|
602
|
+
}[keyof C]>;
|
|
603
|
+
/** What a leaf holds: its kind's value type for a built-in kind, the type of
|
|
604
|
+
* its `default` for an app-defined one. A list holds an array of what its
|
|
605
|
+
* `item` holds, a map a record of it, and a union one variant's fields
|
|
606
|
+
* under that variant's tag — where the schema keeps `tag` a literal
|
|
607
|
+
* (`tag: 'type' as const`); one widened to `string` is typed by its default. */
|
|
608
|
+
type PrefValueOf<L> = L extends {
|
|
609
|
+
kind: 'number';
|
|
610
|
+
} ? number : L extends {
|
|
611
|
+
kind: 'boolean';
|
|
612
|
+
} ? boolean : L extends {
|
|
613
|
+
kind: 'string' | 'color' | 'field';
|
|
614
|
+
} ? string : L extends {
|
|
615
|
+
kind: 'paint';
|
|
616
|
+
} ? unknown : L extends {
|
|
617
|
+
kind: 'enum';
|
|
618
|
+
options: readonly {
|
|
619
|
+
value: infer T;
|
|
620
|
+
}[];
|
|
621
|
+
} ? L extends {
|
|
622
|
+
clearable: true;
|
|
623
|
+
} ? T | undefined : T : L extends {
|
|
624
|
+
kind: 'list';
|
|
625
|
+
item: infer I;
|
|
626
|
+
} ? PrefValueOf<I>[] : L extends {
|
|
627
|
+
kind: 'map';
|
|
628
|
+
item: infer I;
|
|
629
|
+
} ? Record<string, PrefValueOf<I>> : L extends {
|
|
630
|
+
kind: 'union';
|
|
631
|
+
tag: infer T extends string;
|
|
632
|
+
variants: infer V;
|
|
633
|
+
default: infer D;
|
|
634
|
+
} ? string extends keyof V | T ? D : {
|
|
635
|
+
[K in keyof V & string]: {
|
|
636
|
+
[P in T]: K;
|
|
637
|
+
} & (V[K] extends {
|
|
638
|
+
children: infer C;
|
|
639
|
+
} ? PrefFieldsOf<C> : unknown);
|
|
640
|
+
}[keyof V & string] : L extends {
|
|
641
|
+
default: infer D;
|
|
642
|
+
} ? D : unknown;
|
|
643
|
+
/** What the leaf at `P` holds. */
|
|
644
|
+
type PrefValueAt<G, P extends string> = PrefValueOf<PrefAtPath<G, P>>;
|
|
645
|
+
|
|
646
|
+
/** Takes stored values from one version to the next: rename, transform or
|
|
647
|
+
* delete entries in `records`, keyed by leaf path. It sees the values, not
|
|
648
|
+
* the stamps they are stored under, and only those at its own version. */
|
|
649
|
+
type PrefsMigration = (records: Map<string, unknown>) => void;
|
|
650
|
+
|
|
651
|
+
/** Decides what a stored value reads as for one kind of leaf: the value to
|
|
652
|
+
* read, or `undefined` for "invalid, read the default". */
|
|
653
|
+
type PrefValidator = (stored: unknown, leaf: PrefLeaf) => unknown;
|
|
654
|
+
/** What `stored` reads as for `leaf`. Never writes anything back: a schema
|
|
655
|
+
* rolled back finds the original still in storage. */
|
|
656
|
+
declare function repairPrefValue(leaf: PrefLeaf, stored: unknown, validators?: Readonly<Record<string, PrefValidator>>): unknown;
|
|
657
|
+
|
|
658
|
+
/** One leaf changing, as a store subscriber hears it: the value readers now
|
|
659
|
+
* see, and whether this store or another writer made the change. */
|
|
660
|
+
interface PrefChange {
|
|
661
|
+
path: string;
|
|
662
|
+
value: unknown;
|
|
663
|
+
origin: 'local' | 'remote';
|
|
664
|
+
}
|
|
665
|
+
/** Values for one schema, held in memory and persisted behind. */
|
|
666
|
+
interface PrefsStore<S extends PrefGroup> {
|
|
667
|
+
readonly schema: S;
|
|
668
|
+
/** The leaf's value, repaired against the schema; its default when unset. */
|
|
669
|
+
get<P extends PrefPath<S>>(path: P): PrefValueAt<S, P>;
|
|
670
|
+
set<P extends PrefPath<S>>(path: P, value: PrefValueAt<S, P>): void;
|
|
671
|
+
/** Unset every leaf at or under `path`; with no path, all. */
|
|
672
|
+
reset(path?: string): void;
|
|
673
|
+
/** Whether the leaf has a value of its own rather than following its default. */
|
|
674
|
+
isSet(path: PrefPath<S>): boolean;
|
|
675
|
+
/** Every leaf's value as a nested tree. The same object until something changes. */
|
|
676
|
+
values(): Record<string, unknown>;
|
|
677
|
+
/** The leaves following their default. The same set until something changes. */
|
|
678
|
+
unset(): ReadonlySet<string>;
|
|
679
|
+
/** Every stored record as a nested tree, unrepaired, including records no
|
|
680
|
+
* leaf describes. The same object until something changes. */
|
|
681
|
+
stored(): Record<string, unknown>;
|
|
682
|
+
/** `changes` is empty when only records no leaf describes changed. */
|
|
683
|
+
subscribe(listener: (changes: PrefChange[]) => void): () => void;
|
|
684
|
+
/** False while the store cannot persist: storage has not been read yet, or
|
|
685
|
+
* was written by a newer schema. Changes still apply for this session, and
|
|
686
|
+
* ones made before a late read lands are persisted when it does. False for
|
|
687
|
+
* good once the store is closed. */
|
|
688
|
+
readonly writable: boolean;
|
|
689
|
+
/** True once `close` was called. A write after that changes what this store
|
|
690
|
+
* reads and reaches neither storage nor its subscribers, and the first one
|
|
691
|
+
* warns. */
|
|
692
|
+
readonly closed: boolean;
|
|
693
|
+
/** Try again now to read storage that could not be read at open, ahead of
|
|
694
|
+
* the store's own retries. Resolves whether storage has been read. */
|
|
695
|
+
read(): Promise<boolean>;
|
|
696
|
+
/** Resolves once storage has been read: at once for a store that opened
|
|
697
|
+
* with its values, and when a later read lands for one that could not. */
|
|
698
|
+
whenRead(): Promise<void>;
|
|
699
|
+
/** Resolves true when every queued write reached storage. */
|
|
700
|
+
flush(): Promise<boolean>;
|
|
701
|
+
close(): Promise<void>;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/** Options for `openPrefs` and `openPrefsSync`. */
|
|
705
|
+
interface PrefsOptions {
|
|
706
|
+
storage: StorageAdapter;
|
|
707
|
+
/** Prepended to every record's key: `'myapp.prefs.'`. */
|
|
708
|
+
prefix: string;
|
|
709
|
+
/** `migrations[i]` takes stored records from version `i` to `i + 1`. The
|
|
710
|
+
* current version is `migrations.length`. */
|
|
711
|
+
migrations?: readonly PrefsMigration[];
|
|
712
|
+
/** Validators for app-defined kinds, keyed by `kind`. One given for a
|
|
713
|
+
* built-in kind replaces that kind's own rule. */
|
|
714
|
+
validators?: Readonly<Record<string, PrefValidator>>;
|
|
715
|
+
}
|
|
716
|
+
/** Load every stored value for `schema`, migrate it, and return the store. */
|
|
717
|
+
declare function openPrefs<S extends PrefGroup>(schema: S, options: PrefsOptions): Promise<PrefsStore<S>>;
|
|
718
|
+
/** `openPrefs` for an adapter that reads synchronously: the store is ready
|
|
719
|
+
* on return, so values can be read before anything renders. */
|
|
720
|
+
declare function openPrefsSync<S extends PrefGroup>(schema: S, options: PrefsOptions & {
|
|
721
|
+
storage: SyncStorageAdapter;
|
|
722
|
+
}): PrefsStore<S>;
|
|
723
|
+
|
|
724
|
+
export { isPrefCondition as $, type PrefEnumEncoding as A, type BuiltinPref as B, type PrefField as C, type PrefFunctionUnit as D, type PrefGroupAs as E, type PrefLabel as F, type PrefLinearUnit as G, type PrefNumberControl as H, type PrefNumberUnit as I, type PrefPaint as J, type PrefPair as K, type PrefPath as L, type PrefSectionAs as M, type PrefSeparator as N, type PrefString as O, type PrefLeaf as P, type PrefStringControl as Q, type PrefTest as R, type PrefUnion as S, type PrefValidator as T, type PrefValueAt as U, type PrefValueOf as V, type PrefsMigration as W, type PrefsOptions as X, type PrefsStore as Y, type ResolvedPrefUnit as Z, isBuiltinPref as _, type PrefGroup as a, isPrefLinearUnit as a0, mapPrefConditionPaths as a1, openPrefs as a2, openPrefsSync as a3, pairRowsOf as a4, prefAliasName as a5, prefAliasTarget as a6, prefAliasedLeaf as a7, prefConditionHolds as a8, prefConditionPaths as a9, prefConditionReadsItem as aa, prefGroupIsPage as ab, prefIsEnabled as ac, prefIsShown as ad, prefUnit as ae, prefVariantDefault as af, prefVariantOf as ag, repairPrefValue as ah, resolvePrefUnit as ai, type PrefSection as b, type PrefNumber as c, type PrefList as d, type PrefMap as e, type PrefCondition as f, type PrefConditionReader as g, type PrefAlias as h, type PrefObject as i, type PrefKind as j, PREF_KINDS as k, type PrefAction as l, type PrefActionContext as m, type PrefActionControl as n, type PrefAtPath as o, type PrefBase as p, type PrefBoolean as q, type PrefBooleanControl as r, type PrefBooleanEncoding as s, type PrefChange as t, type PrefColor as u, type PrefConditionValue as v, type PrefCustom as w, type PrefEnum as x, type PrefEnumBase as y, type PrefEnumControl as z };
|