@weasel-js/labkit 1.7.3 → 1.8.1
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 +24 -0
- package/dist/_dts/{CanvasStackContext-Cjy6I-Iv.d.ts → CanvasStackContext-B05ZM04l.d.ts} +3 -1
- package/dist/_dts/{Stage-D6t7o0pF.d.ts → Stage-CIJlbjrE.d.ts} +5 -3
- package/dist/_dts/{index-DCMA4Fy1.d.ts → index-8geQNQet.d.ts} +84 -12
- package/dist/_dts/{index-BTmaRy6a.d.ts → index-DRi3V5sN.d.ts} +6 -4
- package/dist/_dts/{types-BUBSIZuV.d.ts → types-DUfQ0isU.d.ts} +5 -1
- package/dist/_dts/{useTrialState-Bh8bzFgE.d.ts → useTrialState-Ar0AFpCe.d.ts} +94 -87
- package/dist/canvas/index.d.ts +5 -5
- package/dist/canvas/index.js +2 -2
- package/dist/chrome/index.d.ts +3 -3
- package/dist/chrome/index.js +7 -7
- package/dist/{chunk-HBGH344L.js → chunk-4RCVWX4M.js} +55 -18
- package/dist/chunk-4RCVWX4M.js.map +1 -0
- package/dist/{chunk-WIG6XHJ7.js → chunk-6IIKLXBZ.js} +13 -4
- package/dist/chunk-6IIKLXBZ.js.map +1 -0
- package/dist/{chunk-F4ACIK7Z.js → chunk-6Q6ACJ3H.js} +3 -3
- package/dist/{chunk-F4ACIK7Z.js.map → chunk-6Q6ACJ3H.js.map} +1 -1
- package/dist/{chunk-PMLZP7RT.js → chunk-7ALJOVGP.js} +5 -9
- package/dist/chunk-7ALJOVGP.js.map +1 -0
- package/dist/{chunk-XE5HJOPL.js → chunk-7FMZT2WL.js} +3 -3
- package/dist/{chunk-XE5HJOPL.js.map → chunk-7FMZT2WL.js.map} +1 -1
- package/dist/{chunk-XVUKDSYV.js → chunk-AVOILDN2.js} +2 -2
- package/dist/{chunk-XVUKDSYV.js.map → chunk-AVOILDN2.js.map} +1 -1
- package/dist/{chunk-2N7UBSS2.js → chunk-J5MDJEOZ.js} +3 -3
- package/dist/{chunk-2N7UBSS2.js.map → chunk-J5MDJEOZ.js.map} +1 -1
- package/dist/{chunk-LPGBC63T.js → chunk-KHB3KRRQ.js} +7 -7
- package/dist/chunk-KHB3KRRQ.js.map +1 -0
- package/dist/{chunk-IBVRMHW5.js → chunk-NHIO2O3O.js} +31 -30
- package/dist/chunk-NHIO2O3O.js.map +1 -0
- package/dist/{chunk-EESJUSYR.js → chunk-QMAY74TP.js} +56 -5
- package/dist/chunk-QMAY74TP.js.map +1 -0
- package/dist/{chunk-4X44DMRS.js → chunk-RN7T7OBO.js} +46 -24
- package/dist/chunk-RN7T7OBO.js.map +1 -0
- package/dist/{chunk-4TJ34FXA.js → chunk-RXO5UEGT.js} +5 -12
- package/dist/chunk-RXO5UEGT.js.map +1 -0
- package/dist/{chunk-E6NARGU7.js → chunk-SQX35X5V.js} +3 -3
- package/dist/{chunk-E6NARGU7.js.map → chunk-SQX35X5V.js.map} +1 -1
- package/dist/{chunk-YCFKW5RX.js → chunk-T5OEUNCB.js} +16 -2
- package/dist/chunk-T5OEUNCB.js.map +1 -0
- package/dist/{chunk-RL2LOLNI.js → chunk-UX66USTN.js} +2 -2
- package/dist/chunk-UX66USTN.js.map +1 -0
- package/dist/{chunk-IRMPZIYU.js → chunk-V4SMGEYY.js} +6732 -6507
- package/dist/chunk-V4SMGEYY.js.map +1 -0
- package/dist/{chunk-E23Q6A3Y.js → chunk-VCK5T6EP.js} +3 -3
- package/dist/{chunk-E23Q6A3Y.js.map → chunk-VCK5T6EP.js.map} +1 -1
- package/dist/{chunk-T6DLGEJB.js → chunk-XWR2P6MR.js} +23 -6
- package/dist/chunk-XWR2P6MR.js.map +1 -0
- package/dist/{chunk-XSJJTXNA.js → chunk-YZA73U4A.js} +19 -19
- package/dist/chunk-YZA73U4A.js.map +1 -0
- package/dist/config/index.d.ts +12 -5
- package/dist/config/index.js +2 -2
- package/dist/controls/index.d.ts +2 -2
- package/dist/controls/index.js +5 -5
- package/dist/dragdrop/index.d.ts +2 -2
- package/dist/dragdrop/index.js +2 -2
- package/dist/index.d.ts +158 -16
- package/dist/index.js +1036 -415
- package/dist/index.js.map +1 -1
- package/dist/layers/index.d.ts +2 -2
- package/dist/layers/index.js +3 -3
- package/dist/loupe/index.d.ts +176 -28
- package/dist/loupe/index.js +547 -141
- package/dist/loupe/index.js.map +1 -1
- package/dist/overview/index.d.ts +1 -1
- package/dist/overview/index.js +5 -5
- package/dist/passthrough/weasel-ui.js +3 -3
- package/dist/primitives/index.d.ts +4 -19
- package/dist/primitives/index.js +7 -7
- package/dist/state/index.d.ts +6 -8
- package/dist/state/index.js +5 -5
- package/dist/styles.css +181 -44
- package/dist/surface/index.d.ts +20 -1
- package/dist/surface/index.js +2 -2
- package/dist/undo/index.d.ts +19 -8
- package/dist/undo/index.js +1 -1
- package/package.json +11 -11
- package/src/annotations/AnnotationOverlay.abandon.test.tsx +4 -0
- package/src/annotations/AnnotationOverlay.tsx +10 -1
- package/src/annotations/Annotations.less +2 -0
- package/src/annotations/Annotations.overlay.test.tsx +29 -0
- package/src/canvas/CanvasStack.test.tsx +35 -0
- package/src/canvas/CanvasStack.tsx +12 -1
- package/src/canvas/useLayerScheduler.ts +14 -0
- package/src/chrome/builtins.test.ts +14 -0
- package/src/chrome/builtins.tsx +17 -2
- package/src/chrome/regions/StatusRegion.tsx +20 -14
- package/src/chrome/regions/regions.test.tsx +28 -0
- package/src/chrome/types.ts +8 -0
- package/src/clock/clock.browser.test.less +5 -0
- package/src/clock/clock.browser.test.tsx +77 -0
- package/src/clock/clock.integration.test.tsx +95 -0
- package/src/clock/clockRegistry.test.ts +33 -0
- package/src/clock/clockRegistry.ts +46 -0
- package/src/clock/hooks.ts +44 -0
- package/src/clock/index.ts +2 -0
- package/src/clock/trialClock.test.ts +265 -0
- package/src/clock/trialClock.ts +245 -0
- package/src/clock/useClockLoop.ts +45 -0
- package/src/config/builder.ts +11 -1
- package/src/config/resolve.test.ts +12 -0
- package/src/config/resolve.ts +5 -0
- package/src/config/types.ts +5 -1
- package/src/controls/ControlMatrix.test.tsx +10 -0
- package/src/controls/ControlMatrix.tsx +110 -58
- package/src/controls/ControlPanel.test.tsx +30 -0
- package/src/index.ts +3 -2
- package/src/instrument/types.ts +21 -1
- package/src/lab/Lab.chrome.test.tsx +8 -1
- package/src/lab/Lab.presentation.test.tsx +113 -0
- package/src/lab/Lab.surface.test.tsx +20 -9
- package/src/lab/Lab.tsx +132 -257
- package/src/lab/LabLightbox.browser.test.less +17 -0
- package/src/lab/LabLightbox.browser.test.tsx +216 -0
- package/src/lab/LabShell.less +10 -3
- package/src/lab/LabSurface.tsx +129 -0
- package/src/lab/Workspace.stories.tsx +18 -0
- package/src/lab/Workspace.surface.test.tsx +4 -0
- package/src/lab/Workspace.test.tsx +37 -1
- package/src/lab/Workspace.tsx +34 -6
- package/src/lab/index.ts +2 -0
- package/src/lab/nebula.ts +30 -0
- package/src/lab/openLab.test.ts +81 -0
- package/src/lab/openLab.ts +119 -0
- package/src/lab/presentation.browser.test.less +5 -0
- package/src/lab/presentation.browser.test.tsx +119 -0
- package/src/lab/presentation.less +64 -0
- package/src/lab/presentation.tsx +47 -0
- package/src/lab/useFocusPick.ts +43 -0
- package/src/lightbox/Lightbox.browser.test.less +14 -0
- package/src/lightbox/Lightbox.browser.test.tsx +113 -0
- package/src/lightbox/Lightbox.less +128 -0
- package/src/lightbox/Lightbox.test.tsx +195 -0
- package/src/lightbox/Lightbox.tsx +205 -0
- package/src/lightbox/LightboxContext.ts +38 -0
- package/src/lightbox/LightboxLayers.tsx +40 -0
- package/src/lightbox/index.ts +8 -0
- package/src/lightbox/modal.ts +94 -0
- package/src/loupe/AGENTS.md +40 -2
- package/src/loupe/CanvasLoupe.tsx +5 -4
- package/src/loupe/DomLoupe.tsx +7 -5
- package/src/loupe/Loupe.less +15 -0
- package/src/loupe/LoupeBubble.tsx +35 -13
- package/src/loupe/SourceLoupe.browser.test.tsx +204 -0
- package/src/loupe/SourceLoupe.tsx +60 -0
- package/src/loupe/TrialLoupe.browser.test.tsx +342 -0
- package/src/loupe/TrialLoupe.tsx +126 -28
- package/src/loupe/canvasLens.ts +20 -17
- package/src/loupe/index.ts +26 -2
- package/src/loupe/sourceLens.test.ts +65 -0
- package/src/loupe/sourceLens.ts +97 -0
- package/src/loupe/types.test.ts +6 -0
- package/src/loupe/types.ts +109 -7
- package/src/loupe/useLoupe.test.tsx +188 -3
- package/src/loupe/useLoupe.ts +106 -11
- package/src/primitives/index.ts +2 -2
- package/src/specimen/Specimen.tsx +0 -7
- package/src/state/helpers.test.ts +4 -11
- package/src/state/helpers.ts +2 -8
- package/src/state/index.ts +0 -2
- package/src/state/openLabStore.test.ts +10 -8
- package/src/state/openLabStore.ts +1 -1
- package/src/state/store.test.ts +2 -2
- package/src/state/store.ts +15 -16
- package/src/state/types.ts +9 -9
- package/src/styles.less +2 -1
- package/src/surface/AGENTS.md +13 -0
- package/src/surface/index.ts +1 -0
- package/src/surface/useSurfaceTile.test.tsx +4 -0
- package/src/surface/useSurfaceTile.ts +17 -1
- package/src/surface/useTiledSurface.test.tsx +65 -0
- package/src/surface/useTiledSurface.ts +68 -1
- package/src/theme/interstellar.theme.json +0 -14
- package/src/trial/Trial.stories.tsx +0 -1
- package/src/trial/Trial.test.tsx +40 -3
- package/src/trial/Trial.tsx +87 -43
- package/src/trial/TrialChrome.tsx +20 -2
- package/src/trial/trialOps.test.ts +1 -2
- package/src/trial/trialOps.ts +2 -3
- package/src/undo/stateOp.ts +21 -0
- package/src/undo/undoStack.ts +18 -6
- package/dist/chunk-4TJ34FXA.js.map +0 -1
- package/dist/chunk-4X44DMRS.js.map +0 -1
- package/dist/chunk-EESJUSYR.js.map +0 -1
- package/dist/chunk-HBGH344L.js.map +0 -1
- package/dist/chunk-IBVRMHW5.js.map +0 -1
- package/dist/chunk-IRMPZIYU.js.map +0 -1
- package/dist/chunk-LPGBC63T.js.map +0 -1
- package/dist/chunk-PMLZP7RT.js.map +0 -1
- package/dist/chunk-RL2LOLNI.js.map +0 -1
- package/dist/chunk-T6DLGEJB.js.map +0 -1
- package/dist/chunk-WIG6XHJ7.js.map +0 -1
- package/dist/chunk-XSJJTXNA.js.map +0 -1
- package/dist/chunk-YCFKW5RX.js.map +0 -1
- package/src/primitives/StatusBar.less +0 -34
- package/src/primitives/StatusBar.stories.tsx +0 -24
- package/src/primitives/StatusBar.test.tsx +0 -25
- package/src/primitives/StatusBar.tsx +0 -28
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/sectionTree.ts","../src/config/useConfigSchema.ts"],"names":[],"mappings":"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","file":"chunk-E6NARGU7.js","sourcesContent":["import type { PrefGroup, PrefLeaf } from '@weasel-js/ui';\nimport { valueAtPath } from './path';\nimport type { ResolvedConfig } from './types';\nimport { isLeafVisible } from './visible';\n\n/**\n * A resolved schema rearranged so its sections are groups.\n *\n * `PrefsForm`'s rail navigates the schema tree — top-level groups are its\n * items, their group children indent under them. A resolved schema keeps its\n * sections beside the tree instead, so a flat schema's rail comes out as one\n * unnamed item however many headings the panel draws. This puts the sections\n * where the rail looks for them.\n */\nexport interface SectionTree {\n /** The rail's schema. Top-level children are the schema's root sections,\n * followed by any root node no section claimed. */\n group: PrefGroup;\n /** `config` renested to mirror `group` — the value tree `PrefsForm` takes. */\n values: Record<string, unknown>;\n /** The config path a path within `group` stands for. */\n pathAt: (railPath: string) => string;\n}\n\n/** Structural rather than `isPrefLeaf`, so the config entry stays free of a\n * runtime import from ui. */\nfunction isLeaf(node: PrefLeaf | PrefGroup): node is PrefLeaf {\n return 'kind' in node;\n}\n\n/** A section label as an object key: no dots, since a dotted path is how every\n * caller addresses a node, and a label is free to hold one. */\nfunction slugOf(label: string, taken: ReadonlySet<string>): string {\n const base =\n label\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '') || 'section';\n if (!taken.has(base)) return base;\n for (let n = 2; ; n += 1) if (!taken.has(`${base}-${n}`)) return `${base}-${n}`;\n}\n\n/** A subtree with everything `showIf` or `hidden` rules out cut away, or null\n * when that is all of it. A group whose children all went is not a rail item\n * the reader can open onto nothing. */\nfunction prune(\n resolved: ResolvedConfig,\n group: PrefGroup,\n at: string,\n config: Record<string, unknown>,\n showHidden: boolean,\n): PrefGroup | null {\n const children: PrefGroup['children'] = {};\n for (const [key, child] of Object.entries(group.children)) {\n const path = at === '' ? key : `${at}.${key}`;\n if (!isLeafVisible(resolved, path, config, showHidden)) continue;\n if (isLeaf(child)) {\n children[key] = child;\n continue;\n }\n const kept = prune(resolved, child, path, config, showHidden);\n if (kept) children[key] = kept;\n }\n return Object.keys(children).length === 0 ? null : { ...group, children };\n}\n\n/**\n * Turn a resolved schema's root sections into the top level of a `PrefGroup`,\n * for `PrefsForm`'s rail layout.\n *\n * A section naming a group brings that group in whole, so it lands as an\n * indented rail item; a section naming a leaf drops it loose into the\n * section's own pane. Sections nested under a group are left alone — they\n * bucket rows inside a pane, which is the panel's job and not the rail's.\n */\nexport function sectionTree(\n resolved: ResolvedConfig,\n config: Record<string, unknown>,\n showHidden = false,\n): SectionTree {\n const children: PrefGroup['children'] = {};\n const values: Record<string, unknown> = {};\n const slugs = new Set<string>();\n const claimed = new Set<string>();\n\n for (const section of resolved.sections) {\n if (section.at !== '') continue;\n const kept: PrefGroup['children'] = {};\n const held: Record<string, unknown> = {};\n for (const path of section.paths) {\n claimed.add(path);\n const child = resolved.group.children[path];\n if (!child || !isLeafVisible(resolved, path, config, showHidden)) continue;\n if (isLeaf(child)) {\n kept[path] = child;\n } else {\n const subtree = prune(resolved, child, path, config, showHidden);\n if (!subtree) continue;\n kept[path] = subtree;\n }\n held[path] = valueAtPath(config, path);\n }\n if (Object.keys(kept).length === 0) continue;\n const slug = slugOf(section.label, slugs);\n slugs.add(slug);\n children[slug] = { name: section.label, children: kept };\n values[slug] = held;\n }\n\n // Whatever no section claimed stays at the top level, where `prefRailItems`\n // gathers loose leaves into one item named for the root.\n for (const [key, child] of Object.entries(resolved.group.children)) {\n if (claimed.has(key) || !isLeafVisible(resolved, key, config, showHidden)) continue;\n if (isLeaf(child)) {\n children[key] = child;\n } else {\n const subtree = prune(resolved, child, key, config, showHidden);\n if (!subtree) continue;\n children[key] = subtree;\n }\n values[key] = valueAtPath(config, key);\n }\n\n return {\n group: { name: resolved.group.name, children },\n values,\n pathAt: (railPath) => {\n const cut = railPath.indexOf('.');\n const head = cut === -1 ? railPath : railPath.slice(0, cut);\n if (!slugs.has(head)) return railPath;\n return cut === -1 ? '' : railPath.slice(cut + 1);\n },\n };\n}\n","import { useContext, useMemo } from 'react';\nimport type { Instrument } from '../instrument/types';\nimport { LabContext } from '../lab/LabContext';\nimport { fromConfigFields } from './fromConfigField';\nimport { resolveConfigSchema } from './resolve';\nimport type { ResolvedConfig } from './types';\n\nconst NO_RULES: readonly [] = [];\n\n/**\n * An instrument's controls, resolved against the surrounding lab's rules.\n *\n * Resolution cannot happen in `defineInstrument` — rules are lab-scoped and\n * that runs at module load — so it happens here, at render. Both instrument\n * paths land in the same shape, so callers never branch on which was used.\n */\nexport function useConfigSchema(\n // biome-ignore lint/suspicious/noExplicitAny: instruments are stored contravariantly; see InstrumentList\n instrument: Instrument<any, any, any>, // eslint-disable-line @typescript-eslint/no-explicit-any\n): ResolvedConfig {\n const lab = useContext(LabContext);\n const rules = lab?.configRules ?? NO_RULES;\n return useMemo(\n () =>\n instrument.config\n ? resolveConfigSchema(instrument.config, rules)\n : fromConfigFields(instrument.configSchema?.() ?? []),\n [instrument, rules],\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/config/sectionTree.ts","../src/config/useConfigSchema.ts"],"names":[],"mappings":"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","file":"chunk-SQX35X5V.js","sourcesContent":["import type { PrefGroup, PrefLeaf } from '@weasel-js/ui';\nimport { valueAtPath } from './path';\nimport type { ResolvedConfig } from './types';\nimport { isLeafVisible } from './visible';\n\n/**\n * A resolved schema rearranged so its sections are groups.\n *\n * `PrefsForm`'s rail navigates the schema tree — top-level groups are its\n * items, their group children indent under them. A resolved schema keeps its\n * sections beside the tree instead, so a flat schema's rail comes out as one\n * unnamed item however many headings the panel draws. This puts the sections\n * where the rail looks for them.\n */\nexport interface SectionTree {\n /** The rail's schema. Top-level children are the schema's root sections,\n * followed by any root node no section claimed. */\n group: PrefGroup;\n /** `config` renested to mirror `group` — the value tree `PrefsForm` takes. */\n values: Record<string, unknown>;\n /** The config path a path within `group` stands for. */\n pathAt: (railPath: string) => string;\n}\n\n/** Structural rather than `isPrefLeaf`, so the config entry stays free of a\n * runtime import from ui. */\nfunction isLeaf(node: PrefLeaf | PrefGroup): node is PrefLeaf {\n return 'kind' in node;\n}\n\n/** A section label as an object key: no dots, since a dotted path is how every\n * caller addresses a node, and a label is free to hold one. */\nfunction slugOf(label: string, taken: ReadonlySet<string>): string {\n const base =\n label\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '') || 'section';\n if (!taken.has(base)) return base;\n for (let n = 2; ; n += 1) if (!taken.has(`${base}-${n}`)) return `${base}-${n}`;\n}\n\n/** A subtree with everything `showIf` or `hidden` rules out cut away, or null\n * when that is all of it. A group whose children all went is not a rail item\n * the reader can open onto nothing. */\nfunction prune(\n resolved: ResolvedConfig,\n group: PrefGroup,\n at: string,\n config: Record<string, unknown>,\n showHidden: boolean,\n): PrefGroup | null {\n const children: PrefGroup['children'] = {};\n for (const [key, child] of Object.entries(group.children)) {\n const path = at === '' ? key : `${at}.${key}`;\n if (!isLeafVisible(resolved, path, config, showHidden)) continue;\n if (isLeaf(child)) {\n children[key] = child;\n continue;\n }\n const kept = prune(resolved, child, path, config, showHidden);\n if (kept) children[key] = kept;\n }\n return Object.keys(children).length === 0 ? null : { ...group, children };\n}\n\n/**\n * Turn a resolved schema's root sections into the top level of a `PrefGroup`,\n * for `PrefsForm`'s rail layout.\n *\n * A section naming a group brings that group in whole, so it lands as an\n * indented rail item; a section naming a leaf drops it loose into the\n * section's own pane. Sections nested under a group are left alone — they\n * bucket rows inside a pane, which is the panel's job and not the rail's.\n */\nexport function sectionTree(\n resolved: ResolvedConfig,\n config: Record<string, unknown>,\n showHidden = false,\n): SectionTree {\n const children: PrefGroup['children'] = {};\n const values: Record<string, unknown> = {};\n const slugs = new Set<string>();\n const claimed = new Set<string>();\n\n for (const section of resolved.sections) {\n if (section.at !== '') continue;\n const kept: PrefGroup['children'] = {};\n const held: Record<string, unknown> = {};\n for (const path of section.paths) {\n claimed.add(path);\n const child = resolved.group.children[path];\n if (!child || !isLeafVisible(resolved, path, config, showHidden)) continue;\n if (isLeaf(child)) {\n kept[path] = child;\n } else {\n const subtree = prune(resolved, child, path, config, showHidden);\n if (!subtree) continue;\n kept[path] = subtree;\n }\n held[path] = valueAtPath(config, path);\n }\n if (Object.keys(kept).length === 0) continue;\n const slug = slugOf(section.label, slugs);\n slugs.add(slug);\n children[slug] = { name: section.label, children: kept };\n values[slug] = held;\n }\n\n // Whatever no section claimed stays at the top level, where `prefRailItems`\n // gathers loose leaves into one item named for the root.\n for (const [key, child] of Object.entries(resolved.group.children)) {\n if (claimed.has(key) || !isLeafVisible(resolved, key, config, showHidden)) continue;\n if (isLeaf(child)) {\n children[key] = child;\n } else {\n const subtree = prune(resolved, child, key, config, showHidden);\n if (!subtree) continue;\n children[key] = subtree;\n }\n values[key] = valueAtPath(config, key);\n }\n\n return {\n group: { name: resolved.group.name, children },\n values,\n pathAt: (railPath) => {\n const cut = railPath.indexOf('.');\n const head = cut === -1 ? railPath : railPath.slice(0, cut);\n if (!slugs.has(head)) return railPath;\n return cut === -1 ? '' : railPath.slice(cut + 1);\n },\n };\n}\n","import { useContext, useMemo } from 'react';\nimport type { Instrument } from '../instrument/types';\nimport { LabContext } from '../lab/LabContext';\nimport { fromConfigFields } from './fromConfigField';\nimport { resolveConfigSchema } from './resolve';\nimport type { ResolvedConfig } from './types';\n\nconst NO_RULES: readonly [] = [];\n\n/**\n * An instrument's controls, resolved against the surrounding lab's rules.\n *\n * Resolution cannot happen in `defineInstrument` — rules are lab-scoped and\n * that runs at module load — so it happens here, at render. Both instrument\n * paths land in the same shape, so callers never branch on which was used.\n */\nexport function useConfigSchema(\n // biome-ignore lint/suspicious/noExplicitAny: instruments are stored contravariantly; see InstrumentList\n instrument: Instrument<any, any, any>, // eslint-disable-line @typescript-eslint/no-explicit-any\n): ResolvedConfig {\n const lab = useContext(LabContext);\n const rules = lab?.configRules ?? NO_RULES;\n return useMemo(\n () =>\n instrument.config\n ? resolveConfigSchema(instrument.config, rules)\n : fromConfigFields(instrument.configSchema?.() ?? []),\n [instrument, rules],\n );\n}\n"]}
|
|
@@ -114,6 +114,15 @@ var NumberNode = class extends BaseNode {
|
|
|
114
114
|
unit(unit) {
|
|
115
115
|
return this.ann({ unit });
|
|
116
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Make the top of the range mean infinity: the slider's `max` stop stores
|
|
119
|
+
* `Infinity` and reads `word` — `.range(0, 5000).endless('never')`. A value
|
|
120
|
+
* of `Infinity` sits at that stop. `at: 'min'` puts it at the bottom
|
|
121
|
+
* instead, as `-Infinity`; `'both'` does both.
|
|
122
|
+
*/
|
|
123
|
+
endless(word, at = "max") {
|
|
124
|
+
return this.ann(word === void 0 ? { endless: at } : { endless: at, infinity: word });
|
|
125
|
+
}
|
|
117
126
|
/** Force a slider even without both bounds. */
|
|
118
127
|
slider() {
|
|
119
128
|
return this.ann({ control: "slider" });
|
|
@@ -366,6 +375,11 @@ function resolveEntry(entry, key, path, sink) {
|
|
|
366
375
|
...entry.kind === null ? {} : { kind: entry.kind }
|
|
367
376
|
});
|
|
368
377
|
const patch = applyRules(seed, { key, path, default: entry.default }, sink.chain);
|
|
378
|
+
if (patch.kind === void 0) {
|
|
379
|
+
throw new Error(
|
|
380
|
+
`[labkit] "${path}" is an f.value whose kind cannot be inferred from its default (${String(entry.default)}) \u2014 declare it with a typed builder, or f.custom(kind, default) for a value with no row`
|
|
381
|
+
);
|
|
382
|
+
}
|
|
369
383
|
const { autoResolve, unpinned, manual } = entry.options;
|
|
370
384
|
return {
|
|
371
385
|
...patch,
|
|
@@ -391,5 +405,5 @@ function useResolvedConfig(schema, config, autoPaths) {
|
|
|
391
405
|
}
|
|
392
406
|
|
|
393
407
|
export { BaseNode, BooleanNode, ColorNode, CustomNode, EnumNode, GroupNode, ListNode, NumberNode, StringNode, ValueNode, applyRules, builtinRules, f, isConfigBranch, resolveConfigSchema, titleCase, useResolvedConfig };
|
|
394
|
-
//# sourceMappingURL=chunk-
|
|
395
|
-
//# sourceMappingURL=chunk-
|
|
408
|
+
//# sourceMappingURL=chunk-T5OEUNCB.js.map
|
|
409
|
+
//# sourceMappingURL=chunk-T5OEUNCB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/builder.ts","../src/config/rules.ts","../src/config/resolve.ts","../src/config/useResolvedConfig.ts"],"names":[],"mappings":"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","file":"chunk-T5OEUNCB.js","sourcesContent":["import type { Display, InfinityText } from '@weasel-js/quantity';\nimport type { PrefLeaf, PrefNumberUnit } from '@weasel-js/ui';\nimport { type Auto, isAuto } from './auto';\nimport type {\n Annotations,\n BranchAnnotations,\n BranchOptions,\n ConfigBranch,\n ConfigEntry,\n ConfigNode,\n ConfigOption,\n ConfigSchema,\n ConfigShape,\n ControlRenderer,\n InDialogOptions,\n InferConfig,\n NodeOptions,\n SectionOption,\n} from './types';\n\n/** Whether a schema entry is a branch rather than a leaf. */\nexport function isConfigBranch(entry: ConfigEntry): entry is ConfigBranch {\n return 'children' in entry;\n}\n\n/** Shared chaining surface. Every method clones, so a node can be reused as a\n * base for several leaves without one bleeding into the next. */\nexport abstract class BaseNode<T> implements ConfigNode<T> {\n abstract readonly kind: string | null;\n\n // `default` is a reserved word in a parameter position, so the field is\n // declared rather than taken as a parameter property.\n readonly default: T;\n\n constructor(\n defaultValue: T,\n readonly annotations: Readonly<Annotations> = {},\n readonly options: Readonly<NodeOptions> = {},\n ) {\n this.default = defaultValue;\n }\n\n /** Clone into the same subclass. Subclasses with extra constructor\n * arguments override this. */\n protected with(annotations: Annotations, options: NodeOptions): this {\n const Ctor = this.constructor as new (d: T, a: Annotations, o: NodeOptions) => this;\n return new Ctor(this.default, annotations, options);\n }\n\n protected ann(patch: Annotations): this {\n return this.with({ ...this.annotations, ...patch }, this.options);\n }\n\n protected opt(patch: NodeOptions): this {\n return this.with(this.annotations, { ...this.options, ...patch });\n }\n\n /** Human-readable label. Defaults to the key, title-cased. */\n label(name: string): this {\n return this.ann({ name });\n }\n\n /** Longer help text, surfaced as a tooltip on the row label. */\n describe(description: string): this {\n return this.ann({ description });\n }\n\n /** Omit from the panel unless it is asked to show hidden leaves. */\n hidden(): this {\n return this.ann({ hidden: true });\n }\n\n /** Pair with a sibling sharing this id, side-by-side on one row. */\n pair(pair: string): this {\n return this.ann({ pair });\n }\n\n /** Render under a named section heading. `collapsed` opens the section\n * folded, and `layout` and `pack` lay out its rows — say each on any one of\n * the section's leaves. */\n section(label: string, opts: Omit<SectionOption, 'label'> = {}): this {\n return this.opt({ section: { label, ...opts } });\n }\n\n /** Show this row only while the predicate holds. Presentational — the value\n * stays in config and the instrument still reads it. */\n showIf(predicate: (config: Record<string, unknown>) => boolean): this {\n return this.opt({ showIf: predicate });\n }\n\n /** Draw this one row yourself, keeping the kind, default and validation. */\n render(renderer: ControlRenderer): this {\n return this.opt({ render: renderer, dialog: undefined });\n }\n\n /** Draw this row as a button that opens a dialog, with `body` as the\n * dialog's content — for an editor too big for the row. */\n dialog(body: ControlRenderer, opts?: InDialogOptions): this {\n return this.opt({ dialog: { ...opts, body }, render: undefined });\n }\n\n /**\n * Compute this leaf's value while it is auto, instead of leaving it\n * `undefined`. The resolver is given the config with every other auto path\n * already resolved.\n */\n auto(resolve: (config: Record<string, unknown>) => T): this {\n return this.opt({ autoResolve: resolve as (c: Record<string, unknown>) => unknown });\n }\n\n /**\n * Start this leaf auto rather than pinned at its default. Takes `auto` and\n * nothing else — the constructor argument already declares the value, and a\n * second way to say it would fight with the first.\n */\n initial(value: Auto): this {\n if (!isAuto(value)) throw new Error('[labkit] .initial() takes `auto` and nothing else');\n return this.opt({ unpinned: true });\n }\n\n /** Never auto. The row's label does not toggle. */\n manual(): this {\n return this.opt({ manual: true });\n }\n}\n\n/** A numeric leaf, built by `f.number`. */\nexport class NumberNode extends BaseNode<number> {\n readonly kind = 'number';\n\n /** Bound the value. A number with both bounds renders as a slider. */\n range(min: number, max: number): this {\n return this.ann({ min, max });\n }\n\n step(step: number): this {\n return this.ann({ step });\n }\n\n /** A display suffix for the value — `'px'`, `'ms'`, `'°'`. Presentation only:\n * it is never parsed, and the stored value stays a plain number. */\n suffix(suffix: string): this {\n return this.ann({ suffix });\n }\n\n /** Show, speak and read the value through a display — `compact()` reads\n * `2.00M`. Presentation only: the stored value stays a plain number. */\n display(display: Display): this {\n return this.ann({ display });\n }\n\n /**\n * Store the value in one unit and edit it in another — radians stored,\n * degrees typed. `min`, `max` and `step` are declared in the stored unit\n * alongside the value, and convert with it. `prefUnit` builds one from a\n * `UnitSystem`.\n */\n unit(unit: PrefNumberUnit): this {\n return this.ann({ unit });\n }\n\n /**\n * Make the top of the range mean infinity: the slider's `max` stop stores\n * `Infinity` and reads `word` — `.range(0, 5000).endless('never')`. A value\n * of `Infinity` sits at that stop. `at: 'min'` puts it at the bottom\n * instead, as `-Infinity`; `'both'` does both.\n */\n endless(word?: InfinityText, at: 'min' | 'max' | 'both' = 'max'): this {\n return this.ann(word === undefined ? { endless: at } : { endless: at, infinity: word });\n }\n\n /** Force a slider even without both bounds. */\n slider(): this {\n return this.ann({ control: 'slider' });\n }\n\n /** Force a typed input even when both bounds are set. */\n input(): this {\n return this.ann({ control: 'input' });\n }\n}\n\n/** A true/false leaf, built by `f.boolean`; a checkbox unless `.toggle()`. */\nexport class BooleanNode extends BaseNode<boolean> {\n readonly kind = 'boolean';\n\n /** Ask for a switch rather than a checkbox. */\n toggle(): this {\n return this.ann({ control: 'switch' });\n }\n}\n\n/** A text leaf, built by `f.string`. */\nexport class StringNode extends BaseNode<string> {\n readonly kind = 'string';\n\n placeholder(placeholder: string): this {\n return this.ann({ placeholder });\n }\n\n maxLength(maxLength: number): this {\n return this.ann({ maxLength });\n }\n\n /** Milliseconds to debounce live writes. 0 commits every keystroke. */\n debounce(debounceMs: number): this {\n return this.ann({ debounceMs });\n }\n}\n\n/** A string-list leaf, built by `f.list`. */\nexport class ListNode extends BaseNode<string[]> {\n readonly kind = 'list';\n\n /** Shown in an empty entry. */\n placeholder(placeholder: string): this {\n return this.ann({ placeholder });\n }\n}\n\n/** A color leaf holding a hex string, built by `f.color`. */\nexport class ColorNode extends BaseNode<string> {\n readonly kind = 'color';\n\n /** The value carries alpha as `#rrggbbaa`, and the row gets an opacity\n * track beside the swatch. */\n alpha(): this {\n return this.ann({ alpha: true });\n }\n}\n\n/** A fixed-choice leaf, built by `f.enum`; a select unless `.radio()`. */\nexport class EnumNode<T extends string> extends BaseNode<T> {\n readonly kind = 'enum';\n\n /** Render as a segmented control rather than a select. */\n radio(): this {\n return this.ann({ control: 'radio' });\n }\n\n /** Relabel the choices. Named `labels` rather than `options` because\n * `options` is the node's own extras bag. */\n labels(options: readonly ConfigOption[]): this {\n return this.ann({ options });\n }\n}\n\n/** A leaf whose kind the rule chain decides. */\nexport class ValueNode<T> extends BaseNode<T> {\n readonly kind = null;\n}\n\n/** A leaf of a kind labkit does not ship a row for. */\nexport class CustomNode<T> extends BaseNode<T> {\n constructor(\n readonly kind: string,\n defaultValue: T,\n annotations: Readonly<Annotations> = {},\n options: Readonly<NodeOptions> = {},\n ) {\n super(defaultValue, annotations, options);\n }\n\n protected override with(annotations: Annotations, options: NodeOptions): this {\n return new CustomNode(this.kind, this.default, annotations, options) as this;\n }\n}\n\n/**\n * A branch of the schema: its children nest under its key, so a leaf inside\n * one is read and written at a dotted path. Distinct from `.section()`, which\n * puts a heading over sibling leaves and leaves their paths alone.\n */\nexport class GroupNode<S extends ConfigShape> implements ConfigBranch<S> {\n constructor(\n readonly children: S,\n readonly annotations: Readonly<BranchAnnotations> = {},\n readonly options: Readonly<BranchOptions> = {},\n ) {}\n\n private with(annotations: BranchAnnotations, options: BranchOptions): GroupNode<S> {\n return new GroupNode(this.children, annotations, options);\n }\n\n /** Heading for the group's rows. Defaults to the key, title-cased. */\n label(name: string): GroupNode<S> {\n return this.with({ ...this.annotations, name }, this.options);\n }\n\n /** Longer help text. Carried on the resolved `PrefGroup`; both weasel-ui's\n * `PrefsForm` and `ControlPanel` draw it under the heading. */\n describe(description: string): GroupNode<S> {\n return this.with({ ...this.annotations, description }, this.options);\n }\n\n /** Render this whole group under a named section heading. */\n section(label: string, opts: Omit<SectionOption, 'label'> = {}): GroupNode<S> {\n return this.with(this.annotations, { ...this.options, section: { label, ...opts } });\n }\n\n /** Show this group only while the predicate holds. Presentational — every\n * value beneath it stays in config and the instrument still reads it. */\n showIf(predicate: (config: Record<string, unknown>) => boolean): GroupNode<S> {\n return this.with(this.annotations, { ...this.options, showIf: predicate });\n }\n\n /** Put a button on the group's heading that returns every value beneath it\n * to its default, leaving the rest of the config alone. */\n resettable(): GroupNode<S> {\n return this.with(this.annotations, { ...this.options, resettable: true });\n }\n}\n\n/** Every default in a shape, nested the way the shape is. */\nfunction shapeDefaults(shape: ConfigShape): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(shape)) {\n out[key] = isConfigBranch(entry) ? shapeDefaults(entry.children) : entry.default;\n }\n return out;\n}\n\nconst expand = <T extends string>(\n options: readonly T[] | readonly ConfigOption[],\n): readonly ConfigOption[] =>\n options.map((o) => (typeof o === 'string' ? { value: o, label: o } : o));\n\n/**\n * Builds an instrument's config: the values, their types, and how each is\n * edited, in one declaration.\n *\n * ```ts\n * const config = f.schema({\n * showGrid: f.boolean(true),\n * cellSize: f.number(20).range(5, 80).step(5).label('Grid spacing'),\n * // Nested: read and written at `grid.color`.\n * grid: f.group({ color: f.color('#ffffff') }),\n * })\n * ```\n */\nexport const f = {\n number: (def: number): NumberNode => new NumberNode(def),\n boolean: (def: boolean): BooleanNode => new BooleanNode(def),\n string: (def: string): StringNode => new StringNode(def),\n color: (def: string): ColorNode => new ColorNode(def),\n /** A list of strings. Its row summarizes the list, and opens a dialog to\n * edit it one entry per field. */\n list: (def: readonly string[]): ListNode => new ListNode([...def]),\n\n /** A fixed set of choices. The default's literal type flows into the config\n * type, so `f.enum('fast', ['fast', 'accurate'])` gives\n * `'fast' | 'accurate'` with no `as const`. */\n enum: <const T extends string>(\n def: T,\n options: readonly T[] | readonly ConfigOption[],\n ): EnumNode<T> => new EnumNode<T>(def, { options: expand(options) }),\n\n /** A leaf with no declared kind: the rule chain decides, which is how a lab\n * states a convention like \"every `*Color` key is a color picker\". */\n value: <T>(def: T): ValueNode<T> => new ValueNode(def),\n\n /** A branch: its children nest under this key, so `grid: f.group({ size })`\n * puts the value at `config.grid.size` and addresses it as `'grid.size'`.\n * Groups nest as deeply as the schema wants. */\n group: <const S extends ConfigShape>(children: S): GroupNode<S> => new GroupNode(children),\n\n /** A leaf of a kind a lab supplies the control for, through `controls`. */\n custom: <T>(\n kind: string,\n def: T,\n validate?: (leaf: PrefLeaf, config: Record<string, unknown>) => string[],\n ): CustomNode<T> => new CustomNode(kind, def, {}, validate ? { validate } : {}),\n\n /** Collect leaves and groups into an instrument's config. */\n schema<S extends ConfigShape>(nodes: S): ConfigSchema<InferConfig<S>> {\n return { nodes, defaults: () => shapeDefaults(nodes) as InferConfig<S> };\n },\n};\n","import type { ConfigRule, ConfigRuleContext, LeafPatch } from './types';\n\n/** `cellSize` -> `Cell size`. Splits camelCase without shattering acronyms. */\nexport function titleCase(key: string): string {\n const words = key\n .replace(/[_-]+/g, ' ')\n .split(/(?<=[a-z0-9])(?=[A-Z])/)\n .join(' ')\n .trim()\n .toLowerCase();\n return words.length === 0 ? words : words[0].toUpperCase() + words.slice(1);\n}\n\n/** An `f.value` leaf takes its kind from the shape of its default. */\nconst kindFromValue: ConfigRule = (ctx) => {\n const t = typeof ctx.default;\n if (t === 'boolean' || t === 'number' || t === 'string') return { kind: t };\n const d = ctx.default;\n if (Array.isArray(d) && d.every((v) => typeof v === 'string')) return { kind: 'list' };\n return null;\n};\n\nconst labelFromKey: ConfigRule = (ctx) => ({ name: titleCase(ctx.key) });\n\n/** A number bounded on both sides is a slider; one bound or none is an input. */\nconst sliderWhenBounded: ConfigRule = (ctx) => {\n if (ctx.leaf.kind !== 'number') return null;\n const bounded = ctx.leaf.min !== undefined && ctx.leaf.max !== undefined;\n return bounded ? { control: 'slider' } : null;\n};\n\n/** `PrefBase.description` is required, so every leaf must end up with one. */\nconst descriptionDefault: ConfigRule = () => ({ description: '' });\n\n/**\n * labkit's own inference, expressed in the same vocabulary a consumer\n * extends. Runs after the consumer's rules, so a lab always wins.\n *\n * If one of these ever needs something a `ConfigRule` cannot express, the\n * seam is too weak — that is the point of writing them this way.\n */\nexport const builtinRules: readonly ConfigRule[] = [\n kindFromValue,\n labelFromKey,\n sliderWhenBounded,\n descriptionDefault,\n];\n\n/**\n * Fold a rule chain into one leaf patch. Gap-filling: a property already\n * settled is never overwritten, so the accumulator seeded with the author's\n * annotations beats every rule, and earlier rules beat later ones.\n */\nexport function applyRules(\n seed: LeafPatch,\n ctx: Omit<ConfigRuleContext, 'leaf'>,\n rules: readonly ConfigRule[],\n): LeafPatch {\n const acc: LeafPatch = { ...seed };\n for (const rule of rules) {\n const patch = rule({ ...ctx, leaf: acc });\n if (patch === null) continue;\n for (const [k, v] of Object.entries(patch)) {\n if (v !== undefined && acc[k as keyof LeafPatch] === undefined) {\n (acc as Record<string, unknown>)[k] = v;\n }\n }\n }\n return acc;\n}\n","import type { PrefGroup, PrefLeaf } from '@weasel-js/ui';\nimport { isConfigBranch } from './builder';\nimport { applyRules, builtinRules, titleCase } from './rules';\nimport type {\n ConfigEntry,\n ConfigRule,\n ConfigSchema,\n ConfigShape,\n ControlRenderer,\n DialogSpec,\n LeafPatch,\n ResolvedConfig,\n SectionSpec,\n} from './types';\n\n/** Drop keys whose value is undefined, so an unset annotation stays a gap the\n * rule chain can fill rather than a settled `undefined`. */\nfunction defined(annotations: Record<string, unknown>): LeafPatch {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(annotations)) if (v !== undefined) out[k] = v;\n return out as LeafPatch;\n}\n\n/** What the walk collects on the side of the `PrefGroup` tree. */\ninterface Sink {\n sections: SectionSpec[];\n showIf: Map<string, (config: Record<string, unknown>) => boolean>;\n renderers: Record<string, ControlRenderer>;\n dialogs: Record<string, DialogSpec>;\n resettable: Set<string>;\n chain: readonly ConfigRule[];\n}\n\n/**\n * Resolve a schema into the vocabulary weasel-ui renders, running each leaf\n * through the consumer's rules and then labkit's own.\n *\n * The group mirrors the schema's own nesting: an `f.group` becomes a nested\n * `PrefGroup`, so a leaf's dotted path within the tree is the path its value\n * is written at, and both `ControlPanel` and `PrefsForm` address it\n * identically.\n */\nexport function resolveConfigSchema<TC>(\n schema: ConfigSchema<TC>,\n rules: readonly ConfigRule[] = [],\n): ResolvedConfig {\n const sink: Sink = {\n sections: [],\n showIf: new Map(),\n renderers: {},\n dialogs: {},\n resettable: new Set(),\n chain: [...rules, ...builtinRules],\n };\n const group = resolveShape(schema.nodes, '', '', sink);\n return {\n group,\n sections: sink.sections,\n showIf: sink.showIf,\n renderers: sink.renderers,\n dialogs: sink.dialogs,\n resettable: sink.resettable,\n };\n}\n\n/** A section while it is still being filled. */\ntype OpenSection = Omit<SectionSpec, 'paths'> & { paths: string[] };\n\nfunction resolveShape(shape: ConfigShape, at: string, name: string, sink: Sink): PrefGroup {\n const children: Record<string, PrefLeaf | PrefGroup> = {};\n const sections = new Map<string, OpenSection>();\n\n for (const [key, entry] of Object.entries(shape)) {\n const path = at === '' ? key : `${at}.${key}`;\n children[key] = resolveEntry(entry, key, path, sink);\n\n const { section, showIf: predicate } = entry.options;\n if (section !== undefined) {\n let spec = sections.get(section.label);\n if (!spec) {\n spec = { at, label: section.label, paths: [] };\n sections.set(section.label, spec);\n sink.sections.push(spec);\n }\n spec.paths.push(path);\n // One node saying `collapsed` settles the section, so a schema does not\n // have to repeat it on every node under the heading.\n if (section.collapsed !== undefined) {\n spec.collapsed = (spec.collapsed ?? false) || section.collapsed;\n }\n if (section.layout !== undefined && spec.layout === undefined) spec.layout = section.layout;\n if (section.pack !== undefined && spec.pack === undefined) spec.pack = section.pack;\n }\n if (predicate) sink.showIf.set(path, predicate);\n if (isConfigBranch(entry) && entry.options.resettable) sink.resettable.add(path);\n if (!isConfigBranch(entry) && entry.options.render) sink.renderers[path] = entry.options.render;\n if (!isConfigBranch(entry) && entry.options.dialog) sink.dialogs[path] = entry.options.dialog;\n }\n\n return { name, children };\n}\n\nfunction resolveEntry(\n entry: ConfigEntry,\n key: string,\n path: string,\n sink: Sink,\n): PrefLeaf | PrefGroup {\n if (isConfigBranch(entry)) {\n const group = resolveShape(\n entry.children,\n path,\n entry.annotations.name ?? titleCase(key),\n sink,\n );\n return entry.annotations.description === undefined\n ? group\n : { ...group, description: entry.annotations.description };\n }\n if (entry.options.manual && entry.options.unpinned) {\n throw new Error(\n `[labkit] \"${path}\" is both .manual() and .initial(auto) — a field that can never be auto cannot start auto`,\n );\n }\n const seed: LeafPatch = defined({\n ...entry.annotations,\n ...(entry.kind === null ? {} : { kind: entry.kind }),\n });\n const patch = applyRules(seed, { key, path, default: entry.default }, sink.chain);\n if (patch.kind === undefined) {\n throw new Error(\n `[labkit] \"${path}\" is an f.value whose kind cannot be inferred from its default (${String(entry.default)}) — declare it with a typed builder, or f.custom(kind, default) for a value with no row`,\n );\n }\n const { autoResolve, unpinned, manual } = entry.options;\n return {\n ...patch,\n default: entry.default,\n // Extra keys survive onto the leaf at runtime; `ControlPanel` reads them\n // back with its `extra<T>` helper, the same as `min`, `step` and the rest.\n ...(autoResolve === undefined ? {} : { autoResolve }),\n ...(unpinned === undefined ? {} : { unpinned }),\n ...(manual === undefined ? {} : { manual }),\n } as PrefLeaf;\n}\n","import { useMemo } from 'react';\nimport { resolveAutoConfig } from './autoConfig';\nimport type { ResolvedConfig } from './types';\n\nconst NONE: ReadonlySet<string> = new Set();\n\n/**\n * The config an instrument reads: the stored one with every unpinned path\n * resolved. The single place resolution happens, so `Trial` and\n * `useTrialState` cannot disagree about what an instrument is looking at.\n */\nexport function useResolvedConfig<TC>(\n schema: ResolvedConfig | undefined,\n config: TC,\n autoPaths: readonly string[] | undefined,\n): { config: TC; auto: ReadonlySet<string> } {\n const auto = useMemo(\n () => (autoPaths && autoPaths.length > 0 ? new Set(autoPaths) : NONE),\n [autoPaths],\n );\n const resolvedConfig = useMemo(\n () => (schema ? resolveAutoConfig(schema, config, auto) : config),\n [schema, config, auto],\n );\n return { config: resolvedConfig, auto };\n}\n"]}
|
|
@@ -50,5 +50,5 @@ function clearUndo(_stack) {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export { clearUndo, createEventBus, emptyStack, pushSnapshot, redo, undo };
|
|
53
|
-
//# sourceMappingURL=chunk-
|
|
54
|
-
//# sourceMappingURL=chunk-
|
|
53
|
+
//# sourceMappingURL=chunk-UX66USTN.js.map
|
|
54
|
+
//# sourceMappingURL=chunk-UX66USTN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/undo/eventBus.ts","../src/undo/undoStack.ts"],"names":[],"mappings":";AAYO,SAAS,cAAA,GAA2B;AACzC,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAgC;AACtD,EAAA,OAAO;AAAA,IACL,EAAA,CAAG,OAAO,QAAA,EAAU;AAClB,MAAA,IAAI,GAAA,GAAM,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA;AAC7B,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,GAAA,uBAAU,GAAA,EAAI;AACd,QAAA,SAAA,CAAU,GAAA,CAAI,OAAO,GAAG,CAAA;AAAA,MAC1B;AACA,MAAA,GAAA,CAAI,IAAI,QAAQ,CAAA;AAChB,MAAA,OAAO,MAAM;AACX,QAAA,GAAA,EAAK,OAAO,QAAQ,CAAA;AAAA,MACtB,CAAA;AAAA,IACF,CAAA;AAAA,IACA,KAAK,KAAA,EAAO;AACV,MAAA,MAAM,GAAA,GAAM,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA;AAC/B,MAAA,IAAI,CAAC,GAAA,EAAK;AACV,MAAA,KAAA,MAAW,EAAA,IAAM,CAAC,GAAG,GAAG,GAAG,EAAA,EAAG;AAAA,IAChC,CAAA;AAAA,IACA,KAAA,GAAQ;AACN,MAAA,SAAA,CAAU,KAAA,EAAM;AAAA,IAClB;AAAA,GACF;AACF;;;ACnBO,SAAS,UAAA,GAAwB;AACtC,EAAA,OAAO,EAAE,IAAA,EAAM,EAAC,EAAG,MAAA,EAAQ,EAAC,EAAE;AAChC;AAKO,SAAS,YAAA,CAAa,KAAA,EAAkB,QAAA,EAAmB,QAAA,EAA6B;AAC7F,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,IAAA,CAAK,MAAA,IAAU,QAAA,GAAW,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,GAAI,KAAA,CAAM,IAAA,CAAK,KAAA,EAAM;AACpF,EAAA,IAAA,CAAK,KAAK,QAAQ,CAAA;AAClB,EAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,EAAC,EAAE;AAC5B;AAMO,SAAS,IAAA,CACd,OACA,OAAA,EACgD;AAChD,EAAA,IAAI,KAAA,CAAM,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AACpC,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,IAAA,CAAK,KAAA,EAAM;AAC9B,EAAA,MAAM,QAAA,GAAW,KAAK,GAAA,EAAI;AAC1B,EAAA,OAAO,EAAE,KAAA,EAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,CAAC,GAAG,KAAA,CAAM,MAAA,EAAQ,OAAO,CAAA,EAAE,EAAG,QAAA,EAAS;AACzE;AAKO,SAAS,IAAA,CACd,OACA,OAAA,EACgD;AAChD,EAAA,IAAI,KAAA,CAAM,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AACtC,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,MAAA,CAAO,KAAA,EAAM;AAClC,EAAA,MAAM,QAAA,GAAW,OAAO,GAAA,EAAI;AAC5B,EAAA,OAAO,EAAE,KAAA,EAAO,EAAE,IAAA,EAAM,CAAC,GAAG,KAAA,CAAM,IAAA,EAAM,OAAO,CAAA,EAAG,MAAA,EAAO,EAAG,QAAA,EAAS;AACvE;AAIO,SAAS,UAAU,MAAA,EAA8B;AACtD,EAAA,OAAO,UAAA,EAAW;AACpB","file":"chunk-UX66USTN.js","sourcesContent":["/** A subscriber to a named event. */\nexport type EventListener = () => void;\n\n/** Named-event pub/sub, the channel an instrument's `emit` writes to and undo\n * snapshotting listens on. */\nexport interface EventBus {\n on(event: string, listener: EventListener): () => void;\n emit(event: string): void;\n clear(): void;\n}\n\n/** Build an empty event bus. */\nexport function createEventBus(): EventBus {\n const listeners = new Map<string, Set<EventListener>>();\n return {\n on(event, listener) {\n let set = listeners.get(event);\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n set.add(listener);\n return () => {\n set?.delete(listener);\n };\n },\n emit(event) {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of [...set]) fn();\n },\n clear() {\n listeners.clear();\n },\n };\n}\n","/**\n * @deprecated The whole module. A trial's undo runs on weasel-history\n * (`TrialRecord.history`); for an undo of your own, `createHistory` from\n * `@weasel-js/core`. Kept until sherpa's studio, its last user, moves off it.\n */\n\n/** Undo history as two stacks of state snapshots: what has been done, and\n * what has been undone. The present state is held elsewhere, not here.\n * @deprecated See the module comment. */\nexport interface UndoStack {\n past: unknown[];\n future: unknown[];\n}\n\n/** A fresh, empty history.\n * @deprecated See the module comment. */\nexport function emptyStack(): UndoStack {\n return { past: [], future: [] };\n}\n\n/** Record a new snapshot, discarding the redo branch and the oldest entry\n * once `maxDepth` is reached.\n * @deprecated See the module comment. */\nexport function pushSnapshot(stack: UndoStack, snapshot: unknown, maxDepth: number): UndoStack {\n const past = stack.past.length >= maxDepth ? stack.past.slice(1) : stack.past.slice();\n past.push(snapshot);\n return { past, future: [] };\n}\n\n/** Step back one snapshot, returning the new history and the state to restore.\n * `null` when there is nothing to undo. The caller supplies `current` so it\n * can be redone.\n * @deprecated See the module comment. */\nexport function undo(\n stack: UndoStack,\n current: unknown,\n): { stack: UndoStack; snapshot: unknown } | null {\n if (stack.past.length === 0) return null;\n const past = stack.past.slice();\n const snapshot = past.pop();\n return { stack: { past, future: [...stack.future, current] }, snapshot };\n}\n\n/** Step forward one snapshot, returning the new history and the state to\n * restore. `null` when there is nothing to redo.\n * @deprecated See the module comment. */\nexport function redo(\n stack: UndoStack,\n current: unknown,\n): { stack: UndoStack; snapshot: unknown } | null {\n if (stack.future.length === 0) return null;\n const future = stack.future.slice();\n const snapshot = future.pop();\n return { stack: { past: [...stack.past, current], future }, snapshot };\n}\n\n/** Discard the whole history.\n * @deprecated See the module comment. */\nexport function clearUndo(_stack: UndoStack): UndoStack {\n return emptyStack();\n}\n"]}
|