@weasel-js/prefs 1.10.0 → 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 +151 -0
- package/dist/chunk-OZFER7VN.js +706 -0
- package/dist/chunk-OZFER7VN.js.map +1 -0
- package/dist/{chunk-5KB3WBJZ.js → chunk-WN6QQICK.js} +118 -363
- 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-BEY-aOGe.d.ts → groups-BDZC-ywb.d.ts} +175 -187
- package/dist/index.d.ts +103 -9
- package/dist/index.js +129 -37
- package/dist/index.js.map +1 -1
- package/dist/open-VJ1zlFJz.d.ts +203 -0
- package/dist/react.d.ts +34 -6
- package/dist/react.js +85 -5
- 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 -5
- package/dist/chunk-5KB3WBJZ.js.map +0 -1
|
@@ -1,211 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
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';
|
|
3
3
|
import { openRecords, openRecordsSync } from '@weasel-js/storage';
|
|
4
4
|
|
|
5
|
-
// src/alias.ts
|
|
6
|
-
function prefAliasTarget(alias, leafAt) {
|
|
7
|
-
const passed = /* @__PURE__ */ new Set();
|
|
8
|
-
let path = alias.of;
|
|
9
|
-
for (; ; ) {
|
|
10
|
-
if (passed.has(path)) return void 0;
|
|
11
|
-
passed.add(path);
|
|
12
|
-
const leaf = leafAt(path);
|
|
13
|
-
if (leaf === void 0) return void 0;
|
|
14
|
-
if (leaf.kind !== "alias") return { path, leaf };
|
|
15
|
-
path = leaf.of;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function prefAliasName(alias, target) {
|
|
19
|
-
if (alias.name !== "") return alias.name;
|
|
20
|
-
return target === void 0 ? "Alias" : target.name;
|
|
21
|
-
}
|
|
22
|
-
function prefAliasedLeaf(alias, target) {
|
|
23
|
-
return {
|
|
24
|
-
...target,
|
|
25
|
-
name: prefAliasName(alias, target),
|
|
26
|
-
description: alias.description === "" ? target.description : alias.description
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
function isPrefLinearUnit(unit) {
|
|
30
|
-
return typeof unit.toDisplay !== "function";
|
|
31
|
-
}
|
|
32
|
-
var SHOWN = "shown";
|
|
33
|
-
function resolvePrefUnit(unit) {
|
|
34
|
-
if (!isPrefLinearUnit(unit)) {
|
|
35
|
-
return { ...unit, format: unit.format ?? ((stored) => `${unit.toDisplay(stored)}${unit.suffix ?? ""}`) };
|
|
36
|
-
}
|
|
37
|
-
const { scale, offset = 0, precision, suffix, accepts } = unit;
|
|
38
|
-
const round = precision === void 0 ? void 0 : 10 ** precision;
|
|
39
|
-
const system = { base: "stored", units: { [SHOWN]: { factor: scale, offset } } };
|
|
40
|
-
return {
|
|
41
|
-
toDisplay: (stored) => {
|
|
42
|
-
const shown = (stored - offset) / scale;
|
|
43
|
-
return round === void 0 ? shown : Math.round(shown * round) / round;
|
|
44
|
-
},
|
|
45
|
-
fromDisplay: (shown) => shown * scale + offset,
|
|
46
|
-
format: (stored) => `${formatUnit(stored, SHOWN, system, { precision: precision ?? 2, suffix: false })}${suffix ?? ""}`,
|
|
47
|
-
...suffix === void 0 ? {} : { suffix },
|
|
48
|
-
...accepts === void 0 ? {} : { accepts }
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
function prefUnit(system, display, opts) {
|
|
52
|
-
let self;
|
|
53
|
-
try {
|
|
54
|
-
self = unitScale(system, display);
|
|
55
|
-
} catch (e) {
|
|
56
|
-
throw new Error(`prefUnit: ${e instanceof Error ? e.message : String(e)}`);
|
|
57
|
-
}
|
|
58
|
-
const suffix = opts?.suffix ?? display;
|
|
59
|
-
const accepts = { [suffix]: 1 };
|
|
60
|
-
for (const name of Object.keys(system.units)) {
|
|
61
|
-
const other = unitScale(system, name);
|
|
62
|
-
const factor = other.factor / self.factor;
|
|
63
|
-
const offset = (other.offset - self.offset) / self.factor;
|
|
64
|
-
accepts[name] = offset === 0 ? factor : { factor, offset };
|
|
65
|
-
}
|
|
66
|
-
return {
|
|
67
|
-
suffix,
|
|
68
|
-
scale: self.factor,
|
|
69
|
-
...self.offset === 0 ? {} : { offset: self.offset },
|
|
70
|
-
accepts,
|
|
71
|
-
...opts?.precision === void 0 ? {} : { precision: opts.precision }
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// src/helpers.ts
|
|
76
|
-
function prefDisplayBounds(p) {
|
|
77
|
-
if (!p.unit) return { min: p.min, max: p.max, step: p.step ?? 1 };
|
|
78
|
-
const { toDisplay } = resolvePrefUnit(p.unit);
|
|
79
|
-
const lo = p.min === void 0 ? void 0 : toDisplay(p.min);
|
|
80
|
-
const hi = p.max === void 0 ? void 0 : toDisplay(p.max);
|
|
81
|
-
const flipped = lo !== void 0 && hi !== void 0 && lo > hi;
|
|
82
|
-
const step = p.step === void 0 ? 1 : Math.abs(toDisplay(p.step) - toDisplay(0)) || p.step;
|
|
83
|
-
return { min: flipped ? hi : lo, max: flipped ? lo : hi, step };
|
|
84
|
-
}
|
|
85
|
-
function isPrefLeaf(node) {
|
|
86
|
-
return "kind" in node;
|
|
87
|
-
}
|
|
88
|
-
var VALUELESS = /* @__PURE__ */ new Set(["action", "alias", "label", "separator"]);
|
|
89
|
-
function prefHoldsValue(leaf) {
|
|
90
|
-
return !VALUELESS.has(leaf.kind);
|
|
91
|
-
}
|
|
92
|
-
function isPrefSection(node) {
|
|
93
|
-
return !isPrefLeaf(node) && "members" in node;
|
|
94
|
-
}
|
|
95
|
-
function prefSectionLeaves(members) {
|
|
96
|
-
return Object.entries(members).flatMap(
|
|
97
|
-
([key, child]) => isPrefLeaf(child) ? [[key, child]] : prefSectionLeaves(child.members)
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
function prefLeafAt(schema, path) {
|
|
101
|
-
if (isPrefSection(schema)) return prefSectionLeaves(schema.members).find(([key]) => key === path)?.[1];
|
|
102
|
-
let node = schema;
|
|
103
|
-
for (const seg of path.split(".")) {
|
|
104
|
-
if (isPrefLeaf(node) || !Object.hasOwn(node.children, seg)) return void 0;
|
|
105
|
-
node = node.children[seg];
|
|
106
|
-
}
|
|
107
|
-
return isPrefLeaf(node) ? node : void 0;
|
|
108
|
-
}
|
|
109
|
-
function prefValueAtPath(values, path) {
|
|
110
|
-
let cur = values;
|
|
111
|
-
for (const seg of path.split(".")) {
|
|
112
|
-
if (cur == null || typeof cur !== "object" || !Object.hasOwn(cur, seg)) return void 0;
|
|
113
|
-
cur = cur[seg];
|
|
114
|
-
}
|
|
115
|
-
return cur;
|
|
116
|
-
}
|
|
117
|
-
function visibleFields(fields, keepEmpty) {
|
|
118
|
-
const out = {};
|
|
119
|
-
for (const [key, child] of Object.entries(fields)) {
|
|
120
|
-
if (isPrefLeaf(child)) {
|
|
121
|
-
const kept = visiblePrefSubtree(child, false, keepEmpty);
|
|
122
|
-
if (kept) out[key] = kept;
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
const members = visibleFields(child.members, keepEmpty);
|
|
126
|
-
if (Object.keys(members).length > 0 || keepEmpty) out[key] = { ...child, members };
|
|
127
|
-
}
|
|
128
|
-
return out;
|
|
129
|
-
}
|
|
130
|
-
function visiblePrefSubtree(node, showHidden, keepEmpty = false) {
|
|
131
|
-
if (isPrefLeaf(node)) {
|
|
132
|
-
if (node.hidden && !showHidden) return null;
|
|
133
|
-
if (showHidden || node.kind !== "object") return node;
|
|
134
|
-
return { ...node, children: visibleFields(node.children, keepEmpty) };
|
|
135
|
-
}
|
|
136
|
-
const group = node;
|
|
137
|
-
const children = {};
|
|
138
|
-
for (const [key, child] of Object.entries(group.children)) {
|
|
139
|
-
const kept = visiblePrefSubtree(child, showHidden, keepEmpty);
|
|
140
|
-
if (kept) children[key] = kept;
|
|
141
|
-
}
|
|
142
|
-
if (Object.keys(children).length === 0 && !keepEmpty) return null;
|
|
143
|
-
return { ...node, children };
|
|
144
|
-
}
|
|
145
|
-
var VERSION_RECORD = "$version";
|
|
146
|
-
function prefLeaves(schema) {
|
|
147
|
-
const out = /* @__PURE__ */ new Map();
|
|
148
|
-
const walk = (group, prefix) => {
|
|
149
|
-
for (const [key, child] of Object.entries(group.children)) {
|
|
150
|
-
if (key.includes(".")) {
|
|
151
|
-
throw new Error(`[prefs] schema key "${key}" contains "."; group keys are path segments`);
|
|
152
|
-
}
|
|
153
|
-
if (prefix === "" && key === VERSION_RECORD) {
|
|
154
|
-
throw new Error(`[prefs] schema key "${VERSION_RECORD}" is reserved`);
|
|
155
|
-
}
|
|
156
|
-
const path = prefix === "" ? key : `${prefix}.${key}`;
|
|
157
|
-
if (isPrefLeaf(child)) out.set(path, child);
|
|
158
|
-
else walk(child, path);
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
walk(schema, "");
|
|
162
|
-
return out;
|
|
163
|
-
}
|
|
164
|
-
function setOwnPrefValue(tree, key, value) {
|
|
165
|
-
Object.defineProperty(tree, key, { value, writable: true, enumerable: true, configurable: true });
|
|
166
|
-
}
|
|
167
|
-
function assignPrefValueAtPath(root, path, value) {
|
|
168
|
-
const parts = path.split(".");
|
|
169
|
-
let cursor = root;
|
|
170
|
-
for (const part of parts.slice(0, -1)) {
|
|
171
|
-
if (!Object.hasOwn(cursor, part) || cursor[part] == null) setOwnPrefValue(cursor, part, {});
|
|
172
|
-
cursor = cursor[part];
|
|
173
|
-
}
|
|
174
|
-
setOwnPrefValue(cursor, parts[parts.length - 1], value);
|
|
175
|
-
}
|
|
176
|
-
function flattenPrefValues(schema, tree) {
|
|
177
|
-
const out = [];
|
|
178
|
-
for (const path of prefLeaves(schema).keys()) {
|
|
179
|
-
const value = prefValueAtPath(tree, path);
|
|
180
|
-
if (value !== void 0) out.push([path, value]);
|
|
181
|
-
}
|
|
182
|
-
return out;
|
|
183
|
-
}
|
|
184
|
-
function prefLeafMatches(pref, path, query) {
|
|
185
|
-
if (pref.name.toLowerCase().includes(query)) return true;
|
|
186
|
-
if (pref.description?.toLowerCase().includes(query)) return true;
|
|
187
|
-
return path.toLowerCase().includes(query);
|
|
188
|
-
}
|
|
189
|
-
function filterPrefSubtree(node, query, path = "", over) {
|
|
190
|
-
const q = query.trim().toLowerCase();
|
|
191
|
-
if (q === "") return node;
|
|
192
|
-
const within = over ?? (isPrefLeaf(node) ? void 0 : node);
|
|
193
|
-
const find = (p) => within && prefLeafAt(within, p);
|
|
194
|
-
if (isPrefLeaf(node)) {
|
|
195
|
-
const target = node.kind === "alias" ? prefAliasTarget(node, find) : void 0;
|
|
196
|
-
const drawn = target ? prefAliasedLeaf(node, target.leaf) : node;
|
|
197
|
-
return prefLeafMatches(drawn, path, q) ? node : null;
|
|
198
|
-
}
|
|
199
|
-
const group = node;
|
|
200
|
-
if (group.name.toLowerCase().includes(q)) return node;
|
|
201
|
-
const children = {};
|
|
202
|
-
for (const [key, child] of Object.entries(group.children)) {
|
|
203
|
-
const kept = filterPrefSubtree(child, q, path === "" ? key : `${path}.${key}`, within);
|
|
204
|
-
if (kept) children[key] = kept;
|
|
205
|
-
}
|
|
206
|
-
if (Object.keys(children).length === 0) return null;
|
|
207
|
-
return { ...node, children };
|
|
208
|
-
}
|
|
209
5
|
var ORDERINGS = ["above", "below", "atLeast", "atMost"];
|
|
210
6
|
var TEST_KEYS = /* @__PURE__ */ new Set(["path", "from", "is", "isNot", "in", ...ORDERINGS]);
|
|
211
7
|
var isValue = (v) => v === null || typeof v === "string" || typeof v === "number" || typeof v === "boolean";
|
|
@@ -309,6 +105,7 @@ var PREF_KINDS = {
|
|
|
309
105
|
union: true,
|
|
310
106
|
field: true,
|
|
311
107
|
action: true,
|
|
108
|
+
actions: true,
|
|
312
109
|
alias: true,
|
|
313
110
|
label: true,
|
|
314
111
|
separator: true
|
|
@@ -412,12 +209,14 @@ function leafProblems(test, schema, site, over) {
|
|
|
412
209
|
if (held === UNSEEN) return [];
|
|
413
210
|
const { leaf } = held;
|
|
414
211
|
const named = inEntry ? path === "" ? "the entry" : `the entry's "${path}"` : `"${path}"`;
|
|
415
|
-
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` }];
|
|
416
213
|
const out = [];
|
|
417
214
|
const compared = [test.is, test.isNot, ...test.in ?? []].filter((value) => value !== void 0);
|
|
418
215
|
for (const value of compared) {
|
|
419
216
|
const why = neverHolds(leaf, value);
|
|
420
|
-
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}` });
|
|
421
220
|
}
|
|
422
221
|
const ordering = ORDERINGS.find((op) => test[op] !== void 0);
|
|
423
222
|
if (ordering !== void 0 && isBuiltinPref(leaf) && leaf.kind !== "number") {
|
|
@@ -483,121 +282,27 @@ function checkPrefConditions(schema, over) {
|
|
|
483
282
|
return out;
|
|
484
283
|
}
|
|
485
284
|
|
|
486
|
-
// src/
|
|
487
|
-
function
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
if (leaf.kind === "number") {
|
|
500
|
-
if (stored === "Infinity") stored = Infinity;
|
|
501
|
-
else if (stored === "-Infinity") stored = -Infinity;
|
|
502
|
-
}
|
|
503
|
-
const validate = validators?.[leaf.kind];
|
|
504
|
-
if (validate) {
|
|
505
|
-
try {
|
|
506
|
-
const out = validate(stored, leaf);
|
|
507
|
-
return out === void 0 ? leaf.default : out;
|
|
508
|
-
} catch {
|
|
509
|
-
return leaf.default;
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
switch (leaf.kind) {
|
|
513
|
-
case "number":
|
|
514
|
-
return repairNumber(leaf, stored);
|
|
515
|
-
case "boolean":
|
|
516
|
-
return leaf.encoding || typeof stored === "boolean" ? stored : leaf.default;
|
|
517
|
-
case "string":
|
|
518
|
-
case "color":
|
|
519
|
-
case "field":
|
|
520
|
-
return typeof stored === "string" ? stored : leaf.default;
|
|
521
|
-
case "enum": {
|
|
522
|
-
const e = leaf;
|
|
523
|
-
if (e.encoding) return stored;
|
|
524
|
-
return e.options.some((o) => o.value === stored) ? stored : leaf.default;
|
|
525
|
-
}
|
|
526
|
-
case "object":
|
|
527
|
-
if (isPlainObject(stored)) return repairFields(leaf, stored, validators);
|
|
528
|
-
return leaf.fromScalar ? stored : leaf.default;
|
|
529
|
-
case "map":
|
|
530
|
-
return repairMap(leaf, stored, validators);
|
|
531
|
-
case "union": {
|
|
532
|
-
const variant = prefVariantOf(leaf, stored);
|
|
533
|
-
return variant ? repairFields(variant[1], stored, validators) : leaf.default;
|
|
534
|
-
}
|
|
535
|
-
case "list":
|
|
536
|
-
return repairList(leaf, stored, validators);
|
|
537
|
-
default:
|
|
538
|
-
return stored;
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
function repairFields(leaf, stored, validators) {
|
|
542
|
-
let out;
|
|
543
|
-
for (const [key, field] of prefSectionLeaves(leaf.children)) {
|
|
544
|
-
if (!Object.hasOwn(stored, key) || stored[key] === void 0) continue;
|
|
545
|
-
const read = repairPrefValue(field, stored[key], validators);
|
|
546
|
-
if (read !== stored[key]) (out ??= { ...stored })[key] = read;
|
|
547
|
-
}
|
|
548
|
-
return out ?? stored;
|
|
549
|
-
}
|
|
550
|
-
function repairMap(leaf, stored, validators) {
|
|
551
|
-
if (!isPlainObject(stored)) return leaf.default;
|
|
552
|
-
const held = stored;
|
|
553
|
-
let out;
|
|
554
|
-
for (const [key, value] of Object.entries(held)) {
|
|
555
|
-
const read = repairPrefValue(leaf.item, value, validators);
|
|
556
|
-
if (read !== value) (out ??= { ...held })[key] = read;
|
|
557
|
-
}
|
|
558
|
-
return out ?? stored;
|
|
559
|
-
}
|
|
560
|
-
function repairList(leaf, stored, validators) {
|
|
561
|
-
if (!Array.isArray(stored)) return leaf.default;
|
|
562
|
-
if (leaf.minItems !== void 0 && stored.length < leaf.minItems) return leaf.default;
|
|
563
|
-
const kept = leaf.maxItems !== void 0 && stored.length > leaf.maxItems ? stored.slice(0, leaf.maxItems) : stored;
|
|
564
|
-
const read = kept.map((entry) => repairPrefValue(leaf.item, entry, validators));
|
|
565
|
-
return kept === stored && read.every((entry, i) => entry === stored[i]) ? stored : read;
|
|
566
|
-
}
|
|
567
|
-
function repairNumber(leaf, stored) {
|
|
568
|
-
if (typeof stored !== "number" || Number.isNaN(stored)) return leaf.default;
|
|
569
|
-
const { endless } = leaf;
|
|
570
|
-
if (stored === Infinity && (endless === "max" || endless === "both")) return stored;
|
|
571
|
-
if (stored === -Infinity && (endless === "min" || endless === "both")) return stored;
|
|
572
|
-
let v = stored;
|
|
573
|
-
if (leaf.min !== void 0 && v < leaf.min) v = leaf.min;
|
|
574
|
-
if (leaf.max !== void 0 && v > leaf.max) v = leaf.max;
|
|
575
|
-
return Number.isFinite(v) ? v : leaf.default;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
// src/stamp.ts
|
|
579
|
-
var isVersion = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0;
|
|
580
|
-
function stampRecord(value, at) {
|
|
581
|
-
return { $at: at, value };
|
|
582
|
-
}
|
|
583
|
-
function isStampedRecord(record) {
|
|
584
|
-
if (record === null || typeof record !== "object") return false;
|
|
585
|
-
const keys = Object.keys(record);
|
|
586
|
-
return keys.length === 2 && Object.hasOwn(record, "value") && isVersion(record.$at);
|
|
587
|
-
}
|
|
588
|
-
function readRecord(record, unstamped) {
|
|
589
|
-
return isStampedRecord(record) ? { at: record.$at, value: record.value, stamped: true } : { at: unstamped, value: record, stamped: false };
|
|
590
|
-
}
|
|
591
|
-
function recordValue(record) {
|
|
592
|
-
return isStampedRecord(record) ? record.value : record;
|
|
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;
|
|
290
|
+
};
|
|
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)}`
|
|
297
|
+
};
|
|
593
298
|
}
|
|
594
299
|
|
|
595
300
|
// src/migrate.ts
|
|
596
|
-
var
|
|
301
|
+
var isVersion = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0;
|
|
597
302
|
function runPrefsMigrations(cache, migrations, { stampAll = true } = {}) {
|
|
598
303
|
const target = migrations.length;
|
|
599
304
|
const raw = cache.get(VERSION_RECORD);
|
|
600
|
-
if (cache.has(VERSION_RECORD) && !
|
|
305
|
+
if (cache.has(VERSION_RECORD) && !isVersion(raw)) {
|
|
601
306
|
console.warn(
|
|
602
307
|
`[prefs] "${cache.prefix}" has an unreadable ${VERSION_RECORD} (${JSON.stringify(raw)}); opening read-only`
|
|
603
308
|
);
|
|
@@ -671,7 +376,7 @@ function watchPrefsVersion(cache, migrations) {
|
|
|
671
376
|
if (!stopped && cache.writable) migrate();
|
|
672
377
|
});
|
|
673
378
|
const heard = (version) => {
|
|
674
|
-
if (!
|
|
379
|
+
if (!isVersion(version)) {
|
|
675
380
|
console.warn(
|
|
676
381
|
`[prefs] "${cache.prefix}" has an unreadable ${VERSION_RECORD} (${JSON.stringify(version)}) from another writer; no longer persisting`
|
|
677
382
|
);
|
|
@@ -700,6 +405,8 @@ function watchPrefsVersion(cache, migrations) {
|
|
|
700
405
|
stopChanges();
|
|
701
406
|
};
|
|
702
407
|
}
|
|
408
|
+
|
|
409
|
+
// src/storeWrites.ts
|
|
703
410
|
var encodeInfinity = (leaf, value) => {
|
|
704
411
|
if (leaf.kind === "number") return value === Infinity || value === -Infinity ? String(value) : value;
|
|
705
412
|
if (leaf.kind === "list" && Array.isArray(value)) {
|
|
@@ -722,6 +429,58 @@ var encodeInfinity = (leaf, value) => {
|
|
|
722
429
|
}
|
|
723
430
|
return out ?? value;
|
|
724
431
|
};
|
|
432
|
+
function prefWrites({ leaves, cache, selectors, version, selection, warnIfClosed }) {
|
|
433
|
+
const unsetLocus = (leaf) => {
|
|
434
|
+
if (leaf.defaultLocus === void 0 || !leaf.splitBy?.length) return void 0;
|
|
435
|
+
return repairLocus(leaf.defaultLocus, leaf.splitBy, (by) => selectors.get(by), (member) => encodeInfinity(leaf, member));
|
|
436
|
+
};
|
|
437
|
+
const rawAt = (path, leaf) => cache.has(path) ? recordValue(cache.get(path)) : unsetLocus(leaf) ?? encodeInfinity(leaf, leaf.default);
|
|
438
|
+
const store = (path, stored) => {
|
|
439
|
+
cache.set(path, stored === void 0 ? void 0 : stampRecord(stored, version));
|
|
440
|
+
};
|
|
441
|
+
const splitOf = (path, by) => {
|
|
442
|
+
warnIfClosed(path);
|
|
443
|
+
const leaf = leaves.get(path);
|
|
444
|
+
const options = selectors.get(by);
|
|
445
|
+
if (leaf?.splitBy?.includes(by) && options) return { leaf, options };
|
|
446
|
+
console.warn(`[prefs] "${path}" cannot be split by "${by}"; ignoring`);
|
|
447
|
+
return void 0;
|
|
448
|
+
};
|
|
449
|
+
const set = (path, value, write) => {
|
|
450
|
+
warnIfClosed(path);
|
|
451
|
+
const leaf = leaves.get(path);
|
|
452
|
+
if (!leaf) {
|
|
453
|
+
console.warn(`[prefs] no leaf at "${path}"; ignoring the write`);
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
if (leaf.splitBy?.length && isPrefLocus(value)) {
|
|
457
|
+
store(path, mapLocusMembers(value, (member) => encodeInfinity(leaf, member)));
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const stored = encodeInfinity(leaf, value);
|
|
461
|
+
const had = cache.has(path) ? recordValue(cache.get(path)) : unsetLocus(leaf);
|
|
462
|
+
const intoMember = stored !== void 0 && leaf.splitBy?.length && isPrefLocus(had);
|
|
463
|
+
const under2 = write?.at ? selectionAt(selectors, selection(), write.at) : selection();
|
|
464
|
+
store(path, intoMember ? writeMember(had, under2, stored) : stored);
|
|
465
|
+
};
|
|
466
|
+
const split = (path, by) => {
|
|
467
|
+
const found = splitOf(path, by);
|
|
468
|
+
if (!found) return;
|
|
469
|
+
const had = rawAt(path, found.leaf);
|
|
470
|
+
const next = splitLocus(had, by, found.options, found.leaf.splitBy);
|
|
471
|
+
if (next !== had) store(path, next);
|
|
472
|
+
};
|
|
473
|
+
const join = (path, by) => {
|
|
474
|
+
const found = splitOf(path, by);
|
|
475
|
+
if (!found) return;
|
|
476
|
+
const had = rawAt(path, found.leaf);
|
|
477
|
+
const next = joinLocus(had, by, selection(), encodeInfinity(found.leaf, found.leaf.default));
|
|
478
|
+
if (next !== had) store(path, next);
|
|
479
|
+
};
|
|
480
|
+
return { set, split, join };
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// src/store.ts
|
|
725
484
|
function storedRecords(cache) {
|
|
726
485
|
const tree = {};
|
|
727
486
|
const branches = new WeakSet([tree]);
|
|
@@ -746,37 +505,14 @@ function storedRecords(cache) {
|
|
|
746
505
|
}
|
|
747
506
|
return tree;
|
|
748
507
|
}
|
|
749
|
-
function createPrefsStore(schema, cache, validators, onClose, version = 0) {
|
|
508
|
+
function createPrefsStore(schema, cache, validators, onClose, version = 0, blends) {
|
|
750
509
|
const leaves = new Map([...prefLeaves(schema)].filter(([, leaf]) => prefHoldsValue(leaf)));
|
|
751
510
|
for (const { field, at, problem } of checkPrefConditions(schema)) {
|
|
752
511
|
console.warn(`[prefs] ${field} of ${at === "" ? "the schema" : `"${at}"`}: ${problem}`);
|
|
753
512
|
}
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
const
|
|
757
|
-
const byPath = /* @__PURE__ */ new Map();
|
|
758
|
-
const raw = /* @__PURE__ */ new Map();
|
|
759
|
-
const unset = /* @__PURE__ */ new Set();
|
|
760
|
-
const tree = {};
|
|
761
|
-
for (const [path, leaf] of leaves) {
|
|
762
|
-
const has = cache.has(path);
|
|
763
|
-
let value;
|
|
764
|
-
if (!has) {
|
|
765
|
-
value = leaf.default;
|
|
766
|
-
unset.add(path);
|
|
767
|
-
} else {
|
|
768
|
-
const record = cache.get(path);
|
|
769
|
-
const stored = recordValue(record);
|
|
770
|
-
raw.set(path, record);
|
|
771
|
-
value = previous?.raw.has(path) && previous.raw.get(path) === record ? previous.byPath.get(path) : repairPrefValue(leaf, stored, validators);
|
|
772
|
-
}
|
|
773
|
-
byPath.set(path, value);
|
|
774
|
-
assignPrefValueAtPath(tree, path, value);
|
|
775
|
-
}
|
|
776
|
-
previous = { raw, byPath };
|
|
777
|
-
return { byPath, tree, unset };
|
|
778
|
-
};
|
|
779
|
-
const current = () => snapshot ??= build();
|
|
513
|
+
for (const { at, problem } of checkPrefSplits(schema)) console.warn(`[prefs] splitBy of "${at}": ${problem}`);
|
|
514
|
+
const source = { leaves, cache, selectors: prefSelectors(leaves), validators, blends };
|
|
515
|
+
const { current, peek, drop } = createSnapshots(source);
|
|
780
516
|
let storedTree = null;
|
|
781
517
|
let changed = createEmitter();
|
|
782
518
|
const stopCache = cache.subscribe((changes) => {
|
|
@@ -784,10 +520,16 @@ function createPrefsStore(schema, cache, validators, onClose, version = 0) {
|
|
|
784
520
|
if (records.length === 0) return;
|
|
785
521
|
storedTree = null;
|
|
786
522
|
const mine = records.filter((c) => leaves.has(c.name));
|
|
787
|
-
|
|
523
|
+
const before = peek();
|
|
524
|
+
if (mine.length > 0) drop();
|
|
788
525
|
const now = current();
|
|
789
|
-
const
|
|
790
|
-
|
|
526
|
+
const origins = new Map(mine.map((c) => [c.name, c.origin]));
|
|
527
|
+
for (const c of mine) {
|
|
528
|
+
for (const path of [...before?.splitBy.get(c.name) ?? [], ...now.splitBy.get(c.name) ?? []]) {
|
|
529
|
+
if (!origins.has(path)) origins.set(path, c.origin);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
changed.emit([...origins].map(([path, origin]) => ({ path, value: now.byPath.get(path), origin })));
|
|
791
533
|
});
|
|
792
534
|
let closed = false;
|
|
793
535
|
let warned = false;
|
|
@@ -798,17 +540,19 @@ function createPrefsStore(schema, cache, validators, onClose, version = 0) {
|
|
|
798
540
|
};
|
|
799
541
|
return {
|
|
800
542
|
schema,
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
543
|
+
...prefWrites({ leaves, cache, selectors: source.selectors, version, selection: () => current().selection, warnIfClosed }),
|
|
544
|
+
get: (path, read) => {
|
|
545
|
+
const now = current();
|
|
546
|
+
if (!read?.weights) return now.byPath.get(path);
|
|
804
547
|
const leaf = leaves.get(path);
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
return;
|
|
808
|
-
}
|
|
809
|
-
const stored = encodeInfinity(leaf, value);
|
|
810
|
-
cache.set(path, stored === void 0 ? void 0 : stampRecord(stored, version));
|
|
548
|
+
const weights = weightsUnder(source.selectors, now.selection, read.weights);
|
|
549
|
+
return leaf ? resolveHeld(source, leaf, now.held.get(path), weights) : void 0;
|
|
811
550
|
},
|
|
551
|
+
locus: (path) => {
|
|
552
|
+
const held = current().held.get(path);
|
|
553
|
+
return isPrefLocus(held) ? held : void 0;
|
|
554
|
+
},
|
|
555
|
+
loci: () => current().loci,
|
|
812
556
|
reset: (path) => {
|
|
813
557
|
warnIfClosed(path);
|
|
814
558
|
for (const p of leaves.keys()) {
|
|
@@ -816,7 +560,18 @@ function createPrefsStore(schema, cache, validators, onClose, version = 0) {
|
|
|
816
560
|
}
|
|
817
561
|
},
|
|
818
562
|
isSet: (path) => cache.has(path),
|
|
819
|
-
values: () =>
|
|
563
|
+
values: (read) => {
|
|
564
|
+
const now = current();
|
|
565
|
+
if (!read?.at) return now.tree;
|
|
566
|
+
const selection = selectionAt(source.selectors, now.selection, read.at);
|
|
567
|
+
const weights = selectionWeights(selection);
|
|
568
|
+
const tree = {};
|
|
569
|
+
for (const [path, leaf] of leaves) {
|
|
570
|
+
const set = source.selectors.has(path) ? selection[path] : resolveHeld(source, leaf, now.held.get(path), weights);
|
|
571
|
+
assignPrefValueAtPath(tree, path, set);
|
|
572
|
+
}
|
|
573
|
+
return tree;
|
|
574
|
+
},
|
|
820
575
|
unset: () => current().unset,
|
|
821
576
|
stored: () => storedTree ??= storedRecords(cache),
|
|
822
577
|
subscribe: (listener) => changed.subscribe(listener),
|
|
@@ -844,11 +599,11 @@ async function openPrefs(schema, options) {
|
|
|
844
599
|
const cache = await openRecords({ storage: options.storage, prefix: options.prefix });
|
|
845
600
|
const stop = watch(cache, options);
|
|
846
601
|
if (runPrefsMigrations(cache, options.migrations ?? [])) await cache.flush();
|
|
847
|
-
return createPrefsStore(schema, cache, options.validators, stop, options.migrations?.length ?? 0);
|
|
602
|
+
return createPrefsStore(schema, cache, options.validators, stop, options.migrations?.length ?? 0, options.blends);
|
|
848
603
|
}
|
|
849
604
|
function openPrefsSync(schema, options) {
|
|
850
605
|
const { cache, stop } = openPrefsCacheSync(options);
|
|
851
|
-
return createPrefsStore(schema, cache, options.validators, stop, options.migrations?.length ?? 0);
|
|
606
|
+
return createPrefsStore(schema, cache, options.validators, stop, options.migrations?.length ?? 0, options.blends);
|
|
852
607
|
}
|
|
853
608
|
function openPrefsCacheSync(options) {
|
|
854
609
|
const cache = openRecordsSync({ storage: options.storage, prefix: options.prefix });
|
|
@@ -858,6 +613,6 @@ function openPrefsCacheSync(options) {
|
|
|
858
613
|
}
|
|
859
614
|
var watch = (cache, options) => watchPrefsVersion(cache, options.migrations ?? []);
|
|
860
615
|
|
|
861
|
-
export { PREF_KINDS, UNSEEN,
|
|
862
|
-
//# sourceMappingURL=chunk-
|
|
863
|
-
//# 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
|