@jbrowse/core 5.0.0-beta.1 → 5.0.0-beta.10

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 (611) hide show
  1. package/README.md +1476 -265
  2. package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.d.ts +3 -2
  3. package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.js +5 -3
  4. package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.d.ts +3 -5
  5. package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.js +34 -29
  6. package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseCard.js +1 -4
  7. package/esm/BaseFeatureWidget/BaseFeatureDetail/BasicValue.d.ts +11 -0
  8. package/esm/BaseFeatureWidget/BaseFeatureDetail/BasicValue.js +16 -9
  9. package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.d.ts +1 -1
  10. package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.js +15 -31
  11. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.d.ts +4 -3
  12. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.js +12 -25
  13. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetailsFrame.d.ts +11 -0
  14. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetailsFrame.js +11 -0
  15. package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.d.ts +8 -0
  16. package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.js +24 -0
  17. package/esm/BaseFeatureWidget/BaseFeatureDetail/Formatter.js +6 -4
  18. package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.d.ts +4 -0
  19. package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.js +17 -0
  20. package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.d.ts +3 -2
  21. package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.js +5 -3
  22. package/esm/BaseFeatureWidget/BaseFeatureDetail/index.d.ts +6 -2
  23. package/esm/BaseFeatureWidget/BaseFeatureDetail/index.js +7 -18
  24. package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.d.ts +16 -0
  25. package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.js +50 -0
  26. package/esm/BaseFeatureWidget/BaseFeatureDetail/util.d.ts +0 -8
  27. package/esm/BaseFeatureWidget/BaseFeatureDetail/util.js +6 -29
  28. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceContents.js +7 -34
  29. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.d.ts +2 -2
  30. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceName.js +2 -2
  31. package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/TranscriptSelector.js +3 -1
  32. package/esm/BaseFeatureWidget/SequenceFeatureDetails/model.d.ts +12 -0
  33. package/esm/BaseFeatureWidget/SequenceFeatureDetails/model.js +12 -5
  34. package/esm/BaseFeatureWidget/configSchema.d.ts +1 -1
  35. package/esm/BaseFeatureWidget/formatDetails.d.ts +13 -29
  36. package/esm/BaseFeatureWidget/formatDetails.js +62 -83
  37. package/esm/BaseFeatureWidget/index.d.ts +2 -1
  38. package/esm/BaseFeatureWidget/stateModelFactory.d.ts +42 -29
  39. package/esm/BaseFeatureWidget/stateModelFactory.js +98 -98
  40. package/esm/BaseFeatureWidget/types.d.ts +12 -6
  41. package/esm/BaseFeatureWidget/util.d.ts +0 -10
  42. package/esm/BaseFeatureWidget/util.js +0 -17
  43. package/esm/CorePlugin.js +2 -2
  44. package/esm/PluginLoader.d.ts +24 -13
  45. package/esm/PluginLoader.js +167 -51
  46. package/esm/PluginManager.d.ts +130 -24
  47. package/esm/PluginManager.js +180 -32
  48. package/esm/ReExports/MuiDataGridReExports.d.ts +1 -0
  49. package/esm/ReExports/MuiDataGridReExports.js +2 -2
  50. package/esm/ReExports/coreModules.generated.d.ts +2 -0
  51. package/esm/ReExports/coreModules.generated.js +528 -0
  52. package/esm/ReExports/coreWorkerModules.generated.d.ts +2 -0
  53. package/esm/ReExports/coreWorkerModules.generated.js +488 -0
  54. package/esm/ReExports/frameworkModules.d.ts +2 -0
  55. package/esm/ReExports/frameworkModules.js +68 -0
  56. package/esm/ReExports/frameworkShared.d.ts +12 -0
  57. package/esm/ReExports/frameworkShared.js +16 -0
  58. package/esm/ReExports/frameworkWorkerModules.generated.d.ts +2 -0
  59. package/esm/ReExports/frameworkWorkerModules.generated.js +130 -0
  60. package/esm/ReExports/list.js +527 -79
  61. package/esm/ReExports/modules.d.ts +1 -1
  62. package/esm/ReExports/modules.js +10 -165
  63. package/esm/ReExports/registry.d.ts +1 -0
  64. package/esm/ReExports/registry.js +23 -5
  65. package/esm/ReExports/uiStub.d.ts +3 -0
  66. package/esm/ReExports/uiStub.js +33 -0
  67. package/esm/ReExports/workerModules.d.ts +2 -0
  68. package/esm/ReExports/workerModules.js +11 -0
  69. package/esm/TextSearch/TextSearchManager.d.ts +27 -13
  70. package/esm/TextSearch/TextSearchManager.js +77 -36
  71. package/esm/TextSearch/places.d.ts +12 -0
  72. package/esm/TextSearch/places.js +94 -0
  73. package/esm/assemblyManager/assembly.d.ts +21 -19
  74. package/esm/assemblyManager/assembly.js +28 -26
  75. package/esm/assemblyManager/assemblyAdapters.d.ts +1 -1
  76. package/esm/assemblyManager/assemblyAdapters.js +8 -2
  77. package/esm/assemblyManager/assemblyConfigSchema.d.ts +31 -90
  78. package/esm/assemblyManager/assemblyConfigSchema.js +35 -47
  79. package/esm/assemblyManager/assemblyManager.d.ts +35 -180
  80. package/esm/assemblyManager/assemblyManager.js +47 -51
  81. package/esm/assemblyManager/expandAssemblyConfigShorthand.d.ts +25 -18
  82. package/esm/assemblyManager/expandAssemblyConfigShorthand.js +78 -49
  83. package/esm/assemblyManager/geneticCodes.js +2 -5
  84. package/esm/assemblyManager/getSequenceAdapterConfig.d.ts +10 -0
  85. package/esm/assemblyManager/getSequenceAdapterConfig.js +10 -0
  86. package/esm/assemblyManager/indexAssemblyNames.d.ts +9 -0
  87. package/esm/assemblyManager/indexAssemblyNames.js +22 -0
  88. package/esm/assemblyManager/loadRefNameMap.d.ts +1 -1
  89. package/esm/assemblyManager/loadRefNameMap.js +4 -9
  90. package/esm/assemblyManager/refNameMapKey.d.ts +7 -0
  91. package/esm/assemblyManager/refNameMapKey.js +12 -0
  92. package/esm/checkPlugins.d.ts +2 -0
  93. package/esm/checkPlugins.js +38 -17
  94. package/esm/configuration/bamIndexFields.d.ts +49 -0
  95. package/esm/configuration/bamIndexFields.js +41 -0
  96. package/esm/configuration/configurationSchema.d.ts +101 -71
  97. package/esm/configuration/configurationSchema.js +207 -134
  98. package/esm/configuration/configurationSchemaUnion.d.ts +39 -0
  99. package/esm/configuration/configurationSchemaUnion.js +56 -0
  100. package/esm/configuration/configurationSlot.d.ts +150 -60
  101. package/esm/configuration/configurationSlot.js +103 -75
  102. package/esm/configuration/fillLocations.d.ts +14 -0
  103. package/esm/configuration/fillLocations.js +14 -0
  104. package/esm/configuration/formatAboutConfigSchema.d.ts +7 -21
  105. package/esm/configuration/formatDetailsConfigSchema.d.ts +11 -37
  106. package/esm/configuration/formatDetailsConfigSchema.js +10 -13
  107. package/esm/configuration/fullConfSnapshot.d.ts +4 -19
  108. package/esm/configuration/fullConfSnapshot.js +30 -52
  109. package/esm/configuration/getConf.d.ts +45 -41
  110. package/esm/configuration/getConf.js +111 -44
  111. package/esm/configuration/index.d.ts +24 -11
  112. package/esm/configuration/index.js +15 -7
  113. package/esm/configuration/indexType.d.ts +26 -0
  114. package/esm/configuration/indexType.js +38 -0
  115. package/esm/configuration/mergeFormatCallbacks.d.ts +6 -7
  116. package/esm/configuration/mergeFormatCallbacks.js +13 -10
  117. package/esm/configuration/readConfObject.d.ts +2 -24
  118. package/esm/configuration/readConfObject.js +20 -63
  119. package/esm/configuration/requirements.d.ts +37 -0
  120. package/esm/configuration/requirements.js +88 -0
  121. package/esm/configuration/schemaRegistry.d.ts +32 -15
  122. package/esm/configuration/schemaRegistry.js +33 -35
  123. package/esm/configuration/schemaTypes.d.ts +21 -5
  124. package/esm/configuration/schemaTypes.js +66 -55
  125. package/esm/configuration/slotFacade.d.ts +12 -29
  126. package/esm/configuration/slotFacade.js +44 -23
  127. package/esm/configuration/snapshotPreprocess.d.ts +43 -0
  128. package/esm/configuration/snapshotPreprocess.js +161 -0
  129. package/esm/configuration/tabixIndexFields.d.ts +30 -4
  130. package/esm/configuration/tabixIndexFields.js +21 -4
  131. package/esm/configuration/tabixShorthand.d.ts +34 -17
  132. package/esm/configuration/tabixShorthand.js +49 -22
  133. package/esm/configuration/types.d.ts +182 -43
  134. package/esm/configuration/uriShorthand.d.ts +9 -0
  135. package/esm/configuration/uriShorthand.js +16 -0
  136. package/esm/data_adapters/BaseAdapter/BaseAdapter.d.ts +13 -19
  137. package/esm/data_adapters/BaseAdapter/BaseAdapter.js +12 -19
  138. package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +40 -2
  139. package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +68 -5
  140. package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +40 -0
  141. package/esm/data_adapters/BaseAdapter/featureDensity.js +31 -0
  142. package/esm/data_adapters/BaseAdapter/index.d.ts +23 -3
  143. package/esm/data_adapters/BaseAdapter/index.js +1 -0
  144. package/esm/data_adapters/BaseAdapter/rowSources.d.ts +37 -0
  145. package/esm/data_adapters/BaseAdapter/rowSources.js +7 -0
  146. package/esm/data_adapters/BaseAdapter/stats.d.ts +33 -1
  147. package/esm/data_adapters/BaseAdapter/stats.js +52 -13
  148. package/esm/data_adapters/BaseAdapter/types.d.ts +8 -12
  149. package/esm/data_adapters/BaseAdapter/zoomRange.d.ts +10 -0
  150. package/esm/data_adapters/CytobandAdapter/CytobandAdapter.js +1 -1
  151. package/esm/data_adapters/CytobandAdapter/configSchema.d.ts +7 -11
  152. package/esm/data_adapters/CytobandAdapter/configSchema.js +3 -17
  153. package/esm/data_adapters/dataAdapterCache.d.ts +19 -2
  154. package/esm/data_adapters/dataAdapterCache.js +44 -10
  155. package/esm/data_adapters/getFeatureAdapter.d.ts +6 -4
  156. package/esm/data_adapters/getFeatureAdapter.js +8 -8
  157. package/esm/data_adapters/getSequenceSubAdapter.d.ts +7 -9
  158. package/esm/data_adapters/getSequenceSubAdapter.js +8 -10
  159. package/esm/pluggableElementTypes/AdapterType.d.ts +8 -8
  160. package/esm/pluggableElementTypes/AdapterType.js +1 -1
  161. package/esm/pluggableElementTypes/DisplayType.d.ts +46 -16
  162. package/esm/pluggableElementTypes/DisplayType.js +22 -12
  163. package/esm/pluggableElementTypes/LazyStateModelElement.d.ts +32 -0
  164. package/esm/pluggableElementTypes/LazyStateModelElement.js +77 -0
  165. package/esm/pluggableElementTypes/PluggableElementBase.d.ts +3 -5
  166. package/esm/pluggableElementTypes/PluggableElementBase.js +3 -5
  167. package/esm/pluggableElementTypes/RpcMethodType.d.ts +11 -1
  168. package/esm/pluggableElementTypes/RpcMethodType.js +25 -9
  169. package/esm/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions.d.ts +1 -2
  170. package/esm/pluggableElementTypes/TextSearchAdapterType.d.ts +7 -7
  171. package/esm/pluggableElementTypes/ViewType.d.ts +20 -4
  172. package/esm/pluggableElementTypes/ViewType.js +32 -4
  173. package/esm/pluggableElementTypes/addMenuItems.d.ts +3 -2
  174. package/esm/pluggableElementTypes/extendElementType.d.ts +1 -2
  175. package/esm/pluggableElementTypes/extendElementType.js +9 -5
  176. package/esm/pluggableElementTypes/index.d.ts +2 -1
  177. package/esm/pluggableElementTypes/index.js +1 -1
  178. package/esm/pluggableElementTypes/models/BaseConnectionModelFactory.d.ts +19 -9
  179. package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +65 -27
  180. package/esm/pluggableElementTypes/models/BaseDisplayModel.js +72 -10
  181. package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +65 -16
  182. package/esm/pluggableElementTypes/models/BaseTrackModel.js +179 -117
  183. package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +85 -16
  184. package/esm/pluggableElementTypes/models/BaseViewModel.js +53 -10
  185. package/esm/pluggableElementTypes/models/InternetAccountModel.d.ts +26 -16
  186. package/esm/pluggableElementTypes/models/assertDisplayContract.d.ts +15 -11
  187. package/esm/pluggableElementTypes/models/assertDisplayContract.js +25 -32
  188. package/esm/pluggableElementTypes/models/baseConnectionConfig.d.ts +22 -18
  189. package/esm/pluggableElementTypes/models/baseConnectionConfig.js +5 -5
  190. package/esm/pluggableElementTypes/models/baseInternetAccountConfig.d.ts +26 -31
  191. package/esm/pluggableElementTypes/models/baseTrackConfig.d.ts +108 -147
  192. package/esm/pluggableElementTypes/models/baseTrackConfig.js +96 -73
  193. package/esm/pluggableElementTypes/models/components/SaveTrackData.js +4 -6
  194. package/esm/pluggableElementTypes/models/components/fetchTrackData.d.ts +3 -4
  195. package/esm/pluggableElementTypes/models/components/fetchTrackData.js +3 -3
  196. package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.d.ts +23 -13
  197. package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.js +80 -48
  198. package/esm/pluggableElementTypes/models/index.d.ts +2 -3
  199. package/esm/pluggableElementTypes/models/index.js +2 -3
  200. package/esm/pluggableElementTypes/models/migrateTrackConfig.d.ts +15 -1
  201. package/esm/pluggableElementTypes/models/migrateTrackConfig.js +85 -25
  202. package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.d.ts +4 -3
  203. package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.js +141 -19
  204. package/esm/pluggableElementTypes/models/saveTrackFileTypes/types.d.ts +3 -3
  205. package/esm/pluginDefinitions.d.ts +34 -7
  206. package/esm/pluginDefinitions.js +54 -20
  207. package/esm/rpc/BaseRpcDriver.d.ts +2 -2
  208. package/esm/rpc/BaseRpcDriver.js +25 -30
  209. package/esm/rpc/MainThreadRpcDriver.d.ts +2 -2
  210. package/esm/rpc/MainThreadRpcDriver.js +13 -8
  211. package/esm/rpc/RpcClient.d.ts +18 -6
  212. package/esm/rpc/RpcClient.js +51 -16
  213. package/esm/rpc/RpcManager.d.ts +14 -10
  214. package/esm/rpc/RpcManager.js +11 -1
  215. package/esm/rpc/RpcRegistry.d.ts +40 -7
  216. package/esm/rpc/RpcServer.d.ts +3 -1
  217. package/esm/rpc/RpcServer.js +19 -12
  218. package/esm/rpc/WebWorkerRpcDriver.d.ts +11 -4
  219. package/esm/rpc/WebWorkerRpcDriver.js +64 -68
  220. package/esm/rpc/byteBudget.d.ts +20 -5
  221. package/esm/rpc/byteBudget.js +16 -5
  222. package/esm/rpc/configSchema.d.ts +7 -21
  223. package/esm/rpc/coreRpcMethods.d.ts +4 -0
  224. package/esm/rpc/coreRpcMethods.js +4 -0
  225. package/esm/rpc/methods/CoreGetEncodedFeature.d.ts +13 -0
  226. package/esm/rpc/methods/CoreGetEncodedFeature.js +32 -0
  227. package/esm/rpc/methods/CoreGetEncodedLayers.d.ts +16 -0
  228. package/esm/rpc/methods/CoreGetEncodedLayers.js +59 -0
  229. package/esm/rpc/methods/CoreGetExportData.js +3 -4
  230. package/esm/rpc/methods/CoreGetFeatureDensity.d.ts +11 -0
  231. package/esm/rpc/methods/CoreGetFeatureDensity.js +22 -0
  232. package/esm/rpc/methods/CoreGetFeatures.js +3 -5
  233. package/esm/rpc/methods/CoreGetRefNames.js +2 -12
  234. package/esm/rpc/methods/CoreGetRegionByteEstimate.js +1 -1
  235. package/esm/rpc/methods/CoreGetSequence.js +2 -2
  236. package/esm/rpc/methods/CoreLoadAdapterCode.d.ts +13 -0
  237. package/esm/rpc/methods/CoreLoadAdapterCode.js +16 -0
  238. package/esm/rpc/methods/layerFeatures.d.ts +33 -0
  239. package/esm/rpc/methods/layerFeatures.js +29 -0
  240. package/esm/svg/SvgExport.js +6 -7
  241. package/esm/svg/SvgThemeProviders.d.ts +12 -0
  242. package/esm/svg/SvgThemeProviders.js +15 -0
  243. package/esm/svg/exportViewSvg.d.ts +28 -0
  244. package/esm/svg/exportViewSvg.js +13 -0
  245. package/esm/svg/normalizeSvgMarkup.d.ts +7 -0
  246. package/esm/svg/normalizeSvgMarkup.js +99 -0
  247. package/esm/svg/serializeSvg.d.ts +7 -0
  248. package/esm/svg/serializeSvg.js +11 -0
  249. package/esm/svg/svgId.d.ts +1 -1
  250. package/esm/svg/svgId.js +1 -1
  251. package/esm/svg/svgReady.d.ts +9 -7
  252. package/esm/svg/svgReady.js +8 -7
  253. package/esm/svg/trackNames.d.ts +7 -5
  254. package/esm/svg/trackNames.js +12 -9
  255. package/esm/svg/wrapSvgExport.js +6 -74
  256. package/esm/ui/AddCustomPluginDialog.js +3 -8
  257. package/esm/ui/AppReadyMarker.d.ts +45 -0
  258. package/esm/ui/AppReadyMarker.js +89 -0
  259. package/esm/ui/BaseExportSvgDialog.d.ts +1 -1
  260. package/esm/ui/CascadingMenu.js +181 -104
  261. package/esm/ui/DropDownMenu.js +2 -1
  262. package/esm/ui/ErrorBanner.js +1 -1
  263. package/esm/ui/ErrorBoundary.d.ts +2 -2
  264. package/esm/ui/ErrorMessageStackTraceContents.js +2 -1
  265. package/esm/ui/ErrorMessageStackTraceDialog.js +5 -11
  266. package/esm/ui/ExportSvgDialog.d.ts +1 -1
  267. package/esm/ui/FileDropZone.js +2 -1
  268. package/esm/ui/FileSelector/useInternetAccounts.d.ts +156 -96
  269. package/esm/ui/HoverMenu.d.ts +1 -2
  270. package/esm/ui/HoverMenu.js +6 -3
  271. package/esm/ui/JexlFilterDialog.d.ts +13 -10
  272. package/esm/ui/JexlFilterDialog.js +122 -49
  273. package/esm/ui/JexlFilterRowEditors.d.ts +15 -0
  274. package/esm/ui/JexlFilterRowEditors.js +90 -0
  275. package/esm/ui/LazyBaseTooltip.d.ts +4 -0
  276. package/esm/ui/LazyBaseTooltip.js +9 -0
  277. package/esm/ui/LegendSwatchGlyph.js +26 -21
  278. package/esm/ui/LoadingOverlay.d.ts +14 -0
  279. package/esm/ui/LoadingOverlay.js +4 -2
  280. package/esm/ui/MenuTypes.d.ts +23 -53
  281. package/esm/ui/MenuTypes.js +3 -0
  282. package/esm/ui/MonospaceTextField.d.ts +2 -1
  283. package/esm/ui/MonospaceTextField.js +23 -20
  284. package/esm/ui/PaletteContext.d.ts +10 -5
  285. package/esm/ui/PaletteContext.js +44 -6
  286. package/esm/ui/RefNameAutocomplete/SearchOption.d.ts +13 -0
  287. package/esm/ui/RefNameAutocomplete/SearchOption.js +45 -0
  288. package/esm/ui/RefNameAutocomplete/index.d.ts +1 -2
  289. package/esm/ui/RefNameAutocomplete/index.js +8 -2
  290. package/esm/ui/RefNameAutocomplete/util.d.ts +13 -0
  291. package/esm/ui/RefNameAutocomplete/util.js +42 -1
  292. package/esm/ui/ResizeHandle.d.ts +3 -1
  293. package/esm/ui/ResizeHandle.js +44 -11
  294. package/esm/ui/ScrollChrome.d.ts +13 -0
  295. package/esm/ui/ScrollChrome.js +11 -0
  296. package/esm/ui/ScrollEdgeShadow.d.ts +6 -9
  297. package/esm/ui/ScrollEdgeShadow.js +14 -35
  298. package/esm/ui/ScrollZoomToggle.d.ts +4 -27
  299. package/esm/ui/ScrollZoomToggle.js +34 -51
  300. package/esm/ui/SessionJsonPanel.d.ts +3 -0
  301. package/esm/ui/SessionJsonPanel.js +14 -0
  302. package/esm/ui/SettingsChangesTable.d.ts +1 -0
  303. package/esm/ui/SettingsChangesTable.js +49 -11
  304. package/esm/ui/ShareLinkField.d.ts +1 -3
  305. package/esm/ui/ShareLinkField.js +13 -40
  306. package/esm/ui/SizeSliderRow.d.ts +1 -3
  307. package/esm/ui/SizeSliderRow.js +4 -6
  308. package/esm/ui/SnackbarModel.js +79 -67
  309. package/esm/ui/StatusProgressBar.js +2 -2
  310. package/esm/ui/SvgColorLegend.d.ts +9 -4
  311. package/esm/ui/SvgColorLegend.js +82 -41
  312. package/esm/ui/VerticalScrollbar.d.ts +13 -34
  313. package/esm/ui/VerticalScrollbar.js +29 -83
  314. package/esm/ui/ViewLoadingScreen.d.ts +5 -4
  315. package/esm/ui/ViewLoadingScreen.js +8 -32
  316. package/esm/ui/colorScale.d.ts +92 -0
  317. package/esm/ui/colorScale.js +72 -0
  318. package/esm/ui/colors.d.ts +64 -0
  319. package/esm/ui/colors.js +230 -1
  320. package/esm/ui/hoverBoxStyle.d.ts +14 -2
  321. package/esm/ui/hoverBoxStyle.js +17 -2
  322. package/esm/ui/index.d.ts +12 -12
  323. package/esm/ui/index.js +14 -22
  324. package/esm/ui/launchViewMenu.js +15 -5
  325. package/esm/ui/legendMenuItem.d.ts +10 -32
  326. package/esm/ui/legendMenuItem.js +9 -36
  327. package/esm/ui/legendSpec.d.ts +15 -8
  328. package/esm/ui/legendSpec.js +14 -23
  329. package/esm/ui/makeSizeMenu.d.ts +0 -6
  330. package/esm/ui/makeSizeMenu.js +6 -30
  331. package/esm/ui/measureLegendText.js +1 -1
  332. package/esm/ui/menuItemAdornment.d.ts +9 -20
  333. package/esm/ui/menuItemAdornment.js +10 -32
  334. package/esm/ui/menuItems.d.ts +2 -7
  335. package/esm/ui/menuItems.js +1 -6
  336. package/esm/ui/multiTrackMenuItems.d.ts +6 -0
  337. package/esm/ui/palette.d.ts +118 -116
  338. package/esm/ui/palette.js +114 -75
  339. package/esm/ui/replaceViewAction.d.ts +1 -1
  340. package/esm/ui/replaceViewAction.js +1 -1
  341. package/esm/ui/theme.d.ts +43 -119
  342. package/esm/ui/theme.js +62 -78
  343. package/esm/ui/toggleMenuItems.d.ts +1 -3
  344. package/esm/ui/toggleMenuItems.js +6 -5
  345. package/esm/ui/useAssemblySelection.d.ts +4 -4
  346. package/esm/ui/viewHeaderHeight.d.ts +1 -0
  347. package/esm/ui/viewHeaderHeight.js +1 -0
  348. package/esm/util/Base1DUtils.d.ts +5 -3
  349. package/esm/util/Base1DUtils.js +14 -6
  350. package/esm/util/Base1DViewModel.d.ts +2 -1
  351. package/esm/util/Base1DViewModel.js +3 -2
  352. package/esm/util/SvgCanvas.d.ts +15 -13
  353. package/esm/util/SvgCanvas.js +76 -56
  354. package/esm/util/aborting.d.ts +39 -0
  355. package/esm/util/aborting.js +88 -6
  356. package/esm/util/adapterMetadata.d.ts +1 -1
  357. package/esm/util/adapterMetadata.js +6 -5
  358. package/esm/util/addAndShowTrack.d.ts +2 -5
  359. package/esm/util/addAndShowTrack.js +5 -1
  360. package/esm/util/addRelativeUris.d.ts +17 -5
  361. package/esm/util/addRelativeUris.js +46 -10
  362. package/esm/util/addTrackFromWidget.d.ts +2 -5
  363. package/esm/util/addTrackFromWidget.js +5 -4
  364. package/esm/util/aggregateFieldName.d.ts +10 -0
  365. package/esm/util/aggregateFieldName.js +8 -0
  366. package/esm/util/analytics.js +46 -13
  367. package/esm/util/animationAllowed.d.ts +9 -0
  368. package/esm/util/animationAllowed.js +13 -0
  369. package/esm/util/applyRowResizeWheel.d.ts +10 -5
  370. package/esm/util/applyRowResizeWheel.js +10 -21
  371. package/esm/util/bandHeight.d.ts +10 -0
  372. package/esm/util/bandHeight.js +29 -0
  373. package/esm/util/bandLayout.d.ts +4 -4
  374. package/esm/util/bandLayout.js +4 -4
  375. package/esm/util/bezierConnector.d.ts +4 -3
  376. package/esm/util/bezierConnector.js +38 -45
  377. package/esm/util/bgzfWorkerPool.d.ts +20 -74
  378. package/esm/util/bgzfWorkerPool.js +20 -74
  379. package/esm/util/binnedAggregate.d.ts +17 -0
  380. package/esm/util/binnedAggregate.js +275 -0
  381. package/esm/util/cacheBudgets.d.ts +22 -19
  382. package/esm/util/cacheBudgets.js +22 -19
  383. package/esm/util/cachedSetup.d.ts +1 -1
  384. package/esm/util/cachedSetup.js +2 -2
  385. package/esm/util/categoricalField.d.ts +56 -0
  386. package/esm/util/categoricalField.js +73 -0
  387. package/esm/util/clampToContig.d.ts +17 -0
  388. package/esm/util/clampToContig.js +19 -0
  389. package/esm/util/coarseStripHTML.js +1 -2
  390. package/esm/util/color/cssColorsLevel4.d.ts +1 -0
  391. package/esm/util/color/cssColorsLevel4.js +1 -0
  392. package/esm/util/color/index.d.ts +5 -3
  393. package/esm/util/color/index.js +7 -4
  394. package/esm/util/colorBits.d.ts +3 -3
  395. package/esm/util/colorBits.js +19 -44
  396. package/esm/util/colorRamp.d.ts +49 -5
  397. package/esm/util/colorRamp.js +169 -18
  398. package/esm/util/colorScale.d.ts +156 -0
  399. package/esm/util/colorScale.js +243 -0
  400. package/esm/util/colorSchemes.d.ts +21 -0
  401. package/esm/util/colorSchemes.js +30 -0
  402. package/esm/util/{createStopTokenRotation.d.ts → createAbortRotation.d.ts} +21 -23
  403. package/esm/util/{createStopTokenRotation.js → createAbortRotation.js} +21 -52
  404. package/esm/util/createSvgRasterCanvas.d.ts +10 -0
  405. package/esm/util/cssColorParse.d.ts +15 -0
  406. package/esm/util/cssColorParse.js +53 -0
  407. package/esm/util/diagonalizeRegions.d.ts +2 -3
  408. package/esm/util/diagonalizeRegions.js +8 -13
  409. package/esm/util/expandLooseSearchIndex.d.ts +19 -0
  410. package/esm/util/expandLooseSearchIndex.js +29 -0
  411. package/esm/util/featureTable.d.ts +224 -0
  412. package/esm/util/featureTable.js +366 -0
  413. package/esm/util/featureTransforms.d.ts +80 -0
  414. package/esm/util/featureTransforms.js +1579 -0
  415. package/esm/util/featureTypes.d.ts +24 -0
  416. package/esm/util/featureTypes.js +35 -0
  417. package/esm/util/fetchAndMaybeUnzip.js +16 -9
  418. package/esm/util/fetchContext.d.ts +7 -8
  419. package/esm/util/fetchContext.js +3 -3
  420. package/esm/util/fetchHub.d.ts +4 -2
  421. package/esm/util/fetchHub.js +2 -2
  422. package/esm/util/fetchPhases.d.ts +10 -10
  423. package/esm/util/fetchSeq.d.ts +2 -3
  424. package/esm/util/fetchSeq.js +2 -2
  425. package/esm/util/fieldReader.d.ts +17 -0
  426. package/esm/util/fieldReader.js +62 -0
  427. package/esm/util/freezeDeep.d.ts +8 -10
  428. package/esm/util/freezeDeep.js +8 -10
  429. package/esm/util/groupKeys.d.ts +77 -0
  430. package/esm/util/groupKeys.js +155 -0
  431. package/esm/util/highlights.d.ts +10 -6
  432. package/esm/util/highlights.js +12 -25
  433. package/esm/util/hooks.d.ts +31 -2
  434. package/esm/util/hooks.js +72 -3
  435. package/esm/util/index.d.ts +11 -11
  436. package/esm/util/index.js +11 -10
  437. package/esm/util/indexCandidates.d.ts +1 -31
  438. package/esm/util/indexCandidates.js +5 -63
  439. package/esm/util/installFetch.d.ts +77 -37
  440. package/esm/util/installFetch.js +65 -38
  441. package/esm/util/installInitAutorun.d.ts +14 -13
  442. package/esm/util/installInitAutorun.js +17 -17
  443. package/esm/util/installPrerequisiteFetch.d.ts +115 -0
  444. package/esm/util/installPrerequisiteFetch.js +111 -0
  445. package/esm/util/io/index.js +19 -14
  446. package/esm/util/isDataCurrent.d.ts +7 -5
  447. package/esm/util/isDataCurrent.js +9 -6
  448. package/esm/util/isTextEntryFocused.d.ts +7 -0
  449. package/esm/util/isTextEntryFocused.js +16 -0
  450. package/esm/util/jexl.js +24 -21
  451. package/esm/util/jexlFilterRows.d.ts +89 -0
  452. package/esm/util/jexlFilterRows.js +252 -0
  453. package/esm/util/jexlFilters.d.ts +20 -27
  454. package/esm/util/jexlFilters.js +23 -11
  455. package/esm/util/jexlStrings.d.ts +3 -4
  456. package/esm/util/jexlStrings.js +2 -3
  457. package/esm/util/layouts/GranularRectLayout.d.ts +8 -1
  458. package/esm/util/layouts/GranularRectLayout.js +25 -8
  459. package/esm/util/lazyAfterAttach.d.ts +13 -0
  460. package/esm/util/lazyAfterAttach.js +31 -0
  461. package/esm/util/lazyWithPreload.d.ts +19 -0
  462. package/esm/util/lazyWithPreload.js +27 -0
  463. package/esm/util/legendCandidates.d.ts +72 -0
  464. package/esm/util/legendCandidates.js +138 -0
  465. package/esm/util/localStorage.js +4 -4
  466. package/esm/util/markEncoding.d.ts +150 -0
  467. package/esm/util/markEncoding.js +845 -0
  468. package/esm/util/markEncodingTypes.d.ts +588 -0
  469. package/esm/util/markEncodingTypes.js +8 -0
  470. package/esm/util/mst-reflection.d.ts +2 -20
  471. package/esm/util/mst-reflection.js +3 -53
  472. package/esm/util/mstUtils.d.ts +31 -23
  473. package/esm/util/mstUtils.js +39 -24
  474. package/esm/util/numericUtils.d.ts +7 -0
  475. package/esm/util/numericUtils.js +16 -0
  476. package/esm/util/numericValue.d.ts +14 -0
  477. package/esm/util/numericValue.js +34 -0
  478. package/esm/util/openFeatureWidget.d.ts +5 -0
  479. package/esm/util/openFeatureWidget.js +2 -2
  480. package/esm/util/openViews.d.ts +17 -0
  481. package/esm/util/openViews.js +22 -0
  482. package/esm/util/parentWalk.d.ts +1 -1
  483. package/esm/util/parentWalk.js +1 -1
  484. package/esm/util/parseLineByLine.d.ts +4 -5
  485. package/esm/util/parseLineByLine.js +8 -14
  486. package/esm/util/pluginStore.d.ts +6 -8
  487. package/esm/util/pluginStore.js +17 -16
  488. package/esm/util/preloadComponent.d.ts +5 -0
  489. package/esm/util/preloadComponent.js +11 -0
  490. package/esm/util/progress.d.ts +22 -22
  491. package/esm/util/progress.js +27 -26
  492. package/esm/util/quantileExtent.d.ts +49 -0
  493. package/esm/util/quantileExtent.js +162 -0
  494. package/esm/util/range.d.ts +13 -9
  495. package/esm/util/range.js +17 -8
  496. package/esm/util/renameRegions.d.ts +26 -6
  497. package/esm/util/renameRegions.js +68 -54
  498. package/esm/util/renderToStaticMarkup.js +24 -14
  499. package/esm/util/rxjs.d.ts +23 -8
  500. package/esm/util/rxjs.js +61 -15
  501. package/esm/util/samplesTsv.d.ts +49 -0
  502. package/esm/util/samplesTsv.js +86 -0
  503. package/esm/util/scheduleDetachedDestroy.d.ts +18 -0
  504. package/esm/util/scheduleDetachedDestroy.js +24 -0
  505. package/esm/util/scrollLatch.d.ts +1 -0
  506. package/esm/util/scrollLatch.js +8 -0
  507. package/esm/util/selectEncodedFeature.d.ts +16 -0
  508. package/esm/util/selectEncodedFeature.js +34 -0
  509. package/esm/util/sessionSharing.d.ts +7 -5
  510. package/esm/util/sessionSharing.js +23 -23
  511. package/esm/util/shapeNameList.d.ts +2 -0
  512. package/esm/util/shapeNameList.js +6 -0
  513. package/esm/util/shapeNames.d.ts +7 -0
  514. package/esm/util/shapeNames.js +11 -0
  515. package/esm/util/simpleFeature.d.ts +0 -1
  516. package/esm/util/starFusion.d.ts +26 -0
  517. package/esm/util/starFusion.js +37 -0
  518. package/esm/util/stepTables.d.ts +82 -0
  519. package/esm/util/stepTables.js +243 -0
  520. package/esm/util/svAlt.d.ts +145 -0
  521. package/esm/util/svAlt.js +364 -0
  522. package/esm/util/svgColorProps.d.ts +11 -0
  523. package/esm/util/svgColorProps.js +28 -1
  524. package/esm/util/systemColorScheme.d.ts +12 -0
  525. package/esm/util/systemColorScheme.js +27 -0
  526. package/esm/util/tabix.d.ts +13 -8
  527. package/esm/util/tabix.js +17 -12
  528. package/esm/util/thresholdScale.d.ts +91 -0
  529. package/esm/util/thresholdScale.js +166 -0
  530. package/esm/util/timeGate.d.ts +4 -5
  531. package/esm/util/timeGate.js +4 -5
  532. package/esm/util/trackConfigDelta.d.ts +26 -26
  533. package/esm/util/trackConfigDelta.js +63 -47
  534. package/esm/util/tracks.d.ts +121 -40
  535. package/esm/util/tracks.js +497 -112
  536. package/esm/util/translateTranscript.d.ts +44 -0
  537. package/esm/util/translateTranscript.js +102 -0
  538. package/esm/util/types/data.d.ts +0 -2
  539. package/esm/util/types/index.d.ts +121 -22
  540. package/esm/util/types/index.js +9 -0
  541. package/esm/util/types/mst.d.ts +3 -0
  542. package/esm/util/types/mst.js +4 -0
  543. package/esm/util/types/renameIds.d.ts +1 -0
  544. package/esm/util/types/renameIds.js +29 -0
  545. package/esm/util/types/services.d.ts +1 -1
  546. package/esm/util/unknownSnapshotKeys.d.ts +51 -0
  547. package/esm/util/unknownSnapshotKeys.js +82 -0
  548. package/esm/util/useFeatureSequence.js +5 -5
  549. package/esm/util/useFetch.d.ts +3 -4
  550. package/esm/util/useFetch.js +19 -10
  551. package/esm/util/useFetchPlugins.d.ts +6 -2
  552. package/esm/util/useFetchPlugins.js +7 -3
  553. package/esm/util/usePanelVirtualScroll.d.ts +7 -35
  554. package/esm/util/usePanelVirtualScroll.js +9 -36
  555. package/esm/util/useRowVirtualScroll.d.ts +6 -29
  556. package/esm/util/useRowVirtualScroll.js +8 -49
  557. package/esm/util/useVirtualScrollWheel.d.ts +20 -4
  558. package/esm/util/useVirtualScrollWheel.js +40 -74
  559. package/esm/util/viewHighlights.d.ts +3 -0
  560. package/esm/util/viewHighlights.js +5 -0
  561. package/esm/util/viewStatus.d.ts +47 -15
  562. package/esm/util/viewStatus.js +34 -0
  563. package/esm/util/wheelZoom.d.ts +7 -1
  564. package/esm/util/wheelZoom.js +85 -19
  565. package/esm/util/whenViewSettled.d.ts +55 -8
  566. package/esm/util/whenViewSettled.js +56 -7
  567. package/esm/util/withLaunchInput.d.ts +174 -0
  568. package/esm/util/withLaunchInput.js +274 -0
  569. package/package.json +70 -20
  570. package/esm/BaseFeatureWidget/BaseFeatureDetail/Position.d.ts +0 -2
  571. package/esm/BaseFeatureWidget/BaseFeatureDetail/Position.js +0 -8
  572. package/esm/BaseFeatureWidget/BaseFeatureDetail/types.d.ts +0 -8
  573. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/DLGAP3.d.ts +0 -80
  574. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/DLGAP3.js +0 -583
  575. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.d.ts +0 -141
  576. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.js +0 -1116
  577. package/esm/ReExports/BaseFeatureDetails.d.ts +0 -1
  578. package/esm/ReExports/BaseFeatureDetails.js +0 -10
  579. package/esm/ReExports/index.d.ts +0 -1
  580. package/esm/ReExports/index.js +0 -1
  581. package/esm/ReExports/publicUtil.d.ts +0 -1
  582. package/esm/ReExports/publicUtil.js +0 -28
  583. package/esm/configuration/promotableDefaults.d.ts +0 -199
  584. package/esm/configuration/promotableDefaults.js +0 -326
  585. package/esm/configuration/promotablePin.d.ts +0 -55
  586. package/esm/configuration/promotablePin.js +0 -1
  587. package/esm/configuration/promotableResolve.d.ts +0 -108
  588. package/esm/configuration/promotableResolve.js +0 -117
  589. package/esm/configuration/promotableSlots.d.ts +0 -12
  590. package/esm/configuration/promotableSlots.js +0 -45
  591. package/esm/configuration/slotShape.d.ts +0 -12
  592. package/esm/configuration/slotShape.js +0 -84
  593. package/esm/pluggableElementTypes/models/HighlightsMixin.d.ts +0 -51
  594. package/esm/pluggableElementTypes/models/HighlightsMixin.js +0 -78
  595. package/esm/ui/PinAdornment.d.ts +0 -5
  596. package/esm/ui/PinAdornment.js +0 -79
  597. package/esm/ui/SvgGradientLegend.d.ts +0 -26
  598. package/esm/ui/SvgGradientLegend.js +0 -26
  599. package/esm/ui/highlightChipReveal.d.ts +0 -32
  600. package/esm/ui/highlightChipReveal.js +0 -39
  601. package/esm/ui/promotableMenuItems.d.ts +0 -19
  602. package/esm/ui/promotableMenuItems.js +0 -89
  603. package/esm/ui/promotablePinCoverage.d.ts +0 -44
  604. package/esm/ui/promotablePinCoverage.js +0 -87
  605. package/esm/util/applyInitSettings.d.ts +0 -79
  606. package/esm/util/applyInitSettings.js +0 -91
  607. package/esm/util/openDisplays.d.ts +0 -23
  608. package/esm/util/openDisplays.js +0 -79
  609. package/esm/util/stopToken.d.ts +0 -211
  610. package/esm/util/stopToken.js +0 -438
  611. /package/esm/{BaseFeatureWidget/BaseFeatureDetail/types.js → data_adapters/BaseAdapter/zoomRange.js} +0 -0
@@ -1,211 +0,0 @@
1
- import type { TimeGate } from './timeGate.ts';
2
- /**
3
- * Stop tokens cancel long-running work wherever an RPC method runs — a web
4
- * worker, or in-band on the main thread under `MainThreadRpcDriver`.
5
- *
6
- * Stopping a token records its id locally and posts it to every booted worker,
7
- * whose `RpcServer` records it too, so a check is a set lookup — free, exact,
8
- * and asking nothing of the deployment. A worker delivers that message whenever
9
- * it yields, so this covers any check reached after a *macrotask-yielding*
10
- * await; awaiting an already-resolved promise only drains microtasks, which is
11
- * the same distinction `abortBreakPoint` in `aborting.ts` exists for.
12
- *
13
- * A loop that never yields can be interrupted only by something it can read
14
- * *synchronously*, which the message path by definition cannot offer. Two
15
- * mechanisms cover that, in {@link checkStopTokenThrottled}:
16
- *
17
- * - an atomic flag in a `SharedArrayBuffer` token, where the page happens to be
18
- * cross-origin isolated. Cheap, but never assume it: SAB needs COOP/COEP on
19
- * the top-level document, which an embeddable library cannot require of its
20
- * host page. **In practice our deployments do not set those headers, so the
21
- * string path below is not the fallback — it is the path.** Judge any
22
- * cancellation bug by what it does to a string token, and don't spend
23
- * complexity optimizing the SAB branch: a lost cancellation that "only"
24
- * affects string tokens affects everybody.
25
- * - otherwise a revocable blob URL probed by synchronous XHR, throttled because
26
- * it is expensive (https://yoyo-code.com/how-to-stop-synchronous-web-worker/,
27
- * (c) 2022 Matyáš Racek, MIT).
28
- *
29
- * **The blob probe was deleted once and had to be restored — don't repeat it.**
30
- * `website/scripts/cancel-bench.ts` measured it at zero (median 513 ms settle
31
- * either way over a 2000x BAM cancel burst) and that measurement was sound but
32
- * scoped: every loop on the alignments path is already chunked by awaits at
33
- * region granularity, so there was nothing there for an intra-loop probe to
34
- * interrupt. The counter-example is `getLDMatrix.ts`'s O(n²) Float32Array fill —
35
- * millions of pair computations with no await anywhere, where this probe is the
36
- * only thing that can stop the work, and which that bench never exercises. Any
37
- * future attempt to delete this needs a cancel measurement on an
38
- * await-free workload (LD or multi-sample-variant), not on a pileup.
39
- *
40
- * ## Which path runs where
41
- *
42
- * | realm | isolated? | token | what a non-yielding loop can read |
43
- * | --- | --- | --- | --- |
44
- * | jbrowse-web / jbrowse.org | no, by decision (ADR-056) | string | stopped-id set + blob probe |
45
- * | embedded (`@jbrowse/react-*`) | only if the HOST sets COOP/COEP | string | stopped-id set + blob probe |
46
- * | jbrowse-desktop, packaged + dev | no — measured, see the gate | string | stopped-id set + blob probe |
47
- * | jest | no | string | stopped-id set only |
48
- * | an isolated embedding host | yes | SharedArrayBuffer | atomic read |
49
- *
50
- * The blob probe is the half that needs a worker (`probeBlobUrl` gates on
51
- * `isWebWorker()` and a `blob:` id), which is why jest reads the set alone —
52
- * and why a cancellation that only a probe could catch has no test covering it.
53
- *
54
- * **So nothing we ship mints a `SharedArrayBuffer` token.** The last row is the
55
- * whole of the SAB branch's reach: a host page that isolates itself gets the
56
- * fast path for free, which is why ADR-056 kept the code and why
57
- * `website/scripts/coi-probe.ts` exists to prove it still works. Every SAB arm
58
- * below is marked, and each one is dead in every configuration we control.
59
- *
60
- * Two consequences worth stating, because both have bitten:
61
- *
62
- * - **Judge every cancellation change by the string path.** A bug that "only"
63
- * affects string tokens affects everybody.
64
- * - **Don't spend complexity on the SAB arms** — no caching, no fast paths, no
65
- * cleverness. They are correctness-only, and their cost is that every reader
66
- * of a `StopToken` has to know a token might not be a string.
67
- */
68
- export type StopToken = string | SharedArrayBuffer;
69
- /**
70
- * Narrow an untyped RPC argument to a StopToken, so a caller holding
71
- * `Record<string, unknown>` can check one without a cast.
72
- */
73
- export declare function isStopToken(value: unknown): value is StopToken;
74
- export declare const hasSharedArrayBuffer: boolean;
75
- /**
76
- * Record that a string token has been stopped, and abort any {@link
77
- * stopTokenSignal} taken against it. Called locally by {@link stopStopToken},
78
- * and in a worker by `RpcServer` when the main thread posts a stopped id.
79
- */
80
- export declare function markStopTokenStopped(id: string): void;
81
- type StopTokenBroadcaster = (id: string) => void;
82
- /**
83
- * Register a transport that forwards a stopped token's id to wherever the work
84
- * is running. Drivers owning a worker pool register at construction and drop it
85
- * on destroy; `MainThreadRpcDriver` needs none — its work shares this module
86
- * instance and reads `stoppedIds` directly, which is why main-thread RPC gets
87
- * exact cancellation without any message at all.
88
- */
89
- export declare function registerStopTokenBroadcaster(fn: StopTokenBroadcaster): () => void;
90
- /**
91
- * Mint a token. **The right-hand branch is the one that runs** — see "Which
92
- * path runs where"; `hasSharedArrayBuffer` is false in everything we ship.
93
- */
94
- export declare function createStopToken(): StopToken;
95
- /**
96
- * Stop a token: every check against it now throws, every {@link
97
- * stopTokenSignal} taken against it aborts, and workers are told so their
98
- * in-flight calls do the same.
99
- *
100
- * Call it when an operation ends, not only when cancelling one — a completed
101
- * fetch's token otherwise pins its signal controllers until the next fetch
102
- * supersedes it.
103
- */
104
- export declare function stopStopToken(stopToken?: StopToken): void;
105
- /**
106
- * Whether this token has been stopped, without throwing. Prefer {@link
107
- * checkStopToken} where an abort should unwind the operation; use this to bail
108
- * out cleanly instead of throwing and catching one frame up.
109
- */
110
- export declare function isStopped(stopToken?: StopToken): boolean;
111
- /**
112
- * Throw an AbortError if this token has been stopped. Place at await
113
- * boundaries; this costs an atomic load or a set lookup, never a probe.
114
- */
115
- export declare function checkStopToken(stopToken?: StopToken): void;
116
- /**
117
- * Run an awaited stage under a stop token: checked before it starts, and again
118
- * once it settles. Prefer this to hand-placing {@link checkStopToken} around an
119
- * await — the point is that the check *after* comes with the one before, and the
120
- * one after is always the one that gets left out.
121
- *
122
- * It reads as sufficient to check at the top of an operation, because at the
123
- * time you write it the await below is not yet the slow part. `BaseRpcDriver`
124
- * checked at entry and then awaited `serializeArguments`, which resolves the
125
- * refName map, which downloads the adapter's index — and for an in-memory
126
- * adapter the whole file. A stop landing in that window woke a worker anyway.
127
- *
128
- * {@link updateStatus} and {@link withProgress} in `progress.ts` are this same
129
- * shape for a stage that also has something to say on the status channel; reach
130
- * for one of those when there is a label, and this when there isn't. What you
131
- * should not reach for is a bare `checkStopToken` sprinkled at a boundary you
132
- * happened to think of — the periodic in-loop case is
133
- * {@link checkStopTokenThrottled}, and it is driven by `createProgressReporter`
134
- * for the same reason.
135
- *
136
- * **Checking twice costs nothing, and it is worth knowing why**, because the
137
- * cost of a stop-token check is otherwise easy to remember backwards. The
138
- * expensive one is the synchronous XHR blob probe, which runs at up to ~10ms a
139
- * call — and it is reached ONLY from {@link checkStopTokenThrottled}, behind a
140
- * wall-clock gate with linear backoff, precisely because of that. This path is
141
- * {@link isStopped}: an atomic load for a SAB token, a `Map.has` for a string
142
- * one. So an extra boundary check here is free, and a per-item one in a tight
143
- * loop is not — which is the split the two functions exist to keep.
144
- */
145
- export declare function withStopTokenCheck<T>(stopToken: StopToken | undefined, fn: () => T | Promise<T>): Promise<T>;
146
- export interface StopTokenSignal {
147
- signal: AbortSignal;
148
- dispose: () => void;
149
- }
150
- /**
151
- * An `AbortSignal` wired to a stop token, so a canceled operation drops its
152
- * in-flight HTTP reads at the socket instead of downloading them to completion
153
- * and discarding the result. Call it where the work runs (worker-side for
154
- * worker RPC) and pass `signal` down through `BaseOptions`, which the gmod
155
- * readers already forward to `fetch`.
156
- *
157
- * No polling and no synchronous probe: a string token aborts off the same
158
- * posted id the await-boundary check reads, and a SharedArrayBuffer token off
159
- * `Atomics.waitAsync`, woken by the `Atomics.notify` in {@link stopStopToken}
160
- * — that one lands a turn or two after the notify rather than synchronously
161
- * with it, which costs nothing when the point is to stop a download.
162
- *
163
- * `dispose()` in a `finally` — an undisposed entry pins its controller until
164
- * the token is stopped.
165
- */
166
- export declare function stopTokenSignal(stopToken?: StopToken): StopTokenSignal;
167
- /**
168
- * Run `fn` with an `AbortSignal` wired to this stop token, releasing the signal
169
- * afterwards however `fn` settles. The shape to reach for at an adapter's read
170
- * call — {@link stopTokenSignal} directly is for the rare case that outlives one
171
- * awaited call, and it then owns remembering to dispose.
172
- */
173
- export declare function withStopTokenSignal<T>(stopToken: StopToken | undefined, fn: (signal: AbortSignal) => Promise<T>): Promise<T>;
174
- /**
175
- * Detects synchronously whether a string token has been stopped, for use where
176
- * no message can be delivered. Returns false when it cannot tell.
177
- *
178
- * A seam on the checker rather than a bare call, because the production
179
- * implementation only works in a worker on a `blob:` token, and is therefore
180
- * **inert under jest**. That inertness is not hypothetical: it let a deletion of
181
- * this whole mechanism pass all 6000+ unit tests. Overriding
182
- * `checker.syncProbe` is how a test asserts the loop consults it at all.
183
- */
184
- export type SyncStopProbe = (stopToken: string) => boolean;
185
- export interface StopTokenChecker {
186
- stopToken?: StopToken;
187
- sabView?: Int32Array;
188
- iters: number;
189
- checkInterval: number;
190
- checkDue: TimeGate;
191
- syncProbe: SyncStopProbe;
192
- }
193
- export declare function createStopTokenChecker(stopToken: StopToken | undefined): StopTokenChecker;
194
- /**
195
- * The in-loop counterpart to {@link checkStopToken}, throttled so a
196
- * million-iteration loop doesn't pay per item.
197
- *
198
- * Reads the stopped-id set *and* the synchronous probe, because a loop that
199
- * awaits between items can see the first and a loop that never yields can only
200
- * see the second. Both are behind the same wall-clock gate, so the per-item cost
201
- * is one counter bump.
202
- */
203
- export declare function checkStopTokenThrottled(checker?: StopTokenChecker): void;
204
- /**
205
- * Former name of {@link StopTokenChecker}. Still the primary spelling in several
206
- * in-tree RPC argument types (the three variants methods, `WiggleRPC/types.ts`)
207
- * as well as in external consumers, so it is a live alias rather than a
208
- * deprecation shim — renaming those is a wire-type edit with no behavior in it.
209
- */
210
- export type LastStopTokenCheck = StopTokenChecker;
211
- export {};
@@ -1,438 +0,0 @@
1
- import { makeAbortError } from './aborting.js';
2
- import { isWebWorker } from './isWebWorker.js';
3
- import { nanoid } from './nanoid.js';
4
- import { createTimeGate } from './timeGate.js';
5
- // Atomic flag values stored in the Int32Array view of the SharedArrayBuffer.
6
- // SAB ARM — unreached unless the host page is cross-origin isolated.
7
- const ABORT_FLAG_CLEAR = 0;
8
- const ABORT_FLAG_SET = 1;
9
- // How often the SAB path performs its (cheap) atomic read. SAB ARM.
10
- const SAB_CHECK_EVERY_N_ITERS = 10;
11
- // THE LIVE PATH's throttle. Minimum ms between a string token's in-loop checks
12
- // (also the linear-backoff step), and a cap so cancel latency stays bounded on a long-running loop. The
13
- // gate exists for the synchronous XHR probe, which is far too expensive per
14
- // item; the free set lookup rides along inside it.
15
- const STRING_CHECK_INTERVAL_MS = 50;
16
- const STRING_CHECK_INTERVAL_MAX_MS = 500;
17
- function isSharedArrayBuffer(value) {
18
- return (typeof SharedArrayBuffer !== 'undefined' &&
19
- value instanceof SharedArrayBuffer);
20
- }
21
- // A view is allocated per use rather than cached per buffer. That looks like an
22
- // easy win and is not one: the deployments this ships to are not cross-origin
23
- // isolated, so `hasSharedArrayBuffer` is false and every token is a string —
24
- // caching here would add a module-global WeakMap to speed up the branch that
25
- // never runs. The string path allocates nothing.
26
- function sabView(stopToken) {
27
- return new Int32Array(stopToken);
28
- }
29
- /**
30
- * Narrow an untyped RPC argument to a StopToken, so a caller holding
31
- * `Record<string, unknown>` can check one without a cast.
32
- */
33
- export function isStopToken(value) {
34
- return typeof value === 'string' || isSharedArrayBuffer(value);
35
- }
36
- // Browser support for SharedArrayBuffer requires cross-origin isolation
37
- // headers (COOP/COEP). Exported so diagnostic surfaces (about widget,
38
- // error stack trace) can show whether the page actually got the fast path.
39
- //
40
- // **ISOLATION IS THE QUESTION, not constructibility**, which is what the
41
- // sentence above has always claimed and what a bare `new SharedArrayBuffer(4)`
42
- // never asked. A browser gates the constructor on isolation, so on the web the
43
- // two agree — but a V8 embedder does not, and both of ours are embedders:
44
- //
45
- // - **jest.** Node constructs one unconditionally, so every test ran the SAB
46
- // path while every browser deployment ran the string path. That inverted the
47
- // fidelity — the SAB check reads its atomic once every 10 iterations where a
48
- // string token's time gate fires on the first call — and hid a real bug for
49
- // as long as it existed (`withProgress`'s kickoff `report(0)` throwing past
50
- // `endPhase()` on an already-stopped token, a9e5daba8f). A test suite that
51
- // cannot reach the deployment path by default is the wrong way round.
52
- // - **Electron.** Measured, because the guess went the other way: with
53
- // `nodeIntegration: true` and `contextIsolation: false` it looks as though
54
- // Node's `SharedArrayBuffer` would reach the renderer off a `file://` page.
55
- // It does not — Blink removes the binding and Node integration does not put
56
- // it back. On Electron 44, packaged (`file://`) and dev (`http://localhost`),
57
- // renderer and worker alike, `typeof SharedArrayBuffer` is `'undefined'` and
58
- // `crossOriginIsolated` is false. So jbrowse-desktop was already on the
59
- // string path and this changes nothing for it.
60
- //
61
- // Which leaves jest as the only realm this moves, and no shipped configuration
62
- // on the SAB branch at all unless a host isolates itself.
63
- //
64
- // What this does NOT change is the one configuration the branch is kept for:
65
- // an embedding host that sets COOP/COEP is cross-origin isolated, reports so
66
- // here, and still gets the fast path (ADR-056). `website/scripts/coi-probe.ts`
67
- // serves exactly that page and is the regression check.
68
- export const hasSharedArrayBuffer = (() => {
69
- if (globalThis.crossOriginIsolated !==
70
- true) {
71
- return false;
72
- }
73
- try {
74
- return isSharedArrayBuffer(new SharedArrayBuffer(4));
75
- }
76
- catch {
77
- return false;
78
- }
79
- })();
80
- // ---------------------------------------------------------------------------
81
- // Stopped-id registry (the message path)
82
- // ---------------------------------------------------------------------------
83
- // Retention for a stopped id. An entry is only useful while work carrying that
84
- // token could still check it, and work unwinds within moments of its own
85
- // cancellation, so this is bounded by *age* rather than by a count: a count cap
86
- // silently drops a still-live token's stopped-ness once enough other operations
87
- // have been cancelled, and answering "not stopped" for a stopped token is a lost
88
- // cancellation, not a slow one. Age bounds memory by cancellation *rate*
89
- // instead, and no plausible check arrives minutes after its own stop.
90
- const STOPPED_ID_TTL_MS = 5 * 60 * 1000;
91
- // Sweep only once the map is big enough that retention could matter, so the
92
- // common case is a plain insert.
93
- const STOPPED_ID_SWEEP_AT = 256;
94
- const stoppedIds = new Map();
95
- const signalControllers = new Map();
96
- /**
97
- * Record that a string token has been stopped, and abort any {@link
98
- * stopTokenSignal} taken against it. Called locally by {@link stopStopToken},
99
- * and in a worker by `RpcServer` when the main thread posts a stopped id.
100
- */
101
- export function markStopTokenStopped(id) {
102
- const now = Date.now();
103
- // delete first: `set` on an existing key keeps its original insertion
104
- // position, so a re-stopped id would sit at the front of the iteration order
105
- // carrying a fresh timestamp, and the sweep below would break there forever
106
- stoppedIds.delete(id);
107
- stoppedIds.set(id, now);
108
- if (stoppedIds.size > STOPPED_ID_SWEEP_AT) {
109
- // a Map iterates in insertion order, and timestamps only increase, so this
110
- // can stop at the first entry still inside the window
111
- for (const [key, stoppedAt] of stoppedIds) {
112
- if (now - stoppedAt < STOPPED_ID_TTL_MS) {
113
- break;
114
- }
115
- stoppedIds.delete(key);
116
- }
117
- }
118
- const controllers = signalControllers.get(id);
119
- if (controllers) {
120
- signalControllers.delete(id);
121
- for (const controller of controllers) {
122
- controller.abort(makeAbortError());
123
- }
124
- }
125
- }
126
- const broadcasters = new Set();
127
- /**
128
- * Register a transport that forwards a stopped token's id to wherever the work
129
- * is running. Drivers owning a worker pool register at construction and drop it
130
- * on destroy; `MainThreadRpcDriver` needs none — its work shares this module
131
- * instance and reads `stoppedIds` directly, which is why main-thread RPC gets
132
- * exact cancellation without any message at all.
133
- */
134
- export function registerStopTokenBroadcaster(fn) {
135
- broadcasters.add(fn);
136
- return () => {
137
- broadcasters.delete(fn);
138
- };
139
- }
140
- // ---------------------------------------------------------------------------
141
- // Create / stop
142
- // ---------------------------------------------------------------------------
143
- /**
144
- * Mint a token. **The right-hand branch is the one that runs** — see "Which
145
- * path runs where"; `hasSharedArrayBuffer` is false in everything we ship.
146
- */
147
- export function createStopToken() {
148
- // A fresh SharedArrayBuffer is already zeroed, i.e. ABORT_FLAG_CLEAR.
149
- return hasSharedArrayBuffer ? new SharedArrayBuffer(4) : createStringToken();
150
- }
151
- // One Blob behind every token. Object URLs minted over the same blob are
152
- // distinct ids and revoke independently, so nothing about the probe changes —
153
- // but a zoom mints these continuously and constructing the blob was showing up
154
- // beside `createObjectURL` in a profile.
155
- const emptyBlob = new Blob();
156
- // Uniqueness for the fallback id below, which is the one thing it must have and
157
- // the one thing `nanoid()` alone does not guarantee: it draws from
158
- // `crypto.getRandomValues`, and an environment is free to replace that. Ours
159
- // does — `config/jest/deterministicIds.js` swaps in a counter PRNG and RESETS
160
- // it before every test, so every test drew the same first id. Since a stopped
161
- // id is recorded in a module-global map, one stopped token then read as stopped
162
- // in every later test of the file, which is a live token that throws.
163
- //
164
- // Invisible until it mattered: this fallback serves the realms with no
165
- // `createObjectURL`, jest among them, and jest minted SharedArrayBuffers — whose
166
- // identity is the object — until `hasSharedArrayBuffer` started asking about
167
- // cross-origin isolation. A browser has `createObjectURL` and mints distinct
168
- // ids per call, so nothing here changes for a deployment.
169
- let stringTokenSeq = 0;
170
- function createStringToken() {
171
- // A blob URL serves as both the token's unique id (which is all the message
172
- // path needs) and the thing the sync probe fails against once revoked. Where
173
- // createObjectURL is unavailable a bare id still gives full await-boundary
174
- // cancellation — it just has no sync probe. That is a real degradation but no
175
- // longer the old hole, where such a token could never be cancelled at all.
176
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
177
- return URL.createObjectURL === undefined
178
- ? `${nanoid()}-${++stringTokenSeq}`
179
- : URL.createObjectURL(emptyBlob);
180
- }
181
- /**
182
- * Stop a token: every check against it now throws, every {@link
183
- * stopTokenSignal} taken against it aborts, and workers are told so their
184
- * in-flight calls do the same.
185
- *
186
- * Call it when an operation ends, not only when cancelling one — a completed
187
- * fetch's token otherwise pins its signal controllers until the next fetch
188
- * supersedes it.
189
- */
190
- export function stopStopToken(stopToken) {
191
- if (stopToken !== undefined) {
192
- // SAB ARM — dead in every configuration we ship
193
- if (isSharedArrayBuffer(stopToken)) {
194
- const view = sabView(stopToken);
195
- Atomics.store(view, 0, ABORT_FLAG_SET);
196
- // wakes the waitAsync watcher stopTokenSignal installs; free when there
197
- // is none waiting
198
- Atomics.notify(view, 0);
199
- }
200
- else if (!stoppedIds.has(stopToken)) {
201
- // Guarded, because one token is stopped two or three times over. A fetch's
202
- // `finally` stops it, the rotation's next `begin` stops what it is
203
- // superseding, and `cancel` stops it again — and each repeat re-inserted
204
- // the id and fanned a postMessage out to every worker in the pool for a
205
- // token they had all already been told about. The revoke is idempotent
206
- // but the broadcast is not free.
207
- markStopTokenStopped(stopToken);
208
- for (const broadcast of broadcasters) {
209
- broadcast(stopToken);
210
- }
211
- // revoking is what makes the sync probe start failing, so this is load
212
- // bearing for in-loop cancellation and not just cleanup
213
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
214
- URL.revokeObjectURL?.(stopToken);
215
- }
216
- }
217
- }
218
- /**
219
- * The production {@link SyncStopProbe}: a synchronous XHR against the token's
220
- * blob URL, which succeeds while the URL is live and throws once the main thread
221
- * has revoked it.
222
- *
223
- * Returns false rather than probing when it cannot tell — outside a worker
224
- * (synchronous XHR there is deprecated and would block the UI) or on a
225
- * non-`blob:` id (probing one would 404 and abort on the first check). jsdom is
226
- * not a worker global, so this is inert under jest; see {@link SyncStopProbe}
227
- * for what that cost us and how tests work around it.
228
- */
229
- function probeBlobUrl(stopToken) {
230
- let stopped = false;
231
- if (isWebWorker() && stopToken.startsWith('blob:')) {
232
- const xhr = new XMLHttpRequest();
233
- xhr.open('GET', stopToken, false);
234
- try {
235
- xhr.send(null);
236
- }
237
- catch {
238
- stopped = true;
239
- }
240
- }
241
- return stopped;
242
- }
243
- // ---------------------------------------------------------------------------
244
- // One-shot check (use at async boundaries)
245
- // ---------------------------------------------------------------------------
246
- /**
247
- * Whether this token has been stopped, without throwing. Prefer {@link
248
- * checkStopToken} where an abort should unwind the operation; use this to bail
249
- * out cleanly instead of throwing and catching one frame up.
250
- */
251
- export function isStopped(stopToken) {
252
- // the third arm is the live one; the middle is the SAB one
253
- return stopToken === undefined
254
- ? false
255
- : isSharedArrayBuffer(stopToken)
256
- ? Atomics.load(sabView(stopToken), 0) === ABORT_FLAG_SET
257
- : stoppedIds.has(stopToken);
258
- }
259
- /**
260
- * Throw an AbortError if this token has been stopped. Place at await
261
- * boundaries; this costs an atomic load or a set lookup, never a probe.
262
- */
263
- export function checkStopToken(stopToken) {
264
- if (isStopped(stopToken)) {
265
- throw makeAbortError();
266
- }
267
- }
268
- /**
269
- * Run an awaited stage under a stop token: checked before it starts, and again
270
- * once it settles. Prefer this to hand-placing {@link checkStopToken} around an
271
- * await — the point is that the check *after* comes with the one before, and the
272
- * one after is always the one that gets left out.
273
- *
274
- * It reads as sufficient to check at the top of an operation, because at the
275
- * time you write it the await below is not yet the slow part. `BaseRpcDriver`
276
- * checked at entry and then awaited `serializeArguments`, which resolves the
277
- * refName map, which downloads the adapter's index — and for an in-memory
278
- * adapter the whole file. A stop landing in that window woke a worker anyway.
279
- *
280
- * {@link updateStatus} and {@link withProgress} in `progress.ts` are this same
281
- * shape for a stage that also has something to say on the status channel; reach
282
- * for one of those when there is a label, and this when there isn't. What you
283
- * should not reach for is a bare `checkStopToken` sprinkled at a boundary you
284
- * happened to think of — the periodic in-loop case is
285
- * {@link checkStopTokenThrottled}, and it is driven by `createProgressReporter`
286
- * for the same reason.
287
- *
288
- * **Checking twice costs nothing, and it is worth knowing why**, because the
289
- * cost of a stop-token check is otherwise easy to remember backwards. The
290
- * expensive one is the synchronous XHR blob probe, which runs at up to ~10ms a
291
- * call — and it is reached ONLY from {@link checkStopTokenThrottled}, behind a
292
- * wall-clock gate with linear backoff, precisely because of that. This path is
293
- * {@link isStopped}: an atomic load for a SAB token, a `Map.has` for a string
294
- * one. So an extra boundary check here is free, and a per-item one in a tight
295
- * loop is not — which is the split the two functions exist to keep.
296
- */
297
- export async function withStopTokenCheck(stopToken, fn) {
298
- checkStopToken(stopToken);
299
- const result = await fn();
300
- checkStopToken(stopToken);
301
- return result;
302
- }
303
- /**
304
- * An `AbortSignal` wired to a stop token, so a canceled operation drops its
305
- * in-flight HTTP reads at the socket instead of downloading them to completion
306
- * and discarding the result. Call it where the work runs (worker-side for
307
- * worker RPC) and pass `signal` down through `BaseOptions`, which the gmod
308
- * readers already forward to `fetch`.
309
- *
310
- * No polling and no synchronous probe: a string token aborts off the same
311
- * posted id the await-boundary check reads, and a SharedArrayBuffer token off
312
- * `Atomics.waitAsync`, woken by the `Atomics.notify` in {@link stopStopToken}
313
- * — that one lands a turn or two after the notify rather than synchronously
314
- * with it, which costs nothing when the point is to stop a download.
315
- *
316
- * `dispose()` in a `finally` — an undisposed entry pins its controller until
317
- * the token is stopped.
318
- */
319
- export function stopTokenSignal(stopToken) {
320
- const controller = new AbortController();
321
- let dispose = () => { };
322
- if (isStopped(stopToken)) {
323
- controller.abort(makeAbortError());
324
- }
325
- else if (stopToken !== undefined) {
326
- // SAB ARM — dead in every configuration we ship
327
- if (isSharedArrayBuffer(stopToken)) {
328
- // waitAsync is specified alongside SharedArrayBuffer, but it postdates it
329
- // in browsers, so treat it as optional rather than assumed: without it a
330
- // SAB deployment simply keeps today's behavior of not aborting sockets.
331
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
332
- if (Atomics.waitAsync !== undefined) {
333
- const wait = Atomics.waitAsync(sabView(stopToken), 0, ABORT_FLAG_CLEAR);
334
- let disposed = false;
335
- dispose = () => {
336
- disposed = true;
337
- };
338
- const onWake = () => {
339
- if (!disposed) {
340
- controller.abort(makeAbortError());
341
- }
342
- };
343
- if (wait.async) {
344
- void wait.value.then(onWake);
345
- }
346
- else {
347
- // 'not-equal' — the flag moved between the isStopped read above and
348
- // here, so it is already set
349
- onWake();
350
- }
351
- }
352
- }
353
- else {
354
- const controllers = signalControllers.get(stopToken);
355
- if (controllers) {
356
- controllers.add(controller);
357
- }
358
- else {
359
- signalControllers.set(stopToken, new Set([controller]));
360
- }
361
- dispose = () => {
362
- const set = signalControllers.get(stopToken);
363
- if (set) {
364
- set.delete(controller);
365
- if (set.size === 0) {
366
- signalControllers.delete(stopToken);
367
- }
368
- }
369
- };
370
- }
371
- }
372
- return { signal: controller.signal, dispose };
373
- }
374
- /**
375
- * Run `fn` with an `AbortSignal` wired to this stop token, releasing the signal
376
- * afterwards however `fn` settles. The shape to reach for at an adapter's read
377
- * call — {@link stopTokenSignal} directly is for the rare case that outlives one
378
- * awaited call, and it then owns remembering to dispose.
379
- */
380
- export async function withStopTokenSignal(stopToken, fn) {
381
- const { signal, dispose } = stopTokenSignal(stopToken);
382
- try {
383
- return await fn(signal);
384
- }
385
- finally {
386
- dispose();
387
- }
388
- }
389
- export function createStopTokenChecker(stopToken) {
390
- return {
391
- stopToken,
392
- sabView: stopToken !== undefined && isSharedArrayBuffer(stopToken)
393
- ? sabView(stopToken)
394
- : undefined,
395
- iters: 0,
396
- checkInterval: STRING_CHECK_INTERVAL_MS,
397
- checkDue: createTimeGate(),
398
- syncProbe: probeBlobUrl,
399
- };
400
- }
401
- /**
402
- * The in-loop counterpart to {@link checkStopToken}, throttled so a
403
- * million-iteration loop doesn't pay per item.
404
- *
405
- * Reads the stopped-id set *and* the synchronous probe, because a loop that
406
- * awaits between items can see the first and a loop that never yields can only
407
- * see the second. Both are behind the same wall-clock gate, so the per-item cost
408
- * is one counter bump.
409
- */
410
- export function checkStopTokenThrottled(checker) {
411
- // narrowed into a local because a checker's `sabView` and its token type move
412
- // together but are separate properties, so the branch below can't discriminate
413
- // on `sabView` alone
414
- const stopToken = checker?.stopToken;
415
- if (checker !== undefined && stopToken !== undefined) {
416
- // THE LIVE PATH. Both halves of it: the set lookup catches a token stopped
417
- // through the message path, the probe catches one in a loop that never
418
- // yields to receive that message.
419
- if (typeof stopToken === 'string') {
420
- if (checker.checkDue(checker.checkInterval)) {
421
- if (stoppedIds.has(stopToken) || checker.syncProbe(stopToken)) {
422
- throw makeAbortError();
423
- }
424
- // Linear backoff, capped, so probe cost thins over a long loop while
425
- // cancel latency stays bounded. Advances only past a probe that ran.
426
- checker.checkInterval = Math.min(checker.checkInterval + STRING_CHECK_INTERVAL_MS, STRING_CHECK_INTERVAL_MAX_MS);
427
- }
428
- // SAB ARM, dead in every configuration we ship: a cheap atomic read,
429
- // gated by a small iteration mask. The counter is bumped here rather than
430
- // above the branch because it is the only reader of it.
431
- }
432
- else if (checker.sabView &&
433
- ++checker.iters % SAB_CHECK_EVERY_N_ITERS === 0 &&
434
- Atomics.load(checker.sabView, 0) === ABORT_FLAG_SET) {
435
- throw makeAbortError();
436
- }
437
- }
438
- }