@weasel-js/labkit 1.6.0 → 1.6.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/dist/_dts/{CanvasStackContext-DQgcH1ny.d.ts → CanvasStackContext-Wo6OwIVM.d.ts} +1 -1
- package/dist/_dts/FloatingPanel-7j0IcXwz.d.ts +30 -0
- package/dist/_dts/{LayerList.d-2c9yup5Y.d.ts → LayerList.d-BoELAMsM.d.ts} +2 -2
- package/dist/_dts/{index-DINmCuLA.d.ts → PropertyField.d-D0ndfIIt.d.ts} +34 -83
- package/dist/_dts/{Select.d-BchGMC2Y.d.ts → Select.d-Cr8-zoup.d.ts} +4 -5
- package/dist/_dts/{usePanZoom-Bq73pwFe.d.ts → Stage-DWBBi8IU.d.ts} +80 -35
- package/dist/_dts/{index-B0--8PEM.d.ts → index-CKyX0ME_.d.ts} +12 -13
- package/dist/_dts/{frac-DTRq7Xpb.d.ts → types-B7yBTTF9.d.ts} +699 -649
- package/dist/_dts/{types-B7y8hX1D.d.ts → types-DTuViBvc.d.ts} +20 -1
- package/dist/_dts/{useTrialState-CP4jfuKl.d.ts → useTrialState-CMaV6UD4.d.ts} +2 -3
- package/dist/canvas/index.d.ts +39 -7
- package/dist/canvas/index.js +5 -3
- package/dist/chrome/index.d.ts +4 -5
- package/dist/chrome/index.js +8 -6
- package/dist/chunk-24W5VEJW.js +18 -0
- package/dist/chunk-24W5VEJW.js.map +1 -0
- package/dist/chunk-3RY6WL5T.js +38 -0
- package/dist/chunk-3RY6WL5T.js.map +1 -0
- package/dist/{chunk-H5VIV7MQ.js → chunk-4TT3PNPR.js} +60 -51
- package/dist/chunk-4TT3PNPR.js.map +1 -0
- package/dist/{chunk-ZORVNOKX.js → chunk-6FLXL3I7.js} +9 -145
- package/dist/chunk-6FLXL3I7.js.map +1 -0
- package/dist/{chunk-HFRE4QQV.js → chunk-ASOK76ZH.js} +53 -22
- package/dist/chunk-ASOK76ZH.js.map +1 -0
- package/dist/chunk-AWQG7FCC.js +19 -0
- package/dist/chunk-AWQG7FCC.js.map +1 -0
- package/dist/chunk-CGHF6RZV.js +300 -0
- package/dist/chunk-CGHF6RZV.js.map +1 -0
- package/dist/chunk-DWMSB4CA.js +228 -0
- package/dist/chunk-DWMSB4CA.js.map +1 -0
- package/dist/{chunk-USO6TERP.js → chunk-GHGO52SO.js} +11 -9
- package/dist/chunk-GHGO52SO.js.map +1 -0
- package/dist/{chunk-MOLIUNVH.js → chunk-HKV7LRHY.js} +4 -4
- package/dist/{chunk-MOLIUNVH.js.map → chunk-HKV7LRHY.js.map} +1 -1
- package/dist/{chunk-VQ47KWD5.js → chunk-IRTGUQ5O.js} +5 -4
- package/dist/chunk-IRTGUQ5O.js.map +1 -0
- package/dist/{chunk-H6ZAOWNE.js → chunk-JVBYV6TL.js} +3 -3
- package/dist/{chunk-H6ZAOWNE.js.map → chunk-JVBYV6TL.js.map} +1 -1
- package/dist/chunk-KHK5FGER.js +145 -0
- package/dist/chunk-KHK5FGER.js.map +1 -0
- package/dist/chunk-NEXR37YJ.js +144 -0
- package/dist/chunk-NEXR37YJ.js.map +1 -0
- package/dist/{chunk-BVL7Y574.js → chunk-O6FFFOHS.js} +14 -6
- package/dist/chunk-O6FFFOHS.js.map +1 -0
- package/dist/chunk-QGMOA2YE.js +731 -0
- package/dist/chunk-QGMOA2YE.js.map +1 -0
- package/dist/{chunk-ERFMC6WU.js → chunk-S4NCI32V.js} +19 -10
- package/dist/chunk-S4NCI32V.js.map +1 -0
- package/dist/{chunk-3FI7Y4R4.js → chunk-SLAQPUI4.js} +4 -4
- package/dist/{chunk-3FI7Y4R4.js.map → chunk-SLAQPUI4.js.map} +1 -1
- package/dist/{chunk-AWH3SRPW.js → chunk-TJ77A4A3.js} +3 -31
- package/dist/chunk-TJ77A4A3.js.map +1 -0
- package/dist/{chunk-WUJXJC5O.js → chunk-TYN6MLXX.js} +691 -1395
- package/dist/chunk-TYN6MLXX.js.map +1 -0
- package/dist/{chunk-RS3HRQWU.js → chunk-WPLAANH4.js} +4 -3
- package/dist/chunk-WPLAANH4.js.map +1 -0
- package/dist/config/index.d.ts +36 -35
- package/dist/config/index.js +4 -5
- package/dist/controls/index.d.ts +91 -7
- package/dist/controls/index.js +5 -4
- package/dist/dragdrop/index.d.ts +8 -6
- package/dist/dragdrop/index.js +3 -2
- package/dist/index.d.ts +50 -77
- package/dist/index.js +138 -254
- package/dist/index.js.map +1 -1
- package/dist/layers/index.d.ts +3 -4
- package/dist/layers/index.js +2 -1
- package/dist/loupe/index.d.ts +19 -16
- package/dist/loupe/index.js +5 -3
- package/dist/overview/index.d.ts +56 -0
- package/dist/overview/index.js +288 -0
- package/dist/overview/index.js.map +1 -0
- package/dist/passthrough/weasel-ui.d.ts +38 -38
- package/dist/passthrough/weasel-ui.js +2 -1
- package/dist/primitives/index.d.ts +19 -43
- package/dist/primitives/index.js +5 -3
- package/dist/state/index.d.ts +7 -7
- package/dist/state/index.js +4 -5
- package/dist/state/index.js.map +1 -1
- package/dist/styles.css +63 -1
- package/dist/undo/index.d.ts +3 -3
- package/package.json +13 -9
- package/src/annotations/index.ts +1 -0
- package/src/annotations/store.test.ts +26 -0
- package/src/annotations/store.ts +25 -6
- package/src/annotations/toolMap.test.ts +37 -2
- package/src/annotations/toolMap.ts +13 -0
- package/src/annotations/types.ts +27 -0
- package/src/canvas/AGENTS.md +8 -10
- package/src/canvas/CameraInput.test.tsx +136 -0
- package/src/canvas/CameraInput.tsx +311 -0
- package/src/canvas/CanvasStack.tsx +42 -58
- package/src/canvas/LinkedCursor.less +16 -0
- package/src/canvas/LinkedCursor.tsx +54 -0
- package/src/canvas/Stage.tsx +42 -37
- package/src/canvas/cameraView.test.ts +60 -0
- package/src/canvas/cameraView.ts +61 -0
- package/src/canvas/index.ts +11 -2
- package/src/chrome/regions/SidebarRegion.test.tsx +9 -2
- package/src/config/builder.ts +3 -3
- package/src/config/entry.test.ts +3 -1
- package/src/config/fromConfigField.ts +1 -0
- package/src/config/index.ts +4 -1
- package/src/config/resolve.ts +11 -1
- package/src/config/sectionTree.test.ts +12 -6
- package/src/config/sectionTree.ts +15 -5
- package/src/config/types.ts +21 -0
- package/src/controls/ControlPanel.test.tsx +12 -2
- package/src/controls/ControlPanel.tsx +28 -9
- package/src/controls/inDialog.test.tsx +18 -0
- package/src/controls/inDialog.tsx +2 -10
- package/src/index.test.ts +1 -1
- package/src/index.ts +8 -4
- package/src/instrument/SineWave.smoke.test.tsx +2 -0
- package/src/instrument/types.ts +10 -1
- package/src/lab/Lab.nebula.test.tsx +11 -2
- package/src/lab/Lab.test.tsx +3 -1
- package/src/lab/Lab.tsx +4 -4
- package/src/loupe/AGENTS.md +7 -6
- package/src/loupe/LoupeGestures.tsx +14 -9
- package/src/loupe/TrialLoupe.tsx +5 -5
- package/src/loupe/index.ts +1 -0
- package/src/loupe/loupeActions.ts +6 -2
- package/src/overview/AGENTS.md +38 -0
- package/src/overview/OverviewMarks.test.tsx +100 -0
- package/src/overview/OverviewMarks.tsx +93 -0
- package/src/overview/TrialOverview.less +53 -0
- package/src/overview/TrialOverview.stories.tsx +50 -0
- package/src/overview/TrialOverview.test.tsx +116 -0
- package/src/overview/TrialOverview.tsx +374 -0
- package/src/overview/index.ts +2 -0
- package/src/passthrough/weasel-ui.ts +7 -0
- package/src/specimen/Specimen.tsx +19 -2
- package/src/state/labRecords.test.ts +4 -1
- package/src/state/store.test.ts +4 -4
- package/src/state/useTrialState.test.tsx +1 -1
- package/src/styles.less +2 -0
- package/src/theme/Interstellar.stories.tsx +1 -5
- package/src/tools/labTool.ts +6 -2
- package/src/trial/Trial.annotations.test.tsx +16 -0
- package/src/trial/Trial.loupe.test.tsx +73 -1
- package/src/trial/Trial.stories.tsx +2 -0
- package/src/trial/Trial.tsx +17 -1
- package/src/trial/trialOps.test.ts +4 -4
- package/dist/_dts/inDialog-D5ZKGjiD.d.ts +0 -23
- package/dist/_dts/number.d-OeQYQoUO.d.ts +0 -28
- package/dist/chunk-2AYGEN57.js +0 -32
- package/dist/chunk-2AYGEN57.js.map +0 -1
- package/dist/chunk-AWH3SRPW.js.map +0 -1
- package/dist/chunk-BVL7Y574.js.map +0 -1
- package/dist/chunk-ERFMC6WU.js.map +0 -1
- package/dist/chunk-H5VIV7MQ.js.map +0 -1
- package/dist/chunk-HFRE4QQV.js.map +0 -1
- package/dist/chunk-RS3HRQWU.js.map +0 -1
- package/dist/chunk-TT5C5S6R.js +0 -368
- package/dist/chunk-TT5C5S6R.js.map +0 -1
- package/dist/chunk-USO6TERP.js.map +0 -1
- package/dist/chunk-VQ47KWD5.js.map +0 -1
- package/dist/chunk-WUJXJC5O.js.map +0 -1
- package/dist/chunk-ZORVNOKX.js.map +0 -1
- package/src/canvas/usePanZoom.test.ts +0 -244
- package/src/canvas/usePanZoom.ts +0 -147
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/state/document.ts","../src/state/undock.ts","../src/instrument/serializers.ts","../src/state/store.ts","../src/state/openLabStore.ts","../src/state/useTrialState.ts"],"names":[],"mappings":"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","file":"chunk-MOLIUNVH.js","sourcesContent":["import { labStorageKey } from './helpers';\nimport type {\n LabDocument,\n LabMode,\n Migration,\n SavedSnapshot,\n SerializedTrial,\n StorageAdapter,\n} from './types';\nimport type { UndockedPanels } from './undock';\n\n/** Bumped whenever the persisted shape changes; every bump needs a migration. */\nexport const CURRENT_DOCUMENT_VERSION = 4;\n\n/** Where a version-3 lab kept its one document. Read once, to fold it into\n * records, then deleted. */\nexport function labDocumentKey(storageKey: string): string {\n return `lk:${storageKey}:doc`;\n}\n\n/** Where a document that failed to migrate is set aside, so a bad migration\n * loses state loudly rather than silently. */\nexport function quarantineKey(storageKey: string): string {\n return `lk:${storageKey}:quarantine`;\n}\n\n/** A fresh document at the current version. */\nexport function emptyDocument(mode: LabMode): LabDocument {\n return {\n version: CURRENT_DOCUMENT_VERSION,\n undockedPanels: {},\n trials: [],\n saves: [],\n layout: {},\n mode,\n };\n}\n\n/** What a migration run produced: the migrated document, or why it refused. */\nexport type MigrationOutcome =\n | { ok: true; doc: Record<string, unknown>; migrated: boolean }\n | { ok: false; reason: 'future' | 'failed'; error?: unknown };\n\n/** Walk a document forward to `target`, one migration at a time. A version\n * above `target` is refused rather than parsed under a shape it may not\n * have. */\nexport function runMigrations(\n raw: Record<string, unknown>,\n migrations: Migration[],\n target: number,\n): MigrationOutcome {\n const from = typeof raw.version === 'number' ? raw.version : 0;\n if (from > target) return { ok: false, reason: 'future' };\n if (from === target) return { ok: true, doc: raw, migrated: false };\n\n let doc = raw;\n try {\n for (let v = from; v < target; v++) {\n const migration = migrations[v];\n if (!migration) throw new Error(`[labkit] no migration from version ${v}`);\n doc = migration(doc);\n }\n } catch (error) {\n return { ok: false, reason: 'failed', error };\n }\n return { ok: true, doc, migrated: true };\n}\n\nconst LEGACY_BUCKETS = ['workspaces', 'saves', 'layout', 'theme'] as const;\n\n/** The four keys a lab used before it was one document. */\nexport function legacyKeys(storageKey: string): string[] {\n return LEGACY_BUCKETS.map((bucket) => labStorageKey(storageKey, bucket));\n}\n\n/** A value some substrate returned for an old key: already parsed, or a JSON\n * string from a store that does not parse. `undefined` when it is neither. */\nexport function parseStored(value: unknown): unknown {\n if (typeof value !== 'string') return value;\n try {\n return JSON.parse(value);\n } catch {\n return undefined;\n }\n}\n\nfunction bucketOr<T>(value: unknown, fallback: T, bucket: string, shape: 'array' | 'object'): T {\n if (value === undefined) return fallback;\n const parsed = parseStored(value);\n const fits = shape === 'array' ? Array.isArray(parsed) : !!parsed && typeof parsed === 'object';\n if (fits) return parsed as T;\n console.warn(`[labkit] unparseable legacy bucket \"${bucket}\", dropping it`);\n return fallback;\n}\n\n/** Assemble a version-0 document out of the four pre-document keys, or null\n * if none of them is present. `fallbackMode` is used when the theme key is\n * absent or holds something unrecognized; `interstellar` passes through\n * untouched for `migrateV0toV1` to coerce. */\nexport async function readLegacyDocument(\n read: (key: string) => Promise<unknown>,\n storageKey: string,\n fallbackMode: LabMode,\n): Promise<Record<string, unknown> | null> {\n const [workspaces, saves, layout, theme] = await Promise.all(\n LEGACY_BUCKETS.map((bucket) => read(labStorageKey(storageKey, bucket))),\n );\n if ([workspaces, saves, layout, theme].every((v) => v === undefined)) return null;\n\n const mode =\n theme === 'light' || theme === 'dark' || theme === 'auto' || theme === 'interstellar'\n ? theme\n : fallbackMode;\n\n return {\n version: 0,\n workspaces: bucketOr(workspaces, [], 'workspaces', 'array'),\n saves: bucketOr(saves, [], 'saves', 'array'),\n layout: bucketOr(layout, {}, 'layout', 'object'),\n mode,\n };\n}\n\n/** Whether two stored values hold the same data. Stored values are\n * structured-clone copies, so identity says nothing. */\nexport function sameStored(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\n/** Delete `keys` and read each back, so an adapter whose delete silently did\n * nothing is caught. `true` only once all of them are gone. */\nexport async function deleteConfirmed(storage: StorageAdapter, keys: string[]): Promise<boolean> {\n try {\n await Promise.all(keys.map((key) => storage.delete(key)));\n const left = await Promise.all(keys.map((key) => storage.get(key)));\n return left.every((v) => v === undefined);\n } catch {\n return false;\n }\n}\n\n/** Set `value` aside under the quarantine key, reading it back to confirm it\n * landed. Returns `false` when it did not — a full disk is exactly when a\n * document goes unreadable — so the caller can leave the original alone\n * rather than overwrite the only copy of it. */\nexport async function quarantineDocument(\n storage: StorageAdapter,\n storageKey: string,\n value: unknown,\n): Promise<boolean> {\n try {\n await storage.set(quarantineKey(storageKey), value);\n return sameStored(await storage.get(quarantineKey(storageKey)), value);\n } catch {\n return false;\n }\n}\n\n/** Fill in whatever a document is missing or holds the wrong shape of, so a\n * hydrated store never sees `undefined` where a section should be. Applied to\n * every document, migrated or already current. */\nexport function normalizeDocument(\n doc: Record<string, unknown>,\n fallbackMode: LabMode,\n): LabDocument {\n const mode =\n doc.mode === 'light' || doc.mode === 'dark' || doc.mode === 'auto' ? doc.mode : fallbackMode;\n return {\n version: CURRENT_DOCUMENT_VERSION,\n trials: Array.isArray(doc.trials) ? (doc.trials as SerializedTrial[]) : [],\n saves: Array.isArray(doc.saves) ? (doc.saves as SavedSnapshot[]) : [],\n layout:\n doc.layout && typeof doc.layout === 'object' ? (doc.layout as Record<string, unknown>) : {},\n undockedPanels:\n doc.undockedPanels && typeof doc.undockedPanels === 'object'\n ? (doc.undockedPanels as UndockedPanels)\n : {},\n mode,\n };\n}\n\n/** Version 0 (four loose keys) to version 1 (one document). Normalizes the\n * mode, including `interstellar` — the dark mode's name back when it was a\n * theme. Coerces against version 1's own field names rather than reusing\n * `normalizeDocument`, which produces the current shape and would drop\n * `workspaces` from a document it labels version 1. */\nexport function migrateV0toV1(doc: Record<string, unknown>): Record<string, unknown> {\n const raw = doc.mode === 'interstellar' ? 'dark' : doc.mode;\n const mode = raw === 'light' || raw === 'dark' || raw === 'auto' ? raw : 'auto';\n return {\n version: 1,\n workspaces: Array.isArray(doc.workspaces) ? doc.workspaces : [],\n saves: Array.isArray(doc.saves) ? doc.saves : [],\n layout: doc.layout && typeof doc.layout === 'object' ? doc.layout : {},\n mode,\n };\n}\n\n/** Version 1 to version 2: the vocabulary refresh renamed a tile from\n * workspace to trial. Only the records field moves; a record's own fields are\n * unchanged. */\nexport function migrateV1toV2(doc: Record<string, unknown>): Record<string, unknown> {\n const { workspaces, ...rest } = doc;\n return { ...rest, trials: Array.isArray(workspaces) ? workspaces : [], version: 2 };\n}\n\n/** Version 2 to version 3: undocked sidebar panels became persisted state.\n * Nothing existing moves; the field simply starts empty. */\nexport function migrateV2toV3(doc: Record<string, unknown>): Record<string, unknown> {\n return { ...doc, undockedPanels: {}, version: 3 };\n}\n\n/** Version 3 to version 4: a lab is stored as records under one prefix\n * instead of one document. The joined shape does not change. */\nexport function migrateV3toV4(doc: Record<string, unknown>): Record<string, unknown> {\n return { ...doc, version: 4 };\n}\n\n/** Index `i` migrates a version-`i` document to version `i + 1`. */\nexport const MIGRATIONS: Migration[] = [migrateV0toV1, migrateV1toV2, migrateV2toV3, migrateV3toV4];\n","/** A sidebar section torn out of its trial, and where it went. */\nexport interface UndockedPanel {\n trialId: string;\n sectionId: string;\n as: 'tile' | 'floating';\n}\n\n/** Undocked panels, keyed by {@link panelKey}. */\nexport type UndockedPanels = Record<string, UndockedPanel>;\n\nexport function panelKey(trialId: string, sectionId: string): string {\n return `${trialId}::${sectionId}`;\n}\n\nexport function undockPanel(\n panels: UndockedPanels,\n trialId: string,\n sectionId: string,\n as: UndockedPanel['as'] = 'tile',\n): UndockedPanels {\n return { ...panels, [panelKey(trialId, sectionId)]: { trialId, sectionId, as } };\n}\n\n/** Dock one section back, or — with no `sectionId` — every panel the trial\n * owns, which is what closing a trial wants. */\nexport function dockPanel(\n panels: UndockedPanels,\n trialId: string,\n sectionId?: string,\n): UndockedPanels {\n const out: UndockedPanels = {};\n for (const [key, panel] of Object.entries(panels)) {\n if (panel.trialId === trialId && (sectionId === undefined || panel.sectionId === sectionId)) {\n continue;\n }\n out[key] = panel;\n }\n return out;\n}\n","import { resolveConfigSchema } from '../config/resolve';\nimport type { ResolvedConfig } from '../config/types';\nimport type { InstrumentSerializers } from '../state/types';\nimport type { Instrument, InstrumentList } from './types';\n\n/**\n * One instrument's config schema, resolved without the lab's rules — which\n * neither the store nor a trial composed outside a lab has access to. No rule\n * can reach `autoResolve`, `unpinned` or `manual`, so for reading those the\n * two resolutions agree; anything reading the rendered leaves wants\n * `useConfigSchema` instead. `undefined` for a legacy `configSchema()`\n * instrument, which declares no auto annotations at all.\n */\nexport function unruledConfigSchema(\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 | undefined {\n return instrument.config ? resolveConfigSchema(instrument.config, []) : undefined;\n}\n\n/** Each instrument's unruled config schema, keyed by name — what the store\n * reads a leaf's auto annotations off. */\nexport function configSchemasOf(instruments: InstrumentList): Record<string, ResolvedConfig> {\n const out: Record<string, ResolvedConfig> = {};\n for (const instrument of instruments) {\n const schema = unruledConfigSchema(instrument);\n if (schema) out[instrument.name] = schema;\n }\n return out;\n}\n\n/**\n * Each instrument's default config, keyed by name — what `createLabStore`\n * fills a stored config's gaps from, so one saved before its schema grew a\n * branch still loads.\n */\nexport function configDefaultsOf(instruments: InstrumentList): Record<string, () => unknown> {\n const out: Record<string, () => unknown> = {};\n for (const instrument of instruments) out[instrument.name] = () => instrument.defaultConfig();\n return out;\n}\n\n/** Each instrument's `migrateConfig`, keyed by name, for those that declare one. */\nexport function configMigrationsOf(\n instruments: InstrumentList,\n): Record<string, (stored: unknown) => unknown> {\n const out: Record<string, (stored: unknown) => unknown> = {};\n for (const { name, migrateConfig } of instruments) {\n if (migrateConfig) out[name] = (stored) => migrateConfig(stored);\n }\n return out;\n}\n\n/**\n * The `serialize` / `deserialize` an instrument list declares, keyed by\n * instrument name — what `createLabStore` needs to rebuild a trial's state\n * from storage.\n *\n * An instrument declaring neither gets no entry, which is what leaves a\n * JSON-safe state to pass through untouched.\n */\nexport function serializersOf(instruments: InstrumentList): InstrumentSerializers {\n const out: InstrumentSerializers = {};\n for (const instrument of instruments) {\n const { name, serialize, deserialize } = instrument;\n if (!serialize && !deserialize) continue;\n out[name] = {\n ...(serialize ? { serialize: (state: unknown) => serialize(state) } : {}),\n ...(deserialize\n ? { deserialize: (data: unknown, config: unknown) => deserialize(data, config) }\n : {}),\n };\n }\n return out;\n}\n","import { createStore, type StoreApi } from 'zustand/vanilla';\nimport { applyConfigWrite } from '../config/autoConfig';\nimport { fillConfigDefaults } from '../config/path';\nimport {\n configDefaultsOf,\n configMigrationsOf,\n configSchemasOf,\n serializersOf,\n} from '../instrument/serializers';\nimport type { InstrumentList } from '../instrument/types';\nimport { emptyDocument } from './document';\nimport { deserializeTrials, emptyUndoStack, newId } from './helpers';\nimport type {\n CreateLabStoreOptions,\n InstrumentHooks,\n InstrumentSerializers,\n LabMode,\n LabStoreState,\n SavedSnapshot,\n SerializedTrial,\n TrialRecord,\n} from './types';\nimport {\n dockPanel as dockPanelIn,\n type UndockedPanel,\n undockPanel as undockPanelIn,\n} from './undock';\n\n/** Every mutation a lab store supports: managing trials, saving and\n * restoring snapshots, and setting the color mode. */\nexport interface LabStoreActions {\n addTrial: (record: Omit<TrialRecord, 'undoStack'>) => void;\n removeTrial: (id: string) => void;\n updateTrialState: <TS>(id: string, next: TS | ((prev: TS) => TS)) => void;\n /** Write one config value. `path` is dotted for a value nested under an\n * `f.group`, and the bare key for one at the root. */\n updateTrialConfig: (id: string, path: string, value: unknown) => void;\n updateTrialView: (id: string, view: unknown) => void;\n updateTrialSidebarWidth: (id: string, width: number) => void;\n /** Retitle a trial. `null` returns it to its instrument's name. */\n setTrialTitle: (id: string, title: string | null) => void;\n /** Fold or unfold one of a trial's sections. */\n setTrialSectionCollapsed: (id: string, key: string, collapsed: boolean) => void;\n updateTrialAnnotations: (id: string, doc: unknown) => void;\n updateTrialUndoStack: (\n id: string,\n next: TrialRecord['undoStack'] | ((prev: TrialRecord['undoStack']) => TrialRecord['undoStack']),\n ) => void;\n setTrialInstrument: (id: string, instrumentName: string) => void;\n saveSnapshot: (trialId: string, name: string) => void;\n loadSnapshot: (snapshotId: string, trialId: string) => void;\n deleteSnapshot: (snapshotId: string) => void;\n listSnapshots: (trialId?: string) => SavedSnapshot[];\n setMode: (mode: LabMode) => void;\n setLabTool: (id: string | null) => void;\n setTrialTool: (trialId: string, id: string | null) => void;\n setLayout: (layout: Record<string, unknown>) => void;\n /** Tear a sidebar section out of its trial. Default target is a workspace tile. */\n undockPanel: (trialId: string, sectionId: string, as?: UndockedPanel['as']) => void;\n /** Put one section back, or — with no `sectionId` — every panel the trial owns. */\n dockPanel: (trialId: string, sectionId?: string) => void;\n /** Replace the lab's instruments. Trials and saves of an instrument that is\n * new or a different object are brought up to date against it in the same\n * write; every other trial keeps its object. */\n setInstruments: (instruments: InstrumentList) => void;\n /** The per-instrument hooks in force now. Read them at use; never keep them. */\n instrumentHooks: () => InstrumentHooks;\n}\n\n/** A lab's store: its state and its actions. How each instrument's state is\n * serialized comes in through `CreateLabStoreOptions.instruments`. */\nexport type LabStore = StoreApi<LabStoreState & LabStoreActions>;\n\n/** Build a lab store holding `initial`, or an empty lab. It knows nothing\n * about storage; `openLabStore` reads a stored lab and binds one of these to\n * it. */\nexport function createLabStore(options: CreateLabStoreOptions = {}): LabStore {\n let hooks: InstrumentHooks = options.instruments\n ? hooksOf(options.instruments)\n : {\n serializers: options.serializers ?? {},\n configDefaults: options.configDefaults ?? {},\n configMigrations: options.configMigrations ?? {},\n configSchemas: options.configSchemas ?? {},\n };\n const initial = options.initial ?? emptyDocument(options.initialMode ?? 'auto');\n\n const store = createStore<LabStoreState & LabStoreActions>()((set, get) => ({\n trials: hydrateTrials(initial.trials, hooks.serializers, hooks),\n savedSnapshots: hydrateSnapshots(initial.saves, hooks),\n mode: initial.mode,\n layout: initial.layout,\n undockedPanels: initial.undockedPanels,\n activeToolId: null,\n instruments: options.instruments ?? null,\n\n addTrial: (record) => {\n set((s) => ({\n trials: [...s.trials, { ...record, undoStack: emptyUndoStack() }],\n }));\n },\n\n removeTrial: (id) => {\n set((s) => ({\n trials: s.trials.filter((w) => w.id !== id),\n undockedPanels: dockPanelIn(s.undockedPanels, id),\n }));\n },\n\n updateTrialState: (id, next) => {\n set((s) => ({\n trials: s.trials.map((w) => {\n if (w.id !== id) return w;\n const nextState =\n typeof next === 'function' ? (next as (prev: unknown) => unknown)(w.state) : next;\n // An updater that returns its input means \"nothing changed\", and must not\n // cost a new record: the trial re-renders on record identity, so\n // allocating here turns the standard React bail-out into a render loop.\n if (Object.is(nextState, w.state)) return w;\n return { ...w, state: nextState };\n }),\n }));\n },\n\n updateTrialConfig: (id, path, value) => {\n set((s) => ({\n trials: s.trials.map((w) => {\n if (w.id !== id) return w;\n const was = w.auto ?? [];\n // The sentinel is never stored: it becomes membership in `auto`, and\n // the pinned value at the path is left exactly where it is.\n const next = applyConfigWrite(w.config, was, path, value);\n if (next.config === w.config && next.autoPaths === was) return w;\n const { auto: _was, ...kept } = w;\n const record: TrialRecord = { ...kept, config: next.config };\n if (next.autoPaths.length > 0) record.auto = next.autoPaths;\n return record;\n }),\n }));\n },\n\n updateTrialView: (id, view) => {\n set((s) => ({\n trials: s.trials.map((w) => (w.id === id && !Object.is(view, w.view) ? { ...w, view } : w)),\n }));\n },\n\n updateTrialSidebarWidth: (id, width) => {\n set((s) => ({\n trials: s.trials.map((w) =>\n w.id === id && w.sidebarWidth !== width ? { ...w, sidebarWidth: width } : w,\n ),\n }));\n },\n\n setTrialTitle: (id, title) => {\n set((s) => ({\n trials: s.trials.map((w) => {\n if (w.id !== id) return w;\n const next = title === null ? undefined : title;\n if ((w.title ?? undefined) === next) return w;\n return { ...w, title: next };\n }),\n }));\n },\n\n setTrialSectionCollapsed: (id, key, collapsed) => {\n set((s) => ({\n trials: s.trials.map((w) => {\n if (w.id !== id) return w;\n if (w.collapsedSections?.[key] === collapsed) return w;\n return { ...w, collapsedSections: { ...w.collapsedSections, [key]: collapsed } };\n }),\n }));\n },\n\n updateTrialAnnotations: (id, doc) => {\n set((s) => ({\n trials: s.trials.map((w) =>\n w.id === id && !Object.is(doc, w.annotations) ? { ...w, annotations: doc } : w,\n ),\n }));\n },\n\n updateTrialUndoStack: (id, next) => {\n set((s) => ({\n trials: s.trials.map((w) => {\n if (w.id !== id) return w;\n const undoStack =\n typeof next === 'function'\n ? (next as (prev: TrialRecord['undoStack']) => TrialRecord['undoStack'])(w.undoStack)\n : next;\n return { ...w, undoStack };\n }),\n }));\n },\n\n setTrialInstrument: (id, instrumentName) => {\n set((s) => ({\n trials: s.trials.map((w) => (w.id === id ? { ...w, instrumentName } : w)),\n }));\n },\n\n saveSnapshot: (trialId, name) => {\n const trial = get().trials.find((w) => w.id === trialId);\n if (!trial) return;\n const reg = hooks.serializers[trial.instrumentName];\n const serializedState = reg?.serialize\n ? reg.serialize(trial.state)\n : structuredClone(trial.state);\n const clonedConfig = structuredClone(trial.config);\n const lastAt = get().savedSnapshots.reduce((m, sn) => (sn.savedAt > m ? sn.savedAt : m), 0);\n const savedAt = Math.max(Date.now(), lastAt + 1);\n const snapshot: SavedSnapshot = {\n id: newId(),\n name,\n trialId,\n instrumentName: trial.instrumentName,\n config: clonedConfig,\n state: serializedState,\n auto: [...(trial.auto ?? [])],\n savedAt,\n };\n set((s) => ({ savedSnapshots: [...s.savedSnapshots, snapshot] }));\n },\n\n loadSnapshot: (snapshotId, trialId) => {\n const snapshot = get().savedSnapshots.find((sn) => sn.id === snapshotId);\n if (!snapshot) return;\n const trial = get().trials.find((w) => w.id === trialId);\n if (!trial) return;\n if (snapshot.instrumentName !== trial.instrumentName) {\n console.warn(\n `[labkit] loadSnapshot: instrument mismatch (snapshot=${snapshot.instrumentName}, trial=${trial.instrumentName}); refusing to load`,\n );\n return;\n }\n const reg = hooks.serializers[snapshot.instrumentName];\n const restoredState = reg?.deserialize\n ? reg.deserialize(snapshot.state, snapshot.config)\n : snapshot.state;\n set((s) => ({\n trials: s.trials.map((w) => {\n if (w.id !== trialId) return w;\n const loaded: TrialRecord = { ...w, state: restoredState, config: snapshot.config };\n if (snapshot.auto === undefined) return loaded;\n delete loaded.auto;\n if (snapshot.auto.length > 0) loaded.auto = [...snapshot.auto];\n return loaded;\n }),\n }));\n },\n\n deleteSnapshot: (snapshotId) => {\n set((s) => ({\n savedSnapshots: s.savedSnapshots.filter((sn) => sn.id !== snapshotId),\n }));\n },\n\n listSnapshots: (trialId) => {\n const all = get().savedSnapshots;\n const filtered = trialId ? all.filter((sn) => sn.trialId === trialId) : all;\n return [...filtered].sort((a, b) => b.savedAt - a.savedAt);\n },\n\n setMode: (mode) => {\n set({ mode });\n },\n\n setLabTool: (id) => set({ activeToolId: id }),\n\n setTrialTool: (trialId, id) =>\n set((s) => ({\n trials: s.trials.map((t) => (t.id === trialId ? { ...t, activeToolId: id } : t)),\n })),\n\n undockPanel: (trialId, sectionId, as) => {\n set((s) => ({ undockedPanels: undockPanelIn(s.undockedPanels, trialId, sectionId, as) }));\n },\n\n dockPanel: (trialId, sectionId) => {\n set((s) => ({ undockedPanels: dockPanelIn(s.undockedPanels, trialId, sectionId) }));\n },\n\n setLayout: (layout) => {\n set({ layout });\n },\n\n setInstruments: (instruments) => {\n const before = get().instruments;\n if (before === instruments) return;\n const next = mergedHooks(hooks, instruments);\n const previous = new Map((before ?? []).map((i) => [i.name, i]));\n const changed = new Set(\n instruments.filter((i) => previous.get(i.name) !== i).map((i) => i.name),\n );\n if (changed.size === 0) {\n hooks = next;\n set({ instruments });\n return;\n }\n const s = get();\n const trials = s.trials.map((w) =>\n changed.has(w.instrumentName)\n ? { ...w, config: hydratedConfig(next, w.instrumentName, w.config) }\n : w,\n );\n const savedSnapshots = s.savedSnapshots.map((sn) =>\n changed.has(sn.instrumentName)\n ? { ...sn, config: hydratedConfig(next, sn.instrumentName, sn.config) }\n : sn,\n );\n hooks = next;\n set({ instruments, trials, savedSnapshots });\n },\n\n instrumentHooks: () => hooks,\n }));\n\n return store;\n}\n\nfunction hooksOf(instruments: InstrumentList): InstrumentHooks {\n return {\n serializers: serializersOf(instruments),\n configDefaults: configDefaultsOf(instruments),\n configSchemas: configSchemasOf(instruments),\n configMigrations: configMigrationsOf(instruments),\n };\n}\n\n/** Hooks for `instruments`, keeping those of any instrument no longer listed:\n * its trials stay open, and their state still has to round-trip. A listed\n * name takes its hooks wholly from the new list. */\nfunction mergedHooks(old: InstrumentHooks, instruments: InstrumentList): InstrumentHooks {\n const listed = new Set(instruments.map((i) => i.name));\n const fresh = hooksOf(instruments);\n const unlisted = <T>(entries: Record<string, T>): Record<string, T> =>\n Object.fromEntries(Object.entries(entries).filter(([name]) => !listed.has(name)));\n return {\n serializers: { ...unlisted(old.serializers), ...fresh.serializers },\n configDefaults: { ...unlisted(old.configDefaults), ...fresh.configDefaults },\n configSchemas: { ...unlisted(old.configSchemas), ...fresh.configSchemas },\n configMigrations: { ...unlisted(old.configMigrations), ...fresh.configMigrations },\n };\n}\n\n/** How a stored config is brought up to date on the way in. */\nexport type ConfigHydration = Pick<CreateLabStoreOptions, 'configDefaults' | 'configMigrations'>;\n\nfunction hydratedConfig(\n hydration: ConfigHydration,\n instrumentName: string,\n config: unknown,\n): unknown {\n const migrate = hydration.configMigrations?.[instrumentName];\n const moved = migrate ? migrate(config) : config;\n const defaults = hydration.configDefaults?.[instrumentName];\n return defaults ? fillConfigDefaults(moved, defaults()) : moved;\n}\n\n/** Rebuild stored trials: migrate each config, fill its gaps from its\n * instrument's defaults, then run the deserializer against the result. */\nexport function hydrateTrials(\n trials: SerializedTrial[],\n serializers: InstrumentSerializers,\n hydration: ConfigHydration = {},\n): TrialRecord[] {\n return deserializeTrials(\n trials.map((t) => ({ ...t, config: hydratedConfig(hydration, t.instrumentName, t.config) })),\n serializers,\n );\n}\n\n/** Bring each stored snapshot's config up to date the way `hydrateTrials` does a trial's. */\nexport function hydrateSnapshots(\n saves: SavedSnapshot[],\n hydration: ConfigHydration = {},\n): SavedSnapshot[] {\n return saves.map((sn) => ({\n ...sn,\n config: hydratedConfig(hydration, sn.instrumentName, sn.config),\n }));\n}\n","import {\n CURRENT_DOCUMENT_VERSION,\n deleteConfirmed,\n emptyDocument,\n labDocumentKey,\n legacyKeys,\n MIGRATIONS,\n normalizeDocument,\n parseStored,\n quarantineDocument,\n readLegacyDocument,\n runMigrations,\n sameStored,\n} from './document';\nimport { serializeTrials } from './helpers';\nimport {\n compareTrialOrder,\n documentOfRecords,\n LAYOUT_RECORD,\n type LabMeta,\n labPrefix,\n META_RECORD,\n parseRecordName,\n recordsOfDocument,\n saveRecord,\n trialRecord,\n trialValuesPrefix,\n UNDOCK_RECORD,\n} from './labRecords';\nimport { type OwnedRecordCache, openRecords, type RecordCache } from './records';\nimport { createLabStore, hydrateSnapshots, hydrateTrials, type LabStore } from './store';\nimport type {\n CreateLabStoreOptions,\n LabDocument,\n LabMode,\n SavedSnapshot,\n SerializedTrial,\n StorageAdapter,\n TrialRecord,\n} from './types';\n\n/** Options for `openLabStore`. `storageKey` names the lab, so two labs on one\n * origin keep separate records. */\nexport interface OpenLabStoreOptions extends Omit<CreateLabStoreOptions, 'initial'> {\n storageKey: string;\n storage: StorageAdapter;\n}\n\n/** A lab store bound to its records. */\nexport interface OpenedLabStore {\n store: LabStore;\n /** Every record of the lab, `usePersistedState` values included. */\n records: RecordCache;\n /** Send queued writes and stop hearing other writers. */\n close(): Promise<void>;\n}\n\n/**\n * Read a stored lab and return a store bound to it: every change to the store\n * is written as the records it touched, and another writer's records are\n * applied back into the store. A lab stored before records existed is folded\n * forward on the way in.\n */\nexport async function openLabStore(options: OpenLabStoreOptions): Promise<OpenedLabStore> {\n const records = await openRecords({\n storage: options.storage,\n prefix: labPrefix(options.storageKey),\n });\n const { doc, orders } = await readLab(options, records);\n const store = createLabStore({ ...options, initial: doc });\n const unbind = bindLabStore(store, records, { orders });\n return {\n store,\n records,\n close: async () => {\n unbind();\n await records.close();\n },\n };\n}\n\ninterface ReadLab {\n doc: LabDocument;\n orders: Map<string, number>;\n}\n\nfunction emptyLab(mode: LabMode): ReadLab {\n return { doc: emptyDocument(mode), orders: new Map() };\n}\n\nfunction ordersOf(doc: LabDocument): Map<string, number> {\n return new Map(doc.trials.map((t, i) => [t.id, i]));\n}\n\nasync function readLab(options: OpenLabStoreOptions, records: OwnedRecordCache): Promise<ReadLab> {\n const mode = options.initialMode ?? 'auto';\n if (!records.writable) return emptyLab(mode);\n\n const joined = documentOfRecords(records.entries());\n if (!joined) return foldOldStorage(options, records);\n\n const outcome = runMigrations(joined.doc, MIGRATIONS, CURRENT_DOCUMENT_VERSION);\n if (outcome.ok) {\n return { doc: normalizeDocument(outcome.doc, mode), orders: joined.orders };\n }\n const why =\n outcome.reason === 'future' ? 'are from a newer version of labkit' : 'failed to migrate';\n console.warn(`[labkit] lab records ${why}; starting empty and leaving them alone`, outcome.error);\n records.stopWriting();\n return emptyLab(mode);\n}\n\n/** Fold a version-3 document, or the four keys before it, into records. The\n * old keys are deleted only once every record has been read back. */\nasync function foldOldStorage(\n options: OpenLabStoreOptions,\n records: OwnedRecordCache,\n): Promise<ReadLab> {\n const { storage, storageKey } = options;\n const mode = options.initialMode ?? 'auto';\n\n let raw: unknown;\n let oldKeys: string[];\n try {\n const stored = await storage.get(labDocumentKey(storageKey));\n if (stored !== undefined) {\n raw = stored;\n oldKeys = [labDocumentKey(storageKey)];\n } else {\n raw = await readLegacyDocument((key) => storage.get(key), storageKey, mode);\n oldKeys = legacyKeys(storageKey);\n if (raw === null) return emptyLab(mode);\n }\n } catch (error) {\n console.warn(\n `[labkit] could not read the old storage for \"${storageKey}\"; not persisting`,\n error,\n );\n records.stopWriting();\n return emptyLab(mode);\n }\n\n const setAside = async (value: unknown, why: string, error?: unknown): Promise<ReadLab> => {\n if (await quarantineDocument(storage, storageKey, value)) {\n console.warn(`[labkit] ${why}; quarantined it and starting empty`, error);\n await deleteConfirmed(storage, oldKeys);\n records.set(META_RECORD, { version: CURRENT_DOCUMENT_VERSION, mode } satisfies LabMeta);\n } else {\n console.warn(\n `[labkit] ${why} and could not be quarantined; leaving it in place and not persisting`,\n error,\n );\n records.stopWriting();\n }\n return emptyLab(mode);\n };\n\n const parsed = parseStored(raw);\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return setAside(raw, 'lab document is unparseable');\n }\n const outcome = runMigrations(\n parsed as Record<string, unknown>,\n MIGRATIONS,\n CURRENT_DOCUMENT_VERSION,\n );\n if (!outcome.ok) {\n if (outcome.reason === 'future') {\n console.warn(\n '[labkit] lab document is from a newer version of labkit; starting empty and leaving it alone',\n );\n records.stopWriting();\n return emptyLab(mode);\n }\n return setAside(parsed, 'lab document failed to migrate', outcome.error);\n }\n\n const doc = normalizeDocument(outcome.doc, mode);\n const entries = recordsOfDocument(doc);\n records.seed(entries);\n if (await writeConfirmed(storage, records.prefix, entries)) {\n await deleteConfirmed(storage, oldKeys);\n } else {\n console.warn(\n `[labkit] keeping the old storage for \"${storageKey}\": could not confirm its records were written`,\n );\n }\n return { doc, orders: ordersOf(doc) };\n}\n\n/** Write `entries` in order and read every one back. */\nasync function writeConfirmed(\n storage: StorageAdapter,\n prefix: string,\n entries: [string, unknown][],\n): Promise<boolean> {\n try {\n for (const [name, value] of entries) await storage.set(prefix + name, value);\n const back = new Map(await storage.list(prefix));\n return entries.every(([name, value]) => sameStored(back.get(prefix + name), value));\n } catch {\n return false;\n }\n}\n\ninterface BindOptions {\n orders: Map<string, number>;\n}\n\nfunction persistedFieldsDiffer(a: TrialRecord, b: TrialRecord): boolean {\n if (a === b) return false;\n const left = a as unknown as Record<string, unknown>;\n const right = b as unknown as Record<string, unknown>;\n for (const key of new Set([...Object.keys(left), ...Object.keys(right)])) {\n if (key !== 'undoStack' && !Object.is(left[key], right[key])) return true;\n }\n return false;\n}\n\n/** Keep `store` and `records` in step, both ways. Returns the unbinding. */\nfunction bindLabStore(store: LabStore, records: RecordCache, options: BindOptions): () => void {\n const orderOf = new Map(options.orders);\n let applyingRemote = false;\n\n const nextOrder = (): number => {\n let max = -1;\n for (const order of orderOf.values()) max = Math.max(max, order);\n return max + 1;\n };\n\n const writeTrial = (trial: TrialRecord): void => {\n const [serialized] = serializeTrials([trial], store.getState().instrumentHooks().serializers);\n records.set(trialRecord(trial.id), { ...serialized, order: orderOf.get(trial.id) });\n };\n\n const inStoredOrder = (trials: TrialRecord[]): boolean => {\n for (let i = 1; i < trials.length; i++) {\n const a = trials[i - 1] as TrialRecord;\n const b = trials[i] as TrialRecord;\n const at = { trial: a, order: orderOf.get(a.id) ?? 0 };\n const bt = { trial: b, order: orderOf.get(b.id) ?? 0 };\n if (compareTrialOrder(at, bt) >= 0) return false;\n }\n return true;\n };\n\n const offStore = store.subscribe((state, prev) => {\n if (applyingRemote) return;\n let wrote = false;\n\n if (state.trials !== prev.trials) {\n const before = new Map(prev.trials.map((t) => [t.id, t]));\n const now = new Set(state.trials.map((t) => t.id));\n for (const t of prev.trials) {\n if (now.has(t.id)) continue;\n records.delete(trialRecord(t.id));\n for (const [name] of records.entries(trialValuesPrefix(t.id))) records.delete(name);\n orderOf.delete(t.id);\n wrote = true;\n }\n const added = state.trials.filter((t) => !before.has(t.id));\n for (const t of added) orderOf.set(t.id, nextOrder());\n if (inStoredOrder(state.trials)) {\n for (const t of state.trials) {\n const old = before.get(t.id);\n if (old && !persistedFieldsDiffer(old, t)) continue;\n writeTrial(t);\n wrote = true;\n }\n } else {\n // A reorder, or a trial inserted mid-list: renumber them all.\n for (const [i, t] of state.trials.entries()) orderOf.set(t.id, i);\n for (const t of state.trials) writeTrial(t);\n wrote = true;\n }\n }\n\n if (state.savedSnapshots !== prev.savedSnapshots) {\n const before = new Map(prev.savedSnapshots.map((s) => [s.id, s]));\n const now = new Set(state.savedSnapshots.map((s) => s.id));\n for (const s of state.savedSnapshots) {\n if (before.get(s.id) === s) continue;\n records.set(saveRecord(s.id), s);\n wrote = true;\n }\n for (const s of prev.savedSnapshots) {\n if (now.has(s.id)) continue;\n records.delete(saveRecord(s.id));\n wrote = true;\n }\n }\n\n if (state.layout !== prev.layout) {\n records.set(LAYOUT_RECORD, state.layout);\n wrote = true;\n }\n if (state.undockedPanels !== prev.undockedPanels) {\n records.set(UNDOCK_RECORD, state.undockedPanels);\n wrote = true;\n }\n if (state.mode !== prev.mode || (wrote && !records.has(META_RECORD))) {\n records.set(META_RECORD, {\n version: CURRENT_DOCUMENT_VERSION,\n mode: state.mode,\n } satisfies LabMeta);\n }\n });\n\n const offRecords = records.subscribe((changes) => {\n const remote = changes.filter((c) => c.origin === 'remote');\n if (remote.length === 0) return;\n\n const current = store.getState();\n let trials = current.trials;\n let saves = current.savedSnapshots;\n const patch: Partial<Pick<typeof current, 'layout' | 'undockedPanels' | 'mode'>> = {};\n\n for (const { name, value } of remote) {\n const parsed = parseRecordName(name);\n if (!parsed) continue;\n switch (parsed.kind) {\n case 'trial': {\n const id = parsed.id;\n if (value === undefined || !value || typeof value !== 'object') {\n trials = trials.filter((t) => t.id !== id);\n orderOf.delete(id);\n break;\n }\n const { order, ...rest } = value as SerializedTrial & { order?: unknown };\n orderOf.set(\n id,\n typeof order === 'number' && Number.isFinite(order) ? order : nextOrder(),\n );\n // Hydrating starts an empty undo history: the old one describes a\n // state that no longer exists.\n const hooks = store.getState().instrumentHooks();\n const [replacement] = hydrateTrials([{ ...rest, id }], hooks.serializers, hooks);\n if (!replacement) break;\n trials = trials.some((t) => t.id === id)\n ? trials.map((t) => (t.id === id ? replacement : t))\n : [...trials, replacement];\n break;\n }\n case 'save': {\n const id = parsed.id;\n if (value === undefined || !value || typeof value !== 'object') {\n saves = saves.filter((s) => s.id !== id);\n break;\n }\n const [snapshot] = hydrateSnapshots(\n [{ ...(value as SavedSnapshot), id }],\n store.getState().instrumentHooks(),\n );\n if (!snapshot) break;\n saves = saves.some((s) => s.id === id)\n ? saves.map((s) => (s.id === id ? snapshot : s))\n : [...saves, snapshot];\n break;\n }\n case 'layout':\n patch.layout = (value as Record<string, unknown> | undefined) ?? {};\n break;\n case 'undock':\n patch.undockedPanels = (value as typeof current.undockedPanels | undefined) ?? {};\n break;\n case 'meta': {\n const meta = value as Partial<LabMeta> | undefined;\n if (typeof meta?.version === 'number' && meta.version > CURRENT_DOCUMENT_VERSION) {\n console.warn(\n '[labkit] another tab wrote this lab with a newer labkit; no longer persisting',\n );\n if ('stopWriting' in records) (records as OwnedRecordCache).stopWriting();\n break;\n }\n if (meta?.mode === 'light' || meta?.mode === 'dark' || meta?.mode === 'auto') {\n patch.mode = meta.mode;\n }\n break;\n }\n }\n }\n\n if (trials !== current.trials) {\n trials = [...trials].sort((a, b) =>\n compareTrialOrder(\n { trial: a, order: orderOf.get(a.id) ?? 0 },\n { trial: b, order: orderOf.get(b.id) ?? 0 },\n ),\n );\n }\n applyingRemote = true;\n try {\n store.setState({ ...patch, trials, savedSnapshots: saves });\n } finally {\n applyingRemote = false;\n }\n });\n\n return () => {\n offStore();\n offRecords();\n };\n}\n","import { useContext } from 'react';\nimport { useStore } from 'zustand/react';\nimport { useResolvedConfig } from '../config/useResolvedConfig';\nimport { LabStoreContext, TrialIdContext } from './context';\nimport type { TrialStateHandle } from './types';\n\n/** An instrument's own state and config, plus setters. Reads the surrounding\n * trial id, so an instrument never has to know which trial it is\n * running in. Throws outside a lab store and trial. */\nexport function useTrialState<TS = unknown, TC = unknown>(): TrialStateHandle<TS, TC> {\n const ctx = useContext(LabStoreContext);\n if (!ctx) throw new Error('[labkit] useTrialState must be used inside <LabStoreProvider>');\n\n const trialId = useContext(TrialIdContext);\n if (!trialId) throw new Error('[labkit] useTrialState must be used inside <TrialIdProvider>');\n\n const record = useStore(ctx.store, (s) => s.trials.find((w) => w.id === trialId));\n\n if (!record) throw new Error(`[labkit] No trial found with id \"${trialId}\"`);\n\n const updateTrialState = useStore(ctx.store, (s) => s.updateTrialState);\n const updateTrialConfig = useStore(ctx.store, (s) => s.updateTrialConfig);\n // The store's own copy, not `useConfigSchema`: that reads `LabContext`, and\n // this hook only has the store's.\n const instrumentHooks = useStore(ctx.store, (s) => s.instrumentHooks);\n const schema = instrumentHooks().configSchemas[record.instrumentName];\n const { config, auto } = useResolvedConfig<TC>(schema, record.config as TC, record.auto);\n\n return {\n state: record.state as TS,\n config,\n raw: record.config as TC,\n auto,\n setState: (next) => updateTrialState(trialId, next as Parameters<typeof updateTrialState>[1]),\n setConfig: (path, value) => updateTrialConfig(trialId, path, value),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/state/document.ts","../src/state/undock.ts","../src/instrument/serializers.ts","../src/state/store.ts","../src/state/openLabStore.ts","../src/state/useTrialState.ts"],"names":[],"mappings":"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","file":"chunk-HKV7LRHY.js","sourcesContent":["import { labStorageKey } from './helpers';\nimport type {\n LabDocument,\n LabMode,\n Migration,\n SavedSnapshot,\n SerializedTrial,\n StorageAdapter,\n} from './types';\nimport type { UndockedPanels } from './undock';\n\n/** Bumped whenever the persisted shape changes; every bump needs a migration. */\nexport const CURRENT_DOCUMENT_VERSION = 4;\n\n/** Where a version-3 lab kept its one document. Read once, to fold it into\n * records, then deleted. */\nexport function labDocumentKey(storageKey: string): string {\n return `lk:${storageKey}:doc`;\n}\n\n/** Where a document that failed to migrate is set aside, so a bad migration\n * loses state loudly rather than silently. */\nexport function quarantineKey(storageKey: string): string {\n return `lk:${storageKey}:quarantine`;\n}\n\n/** A fresh document at the current version. */\nexport function emptyDocument(mode: LabMode): LabDocument {\n return {\n version: CURRENT_DOCUMENT_VERSION,\n undockedPanels: {},\n trials: [],\n saves: [],\n layout: {},\n mode,\n };\n}\n\n/** What a migration run produced: the migrated document, or why it refused. */\nexport type MigrationOutcome =\n | { ok: true; doc: Record<string, unknown>; migrated: boolean }\n | { ok: false; reason: 'future' | 'failed'; error?: unknown };\n\n/** Walk a document forward to `target`, one migration at a time. A version\n * above `target` is refused rather than parsed under a shape it may not\n * have. */\nexport function runMigrations(\n raw: Record<string, unknown>,\n migrations: Migration[],\n target: number,\n): MigrationOutcome {\n const from = typeof raw.version === 'number' ? raw.version : 0;\n if (from > target) return { ok: false, reason: 'future' };\n if (from === target) return { ok: true, doc: raw, migrated: false };\n\n let doc = raw;\n try {\n for (let v = from; v < target; v++) {\n const migration = migrations[v];\n if (!migration) throw new Error(`[labkit] no migration from version ${v}`);\n doc = migration(doc);\n }\n } catch (error) {\n return { ok: false, reason: 'failed', error };\n }\n return { ok: true, doc, migrated: true };\n}\n\nconst LEGACY_BUCKETS = ['workspaces', 'saves', 'layout', 'theme'] as const;\n\n/** The four keys a lab used before it was one document. */\nexport function legacyKeys(storageKey: string): string[] {\n return LEGACY_BUCKETS.map((bucket) => labStorageKey(storageKey, bucket));\n}\n\n/** A value some substrate returned for an old key: already parsed, or a JSON\n * string from a store that does not parse. `undefined` when it is neither. */\nexport function parseStored(value: unknown): unknown {\n if (typeof value !== 'string') return value;\n try {\n return JSON.parse(value);\n } catch {\n return undefined;\n }\n}\n\nfunction bucketOr<T>(value: unknown, fallback: T, bucket: string, shape: 'array' | 'object'): T {\n if (value === undefined) return fallback;\n const parsed = parseStored(value);\n const fits = shape === 'array' ? Array.isArray(parsed) : !!parsed && typeof parsed === 'object';\n if (fits) return parsed as T;\n console.warn(`[labkit] unparseable legacy bucket \"${bucket}\", dropping it`);\n return fallback;\n}\n\n/** Assemble a version-0 document out of the four pre-document keys, or null\n * if none of them is present. `fallbackMode` is used when the theme key is\n * absent or holds something unrecognized; `interstellar` passes through\n * untouched for `migrateV0toV1` to coerce. */\nexport async function readLegacyDocument(\n read: (key: string) => Promise<unknown>,\n storageKey: string,\n fallbackMode: LabMode,\n): Promise<Record<string, unknown> | null> {\n const [workspaces, saves, layout, theme] = await Promise.all(\n LEGACY_BUCKETS.map((bucket) => read(labStorageKey(storageKey, bucket))),\n );\n if ([workspaces, saves, layout, theme].every((v) => v === undefined)) return null;\n\n const mode =\n theme === 'light' || theme === 'dark' || theme === 'auto' || theme === 'interstellar'\n ? theme\n : fallbackMode;\n\n return {\n version: 0,\n workspaces: bucketOr(workspaces, [], 'workspaces', 'array'),\n saves: bucketOr(saves, [], 'saves', 'array'),\n layout: bucketOr(layout, {}, 'layout', 'object'),\n mode,\n };\n}\n\n/** Whether two stored values hold the same data. Stored values are\n * structured-clone copies, so identity says nothing. */\nexport function sameStored(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\n/** Delete `keys` and read each back, so an adapter whose delete silently did\n * nothing is caught. `true` only once all of them are gone. */\nexport async function deleteConfirmed(storage: StorageAdapter, keys: string[]): Promise<boolean> {\n try {\n await Promise.all(keys.map((key) => storage.delete(key)));\n const left = await Promise.all(keys.map((key) => storage.get(key)));\n return left.every((v) => v === undefined);\n } catch {\n return false;\n }\n}\n\n/** Set `value` aside under the quarantine key, reading it back to confirm it\n * landed. Returns `false` when it did not — a full disk is exactly when a\n * document goes unreadable — so the caller can leave the original alone\n * rather than overwrite the only copy of it. */\nexport async function quarantineDocument(\n storage: StorageAdapter,\n storageKey: string,\n value: unknown,\n): Promise<boolean> {\n try {\n await storage.set(quarantineKey(storageKey), value);\n return sameStored(await storage.get(quarantineKey(storageKey)), value);\n } catch {\n return false;\n }\n}\n\n/** Fill in whatever a document is missing or holds the wrong shape of, so a\n * hydrated store never sees `undefined` where a section should be. Applied to\n * every document, migrated or already current. */\nexport function normalizeDocument(\n doc: Record<string, unknown>,\n fallbackMode: LabMode,\n): LabDocument {\n const mode =\n doc.mode === 'light' || doc.mode === 'dark' || doc.mode === 'auto' ? doc.mode : fallbackMode;\n return {\n version: CURRENT_DOCUMENT_VERSION,\n trials: Array.isArray(doc.trials) ? (doc.trials as SerializedTrial[]) : [],\n saves: Array.isArray(doc.saves) ? (doc.saves as SavedSnapshot[]) : [],\n layout:\n doc.layout && typeof doc.layout === 'object' ? (doc.layout as Record<string, unknown>) : {},\n undockedPanels:\n doc.undockedPanels && typeof doc.undockedPanels === 'object'\n ? (doc.undockedPanels as UndockedPanels)\n : {},\n mode,\n };\n}\n\n/** Version 0 (four loose keys) to version 1 (one document). Normalizes the\n * mode, including `interstellar` — the dark mode's name back when it was a\n * theme. Coerces against version 1's own field names rather than reusing\n * `normalizeDocument`, which produces the current shape and would drop\n * `workspaces` from a document it labels version 1. */\nexport function migrateV0toV1(doc: Record<string, unknown>): Record<string, unknown> {\n const raw = doc.mode === 'interstellar' ? 'dark' : doc.mode;\n const mode = raw === 'light' || raw === 'dark' || raw === 'auto' ? raw : 'auto';\n return {\n version: 1,\n workspaces: Array.isArray(doc.workspaces) ? doc.workspaces : [],\n saves: Array.isArray(doc.saves) ? doc.saves : [],\n layout: doc.layout && typeof doc.layout === 'object' ? doc.layout : {},\n mode,\n };\n}\n\n/** Version 1 to version 2: the vocabulary refresh renamed a tile from\n * workspace to trial. Only the records field moves; a record's own fields are\n * unchanged. */\nexport function migrateV1toV2(doc: Record<string, unknown>): Record<string, unknown> {\n const { workspaces, ...rest } = doc;\n return { ...rest, trials: Array.isArray(workspaces) ? workspaces : [], version: 2 };\n}\n\n/** Version 2 to version 3: undocked sidebar panels became persisted state.\n * Nothing existing moves; the field simply starts empty. */\nexport function migrateV2toV3(doc: Record<string, unknown>): Record<string, unknown> {\n return { ...doc, undockedPanels: {}, version: 3 };\n}\n\n/** Version 3 to version 4: a lab is stored as records under one prefix\n * instead of one document. The joined shape does not change. */\nexport function migrateV3toV4(doc: Record<string, unknown>): Record<string, unknown> {\n return { ...doc, version: 4 };\n}\n\n/** Index `i` migrates a version-`i` document to version `i + 1`. */\nexport const MIGRATIONS: Migration[] = [migrateV0toV1, migrateV1toV2, migrateV2toV3, migrateV3toV4];\n","/** A sidebar section torn out of its trial, and where it went. */\nexport interface UndockedPanel {\n trialId: string;\n sectionId: string;\n as: 'tile' | 'floating';\n}\n\n/** Undocked panels, keyed by {@link panelKey}. */\nexport type UndockedPanels = Record<string, UndockedPanel>;\n\nexport function panelKey(trialId: string, sectionId: string): string {\n return `${trialId}::${sectionId}`;\n}\n\nexport function undockPanel(\n panels: UndockedPanels,\n trialId: string,\n sectionId: string,\n as: UndockedPanel['as'] = 'tile',\n): UndockedPanels {\n return { ...panels, [panelKey(trialId, sectionId)]: { trialId, sectionId, as } };\n}\n\n/** Dock one section back, or — with no `sectionId` — every panel the trial\n * owns, which is what closing a trial wants. */\nexport function dockPanel(\n panels: UndockedPanels,\n trialId: string,\n sectionId?: string,\n): UndockedPanels {\n const out: UndockedPanels = {};\n for (const [key, panel] of Object.entries(panels)) {\n if (panel.trialId === trialId && (sectionId === undefined || panel.sectionId === sectionId)) {\n continue;\n }\n out[key] = panel;\n }\n return out;\n}\n","import { resolveConfigSchema } from '../config/resolve';\nimport type { ResolvedConfig } from '../config/types';\nimport type { InstrumentSerializers } from '../state/types';\nimport type { Instrument, InstrumentList } from './types';\n\n/**\n * One instrument's config schema, resolved without the lab's rules — which\n * neither the store nor a trial composed outside a lab has access to. No rule\n * can reach `autoResolve`, `unpinned` or `manual`, so for reading those the\n * two resolutions agree; anything reading the rendered leaves wants\n * `useConfigSchema` instead. `undefined` for a legacy `configSchema()`\n * instrument, which declares no auto annotations at all.\n */\nexport function unruledConfigSchema(\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 | undefined {\n return instrument.config ? resolveConfigSchema(instrument.config, []) : undefined;\n}\n\n/** Each instrument's unruled config schema, keyed by name — what the store\n * reads a leaf's auto annotations off. */\nexport function configSchemasOf(instruments: InstrumentList): Record<string, ResolvedConfig> {\n const out: Record<string, ResolvedConfig> = {};\n for (const instrument of instruments) {\n const schema = unruledConfigSchema(instrument);\n if (schema) out[instrument.name] = schema;\n }\n return out;\n}\n\n/**\n * Each instrument's default config, keyed by name — what `createLabStore`\n * fills a stored config's gaps from, so one saved before its schema grew a\n * branch still loads.\n */\nexport function configDefaultsOf(instruments: InstrumentList): Record<string, () => unknown> {\n const out: Record<string, () => unknown> = {};\n for (const instrument of instruments) out[instrument.name] = () => instrument.defaultConfig();\n return out;\n}\n\n/** Each instrument's `migrateConfig`, keyed by name, for those that declare one. */\nexport function configMigrationsOf(\n instruments: InstrumentList,\n): Record<string, (stored: unknown) => unknown> {\n const out: Record<string, (stored: unknown) => unknown> = {};\n for (const { name, migrateConfig } of instruments) {\n if (migrateConfig) out[name] = (stored) => migrateConfig(stored);\n }\n return out;\n}\n\n/**\n * The `serialize` / `deserialize` an instrument list declares, keyed by\n * instrument name — what `createLabStore` needs to rebuild a trial's state\n * from storage.\n *\n * An instrument declaring neither gets no entry, which is what leaves a\n * JSON-safe state to pass through untouched.\n */\nexport function serializersOf(instruments: InstrumentList): InstrumentSerializers {\n const out: InstrumentSerializers = {};\n for (const instrument of instruments) {\n const { name, serialize, deserialize } = instrument;\n if (!serialize && !deserialize) continue;\n out[name] = {\n ...(serialize ? { serialize: (state: unknown) => serialize(state) } : {}),\n ...(deserialize\n ? { deserialize: (data: unknown, config: unknown) => deserialize(data, config) }\n : {}),\n };\n }\n return out;\n}\n","import { createStore, type StoreApi } from 'zustand/vanilla';\nimport { applyConfigWrite } from '../config/autoConfig';\nimport { fillConfigDefaults } from '../config/path';\nimport {\n configDefaultsOf,\n configMigrationsOf,\n configSchemasOf,\n serializersOf,\n} from '../instrument/serializers';\nimport type { InstrumentList } from '../instrument/types';\nimport { emptyDocument } from './document';\nimport { deserializeTrials, emptyUndoStack, newId } from './helpers';\nimport type {\n CreateLabStoreOptions,\n InstrumentHooks,\n InstrumentSerializers,\n LabMode,\n LabStoreState,\n SavedSnapshot,\n SerializedTrial,\n TrialRecord,\n} from './types';\nimport {\n dockPanel as dockPanelIn,\n type UndockedPanel,\n undockPanel as undockPanelIn,\n} from './undock';\n\n/** Every mutation a lab store supports: managing trials, saving and\n * restoring snapshots, and setting the color mode. */\nexport interface LabStoreActions {\n addTrial: (record: Omit<TrialRecord, 'undoStack'>) => void;\n removeTrial: (id: string) => void;\n updateTrialState: <TS>(id: string, next: TS | ((prev: TS) => TS)) => void;\n /** Write one config value. `path` is dotted for a value nested under an\n * `f.group`, and the bare key for one at the root. */\n updateTrialConfig: (id: string, path: string, value: unknown) => void;\n updateTrialView: (id: string, view: unknown) => void;\n updateTrialSidebarWidth: (id: string, width: number) => void;\n /** Retitle a trial. `null` returns it to its instrument's name. */\n setTrialTitle: (id: string, title: string | null) => void;\n /** Fold or unfold one of a trial's sections. */\n setTrialSectionCollapsed: (id: string, key: string, collapsed: boolean) => void;\n updateTrialAnnotations: (id: string, doc: unknown) => void;\n updateTrialUndoStack: (\n id: string,\n next: TrialRecord['undoStack'] | ((prev: TrialRecord['undoStack']) => TrialRecord['undoStack']),\n ) => void;\n setTrialInstrument: (id: string, instrumentName: string) => void;\n saveSnapshot: (trialId: string, name: string) => void;\n loadSnapshot: (snapshotId: string, trialId: string) => void;\n deleteSnapshot: (snapshotId: string) => void;\n listSnapshots: (trialId?: string) => SavedSnapshot[];\n setMode: (mode: LabMode) => void;\n setLabTool: (id: string | null) => void;\n setTrialTool: (trialId: string, id: string | null) => void;\n setLayout: (layout: Record<string, unknown>) => void;\n /** Tear a sidebar section out of its trial. Default target is a workspace tile. */\n undockPanel: (trialId: string, sectionId: string, as?: UndockedPanel['as']) => void;\n /** Put one section back, or — with no `sectionId` — every panel the trial owns. */\n dockPanel: (trialId: string, sectionId?: string) => void;\n /** Replace the lab's instruments. Trials and saves of an instrument that is\n * new or a different object are brought up to date against it in the same\n * write; every other trial keeps its object. */\n setInstruments: (instruments: InstrumentList) => void;\n /** The per-instrument hooks in force now. Read them at use; never keep them. */\n instrumentHooks: () => InstrumentHooks;\n}\n\n/** A lab's store: its state and its actions. How each instrument's state is\n * serialized comes in through `CreateLabStoreOptions.instruments`. */\nexport type LabStore = StoreApi<LabStoreState & LabStoreActions>;\n\n/** Build a lab store holding `initial`, or an empty lab. It knows nothing\n * about storage; `openLabStore` reads a stored lab and binds one of these to\n * it. */\nexport function createLabStore(options: CreateLabStoreOptions = {}): LabStore {\n let hooks: InstrumentHooks = options.instruments\n ? hooksOf(options.instruments)\n : {\n serializers: options.serializers ?? {},\n configDefaults: options.configDefaults ?? {},\n configMigrations: options.configMigrations ?? {},\n configSchemas: options.configSchemas ?? {},\n };\n const initial = options.initial ?? emptyDocument(options.initialMode ?? 'auto');\n\n const store = createStore<LabStoreState & LabStoreActions>()((set, get) => ({\n trials: hydrateTrials(initial.trials, hooks.serializers, hooks),\n savedSnapshots: hydrateSnapshots(initial.saves, hooks),\n mode: initial.mode,\n layout: initial.layout,\n undockedPanels: initial.undockedPanels,\n activeToolId: null,\n instruments: options.instruments ?? null,\n\n addTrial: (record) => {\n set((s) => ({\n trials: [...s.trials, { ...record, undoStack: emptyUndoStack() }],\n }));\n },\n\n removeTrial: (id) => {\n set((s) => ({\n trials: s.trials.filter((w) => w.id !== id),\n undockedPanels: dockPanelIn(s.undockedPanels, id),\n }));\n },\n\n updateTrialState: (id, next) => {\n set((s) => ({\n trials: s.trials.map((w) => {\n if (w.id !== id) return w;\n const nextState =\n typeof next === 'function' ? (next as (prev: unknown) => unknown)(w.state) : next;\n // An updater that returns its input means \"nothing changed\", and must not\n // cost a new record: the trial re-renders on record identity, so\n // allocating here turns the standard React bail-out into a render loop.\n if (Object.is(nextState, w.state)) return w;\n return { ...w, state: nextState };\n }),\n }));\n },\n\n updateTrialConfig: (id, path, value) => {\n set((s) => ({\n trials: s.trials.map((w) => {\n if (w.id !== id) return w;\n const was = w.auto ?? [];\n // The sentinel is never stored: it becomes membership in `auto`, and\n // the pinned value at the path is left exactly where it is.\n const next = applyConfigWrite(w.config, was, path, value);\n if (next.config === w.config && next.autoPaths === was) return w;\n const { auto: _was, ...kept } = w;\n const record: TrialRecord = { ...kept, config: next.config };\n if (next.autoPaths.length > 0) record.auto = next.autoPaths;\n return record;\n }),\n }));\n },\n\n updateTrialView: (id, view) => {\n set((s) => ({\n trials: s.trials.map((w) => (w.id === id && !Object.is(view, w.view) ? { ...w, view } : w)),\n }));\n },\n\n updateTrialSidebarWidth: (id, width) => {\n set((s) => ({\n trials: s.trials.map((w) =>\n w.id === id && w.sidebarWidth !== width ? { ...w, sidebarWidth: width } : w,\n ),\n }));\n },\n\n setTrialTitle: (id, title) => {\n set((s) => ({\n trials: s.trials.map((w) => {\n if (w.id !== id) return w;\n const next = title === null ? undefined : title;\n if ((w.title ?? undefined) === next) return w;\n return { ...w, title: next };\n }),\n }));\n },\n\n setTrialSectionCollapsed: (id, key, collapsed) => {\n set((s) => ({\n trials: s.trials.map((w) => {\n if (w.id !== id) return w;\n if (w.collapsedSections?.[key] === collapsed) return w;\n return { ...w, collapsedSections: { ...w.collapsedSections, [key]: collapsed } };\n }),\n }));\n },\n\n updateTrialAnnotations: (id, doc) => {\n set((s) => ({\n trials: s.trials.map((w) =>\n w.id === id && !Object.is(doc, w.annotations) ? { ...w, annotations: doc } : w,\n ),\n }));\n },\n\n updateTrialUndoStack: (id, next) => {\n set((s) => ({\n trials: s.trials.map((w) => {\n if (w.id !== id) return w;\n const undoStack =\n typeof next === 'function'\n ? (next as (prev: TrialRecord['undoStack']) => TrialRecord['undoStack'])(w.undoStack)\n : next;\n return { ...w, undoStack };\n }),\n }));\n },\n\n setTrialInstrument: (id, instrumentName) => {\n set((s) => ({\n trials: s.trials.map((w) => (w.id === id ? { ...w, instrumentName } : w)),\n }));\n },\n\n saveSnapshot: (trialId, name) => {\n const trial = get().trials.find((w) => w.id === trialId);\n if (!trial) return;\n const reg = hooks.serializers[trial.instrumentName];\n const serializedState = reg?.serialize\n ? reg.serialize(trial.state)\n : structuredClone(trial.state);\n const clonedConfig = structuredClone(trial.config);\n const lastAt = get().savedSnapshots.reduce((m, sn) => (sn.savedAt > m ? sn.savedAt : m), 0);\n const savedAt = Math.max(Date.now(), lastAt + 1);\n const snapshot: SavedSnapshot = {\n id: newId(),\n name,\n trialId,\n instrumentName: trial.instrumentName,\n config: clonedConfig,\n state: serializedState,\n auto: [...(trial.auto ?? [])],\n savedAt,\n };\n set((s) => ({ savedSnapshots: [...s.savedSnapshots, snapshot] }));\n },\n\n loadSnapshot: (snapshotId, trialId) => {\n const snapshot = get().savedSnapshots.find((sn) => sn.id === snapshotId);\n if (!snapshot) return;\n const trial = get().trials.find((w) => w.id === trialId);\n if (!trial) return;\n if (snapshot.instrumentName !== trial.instrumentName) {\n console.warn(\n `[labkit] loadSnapshot: instrument mismatch (snapshot=${snapshot.instrumentName}, trial=${trial.instrumentName}); refusing to load`,\n );\n return;\n }\n const reg = hooks.serializers[snapshot.instrumentName];\n const restoredState = reg?.deserialize\n ? reg.deserialize(snapshot.state, snapshot.config)\n : snapshot.state;\n set((s) => ({\n trials: s.trials.map((w) => {\n if (w.id !== trialId) return w;\n const loaded: TrialRecord = { ...w, state: restoredState, config: snapshot.config };\n if (snapshot.auto === undefined) return loaded;\n delete loaded.auto;\n if (snapshot.auto.length > 0) loaded.auto = [...snapshot.auto];\n return loaded;\n }),\n }));\n },\n\n deleteSnapshot: (snapshotId) => {\n set((s) => ({\n savedSnapshots: s.savedSnapshots.filter((sn) => sn.id !== snapshotId),\n }));\n },\n\n listSnapshots: (trialId) => {\n const all = get().savedSnapshots;\n const filtered = trialId ? all.filter((sn) => sn.trialId === trialId) : all;\n return [...filtered].sort((a, b) => b.savedAt - a.savedAt);\n },\n\n setMode: (mode) => {\n set({ mode });\n },\n\n setLabTool: (id) => set({ activeToolId: id }),\n\n setTrialTool: (trialId, id) =>\n set((s) => ({\n trials: s.trials.map((t) => (t.id === trialId ? { ...t, activeToolId: id } : t)),\n })),\n\n undockPanel: (trialId, sectionId, as) => {\n set((s) => ({ undockedPanels: undockPanelIn(s.undockedPanels, trialId, sectionId, as) }));\n },\n\n dockPanel: (trialId, sectionId) => {\n set((s) => ({ undockedPanels: dockPanelIn(s.undockedPanels, trialId, sectionId) }));\n },\n\n setLayout: (layout) => {\n set({ layout });\n },\n\n setInstruments: (instruments) => {\n const before = get().instruments;\n if (before === instruments) return;\n const next = mergedHooks(hooks, instruments);\n const previous = new Map((before ?? []).map((i) => [i.name, i]));\n const changed = new Set(\n instruments.filter((i) => previous.get(i.name) !== i).map((i) => i.name),\n );\n if (changed.size === 0) {\n hooks = next;\n set({ instruments });\n return;\n }\n const s = get();\n const trials = s.trials.map((w) =>\n changed.has(w.instrumentName)\n ? { ...w, config: hydratedConfig(next, w.instrumentName, w.config) }\n : w,\n );\n const savedSnapshots = s.savedSnapshots.map((sn) =>\n changed.has(sn.instrumentName)\n ? { ...sn, config: hydratedConfig(next, sn.instrumentName, sn.config) }\n : sn,\n );\n hooks = next;\n set({ instruments, trials, savedSnapshots });\n },\n\n instrumentHooks: () => hooks,\n }));\n\n return store;\n}\n\nfunction hooksOf(instruments: InstrumentList): InstrumentHooks {\n return {\n serializers: serializersOf(instruments),\n configDefaults: configDefaultsOf(instruments),\n configSchemas: configSchemasOf(instruments),\n configMigrations: configMigrationsOf(instruments),\n };\n}\n\n/** Hooks for `instruments`, keeping those of any instrument no longer listed:\n * its trials stay open, and their state still has to round-trip. A listed\n * name takes its hooks wholly from the new list. */\nfunction mergedHooks(old: InstrumentHooks, instruments: InstrumentList): InstrumentHooks {\n const listed = new Set(instruments.map((i) => i.name));\n const fresh = hooksOf(instruments);\n const unlisted = <T>(entries: Record<string, T>): Record<string, T> =>\n Object.fromEntries(Object.entries(entries).filter(([name]) => !listed.has(name)));\n return {\n serializers: { ...unlisted(old.serializers), ...fresh.serializers },\n configDefaults: { ...unlisted(old.configDefaults), ...fresh.configDefaults },\n configSchemas: { ...unlisted(old.configSchemas), ...fresh.configSchemas },\n configMigrations: { ...unlisted(old.configMigrations), ...fresh.configMigrations },\n };\n}\n\n/** How a stored config is brought up to date on the way in. */\nexport type ConfigHydration = Pick<CreateLabStoreOptions, 'configDefaults' | 'configMigrations'>;\n\nfunction hydratedConfig(\n hydration: ConfigHydration,\n instrumentName: string,\n config: unknown,\n): unknown {\n const migrate = hydration.configMigrations?.[instrumentName];\n const moved = migrate ? migrate(config) : config;\n const defaults = hydration.configDefaults?.[instrumentName];\n return defaults ? fillConfigDefaults(moved, defaults()) : moved;\n}\n\n/** Rebuild stored trials: migrate each config, fill its gaps from its\n * instrument's defaults, then run the deserializer against the result. */\nexport function hydrateTrials(\n trials: SerializedTrial[],\n serializers: InstrumentSerializers,\n hydration: ConfigHydration = {},\n): TrialRecord[] {\n return deserializeTrials(\n trials.map((t) => ({ ...t, config: hydratedConfig(hydration, t.instrumentName, t.config) })),\n serializers,\n );\n}\n\n/** Bring each stored snapshot's config up to date the way `hydrateTrials` does a trial's. */\nexport function hydrateSnapshots(\n saves: SavedSnapshot[],\n hydration: ConfigHydration = {},\n): SavedSnapshot[] {\n return saves.map((sn) => ({\n ...sn,\n config: hydratedConfig(hydration, sn.instrumentName, sn.config),\n }));\n}\n","import {\n CURRENT_DOCUMENT_VERSION,\n deleteConfirmed,\n emptyDocument,\n labDocumentKey,\n legacyKeys,\n MIGRATIONS,\n normalizeDocument,\n parseStored,\n quarantineDocument,\n readLegacyDocument,\n runMigrations,\n sameStored,\n} from './document';\nimport { serializeTrials } from './helpers';\nimport {\n compareTrialOrder,\n documentOfRecords,\n LAYOUT_RECORD,\n type LabMeta,\n labPrefix,\n META_RECORD,\n parseRecordName,\n recordsOfDocument,\n saveRecord,\n trialRecord,\n trialValuesPrefix,\n UNDOCK_RECORD,\n} from './labRecords';\nimport { type OwnedRecordCache, openRecords, type RecordCache } from './records';\nimport { createLabStore, hydrateSnapshots, hydrateTrials, type LabStore } from './store';\nimport type {\n CreateLabStoreOptions,\n LabDocument,\n LabMode,\n SavedSnapshot,\n SerializedTrial,\n StorageAdapter,\n TrialRecord,\n} from './types';\n\n/** Options for `openLabStore`. `storageKey` names the lab, so two labs on one\n * origin keep separate records. */\nexport interface OpenLabStoreOptions extends Omit<CreateLabStoreOptions, 'initial'> {\n storageKey: string;\n storage: StorageAdapter;\n}\n\n/** A lab store bound to its records. */\nexport interface OpenedLabStore {\n store: LabStore;\n /** Every record of the lab, `usePersistedState` values included. */\n records: RecordCache;\n /** Send queued writes and stop hearing other writers. */\n close(): Promise<void>;\n}\n\n/**\n * Read a stored lab and return a store bound to it: every change to the store\n * is written as the records it touched, and another writer's records are\n * applied back into the store. A lab stored before records existed is folded\n * forward on the way in.\n */\nexport async function openLabStore(options: OpenLabStoreOptions): Promise<OpenedLabStore> {\n const records = await openRecords({\n storage: options.storage,\n prefix: labPrefix(options.storageKey),\n });\n const { doc, orders } = await readLab(options, records);\n const store = createLabStore({ ...options, initial: doc });\n const unbind = bindLabStore(store, records, { orders });\n return {\n store,\n records,\n close: async () => {\n unbind();\n await records.close();\n },\n };\n}\n\ninterface ReadLab {\n doc: LabDocument;\n orders: Map<string, number>;\n}\n\nfunction emptyLab(mode: LabMode): ReadLab {\n return { doc: emptyDocument(mode), orders: new Map() };\n}\n\nfunction ordersOf(doc: LabDocument): Map<string, number> {\n return new Map(doc.trials.map((t, i) => [t.id, i]));\n}\n\nasync function readLab(options: OpenLabStoreOptions, records: OwnedRecordCache): Promise<ReadLab> {\n const mode = options.initialMode ?? 'auto';\n if (!records.writable) return emptyLab(mode);\n\n const joined = documentOfRecords(records.entries());\n if (!joined) return foldOldStorage(options, records);\n\n const outcome = runMigrations(joined.doc, MIGRATIONS, CURRENT_DOCUMENT_VERSION);\n if (outcome.ok) {\n return { doc: normalizeDocument(outcome.doc, mode), orders: joined.orders };\n }\n const why =\n outcome.reason === 'future' ? 'are from a newer version of labkit' : 'failed to migrate';\n console.warn(`[labkit] lab records ${why}; starting empty and leaving them alone`, outcome.error);\n records.stopWriting();\n return emptyLab(mode);\n}\n\n/** Fold a version-3 document, or the four keys before it, into records. The\n * old keys are deleted only once every record has been read back. */\nasync function foldOldStorage(\n options: OpenLabStoreOptions,\n records: OwnedRecordCache,\n): Promise<ReadLab> {\n const { storage, storageKey } = options;\n const mode = options.initialMode ?? 'auto';\n\n let raw: unknown;\n let oldKeys: string[];\n try {\n const stored = await storage.get(labDocumentKey(storageKey));\n if (stored !== undefined) {\n raw = stored;\n oldKeys = [labDocumentKey(storageKey)];\n } else {\n raw = await readLegacyDocument((key) => storage.get(key), storageKey, mode);\n oldKeys = legacyKeys(storageKey);\n if (raw === null) return emptyLab(mode);\n }\n } catch (error) {\n console.warn(\n `[labkit] could not read the old storage for \"${storageKey}\"; not persisting`,\n error,\n );\n records.stopWriting();\n return emptyLab(mode);\n }\n\n const setAside = async (value: unknown, why: string, error?: unknown): Promise<ReadLab> => {\n if (await quarantineDocument(storage, storageKey, value)) {\n console.warn(`[labkit] ${why}; quarantined it and starting empty`, error);\n await deleteConfirmed(storage, oldKeys);\n records.set(META_RECORD, { version: CURRENT_DOCUMENT_VERSION, mode } satisfies LabMeta);\n } else {\n console.warn(\n `[labkit] ${why} and could not be quarantined; leaving it in place and not persisting`,\n error,\n );\n records.stopWriting();\n }\n return emptyLab(mode);\n };\n\n const parsed = parseStored(raw);\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return setAside(raw, 'lab document is unparseable');\n }\n const outcome = runMigrations(\n parsed as Record<string, unknown>,\n MIGRATIONS,\n CURRENT_DOCUMENT_VERSION,\n );\n if (!outcome.ok) {\n if (outcome.reason === 'future') {\n console.warn(\n '[labkit] lab document is from a newer version of labkit; starting empty and leaving it alone',\n );\n records.stopWriting();\n return emptyLab(mode);\n }\n return setAside(parsed, 'lab document failed to migrate', outcome.error);\n }\n\n const doc = normalizeDocument(outcome.doc, mode);\n const entries = recordsOfDocument(doc);\n records.seed(entries);\n if (await writeConfirmed(storage, records.prefix, entries)) {\n await deleteConfirmed(storage, oldKeys);\n } else {\n console.warn(\n `[labkit] keeping the old storage for \"${storageKey}\": could not confirm its records were written`,\n );\n }\n return { doc, orders: ordersOf(doc) };\n}\n\n/** Write `entries` in order and read every one back. */\nasync function writeConfirmed(\n storage: StorageAdapter,\n prefix: string,\n entries: [string, unknown][],\n): Promise<boolean> {\n try {\n for (const [name, value] of entries) await storage.set(prefix + name, value);\n const back = new Map(await storage.list(prefix));\n return entries.every(([name, value]) => sameStored(back.get(prefix + name), value));\n } catch {\n return false;\n }\n}\n\ninterface BindOptions {\n orders: Map<string, number>;\n}\n\nfunction persistedFieldsDiffer(a: TrialRecord, b: TrialRecord): boolean {\n if (a === b) return false;\n const left = a as unknown as Record<string, unknown>;\n const right = b as unknown as Record<string, unknown>;\n for (const key of new Set([...Object.keys(left), ...Object.keys(right)])) {\n if (key !== 'undoStack' && !Object.is(left[key], right[key])) return true;\n }\n return false;\n}\n\n/** Keep `store` and `records` in step, both ways. Returns the unbinding. */\nfunction bindLabStore(store: LabStore, records: RecordCache, options: BindOptions): () => void {\n const orderOf = new Map(options.orders);\n let applyingRemote = false;\n\n const nextOrder = (): number => {\n let max = -1;\n for (const order of orderOf.values()) max = Math.max(max, order);\n return max + 1;\n };\n\n const writeTrial = (trial: TrialRecord): void => {\n const [serialized] = serializeTrials([trial], store.getState().instrumentHooks().serializers);\n records.set(trialRecord(trial.id), { ...serialized, order: orderOf.get(trial.id) });\n };\n\n const inStoredOrder = (trials: TrialRecord[]): boolean => {\n for (let i = 1; i < trials.length; i++) {\n const a = trials[i - 1] as TrialRecord;\n const b = trials[i] as TrialRecord;\n const at = { trial: a, order: orderOf.get(a.id) ?? 0 };\n const bt = { trial: b, order: orderOf.get(b.id) ?? 0 };\n if (compareTrialOrder(at, bt) >= 0) return false;\n }\n return true;\n };\n\n const offStore = store.subscribe((state, prev) => {\n if (applyingRemote) return;\n let wrote = false;\n\n if (state.trials !== prev.trials) {\n const before = new Map(prev.trials.map((t) => [t.id, t]));\n const now = new Set(state.trials.map((t) => t.id));\n for (const t of prev.trials) {\n if (now.has(t.id)) continue;\n records.delete(trialRecord(t.id));\n for (const [name] of records.entries(trialValuesPrefix(t.id))) records.delete(name);\n orderOf.delete(t.id);\n wrote = true;\n }\n const added = state.trials.filter((t) => !before.has(t.id));\n for (const t of added) orderOf.set(t.id, nextOrder());\n if (inStoredOrder(state.trials)) {\n for (const t of state.trials) {\n const old = before.get(t.id);\n if (old && !persistedFieldsDiffer(old, t)) continue;\n writeTrial(t);\n wrote = true;\n }\n } else {\n // A reorder, or a trial inserted mid-list: renumber them all.\n for (const [i, t] of state.trials.entries()) orderOf.set(t.id, i);\n for (const t of state.trials) writeTrial(t);\n wrote = true;\n }\n }\n\n if (state.savedSnapshots !== prev.savedSnapshots) {\n const before = new Map(prev.savedSnapshots.map((s) => [s.id, s]));\n const now = new Set(state.savedSnapshots.map((s) => s.id));\n for (const s of state.savedSnapshots) {\n if (before.get(s.id) === s) continue;\n records.set(saveRecord(s.id), s);\n wrote = true;\n }\n for (const s of prev.savedSnapshots) {\n if (now.has(s.id)) continue;\n records.delete(saveRecord(s.id));\n wrote = true;\n }\n }\n\n if (state.layout !== prev.layout) {\n records.set(LAYOUT_RECORD, state.layout);\n wrote = true;\n }\n if (state.undockedPanels !== prev.undockedPanels) {\n records.set(UNDOCK_RECORD, state.undockedPanels);\n wrote = true;\n }\n if (state.mode !== prev.mode || (wrote && !records.has(META_RECORD))) {\n records.set(META_RECORD, {\n version: CURRENT_DOCUMENT_VERSION,\n mode: state.mode,\n } satisfies LabMeta);\n }\n });\n\n const offRecords = records.subscribe((changes) => {\n const remote = changes.filter((c) => c.origin === 'remote');\n if (remote.length === 0) return;\n\n const current = store.getState();\n let trials = current.trials;\n let saves = current.savedSnapshots;\n const patch: Partial<Pick<typeof current, 'layout' | 'undockedPanels' | 'mode'>> = {};\n\n for (const { name, value } of remote) {\n const parsed = parseRecordName(name);\n if (!parsed) continue;\n switch (parsed.kind) {\n case 'trial': {\n const id = parsed.id;\n if (value === undefined || !value || typeof value !== 'object') {\n trials = trials.filter((t) => t.id !== id);\n orderOf.delete(id);\n break;\n }\n const { order, ...rest } = value as SerializedTrial & { order?: unknown };\n orderOf.set(\n id,\n typeof order === 'number' && Number.isFinite(order) ? order : nextOrder(),\n );\n // Hydrating starts an empty undo history: the old one describes a\n // state that no longer exists.\n const hooks = store.getState().instrumentHooks();\n const [replacement] = hydrateTrials([{ ...rest, id }], hooks.serializers, hooks);\n if (!replacement) break;\n trials = trials.some((t) => t.id === id)\n ? trials.map((t) => (t.id === id ? replacement : t))\n : [...trials, replacement];\n break;\n }\n case 'save': {\n const id = parsed.id;\n if (value === undefined || !value || typeof value !== 'object') {\n saves = saves.filter((s) => s.id !== id);\n break;\n }\n const [snapshot] = hydrateSnapshots(\n [{ ...(value as SavedSnapshot), id }],\n store.getState().instrumentHooks(),\n );\n if (!snapshot) break;\n saves = saves.some((s) => s.id === id)\n ? saves.map((s) => (s.id === id ? snapshot : s))\n : [...saves, snapshot];\n break;\n }\n case 'layout':\n patch.layout = (value as Record<string, unknown> | undefined) ?? {};\n break;\n case 'undock':\n patch.undockedPanels = (value as typeof current.undockedPanels | undefined) ?? {};\n break;\n case 'meta': {\n const meta = value as Partial<LabMeta> | undefined;\n if (typeof meta?.version === 'number' && meta.version > CURRENT_DOCUMENT_VERSION) {\n console.warn(\n '[labkit] another tab wrote this lab with a newer labkit; no longer persisting',\n );\n if ('stopWriting' in records) (records as OwnedRecordCache).stopWriting();\n break;\n }\n if (meta?.mode === 'light' || meta?.mode === 'dark' || meta?.mode === 'auto') {\n patch.mode = meta.mode;\n }\n break;\n }\n }\n }\n\n if (trials !== current.trials) {\n trials = [...trials].sort((a, b) =>\n compareTrialOrder(\n { trial: a, order: orderOf.get(a.id) ?? 0 },\n { trial: b, order: orderOf.get(b.id) ?? 0 },\n ),\n );\n }\n applyingRemote = true;\n try {\n store.setState({ ...patch, trials, savedSnapshots: saves });\n } finally {\n applyingRemote = false;\n }\n });\n\n return () => {\n offStore();\n offRecords();\n };\n}\n","import { useContext } from 'react';\nimport { useStore } from 'zustand/react';\nimport { useResolvedConfig } from '../config/useResolvedConfig';\nimport { LabStoreContext, TrialIdContext } from './context';\nimport type { TrialStateHandle } from './types';\n\n/** An instrument's own state and config, plus setters. Reads the surrounding\n * trial id, so an instrument never has to know which trial it is\n * running in. Throws outside a lab store and trial. */\nexport function useTrialState<TS = unknown, TC = unknown>(): TrialStateHandle<TS, TC> {\n const ctx = useContext(LabStoreContext);\n if (!ctx) throw new Error('[labkit] useTrialState must be used inside <LabStoreProvider>');\n\n const trialId = useContext(TrialIdContext);\n if (!trialId) throw new Error('[labkit] useTrialState must be used inside <TrialIdProvider>');\n\n const record = useStore(ctx.store, (s) => s.trials.find((w) => w.id === trialId));\n\n if (!record) throw new Error(`[labkit] No trial found with id \"${trialId}\"`);\n\n const updateTrialState = useStore(ctx.store, (s) => s.updateTrialState);\n const updateTrialConfig = useStore(ctx.store, (s) => s.updateTrialConfig);\n // The store's own copy, not `useConfigSchema`: that reads `LabContext`, and\n // this hook only has the store's.\n const instrumentHooks = useStore(ctx.store, (s) => s.instrumentHooks);\n const schema = instrumentHooks().configSchemas[record.instrumentName];\n const { config, auto } = useResolvedConfig<TC>(schema, record.config as TC, record.auto);\n\n return {\n state: record.state as TS,\n config,\n raw: record.config as TC,\n auto,\n setState: (next) => updateTrialState(trialId, next as Parameters<typeof updateTrialState>[1]),\n setConfig: (path, value) => updateTrialConfig(trialId, path, value),\n };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { schemaNodeAtPath } from './chunk-
|
|
1
|
+
import { schemaNodeAtPath } from './chunk-TJ77A4A3.js';
|
|
2
2
|
|
|
3
3
|
// src/config/fromConfigField.ts
|
|
4
4
|
function toLeaf(field) {
|
|
@@ -55,7 +55,8 @@ function fromConfigFields(fields) {
|
|
|
55
55
|
group: { name: "", children },
|
|
56
56
|
sections: [],
|
|
57
57
|
showIf: /* @__PURE__ */ new Map(),
|
|
58
|
-
renderers: {}
|
|
58
|
+
renderers: {},
|
|
59
|
+
dialogs: {}
|
|
59
60
|
};
|
|
60
61
|
}
|
|
61
62
|
|
|
@@ -68,5 +69,5 @@ function isLeafVisible(resolved, path, config, showHidden = false) {
|
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
export { fromConfigFields, isLeafVisible };
|
|
71
|
-
//# sourceMappingURL=chunk-
|
|
72
|
-
//# sourceMappingURL=chunk-
|
|
72
|
+
//# sourceMappingURL=chunk-IRTGUQ5O.js.map
|
|
73
|
+
//# sourceMappingURL=chunk-IRTGUQ5O.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/fromConfigField.ts","../src/config/visible.ts"],"names":[],"mappings":";;;AAOA,SAAS,OAAO,KAAA,EAA+B;AAC7C,EAAA,MAAM,OAAO,EAAE,IAAA,EAAM,KAAA,CAAM,KAAA,EAAO,aAAa,EAAA,EAAG;AAClD,EAAA,QAAQ,MAAM,IAAA;AAAM,IAClB,KAAK,QAAA;AACH,MAAA,OAAO;AAAA,QACL,GAAG,IAAA;AAAA,QACH,IAAA,EAAM,QAAA;AAAA,QACN,OAAA,EAAS,QAAA;AAAA,QACT,KAAK,KAAA,CAAM,GAAA;AAAA,QACX,KAAK,KAAA,CAAM,GAAA;AAAA,QACX,MAAM,KAAA,CAAM;AAAA,OACd;AAAA,IACF,KAAK,QAAA;AACH,MAAA,OAAO;AAAA,QACL,GAAG,IAAA;AAAA,QACH,IAAA,EAAM,QAAA;AAAA,QACN,OAAA,EAAS,OAAA;AAAA,QACT,KAAK,KAAA,CAAM,GAAA;AAAA,QACX,KAAK,KAAA,CAAM,GAAA;AAAA,QACX,MAAM,KAAA,CAAM;AAAA,OACd;AAAA,IACF,KAAK,UAAA;AACH,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,SAAA,EAAW,SAAS,UAAA,EAAW;AAAA,IACzD,KAAK,QAAA;AACH,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,MAAM,MAAA,EAAQ,OAAA,EAAS,MAAM,OAAA,EAAQ;AAAA,IACzD,KAAK,MAAA;AACH,MAAA,OAAO;AAAA,QACL,GAAG,IAAA;AAAA,QACH,IAAA,EAAM,QAAA;AAAA,QACN,aAAa,KAAA,CAAM,WAAA;AAAA,QACnB,WAAW,KAAA,CAAM,SAAA;AAAA,QACjB,YAAY,KAAA,CAAM;AAAA,OACpB;AAAA,IACF,KAAK,OAAA;AACH,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,OAAA,EAAQ;AAAA,IAClC;AAGE,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAO,MAAsB,IAAA,EAAK;AAAA;AAE1D;AASO,SAAS,iBAAiB,MAAA,EAAgD;AAC/E,EAAA,MAAM,WAAqC,EAAC;AAC5C,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,KAAA,GAAQ,OAAO,KAAK,CAAA;AAC1B,IAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,EAAG;AACpC,MAAA,IAAK,KAAA,CAAkC,GAAG,CAAA,KAAM,MAAA,EAAW;AACzD,QAAA,OAAQ,MAAkC,GAAG,CAAA;AAAA,MAC/C;AAAA,IACF;AACA,IAAA,QAAA,CAAS,KAAA,CAAM,GAAG,CAAA,GAAI,EAAE,GAAG,KAAA,EAAO,OAAA,EAAS,MAAM,OAAA,EAAQ;AAAA,EAC3D;AACA,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,EAAE,IAAA,EAAM,EAAA,EAAI,QAAA,EAAS;AAAA,IAC5B,UAAU,EAAC;AAAA,IACX,MAAA,sBAAY,GAAA,EAAI;AAAA,IAChB,WAAW,EAAC;AAAA,IACZ,SAAS;AAAC,GACZ;AACF;;;AC/DO,SAAS,aAAA,CACd,QAAA,EACA,IAAA,EACA,MAAA,EACA,aAAa,KAAA,EACJ;AACT,EAAA,MAAM,IAAA,GAAO,gBAAA,CAAiB,QAAA,CAAS,KAAA,EAAO,IAAI,CAAA;AAClD,EAAA,IAAI,IAAA,IAAQ,YAAY,IAAA,IAAQ,IAAA,CAAK,WAAW,IAAA,IAAQ,CAAC,YAAY,OAAO,KAAA;AAC5E,EAAA,MAAM,SAAA,GAAY,QAAA,CAAS,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA;AAC1C,EAAA,OAAO,SAAA,GAAY,SAAA,CAAU,MAAM,CAAA,GAAI,IAAA;AACzC","file":"chunk-IRTGUQ5O.js","sourcesContent":["import type { PrefLeaf } from '@weasel-js/ui';\nimport type { ConfigField } from '../controls/types';\nimport type { LeafPatch, ResolvedConfig } from './types';\n\n/** One `ConfigField` as the `Pref*` vocabulary spells it. The two describe the\n * same thing; `ConfigField` just keys on the control where `PrefLeaf`\n * separates the value's kind from how it is presented. */\nfunction toLeaf(field: ConfigField): LeafPatch {\n const base = { name: field.label, description: '' };\n switch (field.type) {\n case 'slider':\n return {\n ...base,\n kind: 'number',\n control: 'slider',\n min: field.min,\n max: field.max,\n step: field.step,\n };\n case 'number':\n return {\n ...base,\n kind: 'number',\n control: 'input',\n min: field.min,\n max: field.max,\n step: field.step,\n };\n case 'checkbox':\n return { ...base, kind: 'boolean', control: 'checkbox' };\n case 'select':\n return { ...base, kind: 'enum', options: field.options };\n case 'text':\n return {\n ...base,\n kind: 'string',\n placeholder: field.placeholder,\n maxLength: field.maxLength,\n debounceMs: field.debounceMs,\n };\n case 'color':\n return { ...base, kind: 'color' };\n default:\n // A schema can arrive from outside TypeScript. Carry the kind through\n // so a lab-supplied renderer can still claim it.\n return { ...base, kind: (field as ConfigField).type };\n }\n}\n\n/**\n * Adapt a legacy `configSchema(): ConfigField[]` into the resolved shape, so\n * both instrument paths reach one renderer.\n *\n * Rules do not run here: a hand-written `ConfigField` already states its label\n * and control, which is everything the rule chain would have inferred.\n */\nexport function fromConfigFields(fields: readonly ConfigField[]): ResolvedConfig {\n const children: Record<string, PrefLeaf> = {};\n for (const field of fields) {\n const patch = toLeaf(field);\n for (const key of Object.keys(patch)) {\n if ((patch as Record<string, unknown>)[key] === undefined) {\n delete (patch as Record<string, unknown>)[key];\n }\n }\n children[field.key] = { ...patch, default: field.default } as PrefLeaf;\n }\n return {\n group: { name: '', children },\n sections: [],\n showIf: new Map(),\n renderers: {},\n dialogs: {},\n };\n}\n","import { schemaNodeAtPath } from './path';\nimport type { ResolvedConfig } from './types';\n\n/**\n * Whether the row at a dotted path should be drawn right now. A group answers\n * for its whole subtree — hiding one hides everything under it.\n *\n * `hidden` is the node's own static flag; `showIf` is the schema's predicate\n * over the live config. Both are presentational — a hidden leaf keeps its\n * value and the instrument still reads it.\n */\nexport function isLeafVisible(\n resolved: ResolvedConfig,\n path: string,\n config: Record<string, unknown>,\n showHidden = false,\n): boolean {\n const node = schemaNodeAtPath(resolved.group, path);\n if (node && 'hidden' in node && node.hidden === true && !showHidden) return false;\n const predicate = resolved.showIf.get(path);\n return predicate ? predicate(config) : true;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_FRAME } from './chunk-
|
|
1
|
+
import { DEFAULT_FRAME } from './chunk-24W5VEJW.js';
|
|
2
2
|
import { normalizeZoom } from '@weasel-js/core';
|
|
3
3
|
|
|
4
4
|
function zoomAt(view, factor, at, { frame = DEFAULT_FRAME, min, max } = {}) {
|
|
@@ -29,5 +29,5 @@ function centerOn(world, zoom, size, frame = DEFAULT_FRAME) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export { centerOn, zoomAt };
|
|
32
|
-
//# sourceMappingURL=chunk-
|
|
33
|
-
//# sourceMappingURL=chunk-
|
|
32
|
+
//# sourceMappingURL=chunk-JVBYV6TL.js.map
|
|
33
|
+
//# sourceMappingURL=chunk-JVBYV6TL.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/canvas/camera.ts"],"names":[],"mappings":";;;AAqBO,SAAS,MAAA,CACd,IAAA,EACA,MAAA,EACA,EAAA,EACA,EAAE,KAAA,GAAQ,aAAA,EAAe,GAAA,EAAK,GAAA,EAAI,GAAmB,EAAC,EACvC;AAGf,EAAA,MAAM,OAAA,GAAU,EAAA,CAAG,CAAA,GAAI,KAAA,CAAM,QAAA,CAAS,CAAA;AACtC,EAAA,MAAM,OAAA,GAAU,EAAA,CAAG,CAAA,GAAI,KAAA,CAAM,QAAA,CAAS,CAAA;AACtC,EAAA,MAAM,OAAA,GAAU,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA;AACvC,EAAA,MAAM,IAAA,GAAO,aAAA;AAAA,IACX,IAAA,CAAK,GAAA,CAAI,GAAA,IAAO,MAAA,CAAO,iBAAA,EAAmB,IAAA,CAAK,GAAA,CAAI,GAAA,IAAO,CAAA,EAAG,OAAA,GAAU,MAAM,CAAC;AAAA,GAChF;AACA,EAAA,MAAM,QAAQ,IAAA,GAAO,OAAA;AACrB,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,GAAA,EAAK;AAAA,MACH,CAAA,EAAG,OAAA,GAAA,CAAW,OAAA,GAAU,IAAA,CAAK,IAAI,CAAA,IAAK,KAAA;AAAA,MACtC,CAAA,EAAG,OAAA,GAAA,CAAW,OAAA,GAAU,IAAA,CAAK,IAAI,CAAA,IAAK;AAAA;AACxC,GACF;AACF;AAIO,SAAS,QAAA,CACd,KAAA,EACA,IAAA,EACA,IAAA,EACA,QAAoB,aAAA,EACL;AACf,EAAA,MAAM,CAAA,GAAI,cAAc,IAAI,CAAA;AAC5B,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,CAAA;AAAA,IACN,GAAA,EAAK;AAAA,MACH,CAAA,EAAG,KAAK,KAAA,GAAQ,CAAA,GAAI,MAAM,QAAA,CAAS,CAAA,GAAI,MAAM,CAAA,GAAI,CAAA;AAAA,MACjD,CAAA,EAAG,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,KAAA,CAAM,SAAS,CAAA,GAAI,KAAA,CAAM,CAAA,GAAI,CAAA,GAAI,KAAA,CAAM;AAAA;AAC9D,GACF;AACF","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/canvas/camera.ts"],"names":[],"mappings":";;;AAqBO,SAAS,MAAA,CACd,IAAA,EACA,MAAA,EACA,EAAA,EACA,EAAE,KAAA,GAAQ,aAAA,EAAe,GAAA,EAAK,GAAA,EAAI,GAAmB,EAAC,EACvC;AAGf,EAAA,MAAM,OAAA,GAAU,EAAA,CAAG,CAAA,GAAI,KAAA,CAAM,QAAA,CAAS,CAAA;AACtC,EAAA,MAAM,OAAA,GAAU,EAAA,CAAG,CAAA,GAAI,KAAA,CAAM,QAAA,CAAS,CAAA;AACtC,EAAA,MAAM,OAAA,GAAU,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA;AACvC,EAAA,MAAM,IAAA,GAAO,aAAA;AAAA,IACX,IAAA,CAAK,GAAA,CAAI,GAAA,IAAO,MAAA,CAAO,iBAAA,EAAmB,IAAA,CAAK,GAAA,CAAI,GAAA,IAAO,CAAA,EAAG,OAAA,GAAU,MAAM,CAAC;AAAA,GAChF;AACA,EAAA,MAAM,QAAQ,IAAA,GAAO,OAAA;AACrB,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,GAAA,EAAK;AAAA,MACH,CAAA,EAAG,OAAA,GAAA,CAAW,OAAA,GAAU,IAAA,CAAK,IAAI,CAAA,IAAK,KAAA;AAAA,MACtC,CAAA,EAAG,OAAA,GAAA,CAAW,OAAA,GAAU,IAAA,CAAK,IAAI,CAAA,IAAK;AAAA;AACxC,GACF;AACF;AAIO,SAAS,QAAA,CACd,KAAA,EACA,IAAA,EACA,IAAA,EACA,QAAoB,aAAA,EACL;AACf,EAAA,MAAM,CAAA,GAAI,cAAc,IAAI,CAAA;AAC5B,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,CAAA;AAAA,IACN,GAAA,EAAK;AAAA,MACH,CAAA,EAAG,KAAK,KAAA,GAAQ,CAAA,GAAI,MAAM,QAAA,CAAS,CAAA,GAAI,MAAM,CAAA,GAAI,CAAA;AAAA,MACjD,CAAA,EAAG,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,KAAA,CAAM,SAAS,CAAA,GAAI,KAAA,CAAM,CAAA,GAAI,CAAA,GAAI,KAAA,CAAM;AAAA;AAC9D,GACF;AACF","file":"chunk-JVBYV6TL.js","sourcesContent":["import { normalizeZoom } from '@weasel-js/core';\nimport type { Point, ViewTransform } from '../instrument/types';\nimport { DEFAULT_FRAME, type ViewportSize, type WorldFrame } from './worldSpec';\n\n/** Bounds and coordinate system a {@link zoomAt} works in. */\nexport interface ZoomAtOptions {\n /** The instrument's coordinate system, resolved against the viewport.\n * Omitted, `at` is measured from the element's top-left. */\n frame?: WorldFrame;\n min?: number;\n max?: number;\n}\n\n/**\n * Zoom a view by `factor` about a fixed point, so whatever world coordinate\n * `at` was over stays under it.\n *\n * `at` is in the element's own pixels — a cursor position, or the centre of a\n * lens. The clamp is applied before the pan is solved, so a zoom that hits a\n * bound still anchors on the zoom it actually reached.\n */\nexport function zoomAt(\n view: ViewTransform,\n factor: number,\n at: Point,\n { frame = DEFAULT_FRAME, min, max }: ZoomAtOptions = {},\n): ViewTransform {\n // `pan` is measured from the frame's origin, so anchoring at the raw point\n // drifts by `(1 - ratio) * originPx` per step on any frame that moves it.\n const anchorX = at.x - frame.originPx.x;\n const anchorY = at.y - frame.originPx.y;\n const current = normalizeZoom(view.zoom);\n const zoom = normalizeZoom(\n Math.min(max ?? Number.POSITIVE_INFINITY, Math.max(min ?? 0, current * factor)),\n );\n const ratio = zoom / current;\n return {\n zoom,\n pan: {\n x: anchorX - (anchorX - view.pan.x) * ratio,\n y: anchorY - (anchorY - view.pan.y) * ratio,\n },\n };\n}\n\n/** The view that puts a world point at the centre of a `size` viewport, at\n * `zoom`. What a lens showing a region around one point renders through. */\nexport function centerOn(\n world: Point,\n zoom: number,\n size: ViewportSize,\n frame: WorldFrame = DEFAULT_FRAME,\n): ViewTransform {\n const z = normalizeZoom(zoom);\n return {\n zoom: z,\n pan: {\n x: size.width / 2 - frame.originPx.x - world.x * z,\n y: size.height / 2 - frame.originPx.y - world.y * z * frame.yDir,\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { textCommand, ellipsePath, linePath, markerDrawCommands, rectPath, PathBuilder } from '@weasel-js/core';
|
|
2
|
+
|
|
3
|
+
// src/annotations/paint.ts
|
|
4
|
+
var MARK_COLOR = "#e5484d";
|
|
5
|
+
var MARK_WIDTH = 2;
|
|
6
|
+
var TEXT_SIZE = 14;
|
|
7
|
+
var POINT_RADIUS = 4;
|
|
8
|
+
var toWorld = (p, content) => ({
|
|
9
|
+
x: p.x * content.w,
|
|
10
|
+
y: p.y * content.h
|
|
11
|
+
});
|
|
12
|
+
function vertices(m, content) {
|
|
13
|
+
const stored = m.data.points;
|
|
14
|
+
if (stored && stored.length >= 2) return stored.map((p) => toWorld(p, content));
|
|
15
|
+
const { x, y, width, height } = m.pose;
|
|
16
|
+
return [
|
|
17
|
+
{ x, y },
|
|
18
|
+
{ x: x + width, y: y + height }
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
function polyline(points) {
|
|
22
|
+
const b = new PathBuilder();
|
|
23
|
+
const first = points[0];
|
|
24
|
+
if (!first) return rectPath(0, 0, 0, 0);
|
|
25
|
+
b.moveTo(first.x, first.y);
|
|
26
|
+
for (const p of points.slice(1)) b.lineTo(p.x, p.y);
|
|
27
|
+
return b.build();
|
|
28
|
+
}
|
|
29
|
+
function markCommands(m, content, style = {}) {
|
|
30
|
+
const color = style.color ?? MARK_COLOR;
|
|
31
|
+
const stroke = {
|
|
32
|
+
paint: { color },
|
|
33
|
+
width: MARK_WIDTH,
|
|
34
|
+
cap: "round",
|
|
35
|
+
join: "round",
|
|
36
|
+
...style.stale ? { dash: [6, 4] } : {}
|
|
37
|
+
};
|
|
38
|
+
switch (m.data.kind) {
|
|
39
|
+
case "rect":
|
|
40
|
+
return [
|
|
41
|
+
{ kind: "path", path: rectPath(m.pose.x, m.pose.y, m.pose.width, m.pose.height), stroke }
|
|
42
|
+
];
|
|
43
|
+
case "ellipse":
|
|
44
|
+
return [{ kind: "path", path: ellipsePath(m.pose), stroke }];
|
|
45
|
+
case "line": {
|
|
46
|
+
const [a, b] = vertices(m, content);
|
|
47
|
+
return [{ kind: "path", path: linePath(a, b), stroke }];
|
|
48
|
+
}
|
|
49
|
+
case "arrow": {
|
|
50
|
+
const [a, b] = vertices(m, content);
|
|
51
|
+
const marked = { ...stroke, markerEnd: "arrow" };
|
|
52
|
+
const path = linePath(a, b);
|
|
53
|
+
return [
|
|
54
|
+
{ kind: "path", path, stroke: marked },
|
|
55
|
+
...markerDrawCommands(path, marked, MARK_WIDTH, void 0)
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
case "stroke":
|
|
59
|
+
return [{ kind: "path", path: polyline(vertices(m, content)), stroke }];
|
|
60
|
+
case "point": {
|
|
61
|
+
const stored = m.data.points?.[0];
|
|
62
|
+
const c = stored ? toWorld(stored, content) : { x: m.pose.x, y: m.pose.y };
|
|
63
|
+
const ring = {
|
|
64
|
+
x: c.x - POINT_RADIUS,
|
|
65
|
+
y: c.y - POINT_RADIUS,
|
|
66
|
+
width: 2 * POINT_RADIUS,
|
|
67
|
+
height: 2 * POINT_RADIUS
|
|
68
|
+
};
|
|
69
|
+
return [{ kind: "path", path: ellipsePath(ring), stroke }];
|
|
70
|
+
}
|
|
71
|
+
case "text": {
|
|
72
|
+
const text = m.data.title;
|
|
73
|
+
if (!text) return [];
|
|
74
|
+
return [
|
|
75
|
+
textCommand(
|
|
76
|
+
m.pose.x,
|
|
77
|
+
m.pose.y,
|
|
78
|
+
text,
|
|
79
|
+
{ fontSize: TEXT_SIZE },
|
|
80
|
+
void 0,
|
|
81
|
+
void 0,
|
|
82
|
+
void 0,
|
|
83
|
+
{
|
|
84
|
+
fill: { color }
|
|
85
|
+
}
|
|
86
|
+
)
|
|
87
|
+
];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/annotations/svgNodes.ts
|
|
93
|
+
var NO_PAINT = { kind: "none" };
|
|
94
|
+
function toSvgPaint(paint) {
|
|
95
|
+
if (!paint) return NO_PAINT;
|
|
96
|
+
if ("color" in paint && typeof paint.color === "string") {
|
|
97
|
+
return {
|
|
98
|
+
kind: "solid",
|
|
99
|
+
color: paint.color,
|
|
100
|
+
...paint.opacity != null ? { opacity: paint.opacity } : {}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return { kind: "gradient", paint };
|
|
104
|
+
}
|
|
105
|
+
function toSvgStroke(stroke) {
|
|
106
|
+
return {
|
|
107
|
+
paint: toSvgPaint(stroke.paint),
|
|
108
|
+
width: stroke.width ?? 1,
|
|
109
|
+
...stroke.cap ? { cap: stroke.cap } : {},
|
|
110
|
+
...stroke.join ? { join: stroke.join } : {},
|
|
111
|
+
...stroke.dash ? { dash: [...stroke.dash] } : {},
|
|
112
|
+
...stroke.miterLimit != null ? { miterLimit: stroke.miterLimit } : {},
|
|
113
|
+
...stroke.align ? { align: stroke.align } : {}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function toSvgNode(cmd, m) {
|
|
117
|
+
if (cmd.kind === "path") {
|
|
118
|
+
return {
|
|
119
|
+
kind: "path",
|
|
120
|
+
path: cmd.path,
|
|
121
|
+
fill: toSvgPaint(cmd.fill),
|
|
122
|
+
...cmd.stroke ? { stroke: toSvgStroke(cmd.stroke) } : {}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
if (cmd.kind === "text") {
|
|
126
|
+
return {
|
|
127
|
+
kind: "text",
|
|
128
|
+
x: cmd.x,
|
|
129
|
+
y: cmd.y,
|
|
130
|
+
width: m.pose.width,
|
|
131
|
+
height: m.pose.height,
|
|
132
|
+
text: cmd.runs.map((run) => run.text).join(""),
|
|
133
|
+
style: cmd.style,
|
|
134
|
+
...cmd.runs[0]?.fill ? { fill: cmd.runs[0].fill } : {}
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
throw new Error(`[labkit] a mark drew a '${cmd.kind}' command, which has no vector form`);
|
|
138
|
+
}
|
|
139
|
+
function markSvgNodes(m, content, style = {}) {
|
|
140
|
+
return markCommands(m, content, style).map((cmd) => toSvgNode(cmd, m));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export { markCommands, markSvgNodes };
|
|
144
|
+
//# sourceMappingURL=chunk-KHK5FGER.js.map
|
|
145
|
+
//# sourceMappingURL=chunk-KHK5FGER.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/annotations/paint.ts","../src/annotations/svgNodes.ts"],"names":[],"mappings":";;;AAcA,IAAM,UAAA,GAAa,SAAA;AAGnB,IAAM,UAAA,GAAa,CAAA;AACnB,IAAM,SAAA,GAAY,EAAA;AAClB,IAAM,YAAA,GAAe,CAAA;AAmBrB,IAAM,OAAA,GAAU,CAAC,CAAA,EAAc,OAAA,MAAuC;AAAA,EACpE,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,OAAA,CAAQ,CAAA;AAAA,EACjB,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,OAAA,CAAQ;AACnB,CAAA,CAAA;AAIA,SAAS,QAAA,CAAS,GAAkB,OAAA,EAA+D;AACjG,EAAA,MAAM,MAAA,GAAS,EAAE,IAAA,CAAK,MAAA;AACtB,EAAA,IAAI,MAAA,IAAU,MAAA,CAAO,MAAA,IAAU,CAAA,EAAG,OAAO,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,OAAA,CAAQ,CAAA,EAAG,OAAO,CAAC,CAAA;AAC9E,EAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,MAAA,KAAW,CAAA,CAAE,IAAA;AAClC,EAAA,OAAO;AAAA,IACL,EAAE,GAAG,CAAA,EAAE;AAAA,IACP,EAAE,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAG,IAAI,MAAA;AAAO,GAChC;AACF;AAEA,SAAS,SAAS,MAAA,EAA0C;AAC1D,EAAA,MAAM,CAAA,GAAI,IAAI,WAAA,EAAY;AAC1B,EAAA,MAAM,KAAA,GAAQ,OAAO,CAAC,CAAA;AACtB,EAAA,IAAI,CAAC,KAAA,EAAO,OAAO,SAAS,CAAA,EAAG,CAAA,EAAG,GAAG,CAAC,CAAA;AACtC,EAAA,CAAA,CAAE,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,KAAA,CAAM,CAAC,CAAA;AACzB,EAAA,KAAA,MAAW,CAAA,IAAK,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,IAAK,MAAA,CAAO,CAAA,CAAE,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA;AAClD,EAAA,OAAO,EAAE,KAAA,EAAM;AACjB;AASO,SAAS,YAAA,CACd,CAAA,EACA,OAAA,EACA,KAAA,GAAmB,EAAC,EACL;AACf,EAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,IAAS,UAAA;AAC7B,EAAA,MAAM,MAAA,GAAiB;AAAA,IACrB,KAAA,EAAO,EAAE,KAAA,EAAM;AAAA,IACf,KAAA,EAAO,UAAA;AAAA,IACP,GAAA,EAAK,OAAA;AAAA,IACL,IAAA,EAAM,OAAA;AAAA,IACN,GAAI,KAAA,CAAM,KAAA,GAAQ,EAAE,IAAA,EAAM,CAAC,CAAA,EAAG,CAAC,CAAA,EAAE,GAAI;AAAC,GACxC;AAEA,EAAA,QAAQ,CAAA,CAAE,KAAK,IAAA;AAAM,IACnB,KAAK,MAAA;AACH,MAAA,OAAO;AAAA,QACL,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,QAAA,CAAS,CAAA,CAAE,KAAK,CAAA,EAAG,CAAA,CAAE,IAAA,CAAK,CAAA,EAAG,EAAE,IAAA,CAAK,KAAA,EAAO,EAAE,IAAA,CAAK,MAAM,GAAG,MAAA;AAAO,OAC1F;AAAA,IACF,KAAK,SAAA;AACH,MAAA,OAAO,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,YAAY,CAAA,CAAE,IAAI,CAAA,EAAG,MAAA,EAAQ,CAAA;AAAA,IAC7D,KAAK,MAAA,EAAQ;AACX,MAAA,MAAM,CAAC,CAAA,EAAG,CAAC,CAAA,GAAI,QAAA,CAAS,GAAG,OAAO,CAAA;AAClC,MAAA,OAAO,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,SAAS,CAAA,EAAG,CAAC,CAAA,EAAG,MAAA,EAAQ,CAAA;AAAA,IACxD;AAAA,IACA,KAAK,OAAA,EAAS;AACZ,MAAA,MAAM,CAAC,CAAA,EAAG,CAAC,CAAA,GAAI,QAAA,CAAS,GAAG,OAAO,CAAA;AAKlC,MAAA,MAAM,MAAA,GAAiB,EAAE,GAAG,MAAA,EAAQ,WAAW,OAAA,EAAQ;AACvD,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,CAAA,EAAG,CAAC,CAAA;AAC1B,MAAA,OAAO;AAAA,QACL,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,QAAQ,MAAA,EAAO;AAAA,QACrC,GAAG,kBAAA,CAAmB,IAAA,EAAM,MAAA,EAAQ,YAAY,MAAS;AAAA,OAC3D;AAAA,IACF;AAAA,IACA,KAAK,QAAA;AACH,MAAA,OAAO,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,QAAA,CAAS,QAAA,CAAS,CAAA,EAAG,OAAO,CAAC,CAAA,EAAG,MAAA,EAAQ,CAAA;AAAA,IACxE,KAAK,OAAA,EAAS;AACZ,MAAA,MAAM,MAAA,GAAS,CAAA,CAAE,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AAChC,MAAA,MAAM,CAAA,GAAI,MAAA,GAAS,OAAA,CAAQ,MAAA,EAAQ,OAAO,CAAA,GAAI,EAAE,CAAA,EAAG,CAAA,CAAE,IAAA,CAAK,CAAA,EAAG,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA,EAAE;AACzE,MAAA,MAAM,IAAA,GAAO;AAAA,QACX,CAAA,EAAG,EAAE,CAAA,GAAI,YAAA;AAAA,QACT,CAAA,EAAG,EAAE,CAAA,GAAI,YAAA;AAAA,QACT,OAAO,CAAA,GAAI,YAAA;AAAA,QACX,QAAQ,CAAA,GAAI;AAAA,OACd;AACA,MAAA,OAAO,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,WAAA,CAAY,IAAI,CAAA,EAAG,MAAA,EAAQ,CAAA;AAAA,IAC3D;AAAA,IACA,KAAK,MAAA,EAAQ;AACX,MAAA,MAAM,IAAA,GAAO,EAAE,IAAA,CAAK,KAAA;AACpB,MAAA,IAAI,CAAC,IAAA,EAAM,OAAO,EAAC;AACnB,MAAA,OAAO;AAAA,QACL,WAAA;AAAA,UACE,EAAE,IAAA,CAAK,CAAA;AAAA,UACP,EAAE,IAAA,CAAK,CAAA;AAAA,UACP,IAAA;AAAA,UACA,EAAE,UAAU,SAAA,EAAU;AAAA,UACtB,MAAA;AAAA,UACA,MAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,YACE,IAAA,EAAM,EAAE,KAAA;AAAM;AAChB;AACF,OACF;AAAA,IACF;AAAA;AAEJ;;;ACzIA,IAAM,QAAA,GAAqB,EAAE,IAAA,EAAM,MAAA,EAAO;AAE1C,SAAS,WAAW,KAAA,EAAwC;AAC1D,EAAA,IAAI,CAAC,OAAO,OAAO,QAAA;AACnB,EAAA,IAAI,OAAA,IAAW,KAAA,IAAS,OAAO,KAAA,CAAM,UAAU,QAAA,EAAU;AACvD,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,OAAA;AAAA,MACN,OAAO,KAAA,CAAM,KAAA;AAAA,MACb,GAAI,MAAM,OAAA,IAAW,IAAA,GAAO,EAAE,OAAA,EAAS,KAAA,CAAM,OAAA,EAAQ,GAAI;AAAC,KAC5D;AAAA,EACF;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAM;AACnC;AAKA,SAAS,YAAY,MAAA,EAA2B;AAC9C,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,UAAA,CAAW,MAAA,CAAO,KAAK,CAAA;AAAA,IAC9B,KAAA,EAAO,OAAO,KAAA,IAAS,CAAA;AAAA,IACvB,GAAI,OAAO,GAAA,GAAM,EAAE,KAAK,MAAA,CAAO,GAAA,KAAQ,EAAC;AAAA,IACxC,GAAI,OAAO,IAAA,GAAO,EAAE,MAAM,MAAA,CAAO,IAAA,KAAS,EAAC;AAAA,IAC3C,GAAI,MAAA,CAAO,IAAA,GAAO,EAAE,IAAA,EAAM,CAAC,GAAG,MAAA,CAAO,IAAI,CAAA,EAAE,GAAI,EAAC;AAAA,IAChD,GAAI,OAAO,UAAA,IAAc,IAAA,GAAO,EAAE,UAAA,EAAY,MAAA,CAAO,UAAA,EAAW,GAAI,EAAC;AAAA,IACrE,GAAI,OAAO,KAAA,GAAQ,EAAE,OAAO,MAAA,CAAO,KAAA,KAAU;AAAC,GAChD;AACF;AAEA,SAAS,SAAA,CAAU,KAAkB,CAAA,EAA2B;AAC9D,EAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAQ;AACvB,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,MAAA;AAAA,MACN,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,IAAA,EAAM,UAAA,CAAW,GAAA,CAAI,IAAI,CAAA;AAAA,MACzB,GAAI,GAAA,CAAI,MAAA,GAAS,EAAE,MAAA,EAAQ,YAAY,GAAA,CAAI,MAAM,CAAA,EAAE,GAAI;AAAC,KAC1D;AAAA,EACF;AACA,EAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAQ;AACvB,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,MAAA;AAAA,MACN,GAAG,GAAA,CAAI,CAAA;AAAA,MACP,GAAG,GAAA,CAAI,CAAA;AAAA,MACP,KAAA,EAAO,EAAE,IAAA,CAAK,KAAA;AAAA,MACd,MAAA,EAAQ,EAAE,IAAA,CAAK,MAAA;AAAA,MACf,IAAA,EAAM,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,CAAC,QAAQ,GAAA,CAAI,IAAI,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA;AAAA,MAC7C,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,GAAI,GAAA,CAAI,IAAA,CAAK,CAAC,GAAG,IAAA,GAAO,EAAE,IAAA,EAAM,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,CAAE,IAAA,KAAS;AAAC,KACxD;AAAA,EACF;AAIA,EAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,GAAA,CAAI,IAAI,CAAA,mCAAA,CAAqC,CAAA;AAC1F;AASO,SAAS,YAAA,CACd,CAAA,EACA,OAAA,EACA,KAAA,GAAmB,EAAC,EACT;AACX,EAAA,OAAO,YAAA,CAAa,CAAA,EAAG,OAAA,EAAS,KAAK,CAAA,CAAE,GAAA,CAAI,CAAC,GAAA,KAAQ,SAAA,CAAU,GAAA,EAAK,CAAC,CAAC,CAAA;AACvE","file":"chunk-KHK5FGER.js","sourcesContent":["import type { DrawCommand, Path, Stroke } from '@weasel-js/core';\nimport {\n ellipsePath,\n linePath,\n markerDrawCommands,\n PathBuilder,\n rectPath,\n textCommand,\n} from '@weasel-js/core';\nimport type { WorldRect } from './frac';\nimport type { AnnotationData, FracPoint } from './types';\n\n/** One loud color, not a themed one: a mark sits over the instrument's own\n * picture and has to be legible against whatever that picture is. */\nconst MARK_COLOR = '#e5484d';\n/** World units, so a mark thickens with the picture it annotates — and so the\n * marker geometry can be resolved here, which needs a resolved width. */\nconst MARK_WIDTH = 2;\nconst TEXT_SIZE = 14;\nconst POINT_RADIUS = 4;\n\n/** The subset of a mark's scene node this needs: where it is, and what it is. */\nexport interface PaintableMark {\n pose: WorldRect;\n data: AnnotationData;\n}\n\n/** How a mark is drawn, as opposed to where. Resolved by the overlay from the\n * instrument's vocabulary and the mark's own staleness. */\nexport interface MarkStyle {\n /** The status's color, or the default. */\n color?: string;\n /** A mark whose stored position no longer describes the picture. Drawn\n * dashed rather than hidden: it still describes *something*, and dropping\n * it would lose it. */\n stale?: boolean;\n}\n\nconst toWorld = (p: FracPoint, content: { w: number; h: number }) => ({\n x: p.x * content.w,\n y: p.y * content.h,\n});\n\n/** A mark's stored vertices in world units, or the pose's diagonal — a stored\n * mark whose `points` did not survive still has to draw somewhere. */\nfunction vertices(m: PaintableMark, content: { w: number; h: number }): { x: number; y: number }[] {\n const stored = m.data.points;\n if (stored && stored.length >= 2) return stored.map((p) => toWorld(p, content));\n const { x, y, width, height } = m.pose;\n return [\n { x, y },\n { x: x + width, y: y + height },\n ];\n}\n\nfunction polyline(points: { x: number; y: number }[]): Path {\n const b = new PathBuilder();\n const first = points[0];\n if (!first) return rectPath(0, 0, 0, 0);\n b.moveTo(first.x, first.y);\n for (const p of points.slice(1)) b.lineTo(p.x, p.y);\n return b.build();\n}\n\n/**\n * What one mark draws, in its target's world.\n *\n * Pure: a node and the target's content box in, draw commands out. Geometry\n * that a bounding box cannot describe — a line's ends, a stroke's path — comes\n * from `data.points`, which is in fractions like the bounds.\n */\nexport function markCommands(\n m: PaintableMark,\n content: { w: number; h: number },\n style: MarkStyle = {},\n): DrawCommand[] {\n const color = style.color ?? MARK_COLOR;\n const stroke: Stroke = {\n paint: { color },\n width: MARK_WIDTH,\n cap: 'round',\n join: 'round',\n ...(style.stale ? { dash: [6, 4] } : {}),\n };\n\n switch (m.data.kind) {\n case 'rect':\n return [\n { kind: 'path', path: rectPath(m.pose.x, m.pose.y, m.pose.width, m.pose.height), stroke },\n ];\n case 'ellipse':\n return [{ kind: 'path', path: ellipsePath(m.pose), stroke }];\n case 'line': {\n const [a, b] = vertices(m, content);\n return [{ kind: 'path', path: linePath(a, b), stroke }];\n }\n case 'arrow': {\n const [a, b] = vertices(m, content);\n // The spec's arrow: a line carrying an end marker, not its own geometry.\n // Markers are separate commands — a stroke's `markerEnd` is inert unless\n // something turns it into geometry, and only the kit's own node painter\n // does that, for the nodes it owns.\n const marked: Stroke = { ...stroke, markerEnd: 'arrow' };\n const path = linePath(a, b);\n return [\n { kind: 'path', path, stroke: marked },\n ...markerDrawCommands(path, marked, MARK_WIDTH, undefined),\n ];\n }\n case 'stroke':\n return [{ kind: 'path', path: polyline(vertices(m, content)), stroke }];\n case 'point': {\n const stored = m.data.points?.[0];\n const c = stored ? toWorld(stored, content) : { x: m.pose.x, y: m.pose.y };\n const ring = {\n x: c.x - POINT_RADIUS,\n y: c.y - POINT_RADIUS,\n width: 2 * POINT_RADIUS,\n height: 2 * POINT_RADIUS,\n };\n return [{ kind: 'path', path: ellipsePath(ring), stroke }];\n }\n case 'text': {\n const text = m.data.title;\n if (!text) return [];\n return [\n textCommand(\n m.pose.x,\n m.pose.y,\n text,\n { fontSize: TEXT_SIZE },\n undefined,\n undefined,\n undefined,\n {\n fill: { color },\n },\n ),\n ];\n }\n }\n}\n","import type { DrawCommand, FillStyle, Stroke } from '@weasel-js/core';\nimport type { SvgNode, SvgPaint, SvgStroke } from '@weasel-js/svg';\nimport { type MarkStyle, markCommands, type PaintableMark } from './paint';\n\nconst NO_PAINT: SvgPaint = { kind: 'none' };\n\nfunction toSvgPaint(paint: FillStyle | undefined): SvgPaint {\n if (!paint) return NO_PAINT;\n if ('color' in paint && typeof paint.color === 'string') {\n return {\n kind: 'solid',\n color: paint.color,\n ...(paint.opacity != null ? { opacity: paint.opacity } : {}),\n };\n }\n return { kind: 'gradient', paint };\n}\n\n/** Marker references are deliberately dropped: `markCommands` already resolves\n * a marker into its own path command, and keeping the reference would make\n * the serializer emit a `<marker>` def that draws the head a second time. */\nfunction toSvgStroke(stroke: Stroke): SvgStroke {\n return {\n paint: toSvgPaint(stroke.paint),\n width: stroke.width ?? 1,\n ...(stroke.cap ? { cap: stroke.cap } : {}),\n ...(stroke.join ? { join: stroke.join } : {}),\n ...(stroke.dash ? { dash: [...stroke.dash] } : {}),\n ...(stroke.miterLimit != null ? { miterLimit: stroke.miterLimit } : {}),\n ...(stroke.align ? { align: stroke.align } : {}),\n };\n}\n\nfunction toSvgNode(cmd: DrawCommand, m: PaintableMark): SvgNode {\n if (cmd.kind === 'path') {\n return {\n kind: 'path',\n path: cmd.path,\n fill: toSvgPaint(cmd.fill),\n ...(cmd.stroke ? { stroke: toSvgStroke(cmd.stroke) } : {}),\n };\n }\n if (cmd.kind === 'text') {\n return {\n kind: 'text',\n x: cmd.x,\n y: cmd.y,\n width: m.pose.width,\n height: m.pose.height,\n text: cmd.runs.map((run) => run.text).join(''),\n style: cmd.style,\n ...(cmd.runs[0]?.fill ? { fill: cmd.runs[0].fill } : {}),\n };\n }\n // Unreachable while `markCommands` emits only paths and text. A throw rather\n // than a skip: a new mark kind silently vanishing from every export is a\n // worse afternoon than a loud one.\n throw new Error(`[labkit] a mark drew a '${cmd.kind}' command, which has no vector form`);\n}\n\n/**\n * One mark as SVG nodes, converted from the very commands the pane paints.\n *\n * Deliberately not a second switch over `data.kind`: geometry has one source,\n * and this is a translation of it. `serializeSvg` turns the result into a\n * document.\n */\nexport function markSvgNodes(\n m: PaintableMark,\n content: { w: number; h: number },\n style: MarkStyle = {},\n): SvgNode[] {\n return markCommands(m, content, style).map((cmd) => toSvgNode(cmd, m));\n}\n"]}
|