@weasel-js/labkit 1.6.1 → 1.7.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.
Files changed (256) hide show
  1. package/README.md +3 -3
  2. package/dist/_dts/{CanvasStackContext-Wo6OwIVM.d.ts → CanvasStackContext-Cjy6I-Iv.d.ts} +4 -1
  3. package/dist/_dts/{Stage-DWBBi8IU.d.ts → Stage-D6t7o0pF.d.ts} +59 -18
  4. package/dist/_dts/{index-CKyX0ME_.d.ts → index-BTmaRy6a.d.ts} +10 -6
  5. package/dist/_dts/{types-B7yBTTF9.d.ts → index-DCMA4Fy1.d.ts} +59 -113
  6. package/dist/_dts/{types-DTuViBvc.d.ts → types-BUBSIZuV.d.ts} +18 -8
  7. package/dist/_dts/{useTrialState-CMaV6UD4.d.ts → useTrialState-Bh8bzFgE.d.ts} +1 -1
  8. package/dist/canvas/index.d.ts +8 -6
  9. package/dist/canvas/index.js +6 -6
  10. package/dist/chrome/index.d.ts +6 -4
  11. package/dist/chrome/index.js +11 -10
  12. package/dist/chunk-2ES4W47N.js +8 -0
  13. package/dist/chunk-2ES4W47N.js.map +1 -0
  14. package/dist/{chunk-WPLAANH4.js → chunk-2N7UBSS2.js} +12 -12
  15. package/dist/chunk-2N7UBSS2.js.map +1 -0
  16. package/dist/chunk-4KSC7NXL.js +15491 -0
  17. package/dist/chunk-4KSC7NXL.js.map +1 -0
  18. package/dist/{chunk-SLAQPUI4.js → chunk-CEGFXTBD.js} +10 -63
  19. package/dist/chunk-CEGFXTBD.js.map +1 -0
  20. package/dist/chunk-CZZPXUOU.js +3 -0
  21. package/dist/{chunk-SBXNQW4G.js.map → chunk-CZZPXUOU.js.map} +1 -1
  22. package/dist/{chunk-QGMOA2YE.js → chunk-E23Q6A3Y.js} +296 -104
  23. package/dist/chunk-E23Q6A3Y.js.map +1 -0
  24. package/dist/{chunk-GHGO52SO.js → chunk-E6NARGU7.js} +5 -5
  25. package/dist/{chunk-GHGO52SO.js.map → chunk-E6NARGU7.js.map} +1 -1
  26. package/dist/{chunk-IJJUK4FU.js → chunk-EESJUSYR.js} +5 -6
  27. package/dist/chunk-EESJUSYR.js.map +1 -0
  28. package/dist/{chunk-HXXTULDN.js → chunk-EFXRM6XQ.js} +8 -11
  29. package/dist/chunk-EFXRM6XQ.js.map +1 -0
  30. package/dist/chunk-F4ACIK7Z.js +210 -0
  31. package/dist/chunk-F4ACIK7Z.js.map +1 -0
  32. package/dist/{chunk-6FLXL3I7.js → chunk-FB4MIZOO.js} +77 -45
  33. package/dist/chunk-FB4MIZOO.js.map +1 -0
  34. package/dist/{chunk-AWQG7FCC.js → chunk-FG3EXZDV.js} +3 -3
  35. package/dist/{chunk-AWQG7FCC.js.map → chunk-FG3EXZDV.js.map} +1 -1
  36. package/dist/{chunk-4TT3PNPR.js → chunk-GAHELLJT.js} +95 -95
  37. package/dist/chunk-GAHELLJT.js.map +1 -0
  38. package/dist/{chunk-HKV7LRHY.js → chunk-IBVRMHW5.js} +5 -5
  39. package/dist/{chunk-HKV7LRHY.js.map → chunk-IBVRMHW5.js.map} +1 -1
  40. package/dist/{chunk-ASOK76ZH.js → chunk-JFOJESJF.js} +72 -29
  41. package/dist/chunk-JFOJESJF.js.map +1 -0
  42. package/dist/{chunk-RWNDDKOH.js → chunk-PMLZP7RT.js} +18 -15
  43. package/dist/chunk-PMLZP7RT.js.map +1 -0
  44. package/dist/{chunk-TJ77A4A3.js → chunk-READTDQX.js} +5 -9
  45. package/dist/chunk-READTDQX.js.map +1 -0
  46. package/dist/{chunk-JVBYV6TL.js → chunk-ROGJWDQA.js} +3 -3
  47. package/dist/{chunk-JVBYV6TL.js.map → chunk-ROGJWDQA.js.map} +1 -1
  48. package/dist/{chunk-CGHF6RZV.js → chunk-T6DLGEJB.js} +18 -18
  49. package/dist/chunk-T6DLGEJB.js.map +1 -0
  50. package/dist/{chunk-24W5VEJW.js → chunk-ULYYNWGP.js} +2 -2
  51. package/dist/{chunk-24W5VEJW.js.map → chunk-ULYYNWGP.js.map} +1 -1
  52. package/dist/{chunk-DWMSB4CA.js → chunk-VYVGVBGY.js} +95 -32
  53. package/dist/chunk-VYVGVBGY.js.map +1 -0
  54. package/dist/{chunk-IRTGUQ5O.js → chunk-WLMDTI2Q.js} +16 -6
  55. package/dist/chunk-WLMDTI2Q.js.map +1 -0
  56. package/dist/{chunk-NEXR37YJ.js → chunk-XE5HJOPL.js} +6 -8
  57. package/dist/chunk-XE5HJOPL.js.map +1 -0
  58. package/dist/chunk-XVUKDSYV.js +38 -0
  59. package/dist/chunk-XVUKDSYV.js.map +1 -0
  60. package/dist/{chunk-O6FFFOHS.js → chunk-YCFKW5RX.js} +16 -8
  61. package/dist/chunk-YCFKW5RX.js.map +1 -0
  62. package/dist/{chunk-CQLQPQ4P.js → chunk-ZQIHJXP4.js} +2 -2
  63. package/dist/chunk-ZQIHJXP4.js.map +1 -0
  64. package/dist/config/index.d.ts +28 -13
  65. package/dist/config/index.js +4 -4
  66. package/dist/controls/index.d.ts +4 -7
  67. package/dist/controls/index.js +6 -5
  68. package/dist/dragdrop/index.d.ts +23 -3
  69. package/dist/dragdrop/index.js +4 -3
  70. package/dist/fonts/oswald-tabular-digits.woff2 +0 -0
  71. package/dist/index.d.ts +72 -487
  72. package/dist/index.js +603 -441
  73. package/dist/index.js.map +1 -1
  74. package/dist/job/index.d.ts +8 -0
  75. package/dist/job/index.js +1 -1
  76. package/dist/layers/index.d.ts +6 -5
  77. package/dist/layers/index.js +3 -2
  78. package/dist/loupe/index.d.ts +100 -30
  79. package/dist/loupe/index.js +585 -6
  80. package/dist/loupe/index.js.map +1 -1
  81. package/dist/overview/index.d.ts +4 -2
  82. package/dist/overview/index.js +20 -18
  83. package/dist/overview/index.js.map +1 -1
  84. package/dist/passthrough/weasel-canvas.d.ts +2 -0
  85. package/dist/passthrough/weasel-ui.d.ts +2 -2701
  86. package/dist/passthrough/weasel-ui.js +4 -3
  87. package/dist/primitives/index.d.ts +37 -2
  88. package/dist/primitives/index.js +9 -8
  89. package/dist/state/index.d.ts +7 -5
  90. package/dist/state/index.js +6 -6
  91. package/dist/styles.css +150 -126
  92. package/dist/surface/index.d.ts +10 -2
  93. package/dist/surface/index.js +1 -1
  94. package/dist/undo/index.d.ts +5 -3
  95. package/package.json +14 -13
  96. package/src/annotations/AnnotationOverlay.abandon.test.tsx +143 -0
  97. package/src/annotations/AnnotationOverlay.tsx +52 -33
  98. package/src/annotations/Annotations.less +0 -10
  99. package/src/annotations/Annotations.overlay.test.tsx +31 -0
  100. package/src/annotations/MarkList.tsx +4 -8
  101. package/src/annotations/capture.browser.test.ts +41 -0
  102. package/src/annotations/capture.ts +14 -7
  103. package/src/annotations/drawOne.ts +2 -2
  104. package/src/annotations/frac.test.ts +44 -1
  105. package/src/annotations/frac.ts +46 -18
  106. package/src/annotations/index.ts +1 -0
  107. package/src/annotations/paint.test.ts +76 -46
  108. package/src/annotations/paint.ts +65 -43
  109. package/src/annotations/store.test.ts +212 -2
  110. package/src/annotations/store.ts +130 -27
  111. package/src/annotations/svgNodes.test.ts +28 -19
  112. package/src/annotations/svgNodes.ts +6 -6
  113. package/src/annotations/types.ts +29 -10
  114. package/src/canvas/AGENTS.md +1 -0
  115. package/src/canvas/CameraInput.test.tsx +30 -0
  116. package/src/canvas/CameraInput.tsx +60 -48
  117. package/src/canvas/CanvasStack.tsx +11 -6
  118. package/src/canvas/CanvasStackContext.ts +4 -1
  119. package/src/canvas/LinkedCursor.less +1 -1
  120. package/src/canvas/Stage.test.tsx +33 -4
  121. package/src/canvas/Stage.tsx +9 -4
  122. package/src/canvas/cameraRegistry.test.ts +55 -0
  123. package/src/canvas/cameraRegistry.ts +87 -0
  124. package/src/canvas/cameraZoom.test.ts +46 -0
  125. package/src/canvas/cameraZoom.ts +24 -0
  126. package/src/canvas/index.ts +14 -2
  127. package/src/canvas/sharedScope.test.tsx +94 -0
  128. package/src/canvas/worldSpec.ts +3 -1
  129. package/src/chrome/ChromeRegions.stories.tsx +1 -0
  130. package/src/chrome/builtins.test.ts +7 -6
  131. package/src/chrome/builtins.tsx +5 -1
  132. package/src/chrome/index.ts +1 -1
  133. package/src/chrome/merge.test.ts +5 -0
  134. package/src/chrome/merge.ts +4 -2
  135. package/src/chrome/regions/PaletteRegion.less +0 -7
  136. package/src/chrome/regions/PaletteRegion.test.tsx +2 -3
  137. package/src/chrome/regions/PaletteRegion.tsx +3 -4
  138. package/src/chrome/regions/SidebarRegion.less +12 -2
  139. package/src/chrome/regions/ViewportRegion.browser.test.less +6 -0
  140. package/src/chrome/regions/ViewportRegion.browser.test.tsx +38 -0
  141. package/src/chrome/regions/ViewportRegion.less +6 -0
  142. package/src/chrome/regions/ViewportRegion.tsx +10 -4
  143. package/src/chrome/types.ts +4 -2
  144. package/src/config/auto.ts +1 -0
  145. package/src/config/builder.test.ts +2 -1
  146. package/src/config/builder.ts +18 -5
  147. package/src/config/fromConfigField.test.ts +14 -0
  148. package/src/config/fromConfigField.ts +18 -4
  149. package/src/config/path.ts +2 -5
  150. package/src/config/resolve.ts +4 -0
  151. package/src/config/types.ts +14 -9
  152. package/src/controls/ControlPanel.less +1 -1
  153. package/src/controls/ControlPanel.stories.tsx +3 -2
  154. package/src/controls/ControlPanel.test.tsx +98 -11
  155. package/src/controls/ControlPanel.tsx +61 -2
  156. package/src/dragdrop/DragDropRuntime.tsx +22 -13
  157. package/src/dragdrop/DragGhost.tsx +3 -0
  158. package/src/dragdrop/Palette.tsx +2 -0
  159. package/src/index.test.ts +5 -0
  160. package/src/index.ts +16 -2
  161. package/src/instrument/types.ts +0 -6
  162. package/src/job/useJob.ts +14 -9
  163. package/src/lab/Lab.tsx +88 -73
  164. package/src/lab/{LabFit.stories.less → LabFit.browser.test.less} +1 -1
  165. package/src/lab/{LabFit.stories.tsx → LabFit.browser.test.tsx} +41 -63
  166. package/src/lab/LabFullChrome.stories.tsx +1 -0
  167. package/src/lab/LabHeader.test.tsx +24 -14
  168. package/src/lab/LabHeader.tsx +11 -12
  169. package/src/lab/LabShell.less +9 -17
  170. package/src/lab/LabSwitcher.browser.test.tsx +27 -0
  171. package/src/lab/LabSwitcher.less +8 -6
  172. package/src/lab/LabZoom.test.tsx +223 -0
  173. package/src/lab/LabZoom.tsx +170 -0
  174. package/src/lab/Workspace.tsx +48 -52
  175. package/src/lab/index.ts +1 -0
  176. package/src/loupe/AGENTS.md +28 -15
  177. package/src/loupe/CanvasLoupe.tsx +2 -3
  178. package/src/loupe/DomLoupe.tsx +1 -7
  179. package/src/loupe/Loupe.less +16 -0
  180. package/src/loupe/LoupeGestures.tsx +1 -1
  181. package/src/loupe/TrialLoupe.tsx +120 -57
  182. package/src/loupe/index.ts +1 -6
  183. package/src/loupe/types.test.ts +3 -3
  184. package/src/loupe/types.ts +24 -27
  185. package/src/loupe/useLoupe.test.tsx +29 -4
  186. package/src/loupe/useLoupe.ts +20 -17
  187. package/src/overview/OverviewMarks.tsx +12 -4
  188. package/src/overview/TrialOverview.tsx +10 -8
  189. package/src/passthrough/weasel-ui.test.ts +2 -0
  190. package/src/passthrough/weasel-ui.ts +17 -5
  191. package/src/primitives/FloatingPanel.test.tsx +11 -0
  192. package/src/primitives/FloatingPanel.tsx +8 -7
  193. package/src/primitives/JobProgress.less +2 -1
  194. package/src/primitives/Legend.stories.tsx +1 -0
  195. package/src/primitives/Readout.browser.test.tsx +137 -0
  196. package/src/primitives/Readout.less +12 -0
  197. package/src/primitives/Readout.stories.tsx +58 -0
  198. package/src/primitives/Readout.test.tsx +93 -0
  199. package/src/primitives/Readout.tsx +56 -0
  200. package/src/primitives/Split.tsx +69 -41
  201. package/src/primitives/Toolbar.tsx +3 -3
  202. package/src/primitives/ZoomControl.less +1 -2
  203. package/src/primitives/index.ts +2 -0
  204. package/src/specimen/Specimen.stories.tsx +1 -0
  205. package/src/specimen/Specimen.tsx +2 -3
  206. package/src/state/Persistence.browser.test.tsx +47 -0
  207. package/src/state/store.test.ts +5 -1
  208. package/src/state/undock.ts +3 -0
  209. package/src/state/useOpenOnce.ts +20 -16
  210. package/src/state/usePersistedState.test.tsx +1 -1
  211. package/src/state/view.ts +1 -0
  212. package/src/styles.less +1 -0
  213. package/src/surface/index.ts +1 -1
  214. package/src/surface/useTiledSurface.test.tsx +14 -0
  215. package/src/surface/useTiledSurface.ts +11 -3
  216. package/src/theme/Interstellar.stories.tsx +3 -1
  217. package/src/theme/base.less +21 -47
  218. package/src/theme/interstellar.test.ts +1 -1
  219. package/src/theme/interstellar.theme.json +10 -3
  220. package/src/trial/Trial.annotations.test.tsx +73 -0
  221. package/src/trial/Trial.less +0 -29
  222. package/src/trial/Trial.loupe.test.tsx +28 -11
  223. package/src/trial/Trial.tsx +85 -67
  224. package/src/trial/TrialChrome.tsx +27 -6
  225. package/src/trial/index.ts +2 -0
  226. package/src/trial/loupeSwitch.ts +15 -0
  227. package/dist/_dts/LayerList.d-BoELAMsM.d.ts +0 -83
  228. package/dist/_dts/PrefsRow.d-DFpPIeIC.d.ts +0 -39
  229. package/dist/_dts/PropertyField.d-D0ndfIIt.d.ts +0 -404
  230. package/dist/_dts/Select.d-Cr8-zoup.d.ts +0 -569
  231. package/dist/chunk-4TT3PNPR.js.map +0 -1
  232. package/dist/chunk-6FLXL3I7.js.map +0 -1
  233. package/dist/chunk-ASOK76ZH.js.map +0 -1
  234. package/dist/chunk-CGHF6RZV.js.map +0 -1
  235. package/dist/chunk-CQLQPQ4P.js.map +0 -1
  236. package/dist/chunk-DWMSB4CA.js.map +0 -1
  237. package/dist/chunk-HXXTULDN.js.map +0 -1
  238. package/dist/chunk-IJJUK4FU.js.map +0 -1
  239. package/dist/chunk-IRTGUQ5O.js.map +0 -1
  240. package/dist/chunk-KHK5FGER.js +0 -145
  241. package/dist/chunk-KHK5FGER.js.map +0 -1
  242. package/dist/chunk-NEXR37YJ.js.map +0 -1
  243. package/dist/chunk-O6FFFOHS.js.map +0 -1
  244. package/dist/chunk-QGMOA2YE.js.map +0 -1
  245. package/dist/chunk-RWNDDKOH.js.map +0 -1
  246. package/dist/chunk-S4NCI32V.js +0 -549
  247. package/dist/chunk-S4NCI32V.js.map +0 -1
  248. package/dist/chunk-SBXNQW4G.js +0 -3
  249. package/dist/chunk-SLAQPUI4.js.map +0 -1
  250. package/dist/chunk-TJ77A4A3.js.map +0 -1
  251. package/dist/chunk-TYN6MLXX.js +0 -13864
  252. package/dist/chunk-TYN6MLXX.js.map +0 -1
  253. package/dist/chunk-WPLAANH4.js.map +0 -1
  254. package/src/primitives/useRovingTabIndex.test.ts +0 -48
  255. package/src/primitives/useRovingTabIndex.ts +0 -88
  256. package/src/state/Persistence.stories.tsx +0 -75
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/state/helpers.ts","../src/state/adapters.ts","../src/state/labRecords.ts","../src/state/records.ts","../src/state/useOpenOnce.ts","../src/state/Persistence.tsx","../src/state/usePersistedState.ts"],"names":["useState"],"mappings":"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","file":"chunk-RWNDDKOH.js","sourcesContent":["import type { InstrumentSerializers, SerializedTrial, TrialRecord, UndoStack } from './types';\n\n/** The storage key a lab writes one of its buckets under. Namespaced by\n * `storageKey` so two labs sharing an origin do not collide. */\nexport function labStorageKey(\n storageKey: string,\n bucket: 'workspaces' | 'saves' | 'theme' | 'layout',\n): string {\n return `lk:${storageKey}:${bucket}`;\n}\n\n/** Encode a string for the URL fragment. */\nexport function encodeUrlHash(value: string): string {\n return btoa(encodeURIComponent(value));\n}\n\n/** Decode a URL fragment written by `encodeUrlHash`, or `null` if it is\n * malformed. */\nexport function decodeUrlHash(hash: string): string | null {\n if (!hash) return null;\n try {\n return decodeURIComponent(atob(hash));\n } catch {\n return null;\n }\n}\n\n/**\n * An id for a trial or a snapshot.\n *\n * `crypto.randomUUID` exists only in a secure context, and a LAN address is\n * not one — so a lab opened on a phone or a tablet by IP throws on its first\n * render and shows a blank page with nothing in reach to say why. The counter\n * is per page load, which is all these ids have to survive: they name records\n * inside one session's store, and a saved snapshot carries its own name.\n */\nlet idCounter = 0;\nexport function newId(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (c && typeof c.randomUUID === 'function') return c.randomUUID();\n return `lk-${Date.now().toString(36)}-${idCounter++}`;\n}\n\n/** A fresh, empty undo history. */\nexport function emptyUndoStack(): UndoStack {\n return { past: [], future: [] };\n}\n\n/** Serialize trials for storage, running each instrument's own serializer\n * over its state. Undo history is deliberately dropped — it does not survive\n * a reload. */\nexport function serializeTrials(\n trials: TrialRecord[],\n serializers: InstrumentSerializers,\n): SerializedTrial[] {\n return trials.map(({ undoStack: _undo, ...w }) => {\n const s = serializers[w.instrumentName];\n return { ...w, state: s?.serialize ? s.serialize(w.state) : w.state };\n });\n}\n\n/** Rebuild trials from storage, running each instrument's deserializer\n * over its state and starting each with an empty undo history. Returns an\n * empty list rather than throwing on malformed input. */\nexport function deserializeTrials(\n records: SerializedTrial[],\n deserializers: InstrumentSerializers,\n): TrialRecord[] {\n if (!Array.isArray(records)) {\n console.warn('[labkit] deserializeTrials: not an array, returning empty list');\n return [];\n }\n return records.map((r) => {\n const d = deserializers[r.instrumentName];\n return {\n ...r,\n state: d?.deserialize ? d.deserialize(r.state, r.config) : r.state,\n undoStack: emptyUndoStack(),\n };\n });\n}\n","import { decodeUrlHash, encodeUrlHash } from './helpers';\nimport type { StorageAdapter, StorageChange } from './types';\n\n/** JSON-backed substrates held raw strings before records existed — a theme\n * bucket stored `dark`, not `\"dark\"` — so an unparseable value comes back as\n * the string it is. */\nfunction parse(raw: string): unknown {\n try {\n return JSON.parse(raw);\n } catch {\n return raw;\n }\n}\n\n/** Whether `JSON.stringify` would keep `value` exactly. An object key holding\n * `undefined` counts as kept: JSON drops the key, and reading back an absent\n * key yields the same `undefined`. */\nfunction isJsonSafe(value: unknown, seen: Set<object> = new Set()): boolean {\n if (value === null) return true;\n switch (typeof value) {\n case 'string':\n case 'boolean':\n return true;\n case 'number':\n return Number.isFinite(value);\n case 'object': {\n if (seen.has(value)) return false;\n seen.add(value);\n const proto = Object.getPrototypeOf(value);\n const ok = Array.isArray(value)\n ? value.every((v) => isJsonSafe(v, seen))\n : (proto === Object.prototype || proto === null) &&\n Object.values(value).every((v) => v === undefined || isJsonSafe(v, seen));\n seen.delete(value);\n return ok;\n }\n default:\n return false;\n }\n}\n\nfunction webStorageAdapter(area: () => Storage, name: string, crossTab: boolean): StorageAdapter {\n const warned = new Set<string>();\n const adapter: StorageAdapter = {\n get: async (key) => {\n const raw = area().getItem(key);\n return raw === null ? undefined : parse(raw);\n },\n list: async (prefix) => {\n const store = area();\n const out: [string, unknown][] = [];\n for (let i = 0; i < store.length; i++) {\n const key = store.key(i);\n if (key === null || !key.startsWith(prefix)) continue;\n const raw = store.getItem(key);\n if (raw !== null) out.push([key, parse(raw)]);\n }\n return out;\n },\n set: async (key, value) => {\n if (!warned.has(key) && !isJsonSafe(value)) {\n warned.add(key);\n console.warn(\n `[labkit] \"${key}\" holds a value JSON cannot keep exactly; ${name} stores what JSON keeps. Use IndexedDB for binary or non-JSON state.`,\n );\n }\n area().setItem(key, JSON.stringify(value));\n },\n delete: async (key) => {\n area().removeItem(key);\n },\n };\n if (crossTab) {\n adapter.subscribe = (prefix, on) => {\n if (typeof window === 'undefined') return () => {};\n const handler = (e: StorageEvent): void => {\n if (e.key === null || !e.key.startsWith(prefix)) return;\n if (e.storageArea !== area()) return;\n on([[e.key, e.newValue === null ? undefined : parse(e.newValue)]]);\n };\n window.addEventListener('storage', handler);\n return () => window.removeEventListener('storage', handler);\n };\n }\n return adapter;\n}\n\n/** Persist to `localStorage`, one JSON value per record. Survives a reload and\n * reaches other tabs through the `storage` event. */\nexport const localStorageAdapter: StorageAdapter = webStorageAdapter(\n () => localStorage,\n 'localStorage',\n true,\n);\n\n/** Persist to `sessionStorage` — survives a reload but not a new tab. */\nexport const sessionStorageAdapter: StorageAdapter = webStorageAdapter(\n () => sessionStorage,\n 'sessionStorage',\n false,\n);\n\nconst URL_HASH_GUARD = typeof window !== 'undefined';\n\nfunction readHashMap(): Record<string, string> {\n if (!URL_HASH_GUARD) return {};\n const raw = decodeUrlHash(window.location.hash.replace(/^#/, ''));\n if (!raw) return {};\n try {\n return JSON.parse(raw) as Record<string, string>;\n } catch {\n return {};\n }\n}\n\n/** What each live subscription last saw, refreshed on this page's own writes\n * so `hashchange` reports only somebody else's. */\nconst hashSubscribers = new Set<{ last: Record<string, string> }>();\n\nfunction writeHashMap(map: Record<string, string>): void {\n if (!URL_HASH_GUARD) return;\n const encoded = encodeUrlHash(JSON.stringify(map));\n window.history.replaceState(null, '', `#${encoded}`);\n for (const sub of hashSubscribers) sub.last = { ...map };\n}\n\n/** Persist into the URL fragment, so the page's link carries its state and can\n * be shared or bookmarked. Changes to the fragment made elsewhere — a pasted\n * link, back and forward — arrive through `hashchange`. */\nexport const urlHashAdapter: StorageAdapter = {\n get: async (key) => {\n const raw = readHashMap()[key];\n return raw === undefined ? undefined : parse(raw);\n },\n list: async (prefix) =>\n Object.entries(readHashMap())\n .filter(([key]) => key.startsWith(prefix))\n .map(([key, raw]): [string, unknown] => [key, parse(raw)]),\n set: async (key, value) => {\n const map = readHashMap();\n map[key] = JSON.stringify(value);\n writeHashMap(map);\n },\n delete: async (key) => {\n const map = readHashMap();\n delete map[key];\n writeHashMap(map);\n },\n subscribe: (prefix, on) => {\n if (!URL_HASH_GUARD) return () => {};\n const sub = { last: readHashMap() };\n hashSubscribers.add(sub);\n const handler = (): void => {\n const next = readHashMap();\n const changes: StorageChange[] = [];\n for (const key of new Set([...Object.keys(sub.last), ...Object.keys(next)])) {\n if (!key.startsWith(prefix) || sub.last[key] === next[key]) continue;\n const raw = next[key];\n changes.push([key, raw === undefined ? undefined : parse(raw)]);\n }\n sub.last = next;\n if (changes.length > 0) on(changes);\n };\n window.addEventListener('hashchange', handler);\n return () => {\n hashSubscribers.delete(sub);\n window.removeEventListener('hashchange', handler);\n };\n },\n};\n\ninterface MemorySubscriber {\n owner: StorageAdapter;\n prefix: string;\n on: (changes: StorageChange[]) => void;\n}\n\nconst memorySubscribers = new WeakMap<Map<string, unknown>, Set<MemorySubscriber>>();\n\n/** An in-memory store, discarded on reload. Values are copied in and out, as a\n * real substrate would. Adapters built over one shared `backing` hear each\n * other's writes — two tabs, for a test. */\nexport function createMemoryAdapter(backing: Map<string, unknown> = new Map()): StorageAdapter {\n let subscribers = memorySubscribers.get(backing);\n if (!subscribers) {\n subscribers = new Set();\n memorySubscribers.set(backing, subscribers);\n }\n const peers = subscribers;\n const notify = (key: string, value: unknown): void => {\n for (const sub of peers) {\n if (sub.owner === adapter || !key.startsWith(sub.prefix)) continue;\n const copy = value === undefined ? undefined : structuredClone(value);\n queueMicrotask(() => sub.on([[key, copy]]));\n }\n };\n const adapter: StorageAdapter = {\n get: async (key) => (backing.has(key) ? structuredClone(backing.get(key)) : undefined),\n list: async (prefix) =>\n [...backing]\n .filter(([key]) => key.startsWith(prefix))\n .map(([key, value]): [string, unknown] => [key, structuredClone(value)]),\n set: async (key, value) => {\n const copy = structuredClone(value);\n backing.set(key, copy);\n notify(key, copy);\n },\n delete: async (key) => {\n backing.delete(key);\n notify(key, undefined);\n },\n subscribe: (prefix, on) => {\n const sub = { owner: adapter, prefix, on };\n peers.add(sub);\n return () => {\n peers.delete(sub);\n };\n },\n };\n return adapter;\n}\n\n/** Persists nothing and reads back nothing. */\nexport const noneAdapter: StorageAdapter = {\n get: async () => undefined,\n list: async () => [],\n set: async () => {},\n delete: async () => {},\n};\n\n/** Options for `createIndexedDbAdapter`. */\nexport interface IndexedDbAdapterOptions {\n /** Default `'labkit'`. */\n database?: string;\n /** Default `'records'`. One object store per database: a store added to a\n * database that already exists is not created. */\n store?: string;\n}\n\ninterface NodeChannel extends BroadcastChannel {\n unref?: () => void;\n}\n\n/** Persist to IndexedDB, which stores structured-clone values natively — typed\n * arrays, `Map`s, `Blob`s — and holds far more than localStorage. Other tabs\n * hear writes through a `BroadcastChannel`. The database opens on first use. */\nexport function createIndexedDbAdapter({\n database = 'labkit',\n store = 'records',\n}: IndexedDbAdapterOptions = {}): StorageAdapter {\n let opened: Promise<IDBDatabase> | null = null;\n const open = (): Promise<IDBDatabase> => {\n opened ??= new Promise((resolve, reject) => {\n if (typeof indexedDB === 'undefined') {\n reject(new Error('[labkit] IndexedDB is not available here'));\n return;\n }\n const request = indexedDB.open(database, 1);\n request.onupgradeneeded = () => {\n if (!request.result.objectStoreNames.contains(store)) {\n request.result.createObjectStore(store);\n }\n };\n request.onsuccess = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(store)) {\n reject(new Error(`[labkit] IndexedDB database \"${database}\" has no store \"${store}\"`));\n return;\n }\n resolve(db);\n };\n request.onerror = () => reject(request.error);\n request.onblocked = () => reject(new Error(`[labkit] IndexedDB \"${database}\" is blocked`));\n });\n return opened;\n };\n\n const run = <T>(mode: IDBTransactionMode, body: (s: IDBObjectStore) => () => T): Promise<T> =>\n open().then(\n (db) =>\n new Promise<T>((resolve, reject) => {\n const tx = db.transaction(store, mode);\n const result = body(tx.objectStore(store));\n tx.oncomplete = () => resolve(result());\n tx.onerror = () => reject(tx.error);\n tx.onabort = () => reject(tx.error);\n }),\n );\n\n let channel: NodeChannel | null = null;\n const getChannel = (): NodeChannel | null => {\n if (typeof BroadcastChannel === 'undefined') return null;\n if (!channel) {\n channel = new BroadcastChannel(`labkit:${database}:${store}`) as NodeChannel;\n // Node keeps its event loop alive for an open channel; a browser has no unref.\n channel.unref?.();\n }\n return channel;\n };\n const announce = (changes: StorageChange[]): void => {\n getChannel()?.postMessage(changes);\n };\n\n const adapter: StorageAdapter = {\n get: (key) =>\n run('readonly', (s) => {\n const request = s.get(key);\n return () => request.result as unknown;\n }),\n list: (prefix) =>\n run('readonly', (s) => {\n const range = IDBKeyRange.bound(prefix, `${prefix}￿`);\n const keys = s.getAllKeys(range);\n const values = s.getAll(range);\n return () =>\n keys.result.map((key, i): [string, unknown] => [String(key), values.result[i]]);\n }),\n set: async (key, value) => {\n await run('readwrite', (s) => {\n s.put(value, key);\n return () => undefined;\n });\n announce([[key, value]]);\n },\n delete: async (key) => {\n await run('readwrite', (s) => {\n s.delete(key);\n return () => undefined;\n });\n announce([[key, undefined]]);\n },\n };\n if (typeof BroadcastChannel !== 'undefined') {\n adapter.subscribe = (prefix, on) => {\n const ch = getChannel();\n if (!ch) return () => {};\n const handler = (e: MessageEvent<StorageChange[]>): void => {\n const mine = e.data.filter(([key]) => key.startsWith(prefix));\n if (mine.length > 0) on(mine);\n };\n ch.addEventListener('message', handler);\n return () => ch.removeEventListener('message', handler);\n };\n }\n return adapter;\n}\n\n/** IndexedDB under the default database and store. */\nexport const indexedDbAdapter: StorageAdapter = createIndexedDbAdapter();\n\nlet resolvedDefault: Promise<StorageAdapter> | null = null;\n\n/** What a lab given only a `storageKey` persists to: IndexedDB, or\n * localStorage — with a warning — where IndexedDB will not open. */\nexport function defaultStorage(): Promise<StorageAdapter> {\n resolvedDefault ??= indexedDbAdapter.list('\u0000').then(\n () => indexedDbAdapter,\n (error) => {\n console.warn('[labkit] IndexedDB would not open; persisting to localStorage instead', error);\n return localStorageAdapter;\n },\n );\n return resolvedDefault;\n}\n\n/** Forget which default was chosen. Tests only. */\nexport function resetDefaultStorage(): void {\n resolvedDefault = null;\n}\n","import type { LabDocument, SavedSnapshot, SerializedTrial } from './types';\n\n/** Every record of the lab stored under `storageKey` starts with this. The key\n * is URI-encoded, so it holds no `:` and one lab's prefix can never reach into\n * another lab's records. */\nexport function labPrefix(storageKey: string): string {\n return `lk:${encodeURIComponent(storageKey)}:`;\n}\n\nexport const META_RECORD = 'meta';\nexport const LAYOUT_RECORD = 'layout';\nexport const UNDOCK_RECORD = 'undock';\n\nexport function trialRecord(id: string): string {\n return `trial:${encodeURIComponent(id)}`;\n}\n\nexport function saveRecord(id: string): string {\n return `save:${encodeURIComponent(id)}`;\n}\n\n/** The prefix every value scoped to one trial shares. */\nexport function trialValuesPrefix(trialId: string): string {\n return `value:trial:${encodeURIComponent(trialId)}:`;\n}\n\n/** Where a `usePersistedState` value lives: under its trial, or — with a null\n * trial — under the lab. */\nexport function valueRecord(trialId: string | null, name: string): string {\n const encoded = encodeURIComponent(name);\n return trialId === null ? `value:lab:${encoded}` : `${trialValuesPrefix(trialId)}${encoded}`;\n}\n\n/** What a record name addresses, or null for a name no lab writes. */\nexport type RecordName =\n | { kind: 'meta' | 'layout' | 'undock' | 'value' }\n | { kind: 'trial' | 'save'; id: string };\n\nexport function parseRecordName(name: string): RecordName | null {\n const parts = name.split(':');\n try {\n switch (parts[0]) {\n case 'meta':\n case 'layout':\n case 'undock':\n return parts.length === 1 ? { kind: parts[0] } : null;\n case 'trial':\n case 'save':\n return parts.length === 2 && parts[1]\n ? { kind: parts[0], id: decodeURIComponent(parts[1]) }\n : null;\n case 'value':\n return (parts[1] === 'lab' && parts.length === 3) ||\n (parts[1] === 'trial' && parts.length === 4)\n ? { kind: 'value' }\n : null;\n default:\n return null;\n }\n } catch {\n return null;\n }\n}\n\n/** The fields of the meta record. */\nexport interface LabMeta {\n version: number;\n mode: unknown;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\n/** A document as the records a lab stores it in, `meta` last — so a write in\n * this order that stops partway leaves no `meta`, and the next open folds the\n * old storage again rather than trusting a partial set. */\nexport function recordsOfDocument(doc: LabDocument): [string, unknown][] {\n return [\n ...doc.trials.map((t, order): [string, unknown] => [trialRecord(t.id), { ...t, order }]),\n ...doc.saves.map((s): [string, unknown] => [saveRecord(s.id), s]),\n [LAYOUT_RECORD, doc.layout],\n [UNDOCK_RECORD, doc.undockedPanels],\n [META_RECORD, { version: doc.version, mode: doc.mode } satisfies LabMeta],\n ];\n}\n\n/** Records joined back into an unmigrated document, with each trial's stored\n * order. Null when there is no `meta` record — no lab has been stored here in\n * this form. */\nexport function documentOfRecords(\n entries: Iterable<[string, unknown]>,\n): { doc: Record<string, unknown>; orders: Map<string, number> } | null {\n let meta: unknown;\n let layout: unknown;\n let undock: unknown;\n const trials: { trial: SerializedTrial; order: number }[] = [];\n const saves: SavedSnapshot[] = [];\n\n for (const [name, value] of entries) {\n const parsed = parseRecordName(name);\n if (!parsed) continue;\n switch (parsed.kind) {\n case 'meta':\n meta = value;\n break;\n case 'layout':\n layout = value;\n break;\n case 'undock':\n undock = value;\n break;\n case 'trial':\n if (isObject(value)) {\n const { order, ...rest } = value;\n trials.push({\n trial: { ...rest, id: parsed.id } as SerializedTrial,\n order: typeof order === 'number' && Number.isFinite(order) ? order : Infinity,\n });\n }\n break;\n case 'save':\n if (isObject(value)) saves.push({ ...value, id: parsed.id } as SavedSnapshot);\n break;\n }\n }\n if (!isObject(meta)) return null;\n\n trials.sort(compareTrialOrder);\n const orders = new Map<string, number>();\n let next = 0;\n for (const { trial, order } of trials) {\n const at = Number.isFinite(order) ? order : next;\n orders.set(trial.id, at);\n next = Math.max(next, at + 1);\n }\n saves.sort((a, b) => a.savedAt - b.savedAt);\n\n return {\n doc: {\n version: meta.version,\n mode: meta.mode,\n trials: trials.map((t) => t.trial),\n saves,\n layout,\n undockedPanels: undock,\n },\n orders,\n };\n}\n\n/** Stored order first; two trials added at once in two tabs can share an\n * order, so the id breaks the tie the same way everywhere. */\nexport function compareTrialOrder(\n a: { trial: { id: string }; order: number },\n b: { trial: { id: string }; order: number },\n): number {\n if (a.order !== b.order) return a.order < b.order ? -1 : 1;\n return a.trial.id < b.trial.id ? -1 : a.trial.id > b.trial.id ? 1 : 0;\n}\n","import type { StorageAdapter, StorageChange } from './types';\n\n/** One record changing, as a cache listener hears it. `value` is `undefined`\n * for a delete. `local` changes were made through this cache; `remote` ones\n * came from another writer. */\nexport interface RecordChange {\n name: string;\n value: unknown;\n origin: 'local' | 'remote';\n}\n\n/**\n * Every record under one prefix, held in memory: the only thing that talks to\n * a `StorageAdapter`. Names are keys with the prefix removed.\n *\n * Writes land in memory at once and reach storage on a debounce. The newest\n * write to a record wins: another writer's change to a record with a write\n * still queued here is ignored, since the queued write lands after it.\n */\nexport interface RecordCache {\n readonly prefix: string;\n /** False once writing is off — the records could not be read, or were\n * written by a newer labkit — so nothing here can overwrite them. */\n readonly writable: boolean;\n has(name: string): boolean;\n get(name: string): unknown;\n /** Every record whose name starts with `namePrefix`. */\n entries(namePrefix?: string): [string, unknown][];\n set(name: string, value: unknown): void;\n delete(name: string): void;\n subscribe(listener: (changes: RecordChange[]) => void): () => void;\n /** Send queued writes now. */\n flush(): Promise<void>;\n /** Send queued writes and stop hearing other writers. */\n close(): Promise<void>;\n}\n\n/** The parts of a cache only its opener uses. */\nexport interface OwnedRecordCache extends RecordCache {\n /** Hold these records without writing them back. */\n seed(entries: Iterable<[string, unknown]>): void;\n stopWriting(): void;\n}\n\n/** Options for `createRecordCache` and `openRecords`. */\nexport interface RecordCacheOptions {\n storage: StorageAdapter;\n prefix: string;\n /** Trailing debounce on writes. Default 300 ms. */\n debounceMs?: number;\n /** The longest a write waits under continuous change. Default 1000 ms. */\n maxWaitMs?: number;\n}\n\nconst DELETED = Symbol('deleted');\n\n/** A cache holding `initial`, with nothing read from storage. */\nexport function createRecordCache(\n options: RecordCacheOptions & { initial?: Iterable<[string, unknown]>; writable?: boolean },\n): OwnedRecordCache {\n const { storage, prefix } = options;\n const debounceMs = options.debounceMs ?? 300;\n const maxWaitMs = options.maxWaitMs ?? 1000;\n const values = new Map<string, unknown>(options.initial ?? []);\n const queued = new Map<string, unknown>();\n const listeners = new Set<(changes: RecordChange[]) => void>();\n let writable = options.writable ?? true;\n let closed = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let firstQueuedAt: number | null = null;\n\n const emit = (changes: RecordChange[]): void => {\n for (const listener of [...listeners]) listener(changes);\n };\n\n const schedule = (): void => {\n if (!writable || closed) return;\n const now = Date.now();\n firstQueuedAt ??= now;\n if (timer) clearTimeout(timer);\n const wait = Math.max(0, Math.min(debounceMs, firstQueuedAt + maxWaitMs - now));\n timer = setTimeout(() => {\n timer = null;\n void flush();\n }, wait);\n };\n\n async function flush(): Promise<void> {\n if (timer) clearTimeout(timer);\n timer = null;\n firstQueuedAt = null;\n if (!writable || queued.size === 0) return;\n const batch = [...queued];\n queued.clear();\n await Promise.all(\n batch.map(async ([name, value]) => {\n const key = prefix + name;\n try {\n if (value === DELETED) await storage.delete(key);\n else await storage.set(key, value);\n } catch (error) {\n console.warn(`[labkit] could not write \"${key}\"; keeping it in memory`, error);\n }\n }),\n );\n }\n\n const applyRemote = (changes: StorageChange[]): void => {\n const applied: RecordChange[] = [];\n for (const [key, value] of changes) {\n if (!key.startsWith(prefix)) continue;\n const name = key.slice(prefix.length);\n if (queued.has(name)) continue;\n if (value === undefined) {\n if (!values.has(name)) continue;\n values.delete(name);\n } else {\n values.set(name, value);\n }\n applied.push({ name, value, origin: 'remote' });\n }\n if (applied.length > 0) emit(applied);\n };\n\n const unsubscribe = writable ? storage.subscribe?.(prefix, applyRemote) : undefined;\n\n const onPageHide = (): void => {\n void flush();\n };\n const onVisibility = (): void => {\n if (document.visibilityState === 'hidden') void flush();\n };\n if (typeof window !== 'undefined') {\n window.addEventListener('pagehide', onPageHide);\n document.addEventListener('visibilitychange', onVisibility);\n }\n\n const cache: OwnedRecordCache & { applyRemote: typeof applyRemote } = {\n prefix,\n get writable() {\n return writable;\n },\n has: (name) => values.has(name),\n get: (name) => values.get(name),\n entries: (namePrefix = '') => [...values].filter(([name]) => name.startsWith(namePrefix)),\n set: (name, value) => {\n values.set(name, value);\n queued.set(name, value);\n emit([{ name, value, origin: 'local' }]);\n schedule();\n },\n delete: (name) => {\n if (!values.has(name) && !queued.has(name)) return;\n values.delete(name);\n queued.set(name, DELETED);\n emit([{ name, value: undefined, origin: 'local' }]);\n schedule();\n },\n subscribe: (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n flush,\n close: async () => {\n if (closed) return;\n await flush();\n closed = true;\n unsubscribe?.();\n if (typeof window !== 'undefined') {\n window.removeEventListener('pagehide', onPageHide);\n document.removeEventListener('visibilitychange', onVisibility);\n }\n },\n seed: (entries) => {\n for (const [name, value] of entries) values.set(name, value);\n },\n stopWriting: () => {\n writable = false;\n queued.clear();\n if (timer) clearTimeout(timer);\n timer = null;\n unsubscribe?.();\n },\n applyRemote,\n };\n return cache;\n}\n\n/** Read every record under `prefix` and hold them. A failed read opens the\n * cache empty with writing off, so it never overwrites what it could not\n * read. */\nexport async function openRecords(options: RecordCacheOptions): Promise<OwnedRecordCache> {\n // Listen before listing, so a change landing between the two is not lost.\n const early: StorageChange[] = [];\n const stopEarly = options.storage.subscribe?.(options.prefix, (c) => early.push(...c));\n let listed: [string, unknown][];\n try {\n listed = await options.storage.list(options.prefix);\n } catch (error) {\n stopEarly?.();\n console.warn(\n `[labkit] could not read \"${options.prefix}\"; opening empty and not persisting`,\n error,\n );\n return createRecordCache({ ...options, writable: false });\n }\n const cache = createRecordCache({\n ...options,\n initial: listed.map(([key, value]): [string, unknown] => [\n key.slice(options.prefix.length),\n value,\n ]),\n });\n stopEarly?.();\n (cache as unknown as { applyRemote: (c: StorageChange[]) => void }).applyRemote(early);\n return cache;\n}\n","import { useEffect, useRef, useState } from 'react';\n\ninterface Closable {\n close(): Promise<void> | void;\n}\n\ninterface Entry<T> {\n value: T | null;\n pending: Promise<T> | null;\n mounts: number;\n}\n\n/**\n * Open something once for a component's lifetime: at once when `open` returns\n * a value, after it settles when it returns a promise. Closed on unmount — but\n * the close waits a microtask, and the remount React StrictMode performs right\n * after its rehearsal unmount cancels it, so StrictMode opens it once.\n */\nexport function useOpenOnce<T extends Closable>(open: () => T | Promise<T>): T | null {\n const entry = useRef<Entry<T> | null>(null);\n if (entry.current === null) {\n const result = open();\n entry.current =\n result instanceof Promise\n ? { value: null, pending: result, mounts: 0 }\n : { value: result, pending: null, mounts: 0 };\n }\n const [value, setValue] = useState<T | null>(entry.current.value);\n\n useEffect(() => {\n const e = entry.current as Entry<T>;\n e.mounts += 1;\n let live = true;\n void e.pending?.then((opened) => {\n e.value = opened;\n if (live) setValue(opened);\n });\n return () => {\n live = false;\n e.mounts -= 1;\n queueMicrotask(() => {\n if (e.mounts > 0) return;\n if (e.value) void e.value.close();\n else\n void e.pending?.then((opened) => {\n if (e.mounts === 0) void opened.close();\n });\n });\n };\n }, []);\n\n return value;\n}\n\n/** Warn once, in development, when a prop read only at mount changes after it. */\nexport function useWarnIgnoredChange(component: string, props: Record<string, unknown>): void {\n const first = useRef(props);\n const warned = useRef(false);\n if (process.env.NODE_ENV === 'production' || warned.current) return;\n for (const key of Object.keys(props)) {\n if (Object.is(first.current[key], props[key])) continue;\n warned.current = true;\n console.warn(\n `[labkit] ${component} reads \\`${key}\\` once, at mount; a later change is ignored`,\n );\n return;\n }\n}\n","import { createContext, type ReactNode } from 'react';\nimport { defaultStorage } from './adapters';\nimport { labPrefix } from './labRecords';\nimport { openRecords, type RecordCache } from './records';\nimport type { StorageAdapter } from './types';\nimport { useOpenOnce, useWarnIgnoredChange } from './useOpenOnce';\n\n/** The records `usePersistedState` reads and writes. `<Lab>`,\n * `SingletonExperimentProvider` and `<Persistence>` provide one. */\nexport const PersistenceContext = createContext<RecordCache | null>(null);\n\n/** Props for `<Persistence>`. */\nexport interface PersistenceProps {\n /** Names the records, as `<Lab storageKey>` does. A lab and a\n * `<Persistence>` given the same key share lab-scoped values. */\n storageKey: string;\n /** Default: IndexedDB, or localStorage where IndexedDB will not open. */\n storage?: StorageAdapter;\n /** Rendered until the records have loaded. Default: nothing. */\n fallback?: ReactNode;\n children: ReactNode;\n}\n\n/** Persisted values for a page with no lab: `usePersistedState` below it keeps\n * what it holds across a reload. Both props are read once, at mount. */\nexport function Persistence({ storageKey, storage, fallback = null, children }: PersistenceProps) {\n useWarnIgnoredChange('<Persistence>', { storageKey, storage });\n const records = useOpenOnce(async () =>\n openRecords({ storage: storage ?? (await defaultStorage()), prefix: labPrefix(storageKey) }),\n );\n if (!records) return <>{fallback}</>;\n return <PersistenceContext.Provider value={records}>{children}</PersistenceContext.Provider>;\n}\n","import {\n type Dispatch,\n type SetStateAction,\n useCallback,\n useContext,\n useState,\n useSyncExternalStore,\n} from 'react';\nimport { TrialIdContext } from './context';\nimport { valueRecord } from './labRecords';\nimport { PersistenceContext } from './Persistence';\n\n/** Options for `usePersistedState`. */\nexport interface PersistedStateOptions {\n /** `'trial'` — the default inside a trial — keeps a value per trial, and\n * closing the trial deletes it. `'lab'` shares one value across the lab. */\n scope?: 'trial' | 'lab';\n}\n\n/**\n * `useState` whose value survives a reload: a widget's open tab, a panel's\n * position. Inside a `<Lab>`, `SingletonExperimentProvider` or `<Persistence>`\n * the value is a record, loaded before first render and re-rendered when\n * another tab changes it. With no provider above it, or a null `name`, it is\n * plain `useState` — so a component can offer optional persistence and still\n * mount anywhere.\n *\n * Values must be structured-clone values; the JSON-backed adapters warn about\n * one JSON would change. Snapshots do not include them.\n */\nexport function usePersistedState<T>(\n name: string | null | undefined,\n initial: T | (() => T),\n options: PersistedStateOptions = {},\n): [T, Dispatch<SetStateAction<T>>] {\n const records = useContext(PersistenceContext);\n const trialId = useContext(TrialIdContext);\n const [local, setLocal] = useState(initial);\n\n const record =\n records && name != null ? valueRecord(options.scope === 'lab' ? null : trialId, name) : null;\n\n const subscribe = useCallback(\n (notify: () => void) =>\n records && record\n ? records.subscribe((changes) => {\n if (changes.some((c) => c.name === record)) notify();\n })\n : () => {},\n [records, record],\n );\n const read = (): T =>\n records && record && records.has(record) ? (records.get(record) as T) : local;\n const persisted = useSyncExternalStore(subscribe, read, read);\n\n const setPersisted = useCallback<Dispatch<SetStateAction<T>>>(\n (next) => {\n if (!records || !record) return;\n const prev = records.has(record) ? (records.get(record) as T) : local;\n records.set(record, typeof next === 'function' ? (next as (p: T) => T)(prev) : next);\n },\n [records, record, local],\n );\n\n return records && record ? [persisted, setPersisted] : [local, setLocal];\n}\n"]}