@weasel-js/prefs 1.9.3 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/helpers.ts","../src/migrate.ts","../src/repair.ts","../src/store.ts","../src/open.ts","../src/schema.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { PrefGroup, PrefLeaf, PrefNumber } from './schema';\n\n/**\n * A number leaf's bounds in the unit it is displayed in.\n *\n * Only what the leaf declares converts: an omitted bound has no stored\n * counterpart to put through the conversion, and its fallback — 0..100 for a\n * slider's track, a step of 1 — is a display-space number already. `min` and\n * `max` are points, so they convert the way the value does; `step` is a\n * distance, and a unit with an offset maps zero somewhere else, so converting\n * it as a point would scale it wrong. A decreasing conversion swaps which end\n * is the lower one.\n */\nexport function prefDisplayBounds(\n p: PrefNumber,\n): { min?: number; max?: number; step: number } {\n if (!p.unit) return { min: p.min, max: p.max, step: p.step ?? 1 };\n const { toDisplay } = p.unit;\n const lo = p.min === undefined ? undefined : toDisplay(p.min);\n const hi = p.max === undefined ? undefined : toDisplay(p.max);\n const flipped = lo !== undefined && hi !== undefined && lo > hi;\n const step = p.step === undefined\n ? 1\n : Math.abs(toDisplay(p.step) - toDisplay(0)) || p.step;\n return { min: flipped ? hi : lo, max: flipped ? lo : hi, step };\n}\n\n/** Distinguishes a leaf from a group while walking a schema tree. */\nexport function isPrefLeaf(node: PrefLeaf | PrefGroup): node is PrefLeaf {\n return 'kind' in node;\n}\n\n/** Get the value at a dotted path inside a nested value tree. Returns\n * `undefined` when a segment is missing or hits a non-object. */\nexport function prefValueAtPath(values: unknown, path: string): unknown {\n let cur: unknown = values;\n for (const seg of path.split('.')) {\n if (cur == null || typeof cur !== 'object') return undefined;\n cur = (cur as Record<string, unknown>)[seg];\n }\n return cur;\n}\n\n/**\n * Recursively drop `hidden` leaves (unless `showHidden`), pruning groups\n * that end up empty. Returns null when the entire subtree is hidden.\n */\nexport function visiblePrefSubtree<T extends PrefLeaf | PrefGroup>(\n node: T,\n showHidden: boolean,\n): T | null {\n if (isPrefLeaf(node)) return node.hidden && !showHidden ? null : node;\n const group = node as PrefGroup;\n const children: Record<string, PrefLeaf | PrefGroup> = {};\n for (const [key, child] of Object.entries(group.children)) {\n const kept = visiblePrefSubtree(child, showHidden);\n if (kept) children[key] = kept;\n }\n if (Object.keys(children).length === 0) return null;\n return { ...node, children };\n}\n\n/** The record holding the schema version the stored values were written at.\n * Reserved: no top-level schema key may take its name. */\nexport const VERSION_RECORD = '$version';\n\n/** Every leaf under `schema`, by dotted path, in schema order. */\nexport function prefLeaves(schema: PrefGroup): Map<string, PrefLeaf> {\n const out = new Map<string, PrefLeaf>();\n const walk = (group: PrefGroup, prefix: string): void => {\n for (const [key, child] of Object.entries(group.children)) {\n if (key.includes('.')) {\n throw new Error(`[prefs] schema key \"${key}\" contains \".\"; group keys are path segments`);\n }\n if (prefix === '' && key === VERSION_RECORD) {\n throw new Error(`[prefs] schema key \"${VERSION_RECORD}\" is reserved`);\n }\n const path = prefix === '' ? key : `${prefix}.${key}`;\n if (isPrefLeaf(child)) out.set(path, child);\n else walk(child, path);\n }\n };\n walk(schema, '');\n return out;\n}\n\n/** Set `value` at the dotted `path` in `root` itself, creating missing branches. */\nexport function assignPrefValueAtPath(root: Record<string, unknown>, path: string, value: unknown): void {\n const parts = path.split('.');\n let cursor = root;\n for (let i = 0; i < parts.length - 1; i++) {\n cursor = (cursor[parts[i]!] ??= {}) as Record<string, unknown>;\n }\n cursor[parts[parts.length - 1]!] = value;\n}\n\n/** Each of `schema`'s leaves that `tree` holds a value for, as a path and\n * that value — the inverse of building a tree from per-leaf records. */\nexport function flattenPrefValues(schema: PrefGroup, tree: unknown): [string, unknown][] {\n const out: [string, unknown][] = [];\n for (const path of prefLeaves(schema).keys()) {\n const value = prefValueAtPath(tree, path);\n if (value !== undefined) out.push([path, value]);\n }\n return out;\n}\n\n/** Whether one leaf answers to a filter query, by name, description or path. */\nfunction prefLeafMatches(pref: PrefLeaf, path: string, query: string): boolean {\n if (pref.name.toLowerCase().includes(query)) return true;\n if (pref.description?.toLowerCase().includes(query)) return true;\n return path.toLowerCase().includes(query);\n}\n\n/**\n * Drop every leaf that does not answer to `query`, pruning groups left empty.\n * A group whose own name matches keeps all of its leaves — a reader who typed\n * the group's name is asking for the group, not for leaves repeating it.\n *\n * An empty or whitespace query matches everything, so a cleared field restores\n * the tree rather than emptying it.\n */\nexport function filterPrefSubtree<T extends PrefLeaf | PrefGroup>(\n node: T,\n query: string,\n path = '',\n): T | null {\n const q = query.trim().toLowerCase();\n if (q === '') return node;\n if (isPrefLeaf(node)) return prefLeafMatches(node, path, q) ? node : null;\n const group = node as PrefGroup;\n if (group.name.toLowerCase().includes(q)) return node;\n const children: Record<string, PrefLeaf | PrefGroup> = {};\n for (const [key, child] of Object.entries(group.children)) {\n const kept = filterPrefSubtree(child, q, path === '' ? key : `${path}.${key}`);\n if (kept) children[key] = kept;\n }\n if (Object.keys(children).length === 0) return null;\n return { ...node, children };\n}\n","import type { OwnedRecordCache } from '@weasel-js/storage';\nimport { VERSION_RECORD } from './helpers';\n\nconst isVersion = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v) && v >= 0;\n\n/** Takes stored records from one version to the next: rename, transform or\n * delete entries in `records`, keyed by leaf path. */\nexport type PrefsMigration = (records: Map<string, unknown>) => void;\n\n/**\n * Bring `cache` up to `migrations.length`, the current version. Every record\n * a migration leaves is written back, so a migration may replace values or\n * mutate them in place. Stops writing, and writes nothing, when the stored\n * version is newer than this build knows or a migration throws. Returns\n * whether it wrote.\n */\nexport function runPrefsMigrations(\n cache: OwnedRecordCache,\n migrations: readonly PrefsMigration[],\n): boolean {\n const target = migrations.length;\n const raw = cache.get(VERSION_RECORD);\n if (cache.has(VERSION_RECORD) && !isVersion(raw)) {\n console.warn(\n `[prefs] \"${cache.prefix}\" has an unreadable ${VERSION_RECORD} (${JSON.stringify(raw)}); opening read-only`,\n );\n cache.stopWriting();\n return false;\n }\n const stored = cache.has(VERSION_RECORD) ? (raw as number) : 0;\n if (stored > target) {\n console.warn(\n `[prefs] \"${cache.prefix}\" was written at version ${stored}, newer than this build's ${target}; opening read-only`,\n );\n cache.stopWriting();\n return false;\n }\n if (stored === target || !cache.writable) return false;\n\n const before = cache.entries().filter(([name]) => name !== VERSION_RECORD);\n const records = new Map(before.map(([name, value]): [string, unknown] => [name, structuredClone(value)]));\n for (let v = stored; v < target; v++) {\n try {\n migrations[v]!(records);\n } catch (error) {\n console.warn(\n `[prefs] migration ${v} → ${v + 1} for \"${cache.prefix}\" threw; opening read-only on the unmigrated records`,\n error,\n );\n cache.stopWriting();\n return false;\n }\n }\n for (const [name] of before) if (!records.has(name)) cache.delete(name);\n for (const [name, value] of records) {\n if (value === undefined) cache.delete(name);\n else cache.set(name, value);\n }\n cache.set(VERSION_RECORD, target);\n return true;\n}\n\n/**\n * Stop persisting when another writer, a newer build in another tab, records a\n * version past `target`: this build would otherwise keep writing the old shape.\n * Returns the unsubscribe.\n */\nexport function watchPrefsVersion(cache: OwnedRecordCache, target: number): () => void {\n return cache.subscribe((changes) => {\n for (const change of changes) {\n if (change.origin !== 'remote' || change.name !== VERSION_RECORD || change.value === undefined) continue;\n if (!isVersion(change.value)) {\n console.warn(\n `[prefs] \"${cache.prefix}\" has an unreadable ${VERSION_RECORD} (${JSON.stringify(change.value)}) from another writer; no longer persisting`,\n );\n cache.stopWriting();\n } else if (change.value > target) {\n console.warn(\n `[prefs] \"${cache.prefix}\" was migrated to version ${change.value} by another writer; this build knows ${target}; no longer persisting`,\n );\n cache.stopWriting();\n }\n }\n });\n}\n","import type { PrefBoolean, PrefEnum, PrefLeaf, PrefNumber, PrefObject } from './schema';\n\n/** Decides what a stored value reads as for one kind of leaf: the value to\n * read, or `undefined` for \"invalid, read the default\". */\nexport type PrefValidator = (stored: unknown, leaf: PrefLeaf) => unknown;\n\n/** What `stored` reads as for `leaf`. Never writes anything back: a schema\n * rolled back finds the original still in storage. */\nexport function repairPrefValue(\n leaf: PrefLeaf,\n stored: unknown,\n validators?: Readonly<Record<string, PrefValidator>>,\n): unknown {\n if (leaf.kind === 'number') {\n if (stored === 'Infinity') stored = Infinity;\n else if (stored === '-Infinity') stored = -Infinity;\n }\n const validate = validators?.[leaf.kind];\n if (validate) {\n try {\n const out = validate(stored, leaf);\n return out === undefined ? leaf.default : out;\n } catch {\n return leaf.default;\n }\n }\n switch (leaf.kind) {\n case 'number':\n return repairNumber(leaf as PrefNumber, stored);\n case 'boolean':\n return (leaf as PrefBoolean).encoding || typeof stored === 'boolean' ? stored : leaf.default;\n case 'string':\n case 'color':\n case 'field':\n return typeof stored === 'string' ? stored : leaf.default;\n case 'enum': {\n const e = leaf as PrefEnum;\n if (e.encoding) return stored;\n return e.options.some((o) => o.value === stored) ? stored : leaf.default;\n }\n case 'object':\n if ((leaf as PrefObject).fromScalar || isPlainObject(stored)) return stored;\n return leaf.default;\n default:\n return stored;\n }\n}\n\nfunction isPlainObject(v: unknown): boolean {\n return v !== null && typeof v === 'object' && !Array.isArray(v);\n}\n\nfunction repairNumber(leaf: PrefNumber, stored: unknown): unknown {\n if (typeof stored !== 'number' || Number.isNaN(stored)) return leaf.default;\n const { endless } = leaf;\n if (stored === Infinity && (endless === 'max' || endless === 'both')) return stored;\n if (stored === -Infinity && (endless === 'min' || endless === 'both')) return stored;\n let v = stored;\n if (leaf.min !== undefined && v < leaf.min) v = leaf.min;\n if (leaf.max !== undefined && v > leaf.max) v = leaf.max;\n return Number.isFinite(v) ? v : leaf.default;\n}\n","import type { OwnedRecordCache } from '@weasel-js/storage';\nimport { assignPrefValueAtPath, prefLeaves, VERSION_RECORD } from './helpers';\nimport type { PrefPath, PrefValueAt } from './paths';\nimport { type PrefValidator, repairPrefValue } from './repair';\nimport type { PrefGroup, PrefLeaf } from './schema';\n\n/** One leaf changing, as a store subscriber hears it: the value readers now\n * see, and whether this store or another writer made the change. */\nexport interface PrefChange {\n path: string;\n value: unknown;\n origin: 'local' | 'remote';\n}\n\n/** Values for one schema, held in memory and persisted behind. */\nexport interface PrefsStore<S extends PrefGroup> {\n readonly schema: S;\n /** The leaf's value, repaired against the schema; its default when unset. */\n get<P extends PrefPath<S>>(path: P): PrefValueAt<S, P>;\n set<P extends PrefPath<S>>(path: P, value: PrefValueAt<S, P>): void;\n /** Unset every leaf at or under `path`; with no path, all. */\n reset(path?: string): void;\n /** Whether the leaf has a value of its own rather than following its default. */\n isSet(path: PrefPath<S>): boolean;\n /** Every leaf's value as a nested tree. The same object until something changes. */\n values(): Record<string, unknown>;\n /** The leaves following their default. The same set until something changes. */\n unset(): ReadonlySet<string>;\n /** Every stored record as a nested tree, unrepaired, including records no\n * leaf describes. The same object until something changes. */\n stored(): Record<string, unknown>;\n /** `changes` is empty when only records no leaf describes changed. */\n subscribe(listener: (changes: PrefChange[]) => void): () => void;\n /** False when the store cannot persist: storage was unreadable, or written\n * by a newer schema. Changes still apply for this session. */\n readonly writable: boolean;\n /** Resolves true when every queued write reached storage. */\n flush(): Promise<boolean>;\n close(): Promise<void>;\n}\n\ninterface Snapshot {\n byPath: Map<string, unknown>;\n tree: Record<string, unknown>;\n unset: ReadonlySet<string>;\n}\n\n/** JSON storage cannot keep an infinity; `repairPrefValue` reads these back. */\nconst encodeInfinity = (leaf: PrefLeaf, value: unknown): unknown =>\n leaf.kind === 'number' && (value === Infinity || value === -Infinity) ? String(value) : value;\n\n/** A store over an open cache. `openPrefs` / `openPrefsSync` are the usual\n * way in; they run migrations first. */\nexport function createPrefsStore<S extends PrefGroup>(\n schema: S,\n cache: OwnedRecordCache,\n validators?: Readonly<Record<string, PrefValidator>>,\n onClose?: () => void,\n): PrefsStore<S> {\n const leaves = prefLeaves(schema);\n let snapshot: Snapshot | null = null;\n let previous: { raw: Map<string, unknown>; byPath: Map<string, unknown> } | null = null;\n\n const build = (): Snapshot => {\n const byPath = new Map<string, unknown>();\n const raw = new Map<string, unknown>();\n const unset = new Set<string>();\n const tree: Record<string, unknown> = {};\n for (const [path, leaf] of leaves) {\n const has = cache.has(path);\n let value: unknown;\n if (!has) {\n value = leaf.default;\n unset.add(path);\n } else {\n const stored = cache.get(path);\n raw.set(path, stored);\n value =\n previous?.raw.has(path) && previous.raw.get(path) === stored\n ? previous.byPath.get(path)\n : repairPrefValue(leaf, stored, validators);\n }\n byPath.set(path, value);\n assignPrefValueAtPath(tree, path, value);\n }\n previous = { raw, byPath };\n return { byPath, tree, unset };\n };\n const current = (): Snapshot => (snapshot ??= build());\n\n let storedTree: Record<string, unknown> | null = null;\n const buildStored = (): Record<string, unknown> => {\n const tree: Record<string, unknown> = {};\n const branches = new WeakSet<object>([tree]);\n for (const [name, value] of cache.entries()) {\n if (name === VERSION_RECORD) continue;\n const parts = name.split('.');\n let cursor = tree;\n for (const part of parts.slice(0, -1)) {\n const next = cursor[part];\n // A record's own value is never descended into: one named `a` and\n // another `a.b` cannot both show, and the branch wins.\n if (typeof next === 'object' && next !== null && branches.has(next)) {\n cursor = next as Record<string, unknown>;\n } else {\n const branch: Record<string, unknown> = {};\n branches.add(branch);\n cursor[part] = branch;\n cursor = branch;\n }\n }\n const last = parts[parts.length - 1]!;\n if (!branches.has(cursor[last] as object)) cursor[last] = value;\n }\n return tree;\n };\n\n const listeners = new Set<(changes: PrefChange[]) => void>();\n const stopCache = cache.subscribe((changes) => {\n const records = changes.filter((c) => c.name !== VERSION_RECORD);\n if (records.length === 0) return;\n storedTree = null;\n const mine = records.filter((c) => leaves.has(c.name));\n if (mine.length > 0) snapshot = null;\n const now = current();\n const out = mine.map((c): PrefChange => ({ path: c.name, value: now.byPath.get(c.name), origin: c.origin }));\n for (const listener of [...listeners]) listener(out);\n });\n\n return {\n schema,\n get: (path) => current().byPath.get(path) as never,\n set: (path, value) => {\n const leaf = leaves.get(path);\n if (!leaf) {\n console.warn(`[prefs] no leaf at \"${path}\"; ignoring the write`);\n return;\n }\n cache.set(path, encodeInfinity(leaf, value));\n },\n reset: (path) => {\n for (const p of leaves.keys()) {\n if (path === undefined || p === path || p.startsWith(`${path}.`)) cache.delete(p);\n }\n },\n isSet: (path) => cache.has(path),\n values: () => current().tree,\n unset: () => current().unset,\n stored: () => (storedTree ??= buildStored()),\n subscribe: (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n get writable() {\n return cache.writable;\n },\n flush: () => cache.flush(),\n close: async () => {\n onClose?.();\n stopCache();\n listeners.clear();\n await cache.close();\n },\n };\n}\n","import {\n openRecords,\n openRecordsSync,\n type OwnedRecordCache,\n type StorageAdapter,\n type SyncStorageAdapter,\n} from '@weasel-js/storage';\nimport { type PrefsMigration, runPrefsMigrations, watchPrefsVersion } from './migrate';\nimport type { PrefValidator } from './repair';\nimport type { PrefGroup } from './schema';\nimport { createPrefsStore, type PrefsStore } from './store';\n\n/** Options for `openPrefs` and `openPrefsSync`. */\nexport interface PrefsOptions {\n storage: StorageAdapter;\n /** Prepended to every record's key: `'myapp.prefs.'`. */\n prefix: string;\n /** `migrations[i]` takes stored records from version `i` to `i + 1`. The\n * current version is `migrations.length`. */\n migrations?: readonly PrefsMigration[];\n /** Validators for app-defined kinds, keyed by `kind`. One given for a\n * built-in kind replaces that kind's own rule. */\n validators?: Readonly<Record<string, PrefValidator>>;\n}\n\n/** Load every stored value for `schema`, migrate it, and return the store. */\nexport async function openPrefs<S extends PrefGroup>(\n schema: S,\n options: PrefsOptions,\n): Promise<PrefsStore<S>> {\n const cache = await openRecords({ storage: options.storage, prefix: options.prefix });\n const stop = watch(cache, options);\n if (runPrefsMigrations(cache, options.migrations ?? [])) await cache.flush();\n return createPrefsStore(schema, cache, options.validators, stop);\n}\n\n/** `openPrefs` for an adapter that reads synchronously: the store is ready\n * on return, so values can be read before anything renders. */\nexport function openPrefsSync<S extends PrefGroup>(\n schema: S,\n options: PrefsOptions & { storage: SyncStorageAdapter },\n): PrefsStore<S> {\n const cache = openRecordsSync({ storage: options.storage, prefix: options.prefix });\n const stop = watch(cache, options);\n if (runPrefsMigrations(cache, options.migrations ?? [])) void cache.flush();\n return createPrefsStore(schema, cache, options.validators, stop);\n}\n\n/** Attached before migrations run, so a peer's version bump during the open's\n * own flush is heard. */\nconst watch = (cache: OwnedRecordCache, options: PrefsOptions): (() => void) | undefined =>\n cache.writable ? watchPrefsVersion(cache, (options.migrations ?? []).length) : undefined;\n","// The preferences schema: groups of typed leaves. Tools declare theirs as a\n// `PrefGroup`; apps compose them into one registry, which `PrefsForm` renders\n// and `openPrefs` stores.\n\nimport { formatUnit, unitScale } from '@weasel-js/quantity';\nimport type { Display, InfinityText, Unit, UnitEntry, UnitScale, UnitSystem } from '@weasel-js/quantity';\n\n/** The value types a built-in pref leaf can hold. */\nexport type PrefKind =\n | 'number' | 'boolean' | 'string' | 'enum' | 'color' | 'paint' | 'object' | 'field';\n\n/**\n * Leaves that share one row in a compact property UI (weasel-ui\n * `SelectionPanel`, labkit's `ControlPanel`), declared on the first of them.\n * Purely presentational.\n */\nexport interface PrefPair {\n /** The other leaves on the row, by the full path their values are read and\n * written at (`'pose.y'`, `'camera.type'`), in order. Each must follow the\n * one before it among its siblings. */\n with: string | readonly string[];\n /** What the row reads. Default: the declaring leaf's `name`. */\n label?: string;\n}\n\n/** The fields every leaf pref shares, keyed by its `kind` and typed by its stored value. */\nexport interface PrefBase<K extends string, Value> {\n kind: K;\n /** Human-readable label. */\n name: string;\n /** Longer help text — shown in tooltips / a settings pane. */\n description: string;\n /** Fallback when nothing is persisted. */\n default: Value;\n /** Hide from a host app's settings UI by default. */\n hidden?: boolean;\n /** Render full-width with no label row in schema-driven settings UIs\n * (weasel-ui `PrefsForm` honors this for leaves whose control brings\n * its own chrome). */\n block?: boolean;\n /** Glyph naming this leaf in a host UI's icon set (weasel-ui resolves it\n * against `ICON_PATHS`). A plain string because this package ships no\n * icon set and cannot depend on one. Read where a leaf's `name` has nowhere to go — a\n * `pair`ed row is labeled by the pair, so its fields have only the glyph\n * to tell them apart. */\n icon?: string;\n /** Puts this leaf and the ones it names on one row. */\n pair?: PrefPair;\n /** Shorter forms of `name`, longest first. A surface short of room for\n * `name` — a strip of controls on one line, a segment in a `pair`ed row —\n * shows the longest of them that fits. `name` stays the accessible name, so\n * these abbreviate without costing anything. */\n short?: readonly string[];\n}\n\n/** How a schema-driven UI should present a number pref. */\nexport type PrefNumberControl = 'input' | 'slider';\n/** How a schema-driven UI should present a boolean pref. */\nexport type PrefBooleanControl = 'checkbox' | 'switch' | 'toggle';\n/** How a schema-driven UI should present a string pref. */\nexport type PrefStringControl = 'input' | 'textarea';\n/** How a schema-driven UI should present an enum pref. */\nexport type PrefEnumControl = 'select' | 'radio' | 'toggle';\n\n/** Display-unit conversion for number leaves whose stored value uses a\n * canonical unit the user shouldn't see (e.g. radians stored, degrees\n * shown). The stored value stays canonical; UIs convert at the edge. */\nexport interface PrefNumberUnit {\n toDisplay: (stored: number) => number;\n fromDisplay: (display: number) => number;\n /** Shown after the input, e.g. `'°'`. */\n suffix?: string;\n /** Suffixes a person may type, each mapped to the scale that turns a\n * number in that unit into a display number: `{ mm: 0.1, cm: 1 }` for a\n * field showing centimeters. A unit that disagrees with the display unit\n * about zero carries an `offset` as well. */\n accepts?: Readonly<Record<string, UnitEntry>>;\n /** The stored value as display text, suffix included. */\n format?: (stored: number) => string;\n}\n\n/**\n * A display unit built from a {@link UnitSystem}: values are stored in the\n * system's base and shown in `display`, rounded to `precision` places when\n * given, and every unit in the system is accepted as typed text. `suffix`\n * defaults to the unit's name and is accepted too.\n */\nexport function prefUnit(\n system: UnitSystem,\n display: Unit,\n opts?: { precision?: number; suffix?: string },\n): PrefNumberUnit {\n let self: Required<UnitScale>;\n try {\n self = unitScale(system, display);\n } catch (e) {\n throw new Error(`prefUnit: ${e instanceof Error ? e.message : String(e)}`);\n }\n const scale = opts?.precision === undefined ? undefined : 10 ** opts.precision;\n const suffix = opts?.suffix ?? display;\n const accepts: Record<string, UnitEntry> = { [suffix]: 1 };\n for (const name of Object.keys(system.units)) {\n const other = unitScale(system, name);\n // A number typed in `name` reaches display units through base:\n // `(n * factor + offset - self.offset) / self.factor`.\n const factor = other.factor / self.factor;\n const offset = (other.offset - self.offset) / self.factor;\n accepts[name] = offset === 0 ? factor : { factor, offset };\n }\n const toDisplay = (stored: number) => {\n const shown = (stored - self.offset) / self.factor;\n return scale === undefined ? shown : Math.round(shown * scale) / scale;\n };\n return {\n toDisplay,\n fromDisplay: (shown) => shown * self.factor + self.offset,\n suffix,\n accepts,\n format: (stored) =>\n `${formatUnit(stored, display, system, {\n precision: opts?.precision ?? 2,\n suffix: false,\n })}${suffix}`,\n };\n}\n\n/** A numeric pref, optionally bounded and stepped, and optionally stored in a\n * different unit from the one shown. */\nexport interface PrefNumber extends PrefBase<'number', number> {\n min?: number;\n max?: number;\n step?: number;\n control?: PrefNumberControl;\n /** How the value shows, speaks and reads back when typed — `compact()`\n * reads `2.00M`. Presentation only: the stored value stays a number. */\n display?: Display;\n unit?: PrefNumberUnit;\n /** Which end of a slider stands for infinity: the value there is ±Infinity. */\n endless?: 'min' | 'max' | 'both';\n /** The word infinity shows as — `'never'`, `'uncapped'`. Default `∞`. */\n infinity?: InfinityText;\n}\n/**\n * Stored-value bridge for a boolean leaf whose field is not a boolean — the\n * flag counterpart of {@link PrefEnumEncoding}. `TextStyle.fontStyle` is\n * the case: it stores `'italic'`, and the control is an Italic toggle.\n */\nexport interface PrefBooleanEncoding {\n /** Whether `stored` reads as on. */\n read: (stored: unknown, siblings: Record<string, unknown> | undefined) => boolean;\n /** What to store for `on`. `undefined` removes the field. */\n write: (on: boolean, siblings: Record<string, unknown> | undefined) => unknown;\n}\n\n/** An on/off pref. */\nexport interface PrefBoolean extends PrefBase<'boolean', boolean> {\n control?: PrefBooleanControl;\n encoding?: PrefBooleanEncoding;\n}\n/** A free-text pref. */\nexport interface PrefString extends PrefBase<'string', string> {\n control?: PrefStringControl;\n}\n/**\n * Stored-value bridge for an enum leaf whose value is not the option string —\n * the counterpart of {@link PrefNumberUnit}, which does the same for a\n * number stored in a canonical unit.\n *\n * A dash array is the case that needs it: `Stroke.dash` stores lengths, and\n * the thing a person chooses is a style. The presets scale by the stroke's\n * width, so both directions are given the object's other fields — a style is\n * meaningless without the width it is a multiple of.\n */\nexport interface PrefEnumEncoding<T extends string = string> {\n /**\n * The option `stored` reads as, or `undefined` for none — which a UI shows\n * the way it shows a mixed selection, by selecting nothing.\n *\n * `siblings` is the object the leaf is a field of, or `undefined` when the\n * node does not hold that object (and for a top-level leaf, which has none).\n */\n read: (stored: unknown, siblings: Record<string, unknown> | undefined) => T | undefined;\n /** What to store for `option`. `undefined` removes the field. */\n write: (option: T, siblings: Record<string, unknown> | undefined) => unknown;\n}\n\n/** A pref with a fixed set of labeled choices. `default` is `undefined` only\n * for a {@link PrefEnum.clearable} leaf, whose absence is a value. */\nexport interface PrefEnum<T extends string = string>\n extends PrefBase<'enum', T | undefined> {\n /**\n * The field may hold none of the options, and that absence is a state of\n * its own rather than a missing value — a script that is neither super nor\n * sub. A toggle control then lets the chosen segment be clicked off, which\n * removes the field.\n */\n clearable?: boolean;\n /** `short` holds shorter forms of `label`, longest first, for a segmented\n * control too narrow for the full one — down to a capital or two. `icon`\n * names a glyph in the host UI's set (weasel-ui resolves it against\n * `ICON_PATHS`), drawn in place of any text form where it resolves. It is\n * a plain string because this package ships no icon set and cannot\n * depend on one. The full `label` stays the accessible name, so neither the abbreviation nor the glyph becomes the only thing naming\n * the option.\n *\n * `disabled` marks an option a control reports but cannot author — the\n * value a stored form reads as when it matches nothing offered. Dropping it\n * from the list instead would leave the control selecting nothing and\n * claiming the field is unset. */\n options: readonly {\n value: T;\n label: string;\n short?: readonly string[];\n icon?: string;\n disabled?: boolean;\n }[];\n control?: PrefEnumControl;\n encoding?: PrefEnumEncoding<T>;\n}\n\n/** A single color, stored as a hex string. For a value that may also be a\n * gradient or a pattern, use {@link PrefPaint} instead. */\nexport interface PrefColor extends PrefBase<'color', string> {\n /** Value is `#rrggbb`, or `#rrggbbaa` when `alpha` is set (UIs then\n * offer an opacity control). */\n alpha?: boolean;\n}\n\n/**\n * Open leaf: any node with a `kind` outside the built-ins. Schema-driven\n * UIs (weasel-ui `PrefsForm` / `SelectionPanel`) dispatch it to an\n * app-supplied renderer. Deliberately NOT index-signatured so concrete\n * app interfaces stay assignable. Mirrors weasel-ui's `PrefCustom`.\n */\nexport type PrefCustom = PrefBase<string, unknown>;\n\n/**\n * A whole `FillStyle`, not a color inside one. Use it wherever the value is\n * the tagged paint union — a solid color, a pattern, a gradient — rather\n * than a hex string.\n *\n * Addressing `…fill.color` instead reads `undefined` off a gradient (so the\n * control shows its default and claims the text is black) and writes a\n * hybrid `{ fill: 'gradient', stops, color }` that the renderer's structural\n * `'color' in paint` checks then paint flat solid. The union has to be\n * edited as a union.\n */\nexport interface PrefPaint extends PrefBase<'paint', unknown> {\n /** Offer an opacity control alongside the color. */\n alpha?: boolean;\n}\n\n/**\n * A leaf whose value is one object, with its own fields hanging off it.\n *\n * A compound value — a stroke, a shadow, a pattern spec — could be described\n * as several sibling leaves addressing into it (`data.stroke.width`,\n * `data.stroke.cap`). It shouldn't be: each control would then write one field\n * of a value it can only half see, and writing into something that is not an\n * object yet corrupts it. Here the fields are `children` of one leaf, and\n * every edit commits the parent object whole.\n *\n * `children` paths are relative to the object. They are ordinary leaves, so a\n * field that is itself a union (a stroke's `paint`) declares the kind that\n * edits that union. A child may also be a {@link PrefGroup}, which\n * organises the fields under a heading without contributing to the path —\n * the same rule group keys follow at the top level. A `TextStyle` needs it:\n * its character and paragraph fields belong to one value but read as two\n * lists.\n */\nexport interface PrefObject extends PrefBase<'object', unknown> {\n children: Record<string, PrefLeaf | PrefGroup>;\n /**\n * Lift a non-object value into the object form, for a consumer field that\n * may also be held as a scalar. Called before a child edit is applied;\n * without it a scalar-valued leaf shows its children empty and refuses the\n * edit.\n */\n fromScalar?: (value: unknown) => Record<string, unknown>;\n}\n\n/**\n * A reference to another field of the same schema, held as the full path its\n * value is read and written at (`'camera.type'`) — the currency fields refer\n * to each other in. A surface offers the fields it draws as the choices.\n */\nexport interface PrefField extends PrefBase<'field', string> {\n /** Only fields of these kinds may be named. Default: any leaf. */\n kinds?: readonly string[];\n}\n\n/** One built-in pref leaf. `PrefLeaf` widens this to include\n * app-defined kinds. */\nexport type BuiltinPref =\n | PrefNumber\n | PrefBoolean\n | PrefString\n | PrefEnum\n | PrefColor\n | PrefPaint\n | PrefObject\n | PrefField;\n\n// Compile-time tie: every built-in leaf kind must appear in PrefKind\n// and vice versa (PrefBase's K is open for PrefCustom's sake, so\n// the union no longer enforces it).\ntype _BuiltinKindsExact = [BuiltinPref['kind']] extends [PrefKind]\n ? [PrefKind] extends [BuiltinPref['kind']] ? true : never\n : never;\nconst _builtinKindsExact: _BuiltinKindsExact = true;\nvoid _builtinKindsExact;\n\n/**\n * The built-in kinds, as a table. A kind added to {@link PrefKind} is a\n * compile error here, and from here it is one in every renderer's `never`\n * guard — the only thing standing between a new kind and rendering as\n * nothing in four places at once.\n */\nexport const PREF_KINDS: Record<PrefKind, true> = {\n number: true,\n boolean: true,\n string: true,\n enum: true,\n color: true,\n paint: true,\n object: true,\n field: true,\n};\n\n/** Which row each pairing among `leaves` puts a path on: a `key` the row's\n * members share (the declaring leaf's path) and the `label` it reads. A\n * path no `pair` names is absent. `leaves` are given by the path each\n * surface reads and writes them at, so references resolve in its terms. */\nexport function pairRowsOf(\n leaves: Iterable<readonly [path: string, leaf: PrefLeaf]>,\n): Map<string, { key: string; label: string }> {\n const rows = new Map<string, { key: string; label: string }>();\n for (const [path, leaf] of leaves) {\n if (!leaf.pair || rows.has(path)) continue;\n const row = { key: path, label: leaf.pair.label ?? leaf.name };\n rows.set(path, row);\n const partners = typeof leaf.pair.with === 'string' ? [leaf.pair.with] : leaf.pair.with;\n for (const partner of partners) if (!rows.has(partner)) rows.set(partner, row);\n }\n return rows;\n}\n\n/**\n * Narrows a leaf to the built-in union, so a renderer's switch discriminates\n * on {@link PrefKind} instead of the open `string` that\n * {@link PrefCustom} widens `kind` to. An app-defined kind answers false\n * and belongs to the renderer's custom-renderer path.\n */\nexport function isBuiltinPref(leaf: PrefLeaf): leaf is BuiltinPref {\n return Object.hasOwn(PREF_KINDS, leaf.kind);\n}\n\n/** Built-in or app-defined leaf. */\nexport type PrefLeaf = BuiltinPref | PrefCustom;\n\n/** Nestable group: branch nodes a tool can use to organize its prefs. */\nexport interface PrefGroup {\n /** Heading for the group's rows. **Empty means no heading** — for a group\n * that exists to organise, not to name: one whose children are themselves\n * groups carrying the labels a reader needs. Give it a name whenever the\n * name is the referent (a `Border` group over `Top` / `Right` / `Bottom`\n * reads as nothing without it). */\n name: string;\n description?: string;\n children: Record<string, PrefLeaf | PrefGroup>;\n}\n"]}
1
+ {"version":3,"sources":["../src/tabRuns.ts","../src/shown.ts","../src/judge.ts","../src/scopeAt.ts","../src/scope.ts","../src/aliasTargets.ts","../src/object.ts","../src/type.ts","../src/groups.ts","../src/pair.ts","../src/kinds.ts"],"names":["scope","kept"],"mappings":"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","file":"index.js","sourcesContent":["/** One step of a walk over a group's children: a child on its own, or the neighboring `tab` children that share one strip. */\nexport type PrefTabRun<T> = { item: T; tabs?: undefined } | { tabs: readonly T[]; item?: undefined };\n\n/**\n * `items` in order, each run of neighbors `isTab` holds for folded into one step. What a surface leaves out of\n * `items` neither joins a run nor ends one, and what it keeps and then declines to draw still holds its run together.\n */\nexport function prefTabRuns<T>(items: readonly T[], isTab: (item: T) => boolean): PrefTabRun<T>[] {\n const out: PrefTabRun<T>[] = [];\n let run: T[] | undefined;\n for (const item of items) {\n if (!isTab(item)) {\n run = undefined;\n out.push({ item });\n } else if (run) {\n run.push(item);\n } else {\n out.push({ tabs: (run = [item]) });\n }\n }\n return out;\n}\n","// A stored value as the control over its leaf shows it. A condition compares\n// that, and not the stored form: a person writes \"is on\" about an Italic\n// toggle, whatever string the toggle stores.\n\nimport type { PrefConditionReader } from './condition';\nimport type { PrefGroup, PrefSection } from './groups';\nimport { prefLeafHolding, prefLeafHoldingIn, prefSchemaHolding, UNSEEN } from './holding';\nimport type { PrefBoolean, PrefEnum, PrefLeaf } from './schema';\n\ntype Siblings = Record<string, unknown> | undefined;\n\n/** What the control over `leaf` shows for `stored`: what its `encoding` reads it as, else `stored` itself.\n * `siblings` is the object the leaf is a field of. */\nexport function prefShownValue(leaf: PrefLeaf, stored: unknown, siblings?: Record<string, unknown>): unknown {\n if (leaf.kind !== 'boolean' && leaf.kind !== 'enum') return stored;\n const { encoding } = leaf as PrefBoolean | PrefEnum;\n return encoding ? (encoding.read as (stored: unknown, siblings: Siblings) => unknown)(stored, siblings) : stored;\n}\n\n/**\n * `read` with each value handed back as {@link prefShownValue} gives it, for\n * the leaf of `schema` at that path, a field of an `object` or a `union` leaf\n * included. A field's siblings are what `read` finds at its leaf's path. A\n * path read from the entry is held to `item`, the leaf describing that entry.\n * A path no leaf of `schema` holds is held to `over`, the schema it is drawn\n * over.\n */\nexport function prefShownReader(\n schema: PrefGroup | PrefSection, read: PrefConditionReader, item?: PrefLeaf, over?: PrefGroup | PrefSection,\n): PrefConditionReader {\n return (path, from) => {\n const stored = read(path, from);\n const held = from === 'item' ? item && prefLeafHoldingIn(item, path) : prefLeafHolding(prefSchemaHolding(schema, path, over), path);\n if (held === undefined || held === UNSEEN) return stored;\n const object = held.within === undefined ? undefined : read(held.within, from);\n return prefShownValue(held.leaf, stored, typeof object === 'object' && object !== null ? (object as Siblings) : undefined);\n };\n}\n","// Who answers a condition: a judge, made from a way to read values.\n\nimport { prefConditionHolds, prefConditionReadsItem, type PrefCondition, type PrefConditionReader } from './condition';\nimport type { PrefGroup, PrefSection } from './groups';\nimport { isPrefLeaf, isPrefSection, prefSectionLeaves, prefValueAtPath } from './helpers';\nimport { prefSchemaHolding } from './holding';\nimport type { PrefLeaf } from './schema';\nimport { prefShownReader } from './shown';\n\n/** Which of a node's two conditions a {@link PrefConditionJudge} is asked about. */\nexport type PrefConditionField = 'showIf' | 'enableIf';\n\n/**\n * Says whether one condition holds. {@link prefJudge} makes one from a value\n * reader; a surface drawing several values at once writes its own, to say\n * what a condition that holds for some and not for others comes to.\n */\nexport type PrefConditionJudge = (condition: PrefCondition, field: PrefConditionField) => boolean;\n\n/** One entry of a list or a map: the `item` leaf describing it, and what it holds. */\nexport interface PrefEntry {\n item: PrefLeaf;\n value: unknown;\n}\n\n/** What `entry` holds at `path`, the empty path being the entry itself: its own value, else that part of the item's default. */\nfunction entryValue({ item, value }: PrefEntry, path: string): unknown {\n if (path === '') return value !== undefined ? value : item.default;\n const held = prefValueAtPath(value, path);\n return held !== undefined ? held : prefValueAtPath(item.default, path);\n}\n\n/**\n * A judge over one set of values, read by path. A condition compares each\n * value as the control over its leaf in `schema` shows it\n * ({@link prefShownReader}), so `read` hands back what is stored. A test\n * that reads from the entry (`from: 'item'`) reads `entry`, and finds nothing\n * held where none is given. `over` is the schema `schema` is drawn over: a\n * path no leaf of `schema` holds is compared as the leaf of `over` there\n * shows it.\n */\nexport function prefJudge(\n schema: PrefGroup | PrefSection, read: (path: string) => unknown, entry?: PrefEntry, over?: PrefGroup | PrefSection,\n): PrefConditionJudge {\n const stored: PrefConditionReader = (path, from) => (from === 'item' ? entry && entryValue(entry, path) : read(path));\n const shown = prefShownReader(schema, stored, entry?.item, over);\n return (condition) => prefConditionHolds(condition, shown);\n}\n\n/**\n * `holds` for every condition but one that reads the entry, which is left\n * unanswered, which is to say holding: what a walk with no entry in hand\n * asks inside the item of a list or a map.\n */\nexport function deferEntryConditions(holds: PrefConditionJudge): PrefConditionJudge {\n return (condition, field) => prefConditionReadsItem(condition) || holds(condition, field);\n}\n\n/**\n * Reads a value by path the way a form over `schema` shows it: what `values`\n * holds there, else the default of the leaf at that path, or the part of a\n * leaf's default the rest of the path names. `over` is the schema `schema`\n * is drawn over: a path no leaf of `schema` holds takes its default there.\n */\nexport function prefReader(schema: PrefGroup | PrefSection, values: unknown, over?: PrefGroup | PrefSection): (path: string) => unknown {\n const beyond = over && prefReader(over, values);\n return (path) => {\n const held = prefValueAtPath(values, path);\n if (held !== undefined) return held;\n if (beyond && prefSchemaHolding(schema, path, over) === over) return beyond(path);\n if (isPrefSection(schema)) {\n for (const [key, leaf] of prefSectionLeaves(schema.members)) {\n if (path === key) return leaf.default;\n if (path.startsWith(`${key}.`)) return prefValueAtPath(leaf.default, path.slice(key.length + 1));\n }\n return undefined;\n }\n const steps = path.split('.');\n let node: PrefGroup = schema;\n for (let i = 0; i < steps.length; i++) {\n if (!Object.hasOwn(node.children, steps[i]!)) return undefined;\n const child: PrefLeaf | PrefGroup = node.children[steps[i]!]!;\n if (!isPrefLeaf(child)) node = child;\n else return i === steps.length - 1 ? child.default : prefValueAtPath(child.default, steps.slice(i + 1).join('.'));\n }\n return undefined;\n };\n}\n","// The scope of one node: whether it is drawn and whether it takes input,\n// with everything above it counted.\n\nimport { prefAliasTarget, type PrefAlias } from './alias';\nimport type { PrefCondition } from './condition';\nimport type { PrefGroup, PrefSection } from './groups';\nimport { isPrefLeaf, isPrefSection, prefLeafAt } from './helpers';\nimport { deferEntryConditions, type PrefConditionJudge } from './judge';\nimport type { PrefList } from './list';\nimport type { PrefMap } from './map';\nimport type { PrefLeaf, PrefObject } from './schema';\nimport type { PrefUnion } from './union';\n\n/** Whether a node is drawn and whether it takes input, with what is above it counted. */\nexport interface PrefScope {\n shown: boolean;\n enabled: boolean;\n}\n\n/** The step that stands for any entry of a `list` or a `map` in a path: `'phases.*.hold'` answers for that field of\n * each, by every condition that comes to the same for every entry. */\nexport const PREF_ENTRY = '*';\n\n/** The scope a schema's root sits in. */\nexport const PREF_SCOPE: PrefScope = Object.freeze({ shown: true, enabled: true });\n\n/** The scope of `node`, which sits directly under something whose scope is `above`. */\nexport function prefScopeUnder(\n above: PrefScope,\n node: { showIf?: PrefCondition; enableIf?: PrefCondition },\n holds: PrefConditionJudge,\n): PrefScope {\n const shown = above.shown && (node.showIf === undefined || holds(node.showIf, 'showIf'));\n const enabled = above.enabled && (node.enableIf === undefined || holds(node.enableIf, 'enableIf'));\n return shown === above.shown && enabled === above.enabled ? above : { shown, enabled };\n}\n\n/** The scope of the field at `rest` among an object leaf's children, or `undefined` when none is there. */\nfunction scopeAmong(\n held: PrefSection['members'], rest: string, above: PrefScope, holds: PrefConditionJudge,\n): PrefScope | undefined {\n for (const [key, child] of Object.entries(held)) {\n if (!isPrefLeaf(child)) {\n const found = scopeAmong(child.members, rest, prefScopeUnder(above, child, holds), holds);\n if (found) return found;\n } else if (rest === key) return prefScopeUnder(above, child, holds);\n else if (rest.startsWith(`${key}.`)) return scopeInside(child, rest.slice(key.length + 1), prefScopeUnder(above, child, holds), holds);\n }\n return undefined;\n}\n\n/** The scope at `rest` inside `leaf`, whose own scope is `scope`: that of a field, or the leaf's where `rest` names none. */\nfunction scopeInside(leaf: PrefLeaf, rest: string, scope: PrefScope, holds: PrefConditionJudge): PrefScope {\n if (leaf.kind === 'object') return scopeAmong((leaf as PrefObject).children, rest, scope, holds) ?? scope;\n if (leaf.kind === 'list' || leaf.kind === 'map') {\n const { item } = leaf as Partial<PrefList | PrefMap>;\n if (item === undefined) return scope;\n const inItem = deferEntryConditions(holds);\n const entry = prefScopeUnder(scope, { enableIf: item.enableIf }, inItem);\n const dot = rest.indexOf('.');\n return dot < 0 ? entry : scopeInside(item, rest.slice(dot + 1), entry, inItem);\n }\n if (leaf.kind !== 'union') return scope;\n for (const variant of Object.values((leaf as PrefUnion).variants)) {\n const found = scopeAmong(variant.children, rest, scope, holds);\n if (found) return found;\n }\n return scope;\n}\n\nfunction scopeAt(schema: PrefGroup | PrefSection, path: string, holds: PrefConditionJudge): PrefScope {\n let scope = prefScopeUnder(PREF_SCOPE, schema, holds);\n if (path === '') return scope;\n if (isPrefSection(schema)) return scopeAmong(schema.members, path, scope, holds) ?? scope;\n let node: PrefGroup = schema;\n const steps = path.split('.');\n for (let i = 0; i < steps.length; i++) {\n if (!Object.hasOwn(node.children, steps[i]!)) return scope;\n const child: PrefLeaf | PrefGroup = node.children[steps[i]!]!;\n scope = prefScopeUnder(scope, child, holds);\n if (isPrefLeaf(child)) return i === steps.length - 1 ? scope : scopeInside(child, steps.slice(i + 1).join('.'), scope, holds);\n node = child;\n }\n return scope;\n}\n\n/** `own`, an alias's scope by its own conditions, narrowed by that of the leaf it shows in `over`, as `holds` judges `over`. */\nexport function prefAliasScope(own: PrefScope, alias: PrefAlias, over: PrefGroup | PrefSection, holds: PrefConditionJudge): PrefScope {\n const target = prefAliasTarget(alias, (path) => prefLeafAt(over, path));\n if (target === undefined) return own;\n const theirs = scopeAt(over, target.path, holds);\n const shown = own.shown && theirs.shown;\n const enabled = own.enabled && theirs.enabled;\n return shown === own.shown && enabled === own.enabled ? own : { shown, enabled };\n}\n\n/** What {@link prefScopeAt} is told beyond the schema. */\nexport interface PrefScopeAtOptions {\n /** The schema an alias's `of` names a leaf of. Default: the schema asked. */\n aliasOver?: PrefGroup | PrefSection;\n /** Says which conditions of `aliasOver` hold, where its values are not the ones `holds` reads. Default: `holds`. */\n aliasHolds?: PrefConditionJudge;\n}\n\n/**\n * The scope of the node at `path`: a group, a leaf, a field of an `object`\n * or a `union` leaf, or an entry of a `list` or a `map`, whose step may be\n * any key. Under a {@link PrefSection} schema a leaf's key is its whole\n * path. A path that runs past the schema answers for the last node it\n * reaches. An alias answers for itself and for the leaf it shows, as\n * `applyPrefConditions` has it. Inside an entry, a condition that reads the\n * entry (`from: 'item'`) is not asked and counts as holding, there being no\n * entry here to read: `applyPrefEntryConditions` answers it.\n */\nexport function prefScopeAt(\n schema: PrefGroup | PrefSection, path: string, holds: PrefConditionJudge, { aliasOver, aliasHolds }: PrefScopeAtOptions = {},\n): PrefScope {\n const own = scopeAt(schema, path, holds);\n const leaf = prefLeafAt(schema, path);\n return leaf?.kind === 'alias' ? prefAliasScope(own, leaf as PrefAlias, aliasOver ?? schema, aliasHolds ?? holds) : own;\n}\n","// What a schema's conditions come to once nesting is counted: a node is drawn\n// only while it and everything above it is shown, and takes input only while\n// it and everything above it is enabled. Every surface that draws a schema\n// asks here.\n\nimport type { PrefAlias } from './alias';\nimport { prefConditionReadsItem } from './condition';\nimport type { PrefGroup, PrefSection } from './groups';\nimport { isPrefLeaf, isPrefSection } from './helpers';\nimport { deferEntryConditions, type PrefConditionJudge } from './judge';\nimport type { PrefList } from './list';\nimport type { PrefMap } from './map';\nimport type { PrefLeaf, PrefObject } from './schema';\nimport { PREF_ENTRY, PREF_SCOPE, prefAliasScope, prefScopeUnder, type PrefScope } from './scopeAt';\nimport type { PrefUnion } from './union';\n\nexport { prefJudge, prefReader, type PrefConditionField, type PrefConditionJudge, type PrefEntry } from './judge';\nexport { PREF_ENTRY, PREF_SCOPE, prefScopeAt, prefScopeUnder, type PrefScope, type PrefScopeAtOptions } from './scopeAt';\n\nconst under = (prefix: string, key: string): string => (prefix === '' ? key : `${prefix}.${key}`);\n\n/** A schema with its conditions applied. */\nexport interface PrefConditionsApplied<T> {\n /** The schema without the nodes that are not shown. The schema itself when\n * that is all of it, and `null` when its root is not shown. */\n shown: T | null;\n /**\n * The value path of every leaf that is disabled, a field of an `object` or\n * a `union` leaf included (`'stroke.width'`), and under a {@link PrefGroup}\n * schema the path of every group that is. A `list`'s or a `map`'s item is\n * named once for every entry, with {@link PREF_ENTRY} as the entry's step:\n * `'phases.*'`, and `'phases.*.hold'` for a field of it.\n */\n disabled: ReadonlySet<string>;\n /**\n * With `keepHidden`, the path of everything `shown` holds that is not\n * shown, named as `disabled` names what is disabled. Empty without it,\n * since `shown` then holds none.\n */\n hidden: ReadonlySet<string>;\n}\n\n/** How {@link applyPrefConditions} treats what it would leave out. */\nexport interface PrefConditionsOptions {\n /** Keep a group or a section that leaves with nothing to draw. */\n keepEmpty?: boolean;\n /**\n * Keep every node whose `showIf` fails, and name it in `hidden`: for a\n * surface that edits the schema, where a node not drawn cannot be picked.\n */\n keepHidden?: boolean;\n /** The schema an alias's `of` names a leaf of. Default: the schema walked. */\n aliasOver?: PrefGroup | PrefSection;\n /** Says which conditions of `aliasOver` hold, where its values are not the ones `holds` reads. Default: `holds`. */\n aliasHolds?: PrefConditionJudge;\n}\n\ninterface WalkOptions {\n keepEmpty: boolean;\n keepHidden: boolean;\n /** Asked inside the item of a list or a map met on the way, whose entries the walk does not have. */\n inItem: PrefConditionJudge;\n aliasOver?: PrefGroup | PrefSection;\n aliasHolds?: PrefConditionJudge;\n}\n\n/** The walk over leaves and what is inside them, which the schema's pass and an entry's share. */\nfunction leafWalk({ keepEmpty, keepHidden, inItem, aliasOver, aliasHolds }: WalkOptions) {\n const disabled = new Set<string>();\n const hidden = new Set<string>();\n\n const leaf = (node: PrefLeaf, path: string, above: PrefScope, holds: PrefConditionJudge): PrefLeaf | null => {\n const own = prefScopeUnder(above, node, holds);\n const scope = node.kind === 'alias' && aliasOver ? prefAliasScope(own, node as PrefAlias, aliasOver, aliasHolds ?? holds) : own;\n return scope.shown || keepHidden ? inside(node, path, scope, holds) : null;\n };\n\n /** `node`, whose scope is `scope`, without what its own value hides: a field, or part of a list's or a map's item. */\n const inside = (node: PrefLeaf, path: string, scope: PrefScope, holds: PrefConditionJudge): PrefLeaf => {\n if (!scope.shown) hidden.add(path);\n if (!scope.enabled) disabled.add(path);\n if (node.kind === 'object') {\n const children = members((node as PrefObject).children, path, scope, holds);\n return children === (node as PrefObject).children ? node : ({ ...node, children } as PrefLeaf);\n }\n if (node.kind === 'list' || node.kind === 'map') {\n const { item } = node as Partial<PrefList | PrefMap>;\n // A leaf an app's renderer draws under a built-in's kind may hold no item.\n if (item === undefined) return node;\n // An item is drawn with its entry, so its own `showIf` is not asked.\n const entry = inside(item, under(path, PREF_ENTRY), prefScopeUnder(scope, { enableIf: item.enableIf }, inItem), inItem);\n return entry === item ? node : ({ ...node, item: entry } as PrefLeaf);\n }\n if (node.kind !== 'union') return node;\n const { variants } = node as PrefUnion;\n let changed = false;\n const next: PrefUnion['variants'] = {};\n for (const [key, variant] of Object.entries(variants)) {\n const children = members(variant.children, path, scope, holds);\n changed ||= children !== variant.children;\n next[key] = children === variant.children ? variant : { ...variant, children };\n }\n return changed ? ({ ...node, variants: next } as PrefLeaf) : node;\n };\n\n /** A section's members or an object leaf's children. `prefix` is the object leaf's path, empty in a section schema. */\n const members = (held: PrefSection['members'], prefix: string, above: PrefScope, holds: PrefConditionJudge): PrefSection['members'] => {\n let changed = false;\n const out: PrefSection['members'] = {};\n for (const [key, child] of Object.entries(held)) {\n const kept = isPrefLeaf(child) ? leaf(child, under(prefix, key), above, holds) : section(child, prefix, above, holds);\n changed ||= kept !== child;\n if (kept !== null) out[key] = kept;\n }\n return changed ? out : held;\n };\n\n const section = (node: PrefSection, prefix: string, above: PrefScope, holds: PrefConditionJudge): PrefSection | null => {\n const scope = prefScopeUnder(above, node, holds);\n if (!scope.shown && !keepHidden) return null;\n const kept = members(node.members, prefix, scope, holds);\n if (kept === node.members) return node;\n return Object.keys(kept).length === 0 && !keepEmpty ? null : { ...node, members: kept };\n };\n\n return { disabled, hidden, leaf, inside, members };\n}\n\n/**\n * `schema` as it is drawn while `holds` says which conditions hold. A node\n * whose `showIf` fails is dropped with everything under it, unless\n * `keepHidden`, and so is a group or a section that leaves with nothing to\n * draw, unless `keepEmpty`. A node\n * whose `enableIf` fails is disabled with everything under it. The item of\n * a `list` or a `map` is walked as its entries are drawn: its fields hide and\n * disable by their conditions, and its own `enableIf` disables every entry.\n * A condition there that reads the entry (`from: 'item'`) has no one answer\n * for every entry and is left holding: {@link applyPrefEntryConditions}\n * answers it for each.\n * An alias is shown only while it and the leaf it shows both are, and enabled\n * only while both are, with everything above that leaf counted. That leaf is\n * looked for in `aliasOver`, and its side is asked of `aliasHolds`.\n * Parts with nothing dropped come back as the objects they were.\n */\nexport function applyPrefConditions<T extends PrefGroup | PrefSection>(\n schema: T,\n holds: PrefConditionJudge,\n { keepEmpty = false, keepHidden = false, aliasOver, aliasHolds }: PrefConditionsOptions = {},\n): PrefConditionsApplied<T> {\n const walk = leafWalk({ keepEmpty, keepHidden, inItem: deferEntryConditions(holds), aliasOver: aliasOver ?? schema, aliasHolds });\n const { disabled, hidden } = walk;\n\n const group = (node: PrefGroup, path: string, above: PrefScope): PrefGroup | null => {\n const scope = prefScopeUnder(above, node, holds);\n if (!scope.shown && !keepHidden) return null;\n if (!scope.shown && path !== '') hidden.add(path);\n if (!scope.enabled && path !== '') disabled.add(path);\n let changed = false;\n const children: PrefGroup['children'] = {};\n for (const [key, child] of Object.entries(node.children)) {\n const at = under(path, key);\n const kept = isPrefLeaf(child) ? walk.leaf(child, at, scope, holds) : group(child, at, scope);\n changed ||= kept !== child;\n if (kept !== null) children[key] = kept;\n }\n if (!changed) return node;\n return Object.keys(children).length === 0 && !keepEmpty && path !== '' ? null : { ...node, children };\n };\n\n if (!isPrefSection(schema)) return { shown: group(schema, '', PREF_SCOPE) as T | null, disabled, hidden };\n const scope = prefScopeUnder(PREF_SCOPE, schema, holds);\n if (!scope.shown && !keepHidden) return { shown: null, disabled, hidden };\n const kept = walk.members(schema.members, '', scope, holds);\n return { shown: kept === schema.members ? schema : { ...schema, members: kept }, disabled, hidden };\n}\n\n/** One entry of a list or a map with the conditions that read it applied. */\nexport interface PrefEntryApplied {\n /** The item as this entry draws it: without the fields not shown, and the item itself when that is all of them. */\n item: PrefLeaf;\n /** The path of the entry, and of every field in it, that is disabled, named as {@link PrefConditionsApplied} names them. */\n disabled: ReadonlySet<string>;\n /** With `keepHidden`, the path of every field of the entry that is not shown. */\n hidden: ReadonlySet<string>;\n}\n\nconst ALWAYS: PrefConditionJudge = () => true;\n\n/**\n * The conditions {@link applyPrefConditions} leaves unanswered, answered for\n * one entry: `item`, as that pass left it, drawn for the entry at `path`\n * (`'phases.2'`) while `holds` says which conditions hold. `holds` reads the\n * entry: `prefJudge` given it. Only a condition that reads the entry is\n * asked, the rest being applied already, and one inside a list or a map\n * within the entry is left for that one's own entries.\n */\nexport function applyPrefEntryConditions(\n item: PrefLeaf,\n path: string,\n holds: PrefConditionJudge,\n { keepEmpty = false, keepHidden = false }: Pick<PrefConditionsOptions, 'keepEmpty' | 'keepHidden'> = {},\n): PrefEntryApplied {\n const asked: PrefConditionJudge = (condition, field) => !prefConditionReadsItem(condition) || holds(condition, field);\n const walk = leafWalk({ keepEmpty, keepHidden, inItem: ALWAYS });\n const scope = prefScopeUnder(PREF_SCOPE, { enableIf: item.enableIf }, asked);\n return { item: walk.inside(item, path, scope, asked), disabled: walk.disabled, hidden: walk.hidden };\n}\n","// The leaves a surface's aliases show: the schema they point into, as that\n// schema's own conditions leave it. Every surface that draws an alias asks\n// here, whether the schema is its own or another's.\n\nimport { prefAliasedLeaf, prefAliasTarget, type PrefAlias } from './alias';\nimport type { PrefGroup, PrefSection } from './groups';\nimport { prefLeafAt, visiblePrefSubtree } from './helpers';\nimport type { PrefConditionJudge, PrefEntry } from './judge';\nimport type { PrefLeaf, PrefObject } from './schema';\nimport { applyPrefConditions, applyPrefEntryConditions, type PrefConditionsApplied, type PrefEntryApplied } from './scope';\n\n/** What an alias row reads of the leaf it shows: the schema that leaf is in, as that schema's own conditions leave it. */\nexport interface PrefAliasTargets {\n /** Says which conditions of that schema hold. */\n holds: PrefConditionJudge;\n /** The leaf at a path of that schema, without the fields the surface would leave out of the leaf's own row: one\n * marked `hidden`, and one a `showIf` hides, unless the surface draws those. */\n leafAt: (path: string) => PrefLeaf | undefined;\n /** The leaf `alias` is drawn as, under the alias's own name and description where it gives them, and the path\n * its value is read and written at. `undefined` for an alias of nothing. */\n shown: (alias: PrefAlias) => { path: string; leaf: PrefLeaf } | undefined;\n /** Whether the field at a path of that schema is one an `enableIf` disables. */\n disabledAt: (path: string) => boolean;\n /** Whether the field at a path of that schema is one a `showIf` hides, on a surface that draws those. */\n hiddenAt?: (path: string) => boolean;\n /** An entry of a list or a map of that schema, as the conditions that read the entry leave it. */\n entryAt: (item: PrefLeaf, path: string, value: unknown) => PrefEntryApplied;\n}\n\n/** What a surface draws beyond the default, which its alias rows follow. */\nexport interface PrefAliasTargetsOptions {\n /** The surface draws fields marked `hidden`. */\n showHidden?: boolean;\n /** The surface draws what a `showIf` hides, marked. */\n markHidden?: boolean;\n}\n\n/** `leaf` without its fields marked `hidden`. The leaf's own mark is not asked: an alias shows a leaf the surface leaves out. */\nfunction visibleFieldsOf(leaf: PrefLeaf): PrefLeaf {\n if (leaf.kind !== 'object') return leaf;\n const shown = visiblePrefSubtree({ ...leaf, hidden: false }, false, true) as PrefObject;\n return { ...leaf, children: shown.children } as PrefLeaf;\n}\n\n/**\n * {@link PrefAliasTargets} over `over`, the schema a surface's aliases point\n * into: the surface's own, or another's. `judge` answers `over`'s conditions\n * as the surface reads values, for one entry of a list or a map where it is\n * given one: `prefJudge` over `over`. A surface's own pass drops a leaf it\n * leaves out and keeps no path of another schema, so the leaves aliases show\n * are conditioned here, the first time one is asked for.\n */\nexport function prefAliasTargets(\n over: PrefGroup | PrefSection,\n judge: (entry?: PrefEntry) => PrefConditionJudge,\n { showHidden = false, markHidden = false }: PrefAliasTargetsOptions = {},\n): PrefAliasTargets {\n const holds = judge();\n let applied: PrefConditionsApplied<PrefGroup | PrefSection> | undefined;\n const get = (): PrefConditionsApplied<PrefGroup | PrefSection> =>\n (applied ??= applyPrefConditions(over, holds, { keepEmpty: true, keepHidden: markHidden }));\n const leafAt = (path: string): PrefLeaf | undefined => {\n const { shown } = get();\n const leaf = shown === null ? undefined : prefLeafAt(shown, path);\n return leaf === undefined || showHidden ? leaf : visibleFieldsOf(leaf);\n };\n return {\n holds,\n leafAt,\n shown: (alias) => {\n const target = prefAliasTarget(alias, leafAt);\n return target && { path: target.path, leaf: prefAliasedLeaf(alias, target.leaf) };\n },\n disabledAt: (path) => get().disabled.has(path),\n ...(markHidden ? { hiddenAt: (path: string) => get().hidden.has(path) } : {}),\n entryAt: (item, path, value) => applyPrefEntryConditions(item, path, judge({ item, value }), { keepHidden: markHidden }),\n };\n}\n","import type { PrefObject } from './schema';\n\nconst isObject = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null;\n\n/**\n * The object a write to one field of an `object` leaf starts from: `held` itself where it is one. Where it is\n * not, the write has to make a whole object, so it starts from the scalar lifted by the leaf's `fromScalar`, else\n * from the leaf's `default`: one field on its own is a stroke with a width and no paint.\n */\nexport function prefObjectBase(pref: PrefObject, held: unknown): Record<string, unknown> {\n if (isObject(held)) return held;\n return pref.fromScalar?.(held) ?? (isObject(pref.default) ? pref.default : {});\n}\n\n/** The object an `object` leaf holds after one of its fields is set: {@link prefObjectBase} with `key` at\n * `value`, or without the key for `undefined`. */\nexport function prefObjectWithField(pref: PrefObject, held: unknown, key: string, value: unknown): Record<string, unknown> {\n const base = prefObjectBase(pref, held);\n if (value !== undefined) return { ...base, [key]: value };\n const { [key]: _dropped, ...rest } = base;\n return rest;\n}\n","import type { PrefLeaf } from './schema';\n\n/**\n * `leaf` as a named type: the same leaf carrying `name` in its `type` field.\n * Declared once beside the code that reads its value and used wherever a\n * schema wants one, spread with what that place sets for itself\n * (`{ ...GradientStop, name: 'First stop' }`), or as a list's or a map's\n * `item`. `name` is the identifier the type is exported under, which a schema\n * editor prints in place of the leaf's literal.\n */\nexport function prefType<L extends PrefLeaf>(name: string, leaf: L): L & { type: string } {\n return { ...leaf, type: name };\n}\n","// The two branch nodes of a schema. They differ in whether a key is part of\n// the path a leaf's value lives at, and each holds its members under its own\n// property, so a schema of one kind is neither assignable to nor walkable as\n// the other.\n\nimport type { PrefCondition } from './condition';\nimport type { PrefLeaf } from './schema';\n\n/**\n * How a {@link PrefGroup} is drawn: `page` gets an entry in a form's rail and\n * a pane of its own; `tab` shares a tab strip with the `tab` groups beside it;\n * `panel` is a bordered, titled box; `section` is a heading over its rows;\n * `fragment` draws nothing of its own, so its rows sit among its neighbors'\n * as though they were written there. A fragment exists to hold things\n * together: one key for their values to nest under, one node to move.\n */\nexport type PrefGroupAs = 'page' | 'tab' | 'panel' | 'section' | 'fragment' | 'bar';\n\n/** How a {@link PrefSection} is drawn. */\nexport type PrefSectionAs = Exclude<PrefGroupAs, 'page'>;\n\n/**\n * A group whose key is a path segment: `view` > `gridDensity` is the leaf at\n * `view.gridDensity`, and its value nests the same way. The shape of a\n * preferences schema — what `openPrefs` stores, `PrefsForm` renders, and a\n * tool declares its options as. A key holds no `.`.\n */\nexport interface PrefGroup {\n /** Heading for the group's rows. **Empty means no heading** — for a group\n * that exists to organize, not to name: one whose children are themselves\n * groups carrying the labels a reader needs. Give it a name whenever the\n * name is the referent (a `Border` group over `Top` / `Right` / `Bottom`\n * reads as nothing without it). */\n name: string;\n description?: string;\n /** How the group is drawn. Unset, its depth decides: a top-level group is a\n * `page`, and one inside another is a `section`. */\n as?: PrefGroupAs;\n /** Drawn, with everything under it, only while this holds. */\n showIf?: PrefCondition;\n /** Everything under it is disabled while this does not hold. */\n enableIf?: PrefCondition;\n children: Record<string, PrefLeaf | PrefGroup>;\n}\n\n/**\n * A heading over leaves that adds nothing to their paths: each member is\n * addressed by its own key alone, and the section's key only identifies the\n * section. The shape of a node's property schema, where a leaf's key is the\n * whole dotted node path (`pose.x`, `data.fill`), and of the headings inside\n * a {@link PrefObject}, where a key is relative to the object.\n */\nexport interface PrefSection {\n /** Heading for the section's rows. Empty means no heading, as for a\n * {@link PrefGroup}. */\n name: string;\n description?: string;\n /** How the section is drawn, as a {@link PrefGroup}'s `as` — without\n * `page`, since nothing that draws sections has a rail. Unset: a heading\n * over its rows. */\n as?: PrefSectionAs;\n /** As a {@link PrefGroup}'s. */\n showIf?: PrefCondition;\n /** As a {@link PrefGroup}'s. */\n enableIf?: PrefCondition;\n members: Record<string, PrefLeaf | PrefSection>;\n}\n\n/** Whether a top-level group gets a page of its own, and not a place on the page of the root's own leaves. */\nexport function prefGroupIsPage(group: PrefGroup): boolean {\n return group.as === undefined || group.as === 'page';\n}\n","import { pairRowsOf, type PrefLeaf } from './schema';\n\n/** Neighboring items one row draws, in {@link pairRuns}' answer. */\nexport interface PairRun<T> {\n items: T[];\n /** The pairing the items share: the path of the leaf that declared it, and what the row reads. Absent on a\n * run of one, which is no pair. */\n pair?: { key: string; label: string };\n}\n\n/**\n * `items` as the rows they draw, in order: each leaf a `pair` names joins the row of the leaf naming it where\n * the two are neighbors, and every other item is a run of its own. `leafOf` gives an item's leaf and the path a\n * `pair` would name it by, or nothing for an item that shares no row, which ends a run.\n */\nexport function pairRuns<T>(\n items: readonly T[],\n leafOf: (item: T) => readonly [path: string, leaf: PrefLeaf] | undefined,\n): PairRun<T>[] {\n const leaves = items.map(leafOf);\n const pairs = pairRowsOf(leaves.filter((entry) => entry !== undefined));\n const keys = leaves.map((entry) => (entry === undefined ? undefined : pairs.get(entry[0])));\n const runs: PairRun<T>[] = [];\n for (let i = 0; i < items.length; ) {\n const pair = keys[i];\n let j = i + 1;\n while (pair !== undefined && keys[j]?.key === pair.key) j += 1;\n runs.push(j - i > 1 ? { items: items.slice(i, j), pair } : { items: [items[i]!] });\n i = j;\n }\n return runs;\n}\n","import type { PrefKind } from './schema';\n\n/** What a surface has to know about a kind before it can lay its control out. */\nexport interface PrefKindTraits {\n /** Its value is made of other leaves' values: too much for one control on a\n * line, so a bar opens it in a popover and a compact panel in a dialog. */\n compound: boolean;\n /** Its control is several controls, or a button. A row drawn as a `<label>`\n * would hand a click on its text to the first of them. */\n several: boolean;\n}\n\nconst ONE: PrefKindTraits = { compound: false, several: false };\nconst MANY: PrefKindTraits = { compound: true, several: true };\n\n/**\n * The traits of every built-in kind. A `Record` over {@link PrefKind}, so a\n * kind added to the union does not compile until it says what it is here:\n * a plain set of kind names lets a new one through to draw inline in a\n * `<label>`, on a bar's line, and with no dialog row.\n */\nexport const PREF_KIND_TRAITS: Record<PrefKind, PrefKindTraits> = {\n number: ONE,\n boolean: ONE,\n string: ONE,\n enum: ONE,\n color: ONE,\n paint: ONE,\n object: MANY,\n list: MANY,\n map: MANY,\n union: MANY,\n field: ONE,\n action: { compound: false, several: true },\n alias: ONE,\n label: ONE,\n separator: ONE,\n};\n\nconst traitsOf = (leaf: { kind: string }): PrefKindTraits =>\n (Object.hasOwn(PREF_KIND_TRAITS, leaf.kind) ? PREF_KIND_TRAITS[leaf.kind as PrefKind] : ONE);\n\n/** Whether a leaf's value is made of other leaves' values. An app-defined kind is not: its renderer is one control. */\nexport function prefIsCompound(leaf: { kind: string }): boolean {\n return traitsOf(leaf).compound;\n}\n\n/** Whether a leaf's control is several controls or a button. */\nexport function prefDrawsSeveral(leaf: { kind: string }): boolean {\n return traitsOf(leaf).several;\n}\n"]}