@weasel-js/prefs 1.10.1 → 1.11.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.
@@ -1,226 +1,7 @@
1
- import { formatUnit, unitScale } from '@weasel-js/quantity';
2
- import { isPlainObject, createEmitter } from '@weasel-js/registry';
3
- import { hexToRgba, interpolateSrgb, rgbaToHex } from '@weasel-js/paint';
1
+ import { isPrefSection, prefSectionLeaves, isPrefLeaf, kebab, prefLeaves, prefHoldsValue, checkPrefSplits, prefSelectors, createSnapshots, VERSION_RECORD, selectionAt, selectionWeights, resolveHeld, assignPrefValueAtPath, isPrefLocus, weightsUnder, recordValue, setOwnPrefValue, readRecord, stampRecord, joinLocus, splitLocus, mapLocusMembers, writeMember, prefVariantOf, repairLocus } from './chunk-OZFER7VN.js';
2
+ import { createEmitter, isPlainObject } from '@weasel-js/registry';
4
3
  import { openRecords, openRecordsSync } from '@weasel-js/storage';
5
4
 
6
- // src/alias.ts
7
- function prefAliasTarget(alias, leafAt) {
8
- const passed = /* @__PURE__ */ new Set();
9
- let path = alias.of;
10
- for (; ; ) {
11
- if (passed.has(path)) return void 0;
12
- passed.add(path);
13
- const leaf = leafAt(path);
14
- if (leaf === void 0) return void 0;
15
- if (leaf.kind !== "alias") return { path, leaf };
16
- path = leaf.of;
17
- }
18
- }
19
- function prefAliasName(alias, target) {
20
- if (alias.name !== "") return alias.name;
21
- return target === void 0 ? "Alias" : target.name;
22
- }
23
- function prefAliasedLeaf(alias, target) {
24
- return {
25
- ...target,
26
- name: prefAliasName(alias, target),
27
- description: alias.description === "" ? target.description : alias.description
28
- };
29
- }
30
- function isPrefLinearUnit(unit) {
31
- return typeof unit.toDisplay !== "function";
32
- }
33
- var SHOWN = "shown";
34
- function decimalPlaces(n) {
35
- const text = String(n);
36
- if (text.includes("e")) return void 0;
37
- const dot = text.indexOf(".");
38
- return dot === -1 ? 0 : text.length - dot - 1;
39
- }
40
- var DECIMAL_PLACES = 12;
41
- function storedOf(shown, scale, offset) {
42
- const raw = shown * scale + offset;
43
- const [a, b, c] = [decimalPlaces(shown), decimalPlaces(scale), decimalPlaces(offset)];
44
- if (a === void 0 || b === void 0 || c === void 0 || !Number.isFinite(raw)) return raw;
45
- const places = Math.max(a + b, c);
46
- return places > DECIMAL_PLACES ? raw : Number(raw.toFixed(places));
47
- }
48
- function resolvePrefUnit(unit) {
49
- if (!isPrefLinearUnit(unit)) {
50
- return { ...unit, format: unit.format ?? ((stored) => `${unit.toDisplay(stored)}${unit.suffix ?? ""}`) };
51
- }
52
- const { scale, offset = 0, precision, suffix, accepts } = unit;
53
- const round = precision === void 0 ? void 0 : 10 ** precision;
54
- const system = { base: "stored", units: { [SHOWN]: { factor: scale, offset } } };
55
- return {
56
- toDisplay: (stored) => {
57
- const shown = (stored - offset) / scale;
58
- return round === void 0 ? shown : Math.round(shown * round) / round;
59
- },
60
- fromDisplay: (shown) => storedOf(shown, scale, offset),
61
- format: (stored) => `${formatUnit(stored, SHOWN, system, { precision: precision ?? 2, suffix: false })}${suffix ?? ""}`,
62
- ...suffix === void 0 ? {} : { suffix },
63
- ...accepts === void 0 ? {} : { accepts }
64
- };
65
- }
66
- function prefUnit(system, display, opts) {
67
- let self;
68
- try {
69
- self = unitScale(system, display);
70
- } catch (e) {
71
- throw new Error(`prefUnit: ${e instanceof Error ? e.message : String(e)}`);
72
- }
73
- const suffix = opts?.suffix ?? display;
74
- const accepts = { [suffix]: 1 };
75
- for (const name of Object.keys(system.units)) {
76
- const other = unitScale(system, name);
77
- const factor = other.factor / self.factor;
78
- const offset = (other.offset - self.offset) / self.factor;
79
- accepts[name] = offset === 0 ? factor : { factor, offset };
80
- }
81
- return {
82
- suffix,
83
- scale: self.factor,
84
- ...self.offset === 0 ? {} : { offset: self.offset },
85
- accepts,
86
- ...opts?.precision === void 0 ? {} : { precision: opts.precision }
87
- };
88
- }
89
-
90
- // src/helpers.ts
91
- function prefDisplayBounds(p) {
92
- if (!p.unit) return { min: p.min, max: p.max, step: p.step ?? 1 };
93
- const { toDisplay } = resolvePrefUnit(p.unit);
94
- const lo = p.min === void 0 ? void 0 : toDisplay(p.min);
95
- const hi = p.max === void 0 ? void 0 : toDisplay(p.max);
96
- const flipped = lo !== void 0 && hi !== void 0 && lo > hi;
97
- const step = p.step === void 0 ? 1 : Math.abs(toDisplay(p.step) - toDisplay(0)) || p.step;
98
- return { min: flipped ? hi : lo, max: flipped ? lo : hi, step };
99
- }
100
- function isPrefLeaf(node) {
101
- return "kind" in node;
102
- }
103
- var VALUELESS = /* @__PURE__ */ new Set(["action", "alias", "label", "separator"]);
104
- function prefHoldsValue(leaf) {
105
- return !VALUELESS.has(leaf.kind);
106
- }
107
- function isPrefSection(node) {
108
- return !isPrefLeaf(node) && "members" in node;
109
- }
110
- function prefSectionLeaves(members) {
111
- return Object.entries(members).flatMap(
112
- ([key, child]) => isPrefLeaf(child) ? [[key, child]] : prefSectionLeaves(child.members)
113
- );
114
- }
115
- function prefLeafAt(schema, path) {
116
- if (isPrefSection(schema)) return prefSectionLeaves(schema.members).find(([key]) => key === path)?.[1];
117
- let node = schema;
118
- for (const seg of path.split(".")) {
119
- if (isPrefLeaf(node) || !Object.hasOwn(node.children, seg)) return void 0;
120
- node = node.children[seg];
121
- }
122
- return isPrefLeaf(node) ? node : void 0;
123
- }
124
- function prefValueAtPath(values, path) {
125
- let cur = values;
126
- for (const seg of path.split(".")) {
127
- if (cur == null || typeof cur !== "object" || !Object.hasOwn(cur, seg)) return void 0;
128
- cur = cur[seg];
129
- }
130
- return cur;
131
- }
132
- function visibleFields(fields, keepEmpty) {
133
- const out = {};
134
- for (const [key, child] of Object.entries(fields)) {
135
- if (isPrefLeaf(child)) {
136
- const kept = visiblePrefSubtree(child, false, keepEmpty);
137
- if (kept) out[key] = kept;
138
- continue;
139
- }
140
- const members = visibleFields(child.members, keepEmpty);
141
- if (Object.keys(members).length > 0 || keepEmpty) out[key] = { ...child, members };
142
- }
143
- return out;
144
- }
145
- function visiblePrefSubtree(node, showHidden, keepEmpty = false) {
146
- if (isPrefLeaf(node)) {
147
- if (node.hidden && !showHidden) return null;
148
- if (showHidden || node.kind !== "object") return node;
149
- return { ...node, children: visibleFields(node.children, keepEmpty) };
150
- }
151
- const group = node;
152
- const children = {};
153
- for (const [key, child] of Object.entries(group.children)) {
154
- const kept = visiblePrefSubtree(child, showHidden, keepEmpty);
155
- if (kept) children[key] = kept;
156
- }
157
- if (Object.keys(children).length === 0 && !keepEmpty) return null;
158
- return { ...node, children };
159
- }
160
- var VERSION_RECORD = "$version";
161
- function prefLeaves(schema) {
162
- const out = /* @__PURE__ */ new Map();
163
- const walk = (group, prefix) => {
164
- for (const [key, child] of Object.entries(group.children)) {
165
- if (key.includes(".")) {
166
- throw new Error(`[prefs] schema key "${key}" contains "."; group keys are path segments`);
167
- }
168
- if (prefix === "" && key === VERSION_RECORD) {
169
- throw new Error(`[prefs] schema key "${VERSION_RECORD}" is reserved`);
170
- }
171
- const path = prefix === "" ? key : `${prefix}.${key}`;
172
- if (isPrefLeaf(child)) out.set(path, child);
173
- else walk(child, path);
174
- }
175
- };
176
- walk(schema, "");
177
- return out;
178
- }
179
- function setOwnPrefValue(tree, key, value) {
180
- Object.defineProperty(tree, key, { value, writable: true, enumerable: true, configurable: true });
181
- }
182
- function assignPrefValueAtPath(root, path, value) {
183
- const parts = path.split(".");
184
- let cursor = root;
185
- for (const part of parts.slice(0, -1)) {
186
- if (!Object.hasOwn(cursor, part) || cursor[part] == null) setOwnPrefValue(cursor, part, {});
187
- cursor = cursor[part];
188
- }
189
- setOwnPrefValue(cursor, parts[parts.length - 1], value);
190
- }
191
- function flattenPrefValues(schema, tree) {
192
- const out = [];
193
- for (const path of prefLeaves(schema).keys()) {
194
- const value = prefValueAtPath(tree, path);
195
- if (value !== void 0) out.push([path, value]);
196
- }
197
- return out;
198
- }
199
- function prefLeafMatches(pref, path, query) {
200
- if (pref.name.toLowerCase().includes(query)) return true;
201
- if (pref.description?.toLowerCase().includes(query)) return true;
202
- return path.toLowerCase().includes(query);
203
- }
204
- function filterPrefSubtree(node, query, path = "", over) {
205
- const q = query.trim().toLowerCase();
206
- if (q === "") return node;
207
- const within = over ?? (isPrefLeaf(node) ? void 0 : node);
208
- const find = (p) => within && prefLeafAt(within, p);
209
- if (isPrefLeaf(node)) {
210
- const target = node.kind === "alias" ? prefAliasTarget(node, find) : void 0;
211
- const drawn = target ? prefAliasedLeaf(node, target.leaf) : node;
212
- return prefLeafMatches(drawn, path, q) ? node : null;
213
- }
214
- const group = node;
215
- if (group.name.toLowerCase().includes(q)) return node;
216
- const children = {};
217
- for (const [key, child] of Object.entries(group.children)) {
218
- const kept = filterPrefSubtree(child, q, path === "" ? key : `${path}.${key}`, within);
219
- if (kept) children[key] = kept;
220
- }
221
- if (Object.keys(children).length === 0) return null;
222
- return { ...node, children };
223
- }
224
5
  var ORDERINGS = ["above", "below", "atLeast", "atMost"];
225
6
  var TEST_KEYS = /* @__PURE__ */ new Set(["path", "from", "is", "isNot", "in", ...ORDERINGS]);
226
7
  var isValue = (v) => v === null || typeof v === "string" || typeof v === "number" || typeof v === "boolean";
@@ -324,6 +105,7 @@ var PREF_KINDS = {
324
105
  union: true,
325
106
  field: true,
326
107
  action: true,
108
+ actions: true,
327
109
  alias: true,
328
110
  label: true,
329
111
  separator: true
@@ -427,12 +209,14 @@ function leafProblems(test, schema, site, over) {
427
209
  if (held === UNSEEN) return [];
428
210
  const { leaf } = held;
429
211
  const named = inEntry ? path === "" ? "the entry" : `the entry's "${path}"` : `"${path}"`;
430
- if (!prefHoldsValue(leaf)) return [{ code: "no-value", path, problem: `${named} is a${leaf.kind === "separator" || leaf.kind === "label" ? "" : "n"} ${leaf.kind}, which holds no value` }];
212
+ if (!prefHoldsValue(leaf)) return [{ code: "no-value", path, problem: `${named} is a${leaf.kind === "separator" || leaf.kind === "label" ? "" : "n"} ${leaf.kind === "actions" ? "actions leaf" : leaf.kind}, which holds no value` }];
431
213
  const out = [];
432
214
  const compared = [test.is, test.isNot, ...test.in ?? []].filter((value) => value !== void 0);
433
215
  for (const value of compared) {
434
216
  const why = neverHolds(leaf, value);
435
- if (why !== void 0) out.push({ code: "value", path, problem: `${named} never holds ${show(value)}: ${why}` });
217
+ if (why === void 0) continue;
218
+ const code = leaf.kind === "enum" && typeof value === "string" ? "option" : "value";
219
+ out.push({ code, path, problem: `${named} never holds ${show(value)}: ${why}` });
436
220
  }
437
221
  const ordering = ORDERINGS.find((op) => test[op] !== void 0);
438
222
  if (ordering !== void 0 && isBuiltinPref(leaf) && leaf.kind !== "number") {
@@ -497,297 +281,28 @@ function checkPrefConditions(schema, over) {
497
281
  } else group(schema, "");
498
282
  return out;
499
283
  }
500
- function isPrefLocus(value) {
501
- if (!isPlainObject(value)) return false;
502
- const keys = Object.keys(value);
503
- return keys.length === 2 && typeof value.$by === "string" && isPlainObject(value.$of);
504
- }
505
- function selectionWeights(selection) {
506
- return Object.fromEntries(Object.entries(selection).map(([path, option]) => [path, { [option]: 1 }]));
507
- }
508
- var member = (locus, option, absent) => Object.hasOwn(locus.$of, option) ? locus.$of[option] : absent;
509
- function weighLocus(stored, weights, absent) {
510
- const out = [];
511
- const walk = (value, weight) => {
512
- if (!isPrefLocus(value)) {
513
- out.push({ value, weight });
514
- return;
515
- }
516
- for (const [option, share] of Object.entries(weights[value.$by] ?? {})) {
517
- if (share > 0) walk(member(value, option, absent), weight * share);
518
- }
519
- };
520
- walk(stored, 1);
521
- return out;
522
- }
523
- function memberAt(stored, selection, absent) {
524
- let value = stored;
525
- while (isPrefLocus(value)) {
526
- const option = selection[value.$by];
527
- if (option === void 0) return absent;
528
- value = member(value, option, absent);
529
- }
530
- return value;
531
- }
532
- function writeMember(stored, selection, next) {
533
- if (!isPrefLocus(stored)) return next;
534
- const option = selection[stored.$by];
535
- if (option === void 0) return stored;
536
- return { $by: stored.$by, $of: { ...stored.$of, [option]: writeMember(stored.$of[option], selection, next) } };
537
- }
538
- function splitLocus(stored, by, options, order) {
539
- const across = (value) => ({ $by: by, $of: Object.fromEntries(options.map((option) => [option, value])) });
540
- if (!isPrefLocus(stored)) return across(stored);
541
- if (stored.$by === by) return stored;
542
- if (order.indexOf(stored.$by) > order.indexOf(by)) return across(stored);
543
- return mapMembers(stored, (inner) => splitLocus(inner, by, options, order));
544
- }
545
- function joinLocus(stored, by, selection, absent) {
546
- if (!isPrefLocus(stored)) return stored;
547
- if (stored.$by !== by) return mapMembers(stored, (inner) => joinLocus(inner, by, selection, absent));
548
- const option = selection[by];
549
- return option === void 0 ? absent : member(stored, option, absent);
550
- }
551
- function mapMembers(locus, fn) {
552
- let out;
553
- for (const [option, value] of Object.entries(locus.$of)) {
554
- const next = fn(value);
555
- if (next !== value) (out ??= { ...locus.$of })[option] = next;
556
- }
557
- return out ? { $by: locus.$by, $of: out } : locus;
558
- }
559
- function mapLocusMembers(stored, fn) {
560
- return isPrefLocus(stored) ? mapMembers(stored, (inner) => mapLocusMembers(inner, fn)) : fn(stored);
561
- }
562
- function locusSelectors(stored) {
563
- const out = /* @__PURE__ */ new Set();
564
- const walk = (value) => {
565
- if (!isPrefLocus(value)) return;
566
- out.add(value.$by);
567
- for (const inner of Object.values(value.$of)) walk(inner);
284
+
285
+ // src/kitCss.ts
286
+ function kitSettingsCssOptions(at) {
287
+ const under2 = (path) => {
288
+ if (at === void 0 || at === "") return path;
289
+ return path.startsWith(`${at}.`) ? path.slice(at.length + 1) : null;
568
290
  };
569
- walk(stored);
570
- return out;
571
- }
572
- function repairLocus(stored, allowed, optionsOf, repairMember) {
573
- const BAD = /* @__PURE__ */ Symbol("bad");
574
- const walk = (value, met) => {
575
- if (!isPrefLocus(value)) return repairMember(value);
576
- const options = allowed.includes(value.$by) && !met.includes(value.$by) ? optionsOf(value.$by) : void 0;
577
- if (!options) return BAD;
578
- const of = {};
579
- for (const option of options) {
580
- if (!Object.hasOwn(value.$of, option)) continue;
581
- const read2 = walk(value.$of[option], [...met, value.$by]);
582
- if (read2 === BAD) return BAD;
583
- of[option] = read2;
584
- }
585
- return { $by: value.$by, $of: of };
291
+ return {
292
+ property: (path) => {
293
+ const rest = under2(path);
294
+ return rest === null ? null : `--wzl-kit-${kebab(rest)}`;
295
+ },
296
+ attribute: (selector) => `data-wzl-kit-${kebab(under2(selector) ?? selector)}`
586
297
  };
587
- const read = walk(stored, []);
588
- return read === BAD ? void 0 : read;
589
- }
590
- var heaviest = (members) => members.reduce((most, m) => m.weight > most.weight ? m : most).value;
591
- var blendNumber = (members, leaf) => {
592
- let sum = 0;
593
- let total = 0;
594
- for (const { value, weight } of members) {
595
- if (typeof value !== "number" || !Number.isFinite(value)) return heaviest(members);
596
- sum += value * weight;
597
- total += weight;
598
- }
599
- return sum / total;
600
- };
601
- var blendColor = (members, leaf) => {
602
- let mixed;
603
- let total = 0;
604
- for (const { value, weight } of members) {
605
- let next;
606
- try {
607
- next = hexToRgba(value);
608
- } catch {
609
- return heaviest(members);
610
- }
611
- total += weight;
612
- if (!mixed) {
613
- mixed = next;
614
- continue;
615
- }
616
- const t = weight / total;
617
- const [r, g, b] = interpolateSrgb([mixed[0], mixed[1], mixed[2]], [next[0], next[1], next[2]], t, "oklch");
618
- mixed = [r, g, b, mixed[3] + (next[3] - mixed[3]) * t];
619
- }
620
- return rgbaToHex(mixed);
621
- };
622
- var PREF_BLENDS = { number: blendNumber, color: blendColor };
623
- function blendPref(leaf, members, blends) {
624
- if (members.length === 0) return leaf.default;
625
- if (members.length === 1) return members[0].value;
626
- const blend = (blends && Object.hasOwn(blends, leaf.kind) ? blends[leaf.kind] : void 0) ?? (Object.hasOwn(PREF_BLENDS, leaf.kind) ? PREF_BLENDS[leaf.kind] : void 0) ?? heaviest;
627
- return blend(members, leaf);
628
- }
629
-
630
- // src/splitCheck.ts
631
- var refusal = (leaf) => {
632
- if (!leaf) return ["no-leaf", "names no leaf"];
633
- if (leaf.kind !== "enum") return ["not-enum", `names a ${leaf.kind} leaf, and only an enum has options to split by`];
634
- const selector = leaf;
635
- if (selector.encoding) return ["encoded", "names an enum with an encoding, whose stored value is not its option"];
636
- if (selector.clearable) return ["clearable", "names a clearable enum, which may hold none of its options"];
637
- if (selector.splitBy?.length) return ["split", "names a leaf that may itself be split"];
638
- return void 0;
639
- };
640
- function prefSelectors(leaves) {
641
- const out = /* @__PURE__ */ new Map();
642
- for (const leaf of leaves.values()) {
643
- for (const path of leaf.splitBy ?? []) {
644
- const selector = leaves.get(path);
645
- if (out.has(path) || refusal(selector)) continue;
646
- out.set(path, selector.options.map((option) => option.value));
647
- }
648
- }
649
- return out;
650
- }
651
- function checkPrefSplits(schema) {
652
- const leaves = prefLeaves(schema);
653
- const out = [];
654
- for (const [at, leaf] of leaves) {
655
- for (const path of locusSelectors(leaf.defaultLocus)) {
656
- if (leaf.splitBy?.includes(path)) continue;
657
- out.push({ code: "default", at, path, problem: `its defaultLocus is split by "${path}", which its splitBy does not list` });
658
- }
659
- if (!leaf.splitBy?.length) continue;
660
- if (!prefHoldsValue(leaf)) {
661
- out.push({ code: "valueless", at, problem: `a ${leaf.kind} leaf holds no value to split` });
662
- continue;
663
- }
664
- leaf.splitBy.forEach((path, i) => {
665
- if (leaf.splitBy.indexOf(path) !== i) {
666
- out.push({ code: "twice", at, path, problem: `"${path}" is listed twice` });
667
- return;
668
- }
669
- const why = refusal(leaves.get(path));
670
- if (why) out.push({ code: why[0], at, path, problem: `"${path}" ${why[1]}` });
671
- });
672
- }
673
- return out;
674
- }
675
-
676
- // src/union.ts
677
- function prefVariantOf(leaf, value) {
678
- if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
679
- const key = value[leaf.tag];
680
- if (typeof key !== "string" || !Object.hasOwn(leaf.variants, key)) return void 0;
681
- return [key, leaf.variants[key]];
682
- }
683
- function prefVariantDefault(leaf, key) {
684
- const held = leaf.variants[key]?.default;
685
- const fields = held !== null && typeof held === "object" ? held : {};
686
- return { ...fields, [leaf.tag]: key };
687
- }
688
- function repairPrefValue(leaf, stored, validators) {
689
- if (leaf.kind === "number") {
690
- if (stored === "Infinity") stored = Infinity;
691
- else if (stored === "-Infinity") stored = -Infinity;
692
- }
693
- const validate = validators?.[leaf.kind];
694
- if (validate) {
695
- try {
696
- const out = validate(stored, leaf);
697
- return out === void 0 ? leaf.default : out;
698
- } catch {
699
- return leaf.default;
700
- }
701
- }
702
- switch (leaf.kind) {
703
- case "number":
704
- return repairNumber(leaf, stored);
705
- case "boolean":
706
- return leaf.encoding || typeof stored === "boolean" ? stored : leaf.default;
707
- case "string":
708
- case "color":
709
- case "field":
710
- return typeof stored === "string" ? stored : leaf.default;
711
- case "enum": {
712
- const e = leaf;
713
- if (e.encoding) return stored;
714
- return e.options.some((o) => o.value === stored) ? stored : leaf.default;
715
- }
716
- case "object":
717
- if (isPlainObject(stored)) return repairFields(leaf, stored, validators);
718
- return leaf.fromScalar ? stored : leaf.default;
719
- case "map":
720
- return repairMap(leaf, stored, validators);
721
- case "union": {
722
- const variant = prefVariantOf(leaf, stored);
723
- return variant ? repairFields(variant[1], stored, validators) : leaf.default;
724
- }
725
- case "list":
726
- return repairList(leaf, stored, validators);
727
- default:
728
- return stored;
729
- }
730
- }
731
- function repairFields(leaf, stored, validators) {
732
- let out;
733
- for (const [key, field] of prefSectionLeaves(leaf.children)) {
734
- if (!Object.hasOwn(stored, key) || stored[key] === void 0) continue;
735
- const read = repairPrefValue(field, stored[key], validators);
736
- if (read !== stored[key]) (out ??= { ...stored })[key] = read;
737
- }
738
- return out ?? stored;
739
- }
740
- function repairMap(leaf, stored, validators) {
741
- if (!isPlainObject(stored)) return leaf.default;
742
- const held = stored;
743
- let out;
744
- for (const [key, value] of Object.entries(held)) {
745
- const read = repairPrefValue(leaf.item, value, validators);
746
- if (read !== value) (out ??= { ...held })[key] = read;
747
- }
748
- return out ?? stored;
749
- }
750
- function repairList(leaf, stored, validators) {
751
- if (!Array.isArray(stored)) return leaf.default;
752
- if (leaf.minItems !== void 0 && stored.length < leaf.minItems) return leaf.default;
753
- const kept = leaf.maxItems !== void 0 && stored.length > leaf.maxItems ? stored.slice(0, leaf.maxItems) : stored;
754
- const read = kept.map((entry) => repairPrefValue(leaf.item, entry, validators));
755
- return kept === stored && read.every((entry, i) => entry === stored[i]) ? stored : read;
756
- }
757
- function repairNumber(leaf, stored) {
758
- if (typeof stored !== "number" || Number.isNaN(stored)) return leaf.default;
759
- const { endless } = leaf;
760
- if (stored === Infinity && (endless === "max" || endless === "both")) return stored;
761
- if (stored === -Infinity && (endless === "min" || endless === "both")) return stored;
762
- let v = stored;
763
- if (leaf.min !== void 0 && v < leaf.min) v = leaf.min;
764
- if (leaf.max !== void 0 && v > leaf.max) v = leaf.max;
765
- return Number.isFinite(v) ? v : leaf.default;
766
- }
767
-
768
- // src/stamp.ts
769
- var isVersion = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0;
770
- function stampRecord(value, at) {
771
- return { $at: at, value };
772
- }
773
- function isStampedRecord(record) {
774
- if (record === null || typeof record !== "object") return false;
775
- const keys = Object.keys(record);
776
- return keys.length === 2 && Object.hasOwn(record, "value") && isVersion(record.$at);
777
- }
778
- function readRecord(record, unstamped) {
779
- return isStampedRecord(record) ? { at: record.$at, value: record.value, stamped: true } : { at: unstamped, value: record, stamped: false };
780
- }
781
- function recordValue(record) {
782
- return isStampedRecord(record) ? record.value : record;
783
298
  }
784
299
 
785
300
  // src/migrate.ts
786
- var isVersion2 = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0;
301
+ var isVersion = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0;
787
302
  function runPrefsMigrations(cache, migrations, { stampAll = true } = {}) {
788
303
  const target = migrations.length;
789
304
  const raw = cache.get(VERSION_RECORD);
790
- if (cache.has(VERSION_RECORD) && !isVersion2(raw)) {
305
+ if (cache.has(VERSION_RECORD) && !isVersion(raw)) {
791
306
  console.warn(
792
307
  `[prefs] "${cache.prefix}" has an unreadable ${VERSION_RECORD} (${JSON.stringify(raw)}); opening read-only`
793
308
  );
@@ -861,7 +376,7 @@ function watchPrefsVersion(cache, migrations) {
861
376
  if (!stopped && cache.writable) migrate();
862
377
  });
863
378
  const heard = (version) => {
864
- if (!isVersion2(version)) {
379
+ if (!isVersion(version)) {
865
380
  console.warn(
866
381
  `[prefs] "${cache.prefix}" has an unreadable ${VERSION_RECORD} (${JSON.stringify(version)}) from another writer; no longer persisting`
867
382
  );
@@ -891,83 +406,6 @@ function watchPrefsVersion(cache, migrations) {
891
406
  };
892
407
  }
893
408
 
894
- // src/snapshot.ts
895
- function readStored(source, leaf, stored) {
896
- const repair = (value) => repairPrefValue(leaf, value, source.validators);
897
- if (!leaf.splitBy?.length || !isPrefLocus(stored)) return repair(stored);
898
- const read = repairLocus(stored, leaf.splitBy, (path) => source.selectors.get(path), repair);
899
- return read === void 0 ? leaf.default : read;
900
- }
901
- function resolveHeld(source, leaf, held, weights) {
902
- return isPrefLocus(held) ? blendPref(leaf, weighLocus(held, weights, leaf.default), source.blends) : held;
903
- }
904
- function createSnapshots(source) {
905
- const { leaves, cache, selectors } = source;
906
- let snapshot = null;
907
- let previous = null;
908
- const unsetLoci = /* @__PURE__ */ new Map();
909
- const unsetHeld = (path, leaf) => {
910
- if (leaf.defaultLocus === void 0) return leaf.default;
911
- if (!unsetLoci.has(path)) unsetLoci.set(path, readStored(source, leaf, leaf.defaultLocus));
912
- return unsetLoci.get(path);
913
- };
914
- const build = () => {
915
- const held = /* @__PURE__ */ new Map();
916
- const raw = /* @__PURE__ */ new Map();
917
- const unset = /* @__PURE__ */ new Set();
918
- for (const [path, leaf] of leaves) {
919
- if (!cache.has(path)) {
920
- held.set(path, unsetHeld(path, leaf));
921
- unset.add(path);
922
- continue;
923
- }
924
- const record = cache.get(path);
925
- raw.set(path, record);
926
- const same2 = previous?.raw.has(path) && previous.raw.get(path) === record;
927
- held.set(path, same2 ? previous.held.get(path) : readStored(source, leaf, recordValue(record)));
928
- }
929
- previous = { raw, held };
930
- const selection = {};
931
- for (const path of selectors.keys()) selection[path] = held.get(path);
932
- const weights = selectionWeights(selection);
933
- const byPath = /* @__PURE__ */ new Map();
934
- const splitBy = /* @__PURE__ */ new Map();
935
- const loci = /* @__PURE__ */ new Map();
936
- const tree = {};
937
- for (const [path, leaf] of leaves) {
938
- const value = held.get(path);
939
- if (isPrefLocus(value)) loci.set(path, value);
940
- for (const selector of locusSelectors(value)) splitBy.set(selector, [...splitBy.get(selector) ?? [], path]);
941
- const read = resolveHeld(source, leaf, value, weights);
942
- byPath.set(path, read);
943
- assignPrefValueAtPath(tree, path, read);
944
- }
945
- return { byPath, held, loci, selection, splitBy, tree, unset };
946
- };
947
- return {
948
- current: () => snapshot ??= build(),
949
- peek: () => snapshot,
950
- drop: () => {
951
- snapshot = null;
952
- }
953
- };
954
- }
955
- function weightsUnder(selectors, selection, given) {
956
- const out = {};
957
- for (const [path, options] of selectors) {
958
- const own = Object.hasOwn(given, path) ? given[path] : void 0;
959
- out[path] = own ? Object.fromEntries(options.filter((option) => (own[option] ?? 0) > 0).map((option) => [option, own[option]])) : { [selection[path]]: 1 };
960
- }
961
- return out;
962
- }
963
- function selectionAt(selectors, selection, at) {
964
- const out = { ...selection };
965
- for (const [path, option] of Object.entries(at)) {
966
- if (selectors.get(path)?.includes(option)) out[path] = option;
967
- }
968
- return out;
969
- }
970
-
971
409
  // src/storeWrites.ts
972
410
  var encodeInfinity = (leaf, value) => {
973
411
  if (leaf.kind === "number") return value === Infinity || value === -Infinity ? String(value) : value;
@@ -994,7 +432,7 @@ var encodeInfinity = (leaf, value) => {
994
432
  function prefWrites({ leaves, cache, selectors, version, selection, warnIfClosed }) {
995
433
  const unsetLocus = (leaf) => {
996
434
  if (leaf.defaultLocus === void 0 || !leaf.splitBy?.length) return void 0;
997
- return repairLocus(leaf.defaultLocus, leaf.splitBy, (by) => selectors.get(by), (member2) => encodeInfinity(leaf, member2));
435
+ return repairLocus(leaf.defaultLocus, leaf.splitBy, (by) => selectors.get(by), (member) => encodeInfinity(leaf, member));
998
436
  };
999
437
  const rawAt = (path, leaf) => cache.has(path) ? recordValue(cache.get(path)) : unsetLocus(leaf) ?? encodeInfinity(leaf, leaf.default);
1000
438
  const store = (path, stored) => {
@@ -1016,7 +454,7 @@ function prefWrites({ leaves, cache, selectors, version, selection, warnIfClosed
1016
454
  return;
1017
455
  }
1018
456
  if (leaf.splitBy?.length && isPrefLocus(value)) {
1019
- store(path, mapLocusMembers(value, (member2) => encodeInfinity(leaf, member2)));
457
+ store(path, mapLocusMembers(value, (member) => encodeInfinity(leaf, member)));
1020
458
  return;
1021
459
  }
1022
460
  const stored = encodeInfinity(leaf, value);
@@ -1175,6 +613,6 @@ function openPrefsCacheSync(options) {
1175
613
  }
1176
614
  var watch = (cache, options) => watchPrefsVersion(cache, options.migrations ?? []);
1177
615
 
1178
- export { PREF_BLENDS, PREF_KINDS, UNSEEN, VERSION_RECORD, checkPrefCondition, checkPrefConditions, checkPrefSplits, createPrefsStore, filterPrefSubtree, flattenPrefValues, isBuiltinPref, isPrefCondition, isPrefLeaf, isPrefLinearUnit, isPrefLocus, isPrefSection, locusSelectors, mapPrefConditionPaths, memberAt, openPrefs, openPrefsCacheSync, openPrefsSync, pairRowsOf, prefAliasName, prefAliasTarget, prefAliasedLeaf, prefConditionHolds, prefConditionPaths, prefConditionReadsItem, prefDisplayBounds, prefHoldsValue, prefIsEnabled, prefIsShown, prefLeafAt, prefLeafHolding, prefLeafHoldingIn, prefLeaves, prefSchemaHolding, prefSectionLeaves, prefSelectors, prefUnit, prefValueAtPath, prefVariantDefault, prefVariantOf, repairPrefValue, resolvePrefUnit, visiblePrefSubtree };
1179
- //# sourceMappingURL=chunk-ASSX3JHY.js.map
1180
- //# sourceMappingURL=chunk-ASSX3JHY.js.map
616
+ export { PREF_KINDS, UNSEEN, checkPrefCondition, checkPrefConditions, createPrefsStore, isBuiltinPref, isPrefCondition, kitSettingsCssOptions, mapPrefConditionPaths, openPrefs, openPrefsCacheSync, openPrefsSync, pairRowsOf, prefConditionHolds, prefConditionPaths, prefConditionReadsItem, prefIsEnabled, prefIsShown, prefLeafHolding, prefLeafHoldingIn, prefSchemaHolding };
617
+ //# sourceMappingURL=chunk-WN6QQICK.js.map
618
+ //# sourceMappingURL=chunk-WN6QQICK.js.map