@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.
- package/README.md +51 -0
- package/dist/chunk-OZFER7VN.js +706 -0
- package/dist/chunk-OZFER7VN.js.map +1 -0
- package/dist/{chunk-ASSX3JHY.js → chunk-WN6QQICK.js} +27 -589
- package/dist/chunk-WN6QQICK.js.map +1 -0
- package/dist/chunk-ZLXZRX73.js +32 -0
- package/dist/chunk-ZLXZRX73.js.map +1 -0
- package/dist/css-v-LpmTll.d.ts +49 -0
- package/dist/{open-C83pU7Va.d.ts → groups-BDZC-ywb.d.ts} +115 -229
- package/dist/index.d.ts +51 -53
- package/dist/index.js +60 -103
- package/dist/index.js.map +1 -1
- package/dist/open-VJ1zlFJz.d.ts +203 -0
- package/dist/react.d.ts +27 -4
- package/dist/react.js +75 -3
- package/dist/react.js.map +1 -1
- package/dist/vite.d.ts +23 -0
- package/dist/vite.js +61 -0
- package/dist/vite.js.map +1 -0
- package/package.json +16 -6
- package/dist/chunk-ASSX3JHY.js.map +0 -1
|
@@ -1,226 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
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
|
|
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
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
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
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
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
|
|
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) && !
|
|
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 (!
|
|
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), (
|
|
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, (
|
|
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 {
|
|
1179
|
-
//# sourceMappingURL=chunk-
|
|
1180
|
-
//# sourceMappingURL=chunk-
|
|
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
|