@weasel-js/labkit 1.5.0 → 1.5.2

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 (206) hide show
  1. package/README.md +41 -4
  2. package/dist/_dts/{CanvasStackContext-CqkxkFJW.d.ts → CanvasStackContext-CMMo180l.d.ts} +1 -1
  3. package/dist/_dts/{PrefsForm.d-DDHFANkc.d.ts → PrefsForm.d-DPy9I8It.d.ts} +4 -0
  4. package/dist/_dts/Select.d-ZTiwzYyT.d.ts +479 -0
  5. package/dist/_dts/{frac-8R6UmlvN.d.ts → frac-B4hFJMiN.d.ts} +54 -6
  6. package/dist/_dts/{index-retnAut7.d.ts → index-8LiKe3A-.d.ts} +77 -10
  7. package/dist/_dts/{index-B8uu2ba7.d.ts → index-DlKolEIZ.d.ts} +20 -8
  8. package/dist/_dts/{types-Ca2LCnPq.d.ts → types-Db-3NNk1.d.ts} +28 -4
  9. package/dist/_dts/{usePanZoom-nS798rOF.d.ts → usePanZoom-SSTZe410.d.ts} +4 -47
  10. package/dist/_dts/{useTrialState-jcx_TdU6.d.ts → useTrialState-pnAE-UBD.d.ts} +1 -1
  11. package/dist/canvas/index.d.ts +5 -5
  12. package/dist/canvas/index.js +1 -1
  13. package/dist/chrome/index.d.ts +4 -4
  14. package/dist/chrome/index.js +7 -7
  15. package/dist/chunk-6BUQ77ZV.js +18 -0
  16. package/dist/chunk-6BUQ77ZV.js.map +1 -0
  17. package/dist/{chunk-KJALCDWE.js → chunk-753Y6HE6.js} +9 -9
  18. package/dist/chunk-753Y6HE6.js.map +1 -0
  19. package/dist/{chunk-6ZDGOZQV.js → chunk-A2ACAGW6.js} +72 -20
  20. package/dist/chunk-A2ACAGW6.js.map +1 -0
  21. package/dist/{chunk-NS64DXMN.js → chunk-CKUKF72R.js} +44 -21
  22. package/dist/chunk-CKUKF72R.js.map +1 -0
  23. package/dist/{chunk-MUKOW3TC.js → chunk-D35PFTS7.js} +4 -4
  24. package/dist/{chunk-MUKOW3TC.js.map → chunk-D35PFTS7.js.map} +1 -1
  25. package/dist/{chunk-UU3NJO6N.js → chunk-EMXAIRUJ.js} +3 -3
  26. package/dist/{chunk-UU3NJO6N.js.map → chunk-EMXAIRUJ.js.map} +1 -1
  27. package/dist/{chunk-ZPH5WTWF.js → chunk-ERFMC6WU.js} +142 -66
  28. package/dist/chunk-ERFMC6WU.js.map +1 -0
  29. package/dist/chunk-FKLT3ITC.js +590 -0
  30. package/dist/chunk-FKLT3ITC.js.map +1 -0
  31. package/dist/{chunk-QLSV2N3G.js → chunk-IJJUK4FU.js} +25 -13
  32. package/dist/chunk-IJJUK4FU.js.map +1 -0
  33. package/dist/{chunk-EKIICY6X.js → chunk-KJCUERQF.js} +37 -25
  34. package/dist/chunk-KJCUERQF.js.map +1 -0
  35. package/dist/chunk-LASCBWW7.js +13456 -0
  36. package/dist/chunk-LASCBWW7.js.map +1 -0
  37. package/dist/{chunk-67SJLMC7.js → chunk-LRI3MBGR.js} +45 -12
  38. package/dist/chunk-LRI3MBGR.js.map +1 -0
  39. package/dist/chunk-REOBGYMC.js +150 -0
  40. package/dist/chunk-REOBGYMC.js.map +1 -0
  41. package/dist/{chunk-PGETSEDK.js → chunk-TT5C5S6R.js} +11 -90
  42. package/dist/chunk-TT5C5S6R.js.map +1 -0
  43. package/dist/{chunk-NDRYLVOW.js → chunk-Z76KEZAX.js} +2 -2
  44. package/dist/chunk-Z76KEZAX.js.map +1 -0
  45. package/dist/config/index.d.ts +62 -19
  46. package/dist/config/index.js +6 -4
  47. package/dist/controls/index.d.ts +3 -3
  48. package/dist/controls/index.js +4 -4
  49. package/dist/dragdrop/index.d.ts +3 -3
  50. package/dist/index.d.ts +230 -62
  51. package/dist/index.js +1367 -1698
  52. package/dist/index.js.map +1 -1
  53. package/dist/layers/index.d.ts +4 -4
  54. package/dist/layers/index.js +2 -2
  55. package/dist/loupe/index.d.ts +67 -16
  56. package/dist/loupe/index.js +1 -1
  57. package/dist/passthrough/weasel-ui.d.ts +57 -230
  58. package/dist/passthrough/weasel-ui.js +1 -1
  59. package/dist/primitives/index.d.ts +3 -1
  60. package/dist/primitives/index.js +3 -3
  61. package/dist/state/index.d.ts +5 -5
  62. package/dist/state/index.js +5 -3
  63. package/dist/state/index.js.map +1 -1
  64. package/dist/styles.css +266 -57
  65. package/dist/surface/index.js +1 -1
  66. package/dist/ui/layers/index.js +1 -1
  67. package/dist/undo/index.d.ts +3 -3
  68. package/package.json +9 -9
  69. package/src/annotations/AnnotationOverlay.tsx +3 -0
  70. package/src/annotations/Annotations.less +4 -0
  71. package/src/annotations/Annotations.overlay.test.tsx +20 -0
  72. package/src/annotations/svgNodes.ts +1 -0
  73. package/src/annotations/toolMap.test.ts +9 -5
  74. package/src/annotations/toolMap.ts +3 -0
  75. package/src/canvas/CanvasStack.stories.tsx +1 -1
  76. package/src/canvas/index.ts +0 -9
  77. package/src/canvas/usePanZoom.test.ts +28 -0
  78. package/src/canvas/usePanZoom.ts +11 -4
  79. package/src/chrome/ChromeRegions.stories.tsx +1 -1
  80. package/src/chrome/LabChrome.tsx +21 -5
  81. package/src/chrome/builtins.test.ts +1 -0
  82. package/src/chrome/builtins.tsx +1 -0
  83. package/src/chrome/index.ts +1 -0
  84. package/src/chrome/labTypes.ts +3 -3
  85. package/src/chrome/regions/PaletteRegion.test.tsx +18 -0
  86. package/src/chrome/regions/PaletteRegion.tsx +6 -10
  87. package/src/chrome/regions/SidebarRegion.stories.tsx +44 -0
  88. package/src/chrome/regions/TitleBarRegion.tsx +1 -1
  89. package/src/chrome/regions/ToolbarRegion.tsx +11 -7
  90. package/src/chrome/types.ts +11 -2
  91. package/src/config/auto.test.ts +12 -0
  92. package/src/config/auto.ts +15 -0
  93. package/src/config/autoConfig.test.ts +107 -0
  94. package/src/config/autoConfig.ts +153 -0
  95. package/src/config/builder.test.ts +38 -0
  96. package/src/config/builder.ts +55 -11
  97. package/src/config/index.ts +3 -0
  98. package/src/config/path.ts +7 -2
  99. package/src/config/resolve.test.ts +25 -0
  100. package/src/config/resolve.ts +17 -1
  101. package/src/config/types.ts +32 -2
  102. package/src/config/useResolvedConfig.ts +26 -0
  103. package/src/controls/AutoControls.stories.tsx +88 -0
  104. package/src/controls/ControlPanel.less +23 -0
  105. package/src/controls/ControlPanel.stories.tsx +83 -1
  106. package/src/controls/ControlPanel.test.tsx +457 -4
  107. package/src/controls/ControlPanel.tsx +534 -73
  108. package/src/index.test.ts +0 -2
  109. package/src/index.ts +33 -11
  110. package/src/instrument/serializers.ts +29 -1
  111. package/src/lab/Lab.chrome.test.tsx +16 -0
  112. package/src/lab/Lab.stories.tsx +1 -1
  113. package/src/lab/Lab.surface.test.tsx +7 -2
  114. package/src/lab/Lab.test.tsx +79 -1
  115. package/src/lab/Lab.tsx +124 -16
  116. package/src/lab/LabContext.ts +8 -0
  117. package/src/lab/LabFit.stories.tsx +4 -4
  118. package/src/lab/LabFullChrome.stories.tsx +1 -1
  119. package/src/lab/LabHeader.tsx +0 -1
  120. package/src/lab/LabRoot.test.tsx +56 -0
  121. package/src/lab/LabRoot.tsx +47 -0
  122. package/src/lab/LabShell.less +24 -3
  123. package/src/lab/LabShell.stories.tsx +50 -1
  124. package/src/lab/LabShell.tsx +18 -27
  125. package/src/lab/LabSwitcher.less +10 -10
  126. package/src/lab/LabSwitcher.test.tsx +14 -9
  127. package/src/lab/LabSwitcher.tsx +8 -4
  128. package/src/lab/Workspace.less +1 -1
  129. package/src/lab/Workspace.stories.tsx +1 -1
  130. package/src/lab/Workspace.surface.test.tsx +1 -1
  131. package/src/lab/index.ts +2 -0
  132. package/src/layers/LayerList.less +1 -1
  133. package/src/layers/LayerList.stories.tsx +2 -2
  134. package/src/loupe/AGENTS.md +16 -4
  135. package/src/loupe/LoupeGestures.tsx +67 -0
  136. package/src/loupe/TrialLoupe.tsx +43 -28
  137. package/src/loupe/index.ts +4 -0
  138. package/src/loupe/loupeActions.ts +98 -0
  139. package/src/loupe/useLoupe.test.tsx +59 -2
  140. package/src/loupe/useLoupe.ts +28 -48
  141. package/src/passthrough/weasel-ui.ts +3 -3
  142. package/src/primitives/FloatingPanel.stories.tsx +1 -1
  143. package/src/primitives/FpsMeter.less +6 -1
  144. package/src/primitives/FpsMeter.stories.tsx +1 -1
  145. package/src/primitives/FpsMeter.test.tsx +12 -4
  146. package/src/primitives/FpsMeter.tsx +6 -1
  147. package/src/primitives/JobProgress.stories.tsx +2 -2
  148. package/src/primitives/Legend.stories.tsx +1 -1
  149. package/src/primitives/ScaleIndicator.stories.tsx +1 -1
  150. package/src/primitives/Sidebar.less +7 -0
  151. package/src/primitives/Sidebar.stories.tsx +1 -1
  152. package/src/primitives/Split.test.tsx +25 -0
  153. package/src/primitives/Split.tsx +36 -20
  154. package/src/primitives/StatusBar.less +6 -0
  155. package/src/primitives/StatusBar.stories.tsx +1 -1
  156. package/src/primitives/Toolbar.stories.tsx +1 -1
  157. package/src/specimen/Specimen.less +95 -0
  158. package/src/specimen/Specimen.stories.tsx +13 -0
  159. package/src/specimen/Specimen.test.tsx +13 -0
  160. package/src/specimen/Specimen.tsx +888 -0
  161. package/src/state/Persistence.stories.tsx +4 -4
  162. package/src/state/store.test.ts +65 -0
  163. package/src/state/store.ts +32 -8
  164. package/src/state/types.ts +31 -2
  165. package/src/state/useTrialState.test.tsx +85 -0
  166. package/src/state/useTrialState.ts +9 -1
  167. package/src/state/view.test.ts +4 -4
  168. package/src/styles.less +1 -0
  169. package/src/surface/index.ts +1 -1
  170. package/src/surface/useSurfaceTile.test.tsx +1 -1
  171. package/src/surface/useTiledSurface.test.tsx +65 -10
  172. package/src/surface/useTiledSurface.ts +23 -11
  173. package/src/theme/Interstellar.stories.tsx +2 -2
  174. package/src/theme/interstellar.test.ts +16 -5
  175. package/src/theme/interstellar.theme.json +180 -0
  176. package/src/theme/interstellar.ts +8 -5
  177. package/src/tools/labTool.ts +3 -3
  178. package/src/trial/Trial.annotations.test.tsx +13 -4
  179. package/src/trial/Trial.canvas.test.tsx +36 -0
  180. package/src/trial/Trial.config.test.tsx +75 -2
  181. package/src/trial/Trial.less +4 -0
  182. package/src/trial/Trial.stories.tsx +4 -1
  183. package/src/trial/Trial.test.tsx +3 -0
  184. package/src/trial/Trial.tsx +21 -14
  185. package/src/trial/TrialChrome.tsx +17 -3
  186. package/src/trial/trialOps.test.ts +101 -1
  187. package/src/trial/trialOps.ts +62 -4
  188. package/dist/_dts/ToggleBar.d-DbHoWKIA.d.ts +0 -116
  189. package/dist/chunk-67SJLMC7.js.map +0 -1
  190. package/dist/chunk-6ZDGOZQV.js.map +0 -1
  191. package/dist/chunk-E44SU6XS.js +0 -50
  192. package/dist/chunk-E44SU6XS.js.map +0 -1
  193. package/dist/chunk-EKIICY6X.js.map +0 -1
  194. package/dist/chunk-KJALCDWE.js.map +0 -1
  195. package/dist/chunk-NDRYLVOW.js.map +0 -1
  196. package/dist/chunk-NS64DXMN.js.map +0 -1
  197. package/dist/chunk-PGETSEDK.js.map +0 -1
  198. package/dist/chunk-QLSV2N3G.js.map +0 -1
  199. package/dist/chunk-S2SHZRD7.js +0 -7681
  200. package/dist/chunk-S2SHZRD7.js.map +0 -1
  201. package/dist/chunk-TQBBYTAF.js +0 -280
  202. package/dist/chunk-TQBBYTAF.js.map +0 -1
  203. package/dist/chunk-ZPH5WTWF.js.map +0 -1
  204. package/src/canvas/useOrbit.test.ts +0 -167
  205. package/src/canvas/useOrbit.ts +0 -156
  206. package/src/theme/interstellar.tokens.json +0 -61
@@ -1,10 +1,12 @@
1
- import { openLabStore } from '../chunk-67SJLMC7.js';
2
- export { CURRENT_DOCUMENT_VERSION, createLabStore, dockPanel, labDocumentKey, openLabStore, panelKey, quarantineKey, undockPanel, useTrialState } from '../chunk-67SJLMC7.js';
1
+ import { openLabStore } from '../chunk-LRI3MBGR.js';
2
+ export { CURRENT_DOCUMENT_VERSION, createLabStore, dockPanel, labDocumentKey, openLabStore, panelKey, quarantineKey, undockPanel, useTrialState } from '../chunk-LRI3MBGR.js';
3
3
  import { useWarnIgnoredChange, useOpenOnce, defaultStorage, PersistenceContext } from '../chunk-RWNDDKOH.js';
4
4
  export { Persistence, createIndexedDbAdapter, createMemoryAdapter, decodeUrlHash, deserializeTrials, emptyUndoStack, encodeUrlHash, indexedDbAdapter, labStorageKey, localStorageAdapter, noneAdapter, serializeTrials, sessionStorageAdapter, urlHashAdapter, usePersistedState } from '../chunk-RWNDDKOH.js';
5
- import '../chunk-E44SU6XS.js';
5
+ import '../chunk-A2ACAGW6.js';
6
+ import '../chunk-REOBGYMC.js';
6
7
  import { LabStoreProvider, TrialIdProvider } from '../chunk-2YILQ7Y5.js';
7
8
  export { LabStoreContext, LabStoreProvider, TrialIdContext, TrialIdProvider, useLabStore, useTrialId } from '../chunk-2YILQ7Y5.js';
9
+ import '../chunk-LASCBWW7.js';
8
10
  import { jsx, Fragment } from 'react/jsx-runtime';
9
11
 
10
12
  var SINGLETON_INSTRUMENT = "__singleton__";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/state/SingletonExperiment.tsx"],"names":[],"mappings":";;;;;;;;;AAQA,IAAM,oBAAA,GAAuB,eAAA;AAwBtB,SAAS,2BAAA,CAAoC;AAAA,EAClD,EAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA,GAAW,IAAA;AAAA,EACX;AACF,CAAA,EAA6C;AAC3C,EAAA,oBAAA,CAAqB,+BAAA,EAAiC,EAAE,UAAA,EAAY,OAAA,EAAS,CAAA;AAC7E,EAAA,MAAM,MAAA,GAAS,YAAY,YAAY;AACrC,IAAA,MAAM,GAAA,GAAM,MAAM,YAAA,CAAa,EAAE,UAAA,EAAY,SAAS,OAAA,IAAY,MAAM,cAAA,EAAe,EAAI,CAAA;AAC3F,IAAA,IAAI,CAAC,GAAA,CAAI,KAAA,CAAM,QAAA,EAAS,CAAE,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,EAAE,CAAA,EAAG;AACzD,MAAA,GAAA,CAAI,KAAA,CAAM,QAAA,EAAS,CAAE,QAAA,CAAS;AAAA,QAC5B,EAAA;AAAA,QACA,cAAA,EAAgB,oBAAA;AAAA,QAChB,MAAA,EAAQ,aAAA;AAAA,QACR,KAAA,EAAO,YAAA;AAAA,QACP,IAAA,EAAM,EAAE,IAAA,EAAM,CAAA,EAAG,GAAA,EAAK,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE;AAAE,OACtC,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT,CAAC,CAAA;AACD,EAAA,IAAI,CAAC,MAAA,EAAQ,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAA,QAAA,EAAS,CAAA;AAChC,EAAA,2BACG,gBAAA,EAAA,EAAiB,KAAA,EAAO,OAAO,KAAA,EAC9B,QAAA,kBAAA,GAAA,CAAC,mBAAmB,QAAA,EAAnB,EAA4B,KAAA,EAAO,MAAA,CAAO,SACzC,QAAA,kBAAA,GAAA,CAAC,eAAA,EAAA,EAAgB,SAAS,EAAA,EAAK,QAAA,EAAS,GAC1C,CAAA,EACF,CAAA;AAEJ","file":"index.js","sourcesContent":["import type { ReactNode } from 'react';\nimport { defaultStorage } from './adapters';\nimport { LabStoreProvider, TrialIdProvider } from './context';\nimport { openLabStore } from './openLabStore';\nimport { PersistenceContext } from './Persistence';\nimport type { StorageAdapter } from './types';\nimport { useOpenOnce, useWarnIgnoredChange } from './useOpenOnce';\n\nconst SINGLETON_INSTRUMENT = '__singleton__';\n\n/** Props for `<SingletonExperimentProvider>`. */\nexport interface SingletonExperimentProviderProps<TS, TC> {\n /** Stable id for the synthetic trial; also doubles as the\n * TrialIdContext value. */\n id: string;\n initialConfig: TC;\n initialState: TS;\n storageKey: string;\n /** Default: IndexedDB, or localStorage where IndexedDB will not open. */\n storage?: StorageAdapter;\n /** Rendered until the stored experiment has loaded. Default: nothing. */\n fallback?: ReactNode;\n children: ReactNode;\n}\n\n/**\n * One-trial `<Lab>` substitute for single-screen experiments. Mounts\n * a `LabStoreProvider` + `TrialIdProvider` with one synthetic\n * trial, so `useTrialState` works without going through the\n * full `<Lab instruments={...}>` runtime. `storageKey` and `storage` are read\n * once, at mount.\n */\nexport function SingletonExperimentProvider<TS, TC>({\n id,\n initialConfig,\n initialState,\n storage,\n storageKey,\n fallback = null,\n children,\n}: SingletonExperimentProviderProps<TS, TC>) {\n useWarnIgnoredChange('<SingletonExperimentProvider>', { storageKey, storage });\n const opened = useOpenOnce(async () => {\n const lab = await openLabStore({ storageKey, storage: storage ?? (await defaultStorage()) });\n if (!lab.store.getState().trials.some((w) => w.id === id)) {\n lab.store.getState().addTrial({\n id,\n instrumentName: SINGLETON_INSTRUMENT,\n config: initialConfig,\n state: initialState,\n view: { zoom: 1, pan: { x: 0, y: 0 } },\n });\n }\n return lab;\n });\n if (!opened) return <>{fallback}</>;\n return (\n <LabStoreProvider store={opened.store}>\n <PersistenceContext.Provider value={opened.records}>\n <TrialIdProvider trialId={id}>{children}</TrialIdProvider>\n </PersistenceContext.Provider>\n </LabStoreProvider>\n );\n}\n"]}
1
+ {"version":3,"sources":["../../src/state/SingletonExperiment.tsx"],"names":[],"mappings":";;;;;;;;;;;AAQA,IAAM,oBAAA,GAAuB,eAAA;AAwBtB,SAAS,2BAAA,CAAoC;AAAA,EAClD,EAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA,GAAW,IAAA;AAAA,EACX;AACF,CAAA,EAA6C;AAC3C,EAAA,oBAAA,CAAqB,+BAAA,EAAiC,EAAE,UAAA,EAAY,OAAA,EAAS,CAAA;AAC7E,EAAA,MAAM,MAAA,GAAS,YAAY,YAAY;AACrC,IAAA,MAAM,GAAA,GAAM,MAAM,YAAA,CAAa,EAAE,UAAA,EAAY,SAAS,OAAA,IAAY,MAAM,cAAA,EAAe,EAAI,CAAA;AAC3F,IAAA,IAAI,CAAC,GAAA,CAAI,KAAA,CAAM,QAAA,EAAS,CAAE,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,EAAE,CAAA,EAAG;AACzD,MAAA,GAAA,CAAI,KAAA,CAAM,QAAA,EAAS,CAAE,QAAA,CAAS;AAAA,QAC5B,EAAA;AAAA,QACA,cAAA,EAAgB,oBAAA;AAAA,QAChB,MAAA,EAAQ,aAAA;AAAA,QACR,KAAA,EAAO,YAAA;AAAA,QACP,IAAA,EAAM,EAAE,IAAA,EAAM,CAAA,EAAG,GAAA,EAAK,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE;AAAE,OACtC,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT,CAAC,CAAA;AACD,EAAA,IAAI,CAAC,MAAA,EAAQ,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAA,QAAA,EAAS,CAAA;AAChC,EAAA,2BACG,gBAAA,EAAA,EAAiB,KAAA,EAAO,OAAO,KAAA,EAC9B,QAAA,kBAAA,GAAA,CAAC,mBAAmB,QAAA,EAAnB,EAA4B,KAAA,EAAO,MAAA,CAAO,SACzC,QAAA,kBAAA,GAAA,CAAC,eAAA,EAAA,EAAgB,SAAS,EAAA,EAAK,QAAA,EAAS,GAC1C,CAAA,EACF,CAAA;AAEJ","file":"index.js","sourcesContent":["import type { ReactNode } from 'react';\nimport { defaultStorage } from './adapters';\nimport { LabStoreProvider, TrialIdProvider } from './context';\nimport { openLabStore } from './openLabStore';\nimport { PersistenceContext } from './Persistence';\nimport type { StorageAdapter } from './types';\nimport { useOpenOnce, useWarnIgnoredChange } from './useOpenOnce';\n\nconst SINGLETON_INSTRUMENT = '__singleton__';\n\n/** Props for `<SingletonExperimentProvider>`. */\nexport interface SingletonExperimentProviderProps<TS, TC> {\n /** Stable id for the synthetic trial; also doubles as the\n * TrialIdContext value. */\n id: string;\n initialConfig: TC;\n initialState: TS;\n storageKey: string;\n /** Default: IndexedDB, or localStorage where IndexedDB will not open. */\n storage?: StorageAdapter;\n /** Rendered until the stored experiment has loaded. Default: nothing. */\n fallback?: ReactNode;\n children: ReactNode;\n}\n\n/**\n * One-trial `<Lab>` substitute for single-screen experiments. Mounts\n * a `LabStoreProvider` + `TrialIdProvider` with one synthetic\n * trial, so `useTrialState` works without going through the\n * full `<Lab instruments={...}>` runtime. `storageKey` and `storage` are read\n * once, at mount.\n */\nexport function SingletonExperimentProvider<TS, TC>({\n id,\n initialConfig,\n initialState,\n storage,\n storageKey,\n fallback = null,\n children,\n}: SingletonExperimentProviderProps<TS, TC>) {\n useWarnIgnoredChange('<SingletonExperimentProvider>', { storageKey, storage });\n const opened = useOpenOnce(async () => {\n const lab = await openLabStore({ storageKey, storage: storage ?? (await defaultStorage()) });\n if (!lab.store.getState().trials.some((w) => w.id === id)) {\n lab.store.getState().addTrial({\n id,\n instrumentName: SINGLETON_INSTRUMENT,\n config: initialConfig,\n state: initialState,\n view: { zoom: 1, pan: { x: 0, y: 0 } },\n });\n }\n return lab;\n });\n if (!opened) return <>{fallback}</>;\n return (\n <LabStoreProvider store={opened.store}>\n <PersistenceContext.Provider value={opened.records}>\n <TrialIdProvider trialId={id}>{children}</TrialIdProvider>\n </PersistenceContext.Provider>\n </LabStoreProvider>\n );\n}\n"]}