waybetter 0.1.1 → 0.6.0

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 (515) hide show
  1. package/README.md +140 -6
  2. package/bin/waybetter.mjs +46 -0
  3. package/build/runtime.mjs +105 -0
  4. package/cli/buildenv.mjs +130 -0
  5. package/cli/dev.mjs +97 -0
  6. package/cli/i18n.mjs +382 -0
  7. package/cli/manifests.mjs +383 -0
  8. package/cli/privacy.mjs +768 -0
  9. package/cli/release.mjs +444 -0
  10. package/cli/remote.mjs +260 -0
  11. package/cli/store.mjs +326 -0
  12. package/cli/strings.mjs +121 -0
  13. package/dist/runtime/column.d.ts +93 -0
  14. package/dist/runtime/column.js +451 -0
  15. package/dist/runtime/column.js.map +1 -0
  16. package/dist/runtime/commandReport.d.ts +19 -0
  17. package/dist/runtime/commandReport.js +47 -0
  18. package/dist/runtime/commandReport.js.map +1 -0
  19. package/dist/runtime/commands.d.ts +72 -0
  20. package/dist/runtime/commands.js +214 -0
  21. package/dist/runtime/commands.js.map +1 -0
  22. package/dist/runtime/devErrors.d.ts +16 -0
  23. package/dist/runtime/devErrors.js +30 -0
  24. package/dist/runtime/devErrors.js.map +1 -0
  25. package/dist/runtime/domHub.d.ts +21 -0
  26. package/dist/runtime/domHub.js +139 -4
  27. package/dist/runtime/domHub.js.map +1 -1
  28. package/dist/runtime/featureModules.d.ts +157 -0
  29. package/dist/runtime/featureModules.js +484 -0
  30. package/dist/runtime/featureModules.js.map +1 -0
  31. package/dist/runtime/featureTable.d.ts +144 -0
  32. package/dist/runtime/featureTable.js +223 -0
  33. package/dist/runtime/featureTable.js.map +1 -0
  34. package/dist/runtime/fonts.d.ts +22 -0
  35. package/dist/runtime/fonts.js +72 -0
  36. package/dist/runtime/fonts.js.map +1 -0
  37. package/dist/runtime/i18n.d.ts +138 -0
  38. package/dist/runtime/i18n.js +614 -0
  39. package/dist/runtime/i18n.js.map +1 -0
  40. package/dist/runtime/i18nCheck.d.ts +30 -0
  41. package/dist/runtime/i18nCheck.js +224 -0
  42. package/dist/runtime/i18nCheck.js.map +1 -0
  43. package/dist/runtime/pageLang.d.ts +8 -0
  44. package/dist/runtime/pageLang.js +64 -0
  45. package/dist/runtime/pageLang.js.map +1 -0
  46. package/dist/runtime/pageStrings.d.ts +35 -0
  47. package/dist/runtime/pageStrings.js +76 -0
  48. package/dist/runtime/pageStrings.js.map +1 -0
  49. package/dist/runtime/panelButton.d.ts +33 -0
  50. package/dist/runtime/panelButton.js +83 -0
  51. package/dist/runtime/panelButton.js.map +1 -0
  52. package/dist/runtime/permissions.d.ts +47 -0
  53. package/dist/runtime/permissions.js +141 -0
  54. package/dist/runtime/permissions.js.map +1 -0
  55. package/dist/runtime/pluginApi.d.ts +51 -2
  56. package/dist/runtime/pluginApi.js +137 -22
  57. package/dist/runtime/pluginApi.js.map +1 -1
  58. package/dist/runtime/pluginI18n.d.ts +29 -0
  59. package/dist/runtime/pluginI18n.js +119 -0
  60. package/dist/runtime/pluginI18n.js.map +1 -0
  61. package/dist/runtime/settingsForm.d.ts +66 -0
  62. package/dist/runtime/settingsForm.js +114 -0
  63. package/dist/runtime/settingsForm.js.map +1 -0
  64. package/dist/runtime/site.d.ts +5 -0
  65. package/dist/runtime/site.js +1 -1
  66. package/dist/runtime/site.js.map +1 -1
  67. package/dist/runtime/siteRuntime.d.ts +144 -0
  68. package/dist/runtime/siteRuntime.js +175 -0
  69. package/dist/runtime/siteRuntime.js.map +1 -0
  70. package/dist/runtime/stringPackHook.d.ts +84 -0
  71. package/dist/runtime/stringPackHook.js +220 -0
  72. package/dist/runtime/stringPackHook.js.map +1 -0
  73. package/dist/runtime/stringPackTranslate.d.ts +59 -0
  74. package/dist/runtime/stringPackTranslate.js +264 -0
  75. package/dist/runtime/stringPackTranslate.js.map +1 -0
  76. package/dist/runtime/stringPacks.d.ts +200 -0
  77. package/dist/runtime/stringPacks.js +474 -0
  78. package/dist/runtime/stringPacks.js.map +1 -0
  79. package/dist/runtime/styles.d.ts +15 -0
  80. package/dist/runtime/styles.js +81 -0
  81. package/dist/runtime/styles.js.map +1 -0
  82. package/dist/runtime/textNet.d.ts +15 -0
  83. package/dist/runtime/textNet.js +131 -0
  84. package/dist/runtime/textNet.js.map +1 -0
  85. package/dist/runtime/themeApi.d.ts +121 -0
  86. package/dist/runtime/themeApi.js +220 -0
  87. package/dist/runtime/themeApi.js.map +1 -0
  88. package/dist/runtime/themeChoice.d.ts +52 -0
  89. package/dist/runtime/themeChoice.js +69 -0
  90. package/dist/runtime/themeChoice.js.map +1 -0
  91. package/dist/runtime/themeComponents.d.ts +435 -0
  92. package/dist/runtime/themeComponents.js +463 -0
  93. package/dist/runtime/themeComponents.js.map +1 -0
  94. package/dist/runtime/themeDecor.d.ts +73 -0
  95. package/dist/runtime/themeDecor.js +131 -0
  96. package/dist/runtime/themeDecor.js.map +1 -0
  97. package/dist/runtime/themeDoctor.d.ts +11 -0
  98. package/dist/runtime/themeDoctor.js +51 -0
  99. package/dist/runtime/themeDoctor.js.map +1 -0
  100. package/dist/runtime/themeIcons.d.ts +130 -0
  101. package/dist/runtime/themeIcons.js +263 -0
  102. package/dist/runtime/themeIcons.js.map +1 -0
  103. package/dist/runtime/themeRuntime.d.ts +100 -0
  104. package/dist/runtime/themeRuntime.js +497 -0
  105. package/dist/runtime/themeRuntime.js.map +1 -0
  106. package/dist/runtime/themeSchema.d.ts +10 -0
  107. package/dist/runtime/themeSchema.js +150 -0
  108. package/dist/runtime/themeSchema.js.map +1 -0
  109. package/dist/runtime/themeSpec.d.ts +259 -0
  110. package/dist/runtime/themeSpec.js +439 -0
  111. package/dist/runtime/themeSpec.js.map +1 -0
  112. package/dist/runtime/themeTokens.d.ts +12 -0
  113. package/dist/runtime/themeTokens.js +14 -6
  114. package/dist/runtime/themeTokens.js.map +1 -1
  115. package/dist/runtime/themeVariants.d.ts +30 -0
  116. package/dist/runtime/themeVariants.js +53 -0
  117. package/dist/runtime/themeVariants.js.map +1 -0
  118. package/dist/runtime/ui.d.ts +192 -0
  119. package/dist/runtime/ui.js +926 -0
  120. package/dist/runtime/ui.js.map +1 -0
  121. package/dist/shell/InstallDialog.d.ts +40 -0
  122. package/dist/shell/InstallDialog.js +170 -0
  123. package/dist/shell/InstallDialog.js.map +1 -0
  124. package/dist/shell/StoreView.d.ts +66 -0
  125. package/dist/shell/StoreView.js +103 -0
  126. package/dist/shell/StoreView.js.map +1 -0
  127. package/dist/shell/addressModel.js.map +1 -1
  128. package/dist/shell/chrome.js.map +1 -1
  129. package/dist/shell/deckModel.d.ts +117 -0
  130. package/dist/shell/deckModel.js +267 -0
  131. package/dist/shell/deckModel.js.map +1 -0
  132. package/dist/shell/frame/AccountSwitcher.d.ts +42 -0
  133. package/dist/shell/frame/AccountSwitcher.js +243 -0
  134. package/dist/shell/frame/AccountSwitcher.js.map +1 -0
  135. package/dist/shell/frame/AddColumnDialog.d.ts +8 -0
  136. package/dist/shell/frame/AddColumnDialog.js +81 -0
  137. package/dist/shell/frame/AddColumnDialog.js.map +1 -0
  138. package/dist/shell/frame/AppMenu.d.ts +21 -0
  139. package/dist/shell/frame/AppMenu.js +642 -0
  140. package/dist/shell/frame/AppMenu.js.map +1 -0
  141. package/dist/shell/frame/CommandPalette.d.ts +7 -0
  142. package/dist/shell/frame/CommandPalette.js +118 -0
  143. package/dist/shell/frame/CommandPalette.js.map +1 -0
  144. package/dist/shell/frame/DeckView.d.ts +13 -0
  145. package/dist/shell/frame/DeckView.js +287 -0
  146. package/dist/shell/frame/DeckView.js.map +1 -0
  147. package/dist/shell/frame/FindBar.d.ts +10 -0
  148. package/dist/shell/frame/FindBar.js +108 -0
  149. package/dist/shell/frame/FindBar.js.map +1 -0
  150. package/dist/shell/frame/MediaPanel.d.ts +8 -0
  151. package/dist/shell/frame/MediaPanel.js +76 -0
  152. package/dist/shell/frame/MediaPanel.js.map +1 -0
  153. package/dist/shell/frame/NewTabPage.d.ts +9 -0
  154. package/dist/shell/frame/NewTabPage.js +71 -0
  155. package/dist/shell/frame/NewTabPage.js.map +1 -0
  156. package/dist/shell/frame/PaneTheme.d.ts +16 -0
  157. package/dist/shell/frame/PaneTheme.js +67 -0
  158. package/dist/shell/frame/PaneTheme.js.map +1 -0
  159. package/dist/shell/frame/ReportDialog.d.ts +3 -0
  160. package/dist/shell/frame/ReportDialog.js +95 -0
  161. package/dist/shell/frame/ReportDialog.js.map +1 -0
  162. package/dist/shell/frame/Shell.d.ts +8 -0
  163. package/dist/shell/frame/Shell.js +1131 -0
  164. package/dist/shell/frame/Shell.js.map +1 -0
  165. package/dist/shell/frame/Titlebar.d.ts +16 -0
  166. package/dist/shell/frame/Titlebar.js +77 -0
  167. package/dist/shell/frame/Titlebar.js.map +1 -0
  168. package/dist/shell/frame/TitlebarExtras.d.ts +4 -0
  169. package/dist/shell/frame/TitlebarExtras.js +202 -0
  170. package/dist/shell/frame/TitlebarExtras.js.map +1 -0
  171. package/dist/shell/frame/WebPanel.d.ts +4 -0
  172. package/dist/shell/frame/WebPanel.js +182 -0
  173. package/dist/shell/frame/WebPanel.js.map +1 -0
  174. package/dist/shell/frame/accountModel.d.ts +49 -0
  175. package/dist/shell/frame/accountModel.js +67 -0
  176. package/dist/shell/frame/accountModel.js.map +1 -0
  177. package/dist/shell/frame/accountSwitcher.css +91 -0
  178. package/dist/shell/frame/appI18n.d.ts +44 -0
  179. package/dist/shell/frame/appI18n.js +64 -0
  180. package/dist/shell/frame/appI18n.js.map +1 -0
  181. package/dist/shell/frame/appMenu.css +121 -0
  182. package/dist/shell/frame/backupModel.d.ts +38 -0
  183. package/dist/shell/frame/backupModel.js +192 -0
  184. package/dist/shell/frame/backupModel.js.map +1 -0
  185. package/dist/shell/frame/boot.d.ts +8 -0
  186. package/dist/shell/frame/boot.js +35 -0
  187. package/dist/shell/frame/boot.js.map +1 -0
  188. package/dist/shell/frame/brand.d.ts +1 -0
  189. package/dist/shell/frame/brand.js +4 -0
  190. package/dist/shell/frame/brand.js.map +1 -0
  191. package/dist/shell/frame/bridge.d.ts +35 -0
  192. package/dist/shell/frame/bridge.js +70 -0
  193. package/dist/shell/frame/bridge.js.map +1 -0
  194. package/dist/shell/frame/chromeTheme.d.ts +29 -0
  195. package/dist/shell/frame/chromeTheme.js +81 -0
  196. package/dist/shell/frame/chromeTheme.js.map +1 -0
  197. package/dist/shell/frame/deck.css +209 -0
  198. package/dist/shell/frame/deckStore.d.ts +89 -0
  199. package/dist/shell/frame/deckStore.js +239 -0
  200. package/dist/shell/frame/deckStore.js.map +1 -0
  201. package/dist/shell/frame/devHost.d.ts +35 -0
  202. package/dist/shell/frame/devHost.js +80 -0
  203. package/dist/shell/frame/devHost.js.map +1 -0
  204. package/dist/shell/frame/devModel.d.ts +7 -0
  205. package/dist/shell/frame/devModel.js +17 -0
  206. package/dist/shell/frame/devModel.js.map +1 -0
  207. package/dist/shell/frame/diag.d.ts +7 -0
  208. package/dist/shell/frame/diag.js +39 -0
  209. package/dist/shell/frame/diag.js.map +1 -0
  210. package/dist/shell/frame/findBar.css +14 -0
  211. package/dist/shell/frame/frameMessages.d.ts +248 -0
  212. package/dist/shell/frame/frameMessages.js +252 -0
  213. package/dist/shell/frame/frameMessages.js.map +1 -0
  214. package/dist/shell/frame/hooks.d.ts +39 -0
  215. package/dist/shell/frame/hooks.js +97 -0
  216. package/dist/shell/frame/hooks.js.map +1 -0
  217. package/dist/shell/frame/i18n.d.ts +27 -0
  218. package/dist/shell/frame/i18n.js +66 -0
  219. package/dist/shell/frame/i18n.js.map +1 -0
  220. package/dist/shell/frame/iconPack.d.ts +11 -0
  221. package/dist/shell/frame/iconPack.js +45 -0
  222. package/dist/shell/frame/iconPack.js.map +1 -0
  223. package/dist/shell/frame/icons.d.ts +71 -0
  224. package/dist/shell/frame/icons.js +75 -0
  225. package/dist/shell/frame/icons.js.map +1 -0
  226. package/dist/shell/frame/index.d.ts +34 -0
  227. package/dist/shell/frame/index.js +43 -0
  228. package/dist/shell/frame/index.js.map +1 -0
  229. package/dist/shell/frame/language.d.ts +58 -0
  230. package/dist/shell/frame/language.js +165 -0
  231. package/dist/shell/frame/language.js.map +1 -0
  232. package/dist/shell/frame/mediaModel.d.ts +34 -0
  233. package/dist/shell/frame/mediaModel.js +53 -0
  234. package/dist/shell/frame/mediaModel.js.map +1 -0
  235. package/dist/shell/frame/menuMessages.en.json +54 -0
  236. package/dist/shell/frame/menuModel.d.ts +277 -0
  237. package/dist/shell/frame/menuModel.js +293 -0
  238. package/dist/shell/frame/menuModel.js.map +1 -0
  239. package/dist/shell/frame/paletteModel.d.ts +139 -0
  240. package/dist/shell/frame/paletteModel.js +112 -0
  241. package/dist/shell/frame/paletteModel.js.map +1 -0
  242. package/dist/shell/frame/paneTheme.css +9 -0
  243. package/dist/shell/frame/pluginCommandStore.d.ts +23 -0
  244. package/dist/shell/frame/pluginCommandStore.js +70 -0
  245. package/dist/shell/frame/pluginCommandStore.js.map +1 -0
  246. package/dist/shell/frame/reportModel.d.ts +52 -0
  247. package/dist/shell/frame/reportModel.js +105 -0
  248. package/dist/shell/frame/reportModel.js.map +1 -0
  249. package/dist/shell/frame/safeStore.d.ts +7 -0
  250. package/dist/shell/frame/safeStore.js +40 -0
  251. package/dist/shell/frame/safeStore.js.map +1 -0
  252. package/dist/shell/frame/searchInput.d.ts +2 -0
  253. package/dist/shell/frame/searchInput.js +11 -0
  254. package/dist/shell/frame/searchInput.js.map +1 -0
  255. package/dist/shell/frame/shell.css +629 -0
  256. package/dist/shell/frame/site.d.ts +206 -0
  257. package/dist/shell/frame/site.js +22 -0
  258. package/dist/shell/frame/site.js.map +1 -0
  259. package/dist/shell/frame/state.d.ts +99 -0
  260. package/dist/shell/frame/state.js +284 -0
  261. package/dist/shell/frame/state.js.map +1 -0
  262. package/dist/shell/frame/syncGate.d.ts +10 -0
  263. package/dist/shell/frame/syncGate.js +36 -0
  264. package/dist/shell/frame/syncGate.js.map +1 -0
  265. package/dist/shell/frame/syncHost.d.ts +35 -0
  266. package/dist/shell/frame/syncHost.js +85 -0
  267. package/dist/shell/frame/syncHost.js.map +1 -0
  268. package/dist/shell/frame/tabStill.d.ts +2 -0
  269. package/dist/shell/frame/tabStill.js +62 -0
  270. package/dist/shell/frame/tabStill.js.map +1 -0
  271. package/dist/shell/frame/themeScopes.d.ts +29 -0
  272. package/dist/shell/frame/themeScopes.js +61 -0
  273. package/dist/shell/frame/themeScopes.js.map +1 -0
  274. package/dist/shell/frame/themeStore.d.ts +99 -0
  275. package/dist/shell/frame/themeStore.js +252 -0
  276. package/dist/shell/frame/themeStore.js.map +1 -0
  277. package/dist/shell/frame/windowBinding.d.ts +2 -0
  278. package/dist/shell/frame/windowBinding.js +7 -0
  279. package/dist/shell/frame/windowBinding.js.map +1 -0
  280. package/dist/shell/frame/workspaceModel.d.ts +82 -0
  281. package/dist/shell/frame/workspaceModel.js +250 -0
  282. package/dist/shell/frame/workspaceModel.js.map +1 -0
  283. package/dist/shell/frame/workspaces.css +84 -0
  284. package/dist/shell/frame/workspaces.d.ts +22 -0
  285. package/dist/shell/frame/workspaces.js +125 -0
  286. package/dist/shell/frame/workspaces.js.map +1 -0
  287. package/dist/shell/frame/zoomStore.d.ts +10 -0
  288. package/dist/shell/frame/zoomStore.js +65 -0
  289. package/dist/shell/frame/zoomStore.js.map +1 -0
  290. package/dist/shell/installController.d.ts +122 -0
  291. package/dist/shell/installController.js +146 -0
  292. package/dist/shell/installController.js.map +1 -0
  293. package/dist/shell/installerMessages.d.ts +30 -0
  294. package/dist/shell/installerMessages.js +36 -0
  295. package/dist/shell/installerMessages.js.map +1 -0
  296. package/dist/shell/linkDrop.js.map +1 -1
  297. package/dist/shell/messages.d.ts +16 -0
  298. package/dist/shell/messages.js +27 -0
  299. package/dist/shell/messages.js.map +1 -0
  300. package/dist/shell/palette.js.map +1 -1
  301. package/dist/shell/paneModel.d.ts +22 -0
  302. package/dist/shell/paneModel.js +24 -1
  303. package/dist/shell/paneModel.js.map +1 -1
  304. package/dist/shell/panel/Appearance.d.ts +8 -0
  305. package/dist/shell/panel/Appearance.js +256 -0
  306. package/dist/shell/panel/Appearance.js.map +1 -0
  307. package/dist/shell/panel/BackupPanel.d.ts +5 -0
  308. package/dist/shell/panel/BackupPanel.js +198 -0
  309. package/dist/shell/panel/BackupPanel.js.map +1 -0
  310. package/dist/shell/panel/DeveloperPanel.d.ts +4 -0
  311. package/dist/shell/panel/DeveloperPanel.js +51 -0
  312. package/dist/shell/panel/DeveloperPanel.js.map +1 -0
  313. package/dist/shell/panel/FeatureToggles.d.ts +13 -0
  314. package/dist/shell/panel/FeatureToggles.js +42 -0
  315. package/dist/shell/panel/FeatureToggles.js.map +1 -0
  316. package/dist/shell/panel/Home.d.ts +3 -0
  317. package/dist/shell/panel/Home.js +23 -0
  318. package/dist/shell/panel/Home.js.map +1 -0
  319. package/dist/shell/panel/IconPackInstall.d.ts +15 -0
  320. package/dist/shell/panel/IconPackInstall.js +41 -0
  321. package/dist/shell/panel/IconPackInstall.js.map +1 -0
  322. package/dist/shell/panel/LanguageSettings.d.ts +1 -0
  323. package/dist/shell/panel/LanguageSettings.js +54 -0
  324. package/dist/shell/panel/LanguageSettings.js.map +1 -0
  325. package/dist/shell/panel/MakePanel.d.ts +3 -0
  326. package/dist/shell/panel/MakePanel.js +237 -0
  327. package/dist/shell/panel/MakePanel.js.map +1 -0
  328. package/dist/shell/panel/MarkdownDoc.d.ts +6 -0
  329. package/dist/shell/panel/MarkdownDoc.js +35 -0
  330. package/dist/shell/panel/MarkdownDoc.js.map +1 -0
  331. package/dist/shell/panel/Modes.d.ts +40 -0
  332. package/dist/shell/panel/Modes.js +270 -0
  333. package/dist/shell/panel/Modes.js.map +1 -0
  334. package/dist/shell/panel/NavIcon.d.ts +4 -0
  335. package/dist/shell/panel/NavIcon.js +6 -0
  336. package/dist/shell/panel/NavIcon.js.map +1 -0
  337. package/dist/shell/panel/Panel.d.ts +7 -0
  338. package/dist/shell/panel/Panel.js +139 -0
  339. package/dist/shell/panel/Panel.js.map +1 -0
  340. package/dist/shell/panel/PluginFeatures.d.ts +24 -0
  341. package/dist/shell/panel/PluginFeatures.js +165 -0
  342. package/dist/shell/panel/PluginFeatures.js.map +1 -0
  343. package/dist/shell/panel/Plugins.d.ts +33 -0
  344. package/dist/shell/panel/Plugins.js +112 -0
  345. package/dist/shell/panel/Plugins.js.map +1 -0
  346. package/dist/shell/panel/PowerSettings.d.ts +4 -0
  347. package/dist/shell/panel/PowerSettings.js +52 -0
  348. package/dist/shell/panel/PowerSettings.js.map +1 -0
  349. package/dist/shell/panel/Settings.d.ts +23 -0
  350. package/dist/shell/panel/Settings.js +116 -0
  351. package/dist/shell/panel/Settings.js.map +1 -0
  352. package/dist/shell/panel/ShareSetup.d.ts +8 -0
  353. package/dist/shell/panel/ShareSetup.js +130 -0
  354. package/dist/shell/panel/ShareSetup.js.map +1 -0
  355. package/dist/shell/panel/StoreSection.d.ts +6 -0
  356. package/dist/shell/panel/StoreSection.js +48 -0
  357. package/dist/shell/panel/StoreSection.js.map +1 -0
  358. package/dist/shell/panel/StringPacks.d.ts +11 -0
  359. package/dist/shell/panel/StringPacks.js +106 -0
  360. package/dist/shell/panel/StringPacks.js.map +1 -0
  361. package/dist/shell/panel/ThemeBuilder.d.ts +5 -0
  362. package/dist/shell/panel/ThemeBuilder.js +205 -0
  363. package/dist/shell/panel/ThemeBuilder.js.map +1 -0
  364. package/dist/shell/panel/backup.css +34 -0
  365. package/dist/shell/panel/builder.css +232 -0
  366. package/dist/shell/panel/builderModel.d.ts +55 -0
  367. package/dist/shell/panel/builderModel.js +95 -0
  368. package/dist/shell/panel/builderModel.js.map +1 -0
  369. package/dist/shell/panel/compare.d.ts +10 -0
  370. package/dist/shell/panel/compare.js +51 -0
  371. package/dist/shell/panel/compare.js.map +1 -0
  372. package/dist/shell/panel/controls.d.ts +135 -0
  373. package/dist/shell/panel/controls.js +213 -0
  374. package/dist/shell/panel/controls.js.map +1 -0
  375. package/dist/shell/panel/featureModel.d.ts +69 -0
  376. package/dist/shell/panel/featureModel.js +79 -0
  377. package/dist/shell/panel/featureModel.js.map +1 -0
  378. package/dist/shell/panel/fonts/FontBrowser.d.ts +10 -0
  379. package/dist/shell/panel/fonts/FontBrowser.js +189 -0
  380. package/dist/shell/panel/fonts/FontBrowser.js.map +1 -0
  381. package/dist/shell/panel/fonts/FontRoles.d.ts +20 -0
  382. package/dist/shell/panel/fonts/FontRoles.js +77 -0
  383. package/dist/shell/panel/fonts/FontRoles.js.map +1 -0
  384. package/dist/shell/panel/fonts/catalog.d.ts +37 -0
  385. package/dist/shell/panel/fonts/catalog.js +68 -0
  386. package/dist/shell/panel/fonts/catalog.js.map +1 -0
  387. package/dist/shell/panel/fonts/googleFontsCatalog.json +1 -0
  388. package/dist/shell/panel/index.d.ts +20 -0
  389. package/dist/shell/panel/index.js +34 -0
  390. package/dist/shell/panel/index.js.map +1 -0
  391. package/dist/shell/panel/languageModel.d.ts +5 -0
  392. package/dist/shell/panel/languageModel.js +7 -0
  393. package/dist/shell/panel/languageModel.js.map +1 -0
  394. package/dist/shell/panel/make.css +72 -0
  395. package/dist/shell/panel/makeModel.d.ts +32 -0
  396. package/dist/shell/panel/makeModel.js +84 -0
  397. package/dist/shell/panel/makeModel.js.map +1 -0
  398. package/dist/shell/panel/markdown.d.ts +46 -0
  399. package/dist/shell/panel/markdown.js +100 -0
  400. package/dist/shell/panel/markdown.js.map +1 -0
  401. package/dist/shell/panel/nav.d.ts +12 -0
  402. package/dist/shell/panel/nav.js +50 -0
  403. package/dist/shell/panel/nav.js.map +1 -0
  404. package/dist/shell/panel/panel.css +401 -0
  405. package/dist/shell/panel/panelMessages.d.ts +763 -0
  406. package/dist/shell/panel/panelMessages.js +767 -0
  407. package/dist/shell/panel/panelMessages.js.map +1 -0
  408. package/dist/shell/panel/plugins.css +59 -0
  409. package/dist/shell/panel/setupModel.d.ts +87 -0
  410. package/dist/shell/panel/setupModel.js +152 -0
  411. package/dist/shell/panel/setupModel.js.map +1 -0
  412. package/dist/shell/panel/site.d.ts +259 -0
  413. package/dist/shell/panel/site.js +25 -0
  414. package/dist/shell/panel/site.js.map +1 -0
  415. package/dist/shell/panel/strings.css +7 -0
  416. package/dist/shell/panel/themes.d.ts +10 -0
  417. package/dist/shell/panel/themes.js +8 -0
  418. package/dist/shell/panel/themes.js.map +1 -0
  419. package/dist/shell/profileModel.d.ts +3 -2
  420. package/dist/shell/profileModel.js +7 -5
  421. package/dist/shell/profileModel.js.map +1 -1
  422. package/dist/shell/store.css +230 -0
  423. package/dist/shell/storeMessages.d.ts +169 -0
  424. package/dist/shell/storeMessages.js +172 -0
  425. package/dist/shell/storeMessages.js.map +1 -0
  426. package/dist/shell/storeModel.d.ts +181 -0
  427. package/dist/shell/storeModel.js +133 -0
  428. package/dist/shell/storeModel.js.map +1 -0
  429. package/dist/shell/stringPacksModel.d.ts +44 -0
  430. package/dist/shell/stringPacksModel.js +94 -0
  431. package/dist/shell/stringPacksModel.js.map +1 -0
  432. package/dist/shell/updateModel.d.ts +2 -1
  433. package/dist/shell/updateModel.js +5 -4
  434. package/dist/shell/updateModel.js.map +1 -1
  435. package/dist/shell/windowControls.d.ts +4 -0
  436. package/dist/shell/windowControls.js +5 -0
  437. package/dist/shell/windowControls.js.map +1 -1
  438. package/i18n-config.schema.json +29 -0
  439. package/i18n-meta.schema.json +26 -0
  440. package/i18n.schema.json +42 -0
  441. package/icons.schema.json +646 -0
  442. package/languages.schema.json +23 -0
  443. package/locales/ar-x-fm.json +11 -0
  444. package/locales/ar.json +1281 -0
  445. package/locales/bg.json +1280 -0
  446. package/locales/bn.json +1280 -0
  447. package/locales/ca.json +1280 -0
  448. package/locales/cs.json +1280 -0
  449. package/locales/da.json +1280 -0
  450. package/locales/de.json +1280 -0
  451. package/locales/el.json +1280 -0
  452. package/locales/en-GB.json +27 -0
  453. package/locales/en.json +1280 -0
  454. package/locales/en.meta.json +51 -0
  455. package/locales/es.json +1280 -0
  456. package/locales/eu.json +1280 -0
  457. package/locales/fa.json +1281 -0
  458. package/locales/fi.json +1280 -0
  459. package/locales/fil.json +1280 -0
  460. package/locales/fr.json +1280 -0
  461. package/locales/ga.json +1280 -0
  462. package/locales/gl.json +1280 -0
  463. package/locales/gu.json +1280 -0
  464. package/locales/ha.json +1280 -0
  465. package/locales/he.json +1281 -0
  466. package/locales/hi.json +1280 -0
  467. package/locales/hr.json +1280 -0
  468. package/locales/hu.json +1279 -0
  469. package/locales/id.json +1280 -0
  470. package/locales/ig.json +1280 -0
  471. package/locales/it.json +1280 -0
  472. package/locales/ja.json +1280 -0
  473. package/locales/kn.json +1280 -0
  474. package/locales/ko.json +1280 -0
  475. package/locales/mr.json +1280 -0
  476. package/locales/ms.json +1280 -0
  477. package/locales/nb.json +1280 -0
  478. package/locales/nl.json +1280 -0
  479. package/locales/pl.json +1280 -0
  480. package/locales/pt.json +1280 -0
  481. package/locales/ro.json +1280 -0
  482. package/locales/ru.json +1280 -0
  483. package/locales/sk.json +1280 -0
  484. package/locales/sr.json +1280 -0
  485. package/locales/sv.json +1280 -0
  486. package/locales/ta.json +1280 -0
  487. package/locales/th.json +1280 -0
  488. package/locales/tr.json +1280 -0
  489. package/locales/uk.json +1280 -0
  490. package/locales/ur.json +1281 -0
  491. package/locales/vi.json +1280 -0
  492. package/locales/yo.json +1280 -0
  493. package/locales/zh-Hans.json +1280 -0
  494. package/locales/zh-Hant.json +1280 -0
  495. package/package.json +139 -5
  496. package/store-catalog.schema.json +65 -0
  497. package/theme.schema.json +4659 -0
  498. package/windows/installer.nsi +926 -0
  499. package/windows/languages/Basque.nsh +28 -0
  500. package/windows/languages/Catalan.nsh +28 -0
  501. package/windows/languages/Croatian.nsh +28 -0
  502. package/windows/languages/Czech.nsh +28 -0
  503. package/windows/languages/Danish.nsh +28 -0
  504. package/windows/languages/Finnish.nsh +28 -0
  505. package/windows/languages/Galician.nsh +28 -0
  506. package/windows/languages/Greek.nsh +28 -0
  507. package/windows/languages/Hungarian.nsh +28 -0
  508. package/windows/languages/Indonesian.nsh +28 -0
  509. package/windows/languages/Irish.nsh +28 -0
  510. package/windows/languages/Malay.nsh +28 -0
  511. package/windows/languages/Polish.nsh +28 -0
  512. package/windows/languages/Romanian.nsh +28 -0
  513. package/windows/languages/Serbian.nsh +28 -0
  514. package/windows/languages/Slovak.nsh +28 -0
  515. package/windows/languages/Thai.nsh +28 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/state.ts"],"names":[],"mappings":"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","sourcesContent":["// Shared, non-React shell state: the dock, pane placeholders and the native webview reconciliation\n// (`tabs_sync`, one layout in flight at a time), shell overlays (the shell webview is raised above\n// the tab webviews while a menu, dialog or drag is open), profiles and session layout persistence.\n\nimport type { DockviewApi, IDockviewPanel } from 'dockview';\nimport { cssRgb, paneVisibility, raiseSupported, withNavRedundant } from '../paneModel.ts';\nimport { defaultProfiles, normalizeProfiles, tabProfile, type ProfileSettings } from '../profileModel.ts';\nimport type { PaneInfo } from './accountModel.ts';\nimport { currentWindow, invoke } from './bridge.ts';\nimport { columnSourceUrl, composeTabId, deckById, decks } from './deckStore.ts';\nimport type { PaletteAction } from './paletteModel.ts';\nimport { diag } from './diag.ts';\nimport { site } from './site.ts';\nimport { latestOnly } from './syncGate.ts';\n\n/** `profile`: the account profile (WebView data directory) the tab runs in; missing = default. */\n/** `besideOf`: the group whose \"beside\" link opened this tab; its group is that group's side pane. */\nexport type WebParams = { kind: 'web'; url: string; profile?: string; title?: string; favicon?: string; loading?: boolean; pinned?: boolean; besideOf?: string };\n/** The app's own tab (its settings panel, `site.panel`). */\nexport type PanelParams = { kind: 'panel'; section?: string; nonce?: number; pinned?: boolean };\n/** The new-tab page: drawn by the shell itself (no webview); `profile` is the account it opens links in. */\nexport type StartParams = { kind: 'start'; profile?: string; pinned?: boolean };\n/** A deck of site columns (DeckView.tsx); its columns are tab webviews of their own. */\nexport type DeckParams = { kind: 'deck'; deckId: string; pinned?: boolean };\nexport type TabParams = WebParams | PanelParams | StartParams | DeckParams;\n\nconst LAYOUT_KEY = 'bt.shell.layout.v1';\n\n/** Shared, non-React shell state: pane placeholders and the native webview reconciliation. */\nexport const shell = {\n api: null as DockviewApi | null,\n placeholders: new Map<string, HTMLElement>(),\n /**\n * Open shell overlays (menus, dialogs, palette, drag zones). While > 0 the shell webview is raised\n * above the tab webviews (panes stay visible under it), or, where it cannot be, they are hidden.\n */\n overlay: 0,\n /** Recently closed web tabs, newest last (Ctrl+Shift+T, new-tab page). */\n closed: [] as Array<{ url: string; profile?: string; title?: string }>,\n profiles: defaultProfiles() as ProfileSettings,\n restoring: false,\n /** Toolbar actions implemented by Shell.tsx (split view, the app's panel). */\n split: (_id: string, _direction: 'right' | 'below') => {},\n openPanel: (_from?: string) => {},\n /** Opens the new-tab page in the given profile. */\n newTab: (_profile: string) => {},\n /** The `homeUrl` setting (new-tab page \"Home\" link, first tab); `site.homeUrl` until read. */\n homeUrl: '',\n /** Opens `url` from the new-tab page: replaces that page (`startId`) or, without one, adds a tab. */\n openFromStart: (_url: string, _profile: string, _startId?: string) => {},\n /** Account switcher click: focus a visible pane of that account or open its feed beside (Shell.tsx). */\n openAccount: (_profile: string, _options?: { force?: boolean; url?: string }) => {},\n /** Opens `url` as a web tab in `profile` (a deck column's \"Open as tab\"). */\n openUrl: (_url: string, _profile: string) => {},\n /** Opens the app's panel at a section (e.g. the deck's settings button). */\n openPanelSection: (_section: string) => {},\n /** Runs a shell shortcut by name as if its keys were pressed (`new-tab`, `split-right`, `command-palette`, ...). */\n shortcut: (_name: string) => {},\n /** Runs a palette action (navigation only: open a deck, add a column, restore a workspace, ...). */\n run: (_action: PaletteAction) => {},\n};\n\n/** The app's panel tab id (`site.panel.id`, kept in saved layouts). */\nexport const panelId = () => site().panel.id;\n\n/** Replaces the profile list (after a native save) and tells mounted switchers and tabs. */\nexport function setProfiles(value: unknown) {\n shell.profiles = normalizeProfiles(value, site().accounts);\n window.dispatchEvent(new CustomEvent('bt-profiles'));\n scheduleSync();\n}\n\nexport const newTabId = () => `t${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;\n\nexport const isWeb = (panel: IDockviewPanel) => (panel.params as TabParams | undefined)?.kind === 'web';\n\n/** Every tab as the account switcher sees it. */\nexport function paneInfos(): PaneInfo[] {\n return (shell.api?.panels ?? []).map(panel => {\n const params = panel.params as TabParams | undefined;\n return {\n id: panel.id,\n kind: !params || params.kind === 'deck' ? 'panel' : params.kind,\n profile: params && params.kind !== 'panel' && params.kind !== 'deck' ? params.profile : undefined,\n url: params?.kind === 'web' ? params.url : undefined,\n visible: panel.api.isVisible,\n };\n });\n}\n\n/** Merge params without ever passing `undefined` (dockview deletes keys set to undefined). */\nexport function patchParams(panel: IDockviewPanel, patch: Partial<WebParams>) {\n const clean = Object.fromEntries(Object.entries(patch).filter(([, value]) => value !== undefined));\n if (Object.keys(clean).length) panel.api.updateParameters(clean);\n}\n\nlet frame = 0;\nlet lastPayload = '';\n/** Last `navRedundant` per tab; a hidden tab keeps its value so it shows up without a flicker. */\nconst navRedundant = new Map<string, boolean>();\nexport function scheduleSync() {\n if (frame) return;\n frame = requestAnimationFrame(() => { frame = 0; void syncTabs(); });\n}\n\n/** Sends the layout again even though nothing moved: native code asked to build every tab webview anew (`tabs-rebuild`). */\nexport function resync() {\n lastPayload = '';\n scheduleSync();\n}\n\n/** Sends the tab rectangles now (e.g. so native code knows closed tabs are gone before a profile removal). */\nexport function flushSync(): Promise<void> {\n if (frame) { cancelAnimationFrame(frame); frame = 0; }\n return syncTabs();\n}\n\nfunction syncTabs(): Promise<void> {\n const api = shell.api;\n if (!api) return Promise.resolve();\n const boxes = api.panels.filter(isWeb).map(panel => {\n const params = panel.params as WebParams;\n const el = shell.placeholders.get(panel.id);\n const rect = el?.isConnected ? el.getBoundingClientRect() : null;\n const shown = !!rect && rect.width > 1 && rect.height > 1 && panel.api.isVisible;\n const { visible, parked } = paneVisibility({ shown, overlay: shell.overlay, raiseSupported: layer.supported });\n return {\n id: panel.id,\n url: params.url,\n profile: tabProfile(shell.profiles, params.profile).id,\n x: Math.round(rect?.left ?? 0),\n y: Math.round(rect?.top ?? 0),\n width: Math.round(rect?.width ?? 1),\n height: Math.round(rect?.height ?? 1),\n visible,\n // Not shown for a reason other than a shell overlay: only these drop to low memory.\n parked,\n };\n });\n // Only visible panes are judged (a shell overlay hides them all and so changes nothing).\n const items = withNavRedundant([...boxes, ...columnBoxes()], site().isSiteUrl, navRedundant);\n const payload = JSON.stringify(items);\n if (payload === lastPayload) return Promise.resolve();\n lastPayload = payload;\n saveLayoutSoon();\n // `viewport`: the window size this layout is for; native code re-bases it if the window was\n // resized while it was in flight (it also follows resizes itself, before the shell re-lays out).\n return sendLayout({ items, viewport: [window.innerWidth, window.innerHeight] });\n}\n\n/** One tabs_sync in flight at a time; during a drag only the newest layout waits (syncGate.ts). */\nconst sendLayout = latestOnly<{ items: unknown[]; viewport: [number, number] }>(args =>\n invoke('tabs_sync', args).then(() => {}, error => console.error('[shell] tabs_sync', error)));\n\n/**\n * Deck columns (and each deck's compose dock) of every open deck tab. A column on another page of\n * its deck has no placeholder: hidden, and parked (low memory) when the setting says so; a deck\n * tab in the background parks all of its columns.\n */\nfunction columnBoxes() {\n const api = shell.api;\n const composeUrl = site().deck?.compose?.url;\n if (!api) return [];\n const boxes = [];\n for (const panel of api.panels) {\n const params = panel.params as TabParams | undefined;\n if (params?.kind !== 'deck') continue;\n const deck = deckById(params.deckId);\n if (!deck) continue;\n const deckShown = panel.api.isVisible;\n const entries = deck.columns.map(column => ({ id: column.tabId, profile: column.profile, url: columnSourceUrl(column.source) }));\n const compose = decks.compose.get(deck.id);\n if (compose && composeUrl) entries.push({ id: composeTabId(deck.id), profile: compose.profile, url: composeUrl });\n for (const entry of entries) {\n if (!entry.url || !decks.ready.has(entry.id)) continue;\n const el = shell.placeholders.get(entry.id);\n const rect = el?.isConnected ? el.getBoundingClientRect() : null;\n const shown = !!rect && rect.width > 1 && rect.height > 1 && deckShown;\n boxes.push({\n id: entry.id,\n url: entry.url,\n profile: tabProfile(shell.profiles, entry.profile).id,\n x: Math.round(rect?.left ?? 0),\n y: Math.round(rect?.top ?? 0),\n width: Math.round(rect?.width ?? 1),\n height: Math.round(rect?.height ?? 1),\n visible: paneVisibility({ shown, overlay: shell.overlay, raiseSupported: layer.supported }).visible,\n parked: !shown && (decks.settings.parkOffPage || !deckShown),\n role: 'column' as const,\n });\n }\n }\n return boxes;\n}\n\nexport function setOverlay(delta: number) {\n const before = shell.overlay;\n shell.overlay = Math.max(0, before + delta);\n diag(`overlay ${before} -> ${shell.overlay}`);\n if ((before === 0) !== (shell.overlay === 0)) {\n window.dispatchEvent(new Event('bt-overlay-changed'));\n syncLayer();\n }\n scheduleSync();\n}\n\n/**\n * The shell webview's place relative to the tab webviews. `supported`: `shell_raise` works here\n * (Windows, Linux, macOS; probed once at startup, which also lowers a shell left raised by a reload). While raised,\n * `html.bt-raised` makes the page see-through where panes are (shell.css).\n */\nconst layer = { supported: false, raised: false, queue: Promise.resolve(), probed: false };\nlet layerProbe: Promise<void> = Promise.resolve();\nconst frames = () => new Promise<void>(resolve => requestAnimationFrame(() => requestAnimationFrame(() => resolve())));\n\n/** The startup probe (createShell): whether this platform can raise the shell above its tabs. */\nexport function probeLayer() {\n if (layer.probed) return;\n layer.probed = true;\n // `localStorage['bt.dev.noRaise'] = '1'` (then reload): overlays hide the tabs as where raising\n // is not supported, for before/after comparisons.\n const off = (() => { try { return localStorage.getItem('bt.dev.noRaise') === '1'; } catch { return false; } })();\n layerProbe = invoke<boolean>('shell_raise', { on: false }).then(ok => { layer.supported = raiseSupported(ok, off); syncLayer(); scheduleSync(); }, () => {});\n}\n\n/** Wait until the startup cover has either raised the shell or hidden the native tabs. */\nexport async function flushLayer(): Promise<void> {\n await layerProbe;\n await layer.queue;\n}\n\n/**\n * While the shell is see-through, the few px of gutter between panes show the window's own\n * background: paint it the theme's ground (read before `bt-raised` clears the page's).\n */\nlet windowGround = '';\nfunction paintWindowGround() {\n const ground = cssRgb(getComputedStyle(document.documentElement).backgroundColor);\n if (!ground || ground.join() === windowGround) return;\n windowGround = ground.join();\n currentWindow().setBackgroundColor([...ground, 255]).catch(() => { windowGround = ''; });\n}\n\nfunction syncLayer() {\n if (!layer.supported) return;\n layer.queue = layer.queue.then(async () => {\n const want = shell.overlay > 0;\n if (want === layer.raised) return;\n const root = document.documentElement;\n if (want) {\n // See-through first (still under the tabs, so nothing changes on screen), then on top.\n paintWindowGround();\n root.classList.add('bt-raised');\n await frames();\n layer.raised = true;\n diag('raise: on');\n await invoke('shell_raise', { on: true });\n diag(`raised (hasFocus=${document.hasFocus()})`);\n } else {\n // Under the tabs first, then opaque again: the panes never blink.\n const refocus = document.hasFocus() && (!document.activeElement || document.activeElement === document.body);\n layer.raised = false;\n diag('raise: off');\n await invoke('shell_raise', { on: false });\n diag(`lowered (hasFocus=${document.hasFocus()})`);\n await frames();\n if (shell.overlay === 0) root.classList.remove('bt-raised');\n // Closed from the keyboard or a click in the shell (not by the window losing focus) with\n // nothing in the shell focused: typing goes back to the active pane.\n const active = shell.api?.activePanel;\n if (refocus && shell.overlay === 0 && active && isWeb(active)) void tabAction(active.id, 'focus');\n }\n }).catch(error => console.error('[shell] shell_raise', error));\n}\n\nlet saveTimer: ReturnType<typeof setTimeout> | undefined;\nexport function saveLayoutSoon() {\n clearTimeout(saveTimer);\n saveTimer = setTimeout(() => {\n if (!shell.api || shell.restoring) return;\n try { localStorage.setItem(LAYOUT_KEY, JSON.stringify(shell.api.toJSON())); } catch { /* Session restore is best effort. */ }\n }, 400);\n}\n\nexport function loadLayout(): unknown {\n try { return JSON.parse(localStorage.getItem(LAYOUT_KEY) || 'null'); } catch { return null; }\n}\n\nexport const tabAction = (id: string, action: 'back' | 'forward' | 'reload' | 'stop' | 'focus') =>\n invoke('tab_action', { id, action }).catch(() => {});\n"]}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * At most one send in flight; while one is, only the newest value waits and goes out right after
3
+ * it (older ones are dropped). The tab layout IPC uses it: during a divider drag or a window resize
4
+ * the shell lays out every frame, and queueing every frame's rectangles made native code replay
5
+ * stale layouts one after another (each a WebView2 re-layout) while falling further behind.
6
+ *
7
+ * The returned promise settles once this value, or a newer one that replaced it, was sent and
8
+ * acknowledged, so a caller that awaits it knows native code has seen at least its layout.
9
+ */
10
+ export declare function latestOnly<T>(send: (value: T) => Promise<void>): (value: T) => Promise<void>;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * At most one send in flight; while one is, only the newest value waits and goes out right after
3
+ * it (older ones are dropped). The tab layout IPC uses it: during a divider drag or a window resize
4
+ * the shell lays out every frame, and queueing every frame's rectangles made native code replay
5
+ * stale layouts one after another (each a WebView2 re-layout) while falling further behind.
6
+ *
7
+ * The returned promise settles once this value, or a newer one that replaced it, was sent and
8
+ * acknowledged, so a caller that awaits it knows native code has seen at least its layout.
9
+ */
10
+ export function latestOnly(send) {
11
+ let busy = false;
12
+ let next = null;
13
+ const run = async (value, waiters) => {
14
+ busy = true;
15
+ try {
16
+ await send(value);
17
+ }
18
+ catch { /* The sender reports its own errors. */ }
19
+ for (const resolve of waiters)
20
+ resolve();
21
+ const queued = next;
22
+ next = null;
23
+ if (queued)
24
+ void run(queued.value, queued.waiters);
25
+ else
26
+ busy = false;
27
+ };
28
+ return value => new Promise(resolve => {
29
+ if (!busy) {
30
+ void run(value, [resolve]);
31
+ return;
32
+ }
33
+ next = { value, waiters: [...(next?.waiters ?? []), resolve] };
34
+ });
35
+ }
36
+ //# sourceMappingURL=syncGate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syncGate.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/syncGate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAI,IAAiC;IAC7D,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,IAAI,GAAoD,IAAI,CAAC;IACjE,MAAM,GAAG,GAAG,KAAK,EAAE,KAAQ,EAAE,OAA0B,EAAE,EAAE;QACzD,IAAI,GAAG,IAAI,CAAC;QACZ,IAAI,CAAC;YAAC,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,wCAAwC,CAAC,CAAC;QAC7E,KAAK,MAAM,OAAO,IAAI,OAAO;YAAE,OAAO,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC;QACpB,IAAI,GAAG,IAAI,CAAC;QACZ,IAAI,MAAM;YAAE,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;;YAC9C,IAAI,GAAG,KAAK,CAAC;IACpB,CAAC,CAAC;IACF,OAAO,KAAK,CAAC,EAAE,CAAC,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;QAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;YAAC,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QAClD,IAAI,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * At most one send in flight; while one is, only the newest value waits and goes out right after\n * it (older ones are dropped). The tab layout IPC uses it: during a divider drag or a window resize\n * the shell lays out every frame, and queueing every frame's rectangles made native code replay\n * stale layouts one after another (each a WebView2 re-layout) while falling further behind.\n *\n * The returned promise settles once this value, or a newer one that replaced it, was sent and\n * acknowledged, so a caller that awaits it knows native code has seen at least its layout.\n */\nexport function latestOnly<T>(send: (value: T) => Promise<void>): (value: T) => Promise<void> {\n let busy = false;\n let next: { value: T; waiters: Array<() => void> } | null = null;\n const run = async (value: T, waiters: Array<() => void>) => {\n busy = true;\n try { await send(value); } catch { /* The sender reports its own errors. */ }\n for (const resolve of waiters) resolve();\n const queued = next;\n next = null;\n if (queued) void run(queued.value, queued.waiters);\n else busy = false;\n };\n return value => new Promise<void>(resolve => {\n if (!busy) { void run(value, [resolve]); return; }\n next = { value, waiters: [...(next?.waiters ?? []), resolve] };\n });\n}\n"]}
@@ -0,0 +1,35 @@
1
+ export type SnapshotInfo = {
2
+ name: string;
3
+ device: string;
4
+ deviceName: string;
5
+ createdAt: number;
6
+ size: number;
7
+ };
8
+ export type SyncStatus = {
9
+ folder: string | null;
10
+ device: string;
11
+ deviceName: string;
12
+ autoPush: boolean;
13
+ initialized: boolean;
14
+ unlocked: boolean;
15
+ remembered: boolean;
16
+ lastPushedAt: number;
17
+ lastPulled: number;
18
+ snapshots: SnapshotInfo[];
19
+ error: string | null;
20
+ };
21
+ export declare const syncState: {
22
+ status: SyncStatus | null;
23
+ /** A newer snapshot from another computer, not pulled or dismissed yet. */
24
+ newer: SnapshotInfo | null;
25
+ };
26
+ /** The shell's own sections for backups and snapshots. */
27
+ export declare const shellSections: () => {
28
+ [x: string]: unknown;
29
+ };
30
+ export declare function refreshSync(): Promise<SyncStatus | null>;
31
+ export declare function setSyncStatus(status: SyncStatus): void;
32
+ export declare function pushNow(force?: boolean): Promise<boolean>;
33
+ export declare function checkNewer(): Promise<SnapshotInfo | null>;
34
+ export declare function clearNewer(): void;
35
+ export declare function installSyncHost(): () => void;
@@ -0,0 +1,85 @@
1
+ // Encrypted folder sync in the shell: while a sync folder is unlocked, the settings are pushed as
2
+ // an encrypted snapshot when they change (native code skips unchanged ones), and a newer snapshot
3
+ // from another computer is offered (titlebar chip → the app's backup settings, with the same
4
+ // preview and per-section checkboxes as a file import). Crypto and files are native
5
+ // (waybetter-host `sync`).
6
+ import { localSections } from "./backupModel.js";
7
+ import { invoke } from "./bridge.js";
8
+ import { decks } from "./deckStore.js";
9
+ export const syncState = {
10
+ status: null,
11
+ /** A newer snapshot from another computer, not pulled or dismissed yet. */
12
+ newer: null,
13
+ };
14
+ const emit = () => window.dispatchEvent(new CustomEvent('bt-sync'));
15
+ const PUSH_MS = 30_000;
16
+ const CHECK_MS = 180_000;
17
+ /** The shell's own sections for backups and snapshots. */
18
+ export const shellSections = () => localSections({ decks: decks.list, deckSettings: decks.settings });
19
+ export async function refreshSync() {
20
+ try {
21
+ syncState.status = await invoke('sync_status');
22
+ }
23
+ catch {
24
+ syncState.status = null;
25
+ }
26
+ emit();
27
+ return syncState.status;
28
+ }
29
+ export function setSyncStatus(status) {
30
+ syncState.status = status;
31
+ emit();
32
+ }
33
+ export async function pushNow(force = false) {
34
+ const status = syncState.status;
35
+ if (!status?.folder || !status.unlocked)
36
+ return false;
37
+ const result = await invoke('sync_push', { extra: shellSections(), force });
38
+ if (result.pushed)
39
+ await refreshSync();
40
+ return result.pushed;
41
+ }
42
+ export async function checkNewer() {
43
+ const status = syncState.status;
44
+ if (!status?.folder || !status.unlocked)
45
+ return null;
46
+ try {
47
+ syncState.newer = await invoke('sync_check', { extra: shellSections() });
48
+ }
49
+ catch {
50
+ syncState.newer = null;
51
+ }
52
+ emit();
53
+ return syncState.newer;
54
+ }
55
+ export function clearNewer() {
56
+ syncState.newer = null;
57
+ emit();
58
+ }
59
+ export function installSyncHost() {
60
+ let alive = true;
61
+ void refreshSync().then(status => { if (alive && status?.unlocked)
62
+ void checkNewer(); });
63
+ const push = setInterval(() => { if (syncState.status?.autoPush)
64
+ pushNow().catch(() => { }); }, PUSH_MS);
65
+ const check = setInterval(() => void checkNewer(), CHECK_MS);
66
+ // Coming back to the window is when another computer's changes are most likely waiting.
67
+ const onFocus = () => void checkNewer();
68
+ // Settings changed through the panel: push soon (native code skips unchanged settings).
69
+ let soon;
70
+ const onChanged = () => { clearTimeout(soon); soon = setTimeout(() => { if (syncState.status?.autoPush)
71
+ pushNow().catch(() => { }); }, 2500); };
72
+ window.addEventListener('focus', onFocus);
73
+ window.addEventListener('bt-settings-changed', onChanged);
74
+ window.addEventListener('bt-decks', onChanged);
75
+ return () => {
76
+ alive = false;
77
+ clearInterval(push);
78
+ clearInterval(check);
79
+ clearTimeout(soon);
80
+ window.removeEventListener('focus', onFocus);
81
+ window.removeEventListener('bt-settings-changed', onChanged);
82
+ window.removeEventListener('bt-decks', onChanged);
83
+ };
84
+ }
85
+ //# sourceMappingURL=syncHost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syncHost.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/syncHost.ts"],"names":[],"mappings":"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","sourcesContent":["// Encrypted folder sync in the shell: while a sync folder is unlocked, the settings are pushed as\n// an encrypted snapshot when they change (native code skips unchanged ones), and a newer snapshot\n// from another computer is offered (titlebar chip → the app's backup settings, with the same\n// preview and per-section checkboxes as a file import). Crypto and files are native\n// (waybetter-host `sync`).\n\nimport { localSections } from './backupModel.ts';\nimport { invoke } from './bridge.ts';\nimport { decks } from './deckStore.ts';\n\nexport type SnapshotInfo = { name: string; device: string; deviceName: string; createdAt: number; size: number };\nexport type SyncStatus = {\n folder: string | null; device: string; deviceName: string; autoPush: boolean; initialized: boolean; unlocked: boolean;\n remembered: boolean; lastPushedAt: number; lastPulled: number; snapshots: SnapshotInfo[]; error: string | null;\n};\n\nexport const syncState = {\n status: null as SyncStatus | null,\n /** A newer snapshot from another computer, not pulled or dismissed yet. */\n newer: null as SnapshotInfo | null,\n};\n\nconst emit = () => window.dispatchEvent(new CustomEvent('bt-sync'));\nconst PUSH_MS = 30_000;\nconst CHECK_MS = 180_000;\n\n/** The shell's own sections for backups and snapshots. */\nexport const shellSections = () => localSections({ decks: decks.list, deckSettings: decks.settings });\n\nexport async function refreshSync(): Promise<SyncStatus | null> {\n try { syncState.status = await invoke<SyncStatus>('sync_status'); } catch { syncState.status = null; }\n emit();\n return syncState.status;\n}\n\nexport function setSyncStatus(status: SyncStatus) {\n syncState.status = status;\n emit();\n}\n\nexport async function pushNow(force = false): Promise<boolean> {\n const status = syncState.status;\n if (!status?.folder || !status.unlocked) return false;\n const result = await invoke<{ pushed: boolean }>('sync_push', { extra: shellSections(), force });\n if (result.pushed) await refreshSync();\n return result.pushed;\n}\n\nexport async function checkNewer(): Promise<SnapshotInfo | null> {\n const status = syncState.status;\n if (!status?.folder || !status.unlocked) return null;\n try { syncState.newer = await invoke<SnapshotInfo | null>('sync_check', { extra: shellSections() }); } catch { syncState.newer = null; }\n emit();\n return syncState.newer;\n}\n\nexport function clearNewer() {\n syncState.newer = null;\n emit();\n}\n\nexport function installSyncHost(): () => void {\n let alive = true;\n void refreshSync().then(status => { if (alive && status?.unlocked) void checkNewer(); });\n const push = setInterval(() => { if (syncState.status?.autoPush) pushNow().catch(() => {}); }, PUSH_MS);\n const check = setInterval(() => void checkNewer(), CHECK_MS);\n // Coming back to the window is when another computer's changes are most likely waiting.\n const onFocus = () => void checkNewer();\n // Settings changed through the panel: push soon (native code skips unchanged settings).\n let soon: ReturnType<typeof setTimeout> | undefined;\n const onChanged = () => { clearTimeout(soon); soon = setTimeout(() => { if (syncState.status?.autoPush) pushNow().catch(() => {}); }, 2500); };\n window.addEventListener('focus', onFocus);\n window.addEventListener('bt-settings-changed', onChanged);\n window.addEventListener('bt-decks', onChanged);\n return () => {\n alive = false;\n clearInterval(push);\n clearInterval(check);\n clearTimeout(soon);\n window.removeEventListener('focus', onFocus);\n window.removeEventListener('bt-settings-changed', onChanged);\n window.removeEventListener('bt-decks', onChanged);\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ /** Cached native tab frame for the shell's no-raise placeholder. */
2
+ export declare function useTabStill(id: string): string | null;
@@ -0,0 +1,62 @@
1
+ import { useLayoutEffect, useState } from 'react';
2
+ import { flushSync } from 'react-dom';
3
+ import { invoke, listen } from "./bridge.js";
4
+ import { shell } from "./state.js";
5
+ /** Cached native tab frame for the shell's no-raise placeholder. */
6
+ export function useTabStill(id) {
7
+ const [still, setStill] = useState(null);
8
+ useLayoutEffect(() => {
9
+ const off = [];
10
+ let gone = false;
11
+ let active = null;
12
+ setStill(null);
13
+ const overlayChanged = () => { active = null; setStill(null); };
14
+ window.addEventListener('bt-overlay-changed', overlayChanged);
15
+ const watch = (event, handler) => {
16
+ listen(event, ({ payload }) => { if (!gone)
17
+ handler(payload); })
18
+ .then(dispose => { if (gone)
19
+ dispose();
20
+ else
21
+ off.push(dispose); }, () => { });
22
+ };
23
+ watch('tab-still-start', payload => {
24
+ if (payload.id !== id)
25
+ return;
26
+ active = payload.token;
27
+ setStill(null);
28
+ });
29
+ watch('tab-still-cancel', payload => {
30
+ if (payload.id !== id || active !== payload.token)
31
+ return;
32
+ active = null;
33
+ setStill(null);
34
+ });
35
+ watch('tab-still-reset', tabId => {
36
+ if (tabId !== id)
37
+ return;
38
+ active = null;
39
+ setStill(null);
40
+ });
41
+ watch('tab-still', payload => {
42
+ if (payload.id !== id || active !== payload.token || shell.overlay === 0)
43
+ return;
44
+ // Keep the native tab over this pane until its replacement image is decoded and painted.
45
+ const picture = new Image();
46
+ picture.src = payload.image;
47
+ void picture.decode().catch(() => { }).then(() => {
48
+ if (gone || active !== payload.token || shell.overlay === 0)
49
+ return;
50
+ flushSync(() => setStill(payload.image));
51
+ requestAnimationFrame(() => setTimeout(() => {
52
+ if (!gone && active === payload.token && shell.overlay > 0) {
53
+ void invoke('tab_still_ready', { id, token: payload.token }).catch(() => { });
54
+ }
55
+ }, 0));
56
+ });
57
+ });
58
+ return () => { gone = true; window.removeEventListener('bt-overlay-changed', overlayChanged); off.forEach(dispose => dispose()); };
59
+ }, [id]);
60
+ return still;
61
+ }
62
+ //# sourceMappingURL=tabStill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabStill.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/tabStill.ts"],"names":[],"mappings":"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","sourcesContent":["import { useLayoutEffect, useState } from 'react';\nimport { flushSync } from 'react-dom';\nimport { invoke, listen } from './bridge.ts';\nimport { shell } from './state.ts';\n\n/** Cached native tab frame for the shell's no-raise placeholder. */\nexport function useTabStill(id: string): string | null {\n const [still, setStill] = useState<string | null>(null);\n useLayoutEffect(() => {\n const off: Array<() => void> = [];\n let gone = false;\n let active: number | null = null;\n setStill(null);\n const overlayChanged = () => { active = null; setStill(null); };\n window.addEventListener('bt-overlay-changed', overlayChanged);\n const watch = <T,>(event: string, handler: (payload: T) => void) => {\n listen<T>(event, ({ payload }) => { if (!gone) handler(payload); })\n .then(dispose => { if (gone) dispose(); else off.push(dispose); }, () => {});\n };\n watch<{ id: string; token: number }>('tab-still-start', payload => {\n if (payload.id !== id) return;\n active = payload.token;\n setStill(null);\n });\n watch<{ id: string; token: number }>('tab-still-cancel', payload => {\n if (payload.id !== id || active !== payload.token) return;\n active = null;\n setStill(null);\n });\n watch<string>('tab-still-reset', tabId => {\n if (tabId !== id) return;\n active = null;\n setStill(null);\n });\n watch<{ id: string; image: string; token: number }>('tab-still', payload => {\n if (payload.id !== id || active !== payload.token || shell.overlay === 0) return;\n // Keep the native tab over this pane until its replacement image is decoded and painted.\n const picture = new Image();\n picture.src = payload.image;\n void picture.decode().catch(() => {}).then(() => {\n if (gone || active !== payload.token || shell.overlay === 0) return;\n flushSync(() => setStill(payload.image));\n requestAnimationFrame(() => setTimeout(() => {\n if (!gone && active === payload.token && shell.overlay > 0) {\n void invoke('tab_still_ready', { id, token: payload.token }).catch(() => {});\n }\n }, 0));\n });\n });\n return () => { gone = true; window.removeEventListener('bt-overlay-changed', overlayChanged); off.forEach(dispose => dispose()); };\n }, [id]);\n return still;\n}\n"]}
@@ -0,0 +1,29 @@
1
+ export type ThemeScopes = {
2
+ /** wayBetter's window (tabs, address bar, titlebar, panel) follows the theme, or keeps its own style. */
3
+ chrome: 'theme' | 'own';
4
+ /** Account profile id -> theme id. */
5
+ profiles: Record<string, string>;
6
+ /** Pane (tab) id -> theme id. */
7
+ panes: Record<string, string>;
8
+ };
9
+ export declare const MAX_PROFILE_THEMES = 32;
10
+ export declare const MAX_PANE_THEMES = 64;
11
+ export declare const SCOPES_DEFAULT: ThemeScopes;
12
+ /** Any JSON to valid scopes (bounded; unknown values dropped). */
13
+ export declare function normalizeScopes(input: unknown): ThemeScopes;
14
+ export type ScopeSource = 'pane' | 'account' | 'global';
15
+ /**
16
+ * The theme id a tab shows and where it comes from: the pane's own, else its account's, else the
17
+ * global one. An id that no longer exists (a removed imported theme) falls through.
18
+ */
19
+ export declare function themeIdFor(scopes: ThemeScopes, tab: {
20
+ id?: string;
21
+ profile?: string;
22
+ }, globalPreset: string, known: (id: string) => boolean): {
23
+ id: string;
24
+ source: ScopeSource;
25
+ };
26
+ /** Drops pane entries whose pane is gone (the shell calls this with its open tab ids). */
27
+ export declare function prunePanes(scopes: ThemeScopes, open: Iterable<string>): ThemeScopes;
28
+ /** Sets (or with null clears) one pane's or account's theme. */
29
+ export declare function assign(scopes: ThemeScopes, kind: 'panes' | 'profiles', id: string, theme: string | null): ThemeScopes;
@@ -0,0 +1,61 @@
1
+ // Which theme each site tab gets. The global theme applies everywhere unless an account profile
2
+ // has a theme of its own, and any pane can override both (the pane's “…” menu, the app's theme
3
+ // settings). A pane or account theme is the theme document as it is (the global theme's
4
+ // customizations and accent belong to the global theme). Native code keeps the same rules and
5
+ // delivers each tab its theme; the shell uses them for pane chrome. Pure (tests, shell, panel).
6
+ export const MAX_PROFILE_THEMES = 32;
7
+ export const MAX_PANE_THEMES = 64;
8
+ export const SCOPES_DEFAULT = { chrome: 'theme', profiles: {}, panes: {} };
9
+ const THEME_ID = /^[a-z0-9-]{1,40}$/;
10
+ const PROFILE_ID = /^(default|p[a-z0-9]{1,32})$/;
11
+ const TAB_ID = /^[A-Za-z0-9-]{1,40}$/;
12
+ function entries(value, key, max) {
13
+ if (!value || typeof value !== 'object' || Array.isArray(value))
14
+ return {};
15
+ const out = {};
16
+ for (const [id, theme] of Object.entries(value)) {
17
+ if (Object.keys(out).length >= max)
18
+ break;
19
+ if (key.test(id) && typeof theme === 'string' && THEME_ID.test(theme))
20
+ out[id] = theme;
21
+ }
22
+ return out;
23
+ }
24
+ /** Any JSON to valid scopes (bounded; unknown values dropped). */
25
+ export function normalizeScopes(input) {
26
+ const source = input && typeof input === 'object' ? input : {};
27
+ return {
28
+ chrome: source.chrome === 'own' ? 'own' : 'theme',
29
+ profiles: entries(source.profiles, PROFILE_ID, MAX_PROFILE_THEMES),
30
+ panes: entries(source.panes, TAB_ID, MAX_PANE_THEMES),
31
+ };
32
+ }
33
+ /**
34
+ * The theme id a tab shows and where it comes from: the pane's own, else its account's, else the
35
+ * global one. An id that no longer exists (a removed imported theme) falls through.
36
+ */
37
+ export function themeIdFor(scopes, tab, globalPreset, known) {
38
+ const pane = tab.id ? scopes.panes[tab.id] : undefined;
39
+ if (pane && known(pane))
40
+ return { id: pane, source: 'pane' };
41
+ const account = tab.profile ? scopes.profiles[tab.profile] : undefined;
42
+ if (account && known(account))
43
+ return { id: account, source: 'account' };
44
+ return { id: globalPreset, source: 'global' };
45
+ }
46
+ /** Drops pane entries whose pane is gone (the shell calls this with its open tab ids). */
47
+ export function prunePanes(scopes, open) {
48
+ const keep = new Set(open);
49
+ const panes = Object.fromEntries(Object.entries(scopes.panes).filter(([id]) => keep.has(id)));
50
+ return Object.keys(panes).length === Object.keys(scopes.panes).length ? scopes : { ...scopes, panes };
51
+ }
52
+ /** Sets (or with null clears) one pane's or account's theme. */
53
+ export function assign(scopes, kind, id, theme) {
54
+ const next = { ...scopes[kind] };
55
+ if (theme)
56
+ next[id] = theme;
57
+ else
58
+ delete next[id];
59
+ return normalizeScopes({ ...scopes, [kind]: next });
60
+ }
61
+ //# sourceMappingURL=themeScopes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themeScopes.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/themeScopes.ts"],"names":[],"mappings":"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","sourcesContent":["// Which theme each site tab gets. The global theme applies everywhere unless an account profile\n// has a theme of its own, and any pane can override both (the pane's “…” menu, the app's theme\n// settings). A pane or account theme is the theme document as it is (the global theme's\n// customizations and accent belong to the global theme). Native code keeps the same rules and\n// delivers each tab its theme; the shell uses them for pane chrome. Pure (tests, shell, panel).\n\nexport type ThemeScopes = {\n /** wayBetter's window (tabs, address bar, titlebar, panel) follows the theme, or keeps its own style. */\n chrome: 'theme' | 'own';\n /** Account profile id -> theme id. */\n profiles: Record<string, string>;\n /** Pane (tab) id -> theme id. */\n panes: Record<string, string>;\n};\n\nexport const MAX_PROFILE_THEMES = 32;\nexport const MAX_PANE_THEMES = 64;\nexport const SCOPES_DEFAULT: ThemeScopes = { chrome: 'theme', profiles: {}, panes: {} };\n\nconst THEME_ID = /^[a-z0-9-]{1,40}$/;\nconst PROFILE_ID = /^(default|p[a-z0-9]{1,32})$/;\nconst TAB_ID = /^[A-Za-z0-9-]{1,40}$/;\n\nfunction entries(value: unknown, key: RegExp, max: number): Record<string, string> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {};\n const out: Record<string, string> = {};\n for (const [id, theme] of Object.entries(value)) {\n if (Object.keys(out).length >= max) break;\n if (key.test(id) && typeof theme === 'string' && THEME_ID.test(theme)) out[id] = theme;\n }\n return out;\n}\n\n/** Any JSON to valid scopes (bounded; unknown values dropped). */\nexport function normalizeScopes(input: unknown): ThemeScopes {\n const source = input && typeof input === 'object' ? input as Record<string, unknown> : {};\n return {\n chrome: source.chrome === 'own' ? 'own' : 'theme',\n profiles: entries(source.profiles, PROFILE_ID, MAX_PROFILE_THEMES),\n panes: entries(source.panes, TAB_ID, MAX_PANE_THEMES),\n };\n}\n\nexport type ScopeSource = 'pane' | 'account' | 'global';\n\n/**\n * The theme id a tab shows and where it comes from: the pane's own, else its account's, else the\n * global one. An id that no longer exists (a removed imported theme) falls through.\n */\nexport function themeIdFor(scopes: ThemeScopes, tab: { id?: string; profile?: string }, globalPreset: string, known: (id: string) => boolean): { id: string; source: ScopeSource } {\n const pane = tab.id ? scopes.panes[tab.id] : undefined;\n if (pane && known(pane)) return { id: pane, source: 'pane' };\n const account = tab.profile ? scopes.profiles[tab.profile] : undefined;\n if (account && known(account)) return { id: account, source: 'account' };\n return { id: globalPreset, source: 'global' };\n}\n\n\n/** Drops pane entries whose pane is gone (the shell calls this with its open tab ids). */\nexport function prunePanes(scopes: ThemeScopes, open: Iterable<string>): ThemeScopes {\n const keep = new Set(open);\n const panes = Object.fromEntries(Object.entries(scopes.panes).filter(([id]) => keep.has(id)));\n return Object.keys(panes).length === Object.keys(scopes.panes).length ? scopes : { ...scopes, panes };\n}\n\n/** Sets (or with null clears) one pane's or account's theme. */\nexport function assign(scopes: ThemeScopes, kind: 'panes' | 'profiles', id: string, theme: string | null): ThemeScopes {\n const next = { ...scopes[kind] };\n if (theme) next[id] = theme; else delete next[id];\n return normalizeScopes({ ...scopes, [kind]: next });\n}\n"]}
@@ -0,0 +1,99 @@
1
+ import type { IconPack } from '../../runtime/themeIcons.ts';
2
+ import type { DockviewApi } from 'dockview';
3
+ import { type ChromeTheme } from './chromeTheme.ts';
4
+ import { type ScopeSource, type ThemeScopes } from './themeScopes.ts';
5
+ export type Weights = {
6
+ kind: 'range';
7
+ min: number;
8
+ max: number;
9
+ } | {
10
+ kind: 'list';
11
+ values: number[];
12
+ };
13
+ export type InstalledFont = {
14
+ family: string;
15
+ weights: Weights;
16
+ bytes: number;
17
+ faces: number;
18
+ installedAt: string;
19
+ };
20
+ /** A theme document as the frame needs it: an id and a name (the rest is the app's). */
21
+ export type ThemeDoc = {
22
+ id: string;
23
+ name: string;
24
+ };
25
+ /** What the app's themes are and how native code stores them. */
26
+ export type ThemeAdapter<Choice = unknown, Spec extends ThemeDoc = ThemeDoc> = {
27
+ /** The choice before anything is read (and when reading fails). */
28
+ defaultChoice: Choice;
29
+ /** Reads the persisted global choice (normalized). */
30
+ load(): Promise<Choice>;
31
+ /** Persists `choice` and themes every site tab (throws native code's error). */
32
+ commit(choice: Choice): Promise<void>;
33
+ /** Shows `spec` (a draft) in every site tab until it is saved or closed; null ends it. */
34
+ preview(spec: Spec | null): Promise<void>;
35
+ /** The theme document a choice shows (its customizations applied). */
36
+ resolve(choice: Choice): Spec;
37
+ /** The chosen theme's id. */
38
+ preset(choice: Choice): string;
39
+ /** The choice a theme id stands for: the global choice itself, or that theme without customizations. */
40
+ choiceForId(choice: Choice, id: string): Choice;
41
+ /** Every theme that can be picked: built-in ones and the choice's imported ones. */
42
+ all(choice: Choice): Spec[];
43
+ /** Google font families a theme uses (in `roles` only, when given). */
44
+ googleFonts(spec: Spec, roles?: readonly string[]): string[];
45
+ /** The chrome's colors and fonts for a theme. */
46
+ chrome(spec: Spec): ChromeTheme;
47
+ /** The icon pack a theme suggests for the chrome (theme engine v2); absent: the frame's own glyphs. */
48
+ iconPack?(spec: Spec, choice?: Choice): IconPack | null;
49
+ /** Three swatch colors for menus (page, text, accent, on the theme's surface and border). */
50
+ dots(spec: Spec): {
51
+ page: string;
52
+ bg: string;
53
+ border: string;
54
+ text: string;
55
+ accent: string;
56
+ };
57
+ };
58
+ export type ThemeState<Choice, Spec> = {
59
+ ready: boolean;
60
+ choice: Choice;
61
+ scopes: ThemeScopes;
62
+ fonts: InstalledFont[];
63
+ preview: Spec | null;
64
+ };
65
+ export type ThemeStore<Choice = unknown, Spec extends ThemeDoc = ThemeDoc> = ReturnType<typeof createThemeStore<Choice, Spec>>;
66
+ export declare function createThemeStore<Choice, Spec extends ThemeDoc>(adapter: ThemeAdapter<Choice, Spec>): {
67
+ adapter: ThemeAdapter<Choice, Spec>;
68
+ loadThemes: () => Promise<void>;
69
+ setChoice: (next: Choice, commit?: boolean) => Promise<void>;
70
+ setScopes: (next: ThemeScopes) => Promise<void>;
71
+ setPreview: (theme: Spec | null) => Promise<void>;
72
+ themeState: () => ThemeState<Choice, Spec>;
73
+ allThemes: (choice?: Choice) => Spec[];
74
+ knownTheme: (id: string, choice?: Choice) => boolean;
75
+ themeName: (id: string) => string;
76
+ tabTheme: (tab: {
77
+ id?: string;
78
+ profile?: string;
79
+ }) => {
80
+ id: string;
81
+ source: ScopeSource;
82
+ theme: Spec;
83
+ };
84
+ ensureShellFont: (family: string) => Promise<boolean>;
85
+ previewFont: (family: string, weights: Weights, text: string) => Promise<string | null>;
86
+ installFont: (family: string, weights: Weights) => Promise<InstalledFont>;
87
+ removeFont: (family: string) => Promise<void>;
88
+ isInstalled: (family: string) => boolean;
89
+ missingFonts: (theme: Spec) => string[];
90
+ attachDock: (api: DockviewApi) => void;
91
+ subscribe: (listener: () => void) => () => void;
92
+ current: () => {
93
+ ready: boolean;
94
+ choice: Choice;
95
+ scopes: ThemeScopes;
96
+ fonts: InstalledFont[];
97
+ preview: Spec | null;
98
+ };
99
+ };