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.
- package/README.md +140 -6
- package/bin/waybetter.mjs +46 -0
- package/build/runtime.mjs +105 -0
- package/cli/buildenv.mjs +130 -0
- package/cli/dev.mjs +97 -0
- package/cli/i18n.mjs +382 -0
- package/cli/manifests.mjs +383 -0
- package/cli/privacy.mjs +768 -0
- package/cli/release.mjs +444 -0
- package/cli/remote.mjs +260 -0
- package/cli/store.mjs +326 -0
- package/cli/strings.mjs +121 -0
- package/dist/runtime/column.d.ts +93 -0
- package/dist/runtime/column.js +451 -0
- package/dist/runtime/column.js.map +1 -0
- package/dist/runtime/commandReport.d.ts +19 -0
- package/dist/runtime/commandReport.js +47 -0
- package/dist/runtime/commandReport.js.map +1 -0
- package/dist/runtime/commands.d.ts +72 -0
- package/dist/runtime/commands.js +214 -0
- package/dist/runtime/commands.js.map +1 -0
- package/dist/runtime/devErrors.d.ts +16 -0
- package/dist/runtime/devErrors.js +30 -0
- package/dist/runtime/devErrors.js.map +1 -0
- package/dist/runtime/domHub.d.ts +21 -0
- package/dist/runtime/domHub.js +139 -4
- package/dist/runtime/domHub.js.map +1 -1
- package/dist/runtime/featureModules.d.ts +157 -0
- package/dist/runtime/featureModules.js +484 -0
- package/dist/runtime/featureModules.js.map +1 -0
- package/dist/runtime/featureTable.d.ts +144 -0
- package/dist/runtime/featureTable.js +223 -0
- package/dist/runtime/featureTable.js.map +1 -0
- package/dist/runtime/fonts.d.ts +22 -0
- package/dist/runtime/fonts.js +72 -0
- package/dist/runtime/fonts.js.map +1 -0
- package/dist/runtime/i18n.d.ts +138 -0
- package/dist/runtime/i18n.js +614 -0
- package/dist/runtime/i18n.js.map +1 -0
- package/dist/runtime/i18nCheck.d.ts +30 -0
- package/dist/runtime/i18nCheck.js +224 -0
- package/dist/runtime/i18nCheck.js.map +1 -0
- package/dist/runtime/pageLang.d.ts +8 -0
- package/dist/runtime/pageLang.js +64 -0
- package/dist/runtime/pageLang.js.map +1 -0
- package/dist/runtime/pageStrings.d.ts +35 -0
- package/dist/runtime/pageStrings.js +76 -0
- package/dist/runtime/pageStrings.js.map +1 -0
- package/dist/runtime/panelButton.d.ts +33 -0
- package/dist/runtime/panelButton.js +83 -0
- package/dist/runtime/panelButton.js.map +1 -0
- package/dist/runtime/permissions.d.ts +47 -0
- package/dist/runtime/permissions.js +141 -0
- package/dist/runtime/permissions.js.map +1 -0
- package/dist/runtime/pluginApi.d.ts +51 -2
- package/dist/runtime/pluginApi.js +137 -22
- package/dist/runtime/pluginApi.js.map +1 -1
- package/dist/runtime/pluginI18n.d.ts +29 -0
- package/dist/runtime/pluginI18n.js +119 -0
- package/dist/runtime/pluginI18n.js.map +1 -0
- package/dist/runtime/settingsForm.d.ts +66 -0
- package/dist/runtime/settingsForm.js +114 -0
- package/dist/runtime/settingsForm.js.map +1 -0
- package/dist/runtime/site.d.ts +5 -0
- package/dist/runtime/site.js +1 -1
- package/dist/runtime/site.js.map +1 -1
- package/dist/runtime/siteRuntime.d.ts +144 -0
- package/dist/runtime/siteRuntime.js +175 -0
- package/dist/runtime/siteRuntime.js.map +1 -0
- package/dist/runtime/stringPackHook.d.ts +84 -0
- package/dist/runtime/stringPackHook.js +220 -0
- package/dist/runtime/stringPackHook.js.map +1 -0
- package/dist/runtime/stringPackTranslate.d.ts +59 -0
- package/dist/runtime/stringPackTranslate.js +264 -0
- package/dist/runtime/stringPackTranslate.js.map +1 -0
- package/dist/runtime/stringPacks.d.ts +200 -0
- package/dist/runtime/stringPacks.js +474 -0
- package/dist/runtime/stringPacks.js.map +1 -0
- package/dist/runtime/styles.d.ts +15 -0
- package/dist/runtime/styles.js +81 -0
- package/dist/runtime/styles.js.map +1 -0
- package/dist/runtime/textNet.d.ts +15 -0
- package/dist/runtime/textNet.js +131 -0
- package/dist/runtime/textNet.js.map +1 -0
- package/dist/runtime/themeApi.d.ts +121 -0
- package/dist/runtime/themeApi.js +220 -0
- package/dist/runtime/themeApi.js.map +1 -0
- package/dist/runtime/themeChoice.d.ts +52 -0
- package/dist/runtime/themeChoice.js +69 -0
- package/dist/runtime/themeChoice.js.map +1 -0
- package/dist/runtime/themeComponents.d.ts +435 -0
- package/dist/runtime/themeComponents.js +463 -0
- package/dist/runtime/themeComponents.js.map +1 -0
- package/dist/runtime/themeDecor.d.ts +73 -0
- package/dist/runtime/themeDecor.js +131 -0
- package/dist/runtime/themeDecor.js.map +1 -0
- package/dist/runtime/themeDoctor.d.ts +11 -0
- package/dist/runtime/themeDoctor.js +51 -0
- package/dist/runtime/themeDoctor.js.map +1 -0
- package/dist/runtime/themeIcons.d.ts +130 -0
- package/dist/runtime/themeIcons.js +263 -0
- package/dist/runtime/themeIcons.js.map +1 -0
- package/dist/runtime/themeRuntime.d.ts +100 -0
- package/dist/runtime/themeRuntime.js +497 -0
- package/dist/runtime/themeRuntime.js.map +1 -0
- package/dist/runtime/themeSchema.d.ts +10 -0
- package/dist/runtime/themeSchema.js +150 -0
- package/dist/runtime/themeSchema.js.map +1 -0
- package/dist/runtime/themeSpec.d.ts +259 -0
- package/dist/runtime/themeSpec.js +439 -0
- package/dist/runtime/themeSpec.js.map +1 -0
- package/dist/runtime/themeTokens.d.ts +12 -0
- package/dist/runtime/themeTokens.js +14 -6
- package/dist/runtime/themeTokens.js.map +1 -1
- package/dist/runtime/themeVariants.d.ts +30 -0
- package/dist/runtime/themeVariants.js +53 -0
- package/dist/runtime/themeVariants.js.map +1 -0
- package/dist/runtime/ui.d.ts +192 -0
- package/dist/runtime/ui.js +926 -0
- package/dist/runtime/ui.js.map +1 -0
- package/dist/shell/InstallDialog.d.ts +40 -0
- package/dist/shell/InstallDialog.js +170 -0
- package/dist/shell/InstallDialog.js.map +1 -0
- package/dist/shell/StoreView.d.ts +66 -0
- package/dist/shell/StoreView.js +103 -0
- package/dist/shell/StoreView.js.map +1 -0
- package/dist/shell/addressModel.js.map +1 -1
- package/dist/shell/chrome.js.map +1 -1
- package/dist/shell/deckModel.d.ts +117 -0
- package/dist/shell/deckModel.js +267 -0
- package/dist/shell/deckModel.js.map +1 -0
- package/dist/shell/frame/AccountSwitcher.d.ts +42 -0
- package/dist/shell/frame/AccountSwitcher.js +243 -0
- package/dist/shell/frame/AccountSwitcher.js.map +1 -0
- package/dist/shell/frame/AddColumnDialog.d.ts +8 -0
- package/dist/shell/frame/AddColumnDialog.js +81 -0
- package/dist/shell/frame/AddColumnDialog.js.map +1 -0
- package/dist/shell/frame/AppMenu.d.ts +21 -0
- package/dist/shell/frame/AppMenu.js +642 -0
- package/dist/shell/frame/AppMenu.js.map +1 -0
- package/dist/shell/frame/CommandPalette.d.ts +7 -0
- package/dist/shell/frame/CommandPalette.js +118 -0
- package/dist/shell/frame/CommandPalette.js.map +1 -0
- package/dist/shell/frame/DeckView.d.ts +13 -0
- package/dist/shell/frame/DeckView.js +287 -0
- package/dist/shell/frame/DeckView.js.map +1 -0
- package/dist/shell/frame/FindBar.d.ts +10 -0
- package/dist/shell/frame/FindBar.js +108 -0
- package/dist/shell/frame/FindBar.js.map +1 -0
- package/dist/shell/frame/MediaPanel.d.ts +8 -0
- package/dist/shell/frame/MediaPanel.js +76 -0
- package/dist/shell/frame/MediaPanel.js.map +1 -0
- package/dist/shell/frame/NewTabPage.d.ts +9 -0
- package/dist/shell/frame/NewTabPage.js +71 -0
- package/dist/shell/frame/NewTabPage.js.map +1 -0
- package/dist/shell/frame/PaneTheme.d.ts +16 -0
- package/dist/shell/frame/PaneTheme.js +67 -0
- package/dist/shell/frame/PaneTheme.js.map +1 -0
- package/dist/shell/frame/ReportDialog.d.ts +3 -0
- package/dist/shell/frame/ReportDialog.js +95 -0
- package/dist/shell/frame/ReportDialog.js.map +1 -0
- package/dist/shell/frame/Shell.d.ts +8 -0
- package/dist/shell/frame/Shell.js +1131 -0
- package/dist/shell/frame/Shell.js.map +1 -0
- package/dist/shell/frame/Titlebar.d.ts +16 -0
- package/dist/shell/frame/Titlebar.js +77 -0
- package/dist/shell/frame/Titlebar.js.map +1 -0
- package/dist/shell/frame/TitlebarExtras.d.ts +4 -0
- package/dist/shell/frame/TitlebarExtras.js +202 -0
- package/dist/shell/frame/TitlebarExtras.js.map +1 -0
- package/dist/shell/frame/WebPanel.d.ts +4 -0
- package/dist/shell/frame/WebPanel.js +182 -0
- package/dist/shell/frame/WebPanel.js.map +1 -0
- package/dist/shell/frame/accountModel.d.ts +49 -0
- package/dist/shell/frame/accountModel.js +67 -0
- package/dist/shell/frame/accountModel.js.map +1 -0
- package/dist/shell/frame/accountSwitcher.css +91 -0
- package/dist/shell/frame/appI18n.d.ts +44 -0
- package/dist/shell/frame/appI18n.js +64 -0
- package/dist/shell/frame/appI18n.js.map +1 -0
- package/dist/shell/frame/appMenu.css +121 -0
- package/dist/shell/frame/backupModel.d.ts +38 -0
- package/dist/shell/frame/backupModel.js +192 -0
- package/dist/shell/frame/backupModel.js.map +1 -0
- package/dist/shell/frame/boot.d.ts +8 -0
- package/dist/shell/frame/boot.js +35 -0
- package/dist/shell/frame/boot.js.map +1 -0
- package/dist/shell/frame/brand.d.ts +1 -0
- package/dist/shell/frame/brand.js +4 -0
- package/dist/shell/frame/brand.js.map +1 -0
- package/dist/shell/frame/bridge.d.ts +35 -0
- package/dist/shell/frame/bridge.js +70 -0
- package/dist/shell/frame/bridge.js.map +1 -0
- package/dist/shell/frame/chromeTheme.d.ts +29 -0
- package/dist/shell/frame/chromeTheme.js +81 -0
- package/dist/shell/frame/chromeTheme.js.map +1 -0
- package/dist/shell/frame/deck.css +209 -0
- package/dist/shell/frame/deckStore.d.ts +89 -0
- package/dist/shell/frame/deckStore.js +239 -0
- package/dist/shell/frame/deckStore.js.map +1 -0
- package/dist/shell/frame/devHost.d.ts +35 -0
- package/dist/shell/frame/devHost.js +80 -0
- package/dist/shell/frame/devHost.js.map +1 -0
- package/dist/shell/frame/devModel.d.ts +7 -0
- package/dist/shell/frame/devModel.js +17 -0
- package/dist/shell/frame/devModel.js.map +1 -0
- package/dist/shell/frame/diag.d.ts +7 -0
- package/dist/shell/frame/diag.js +39 -0
- package/dist/shell/frame/diag.js.map +1 -0
- package/dist/shell/frame/findBar.css +14 -0
- package/dist/shell/frame/frameMessages.d.ts +248 -0
- package/dist/shell/frame/frameMessages.js +252 -0
- package/dist/shell/frame/frameMessages.js.map +1 -0
- package/dist/shell/frame/hooks.d.ts +39 -0
- package/dist/shell/frame/hooks.js +97 -0
- package/dist/shell/frame/hooks.js.map +1 -0
- package/dist/shell/frame/i18n.d.ts +27 -0
- package/dist/shell/frame/i18n.js +66 -0
- package/dist/shell/frame/i18n.js.map +1 -0
- package/dist/shell/frame/iconPack.d.ts +11 -0
- package/dist/shell/frame/iconPack.js +45 -0
- package/dist/shell/frame/iconPack.js.map +1 -0
- package/dist/shell/frame/icons.d.ts +71 -0
- package/dist/shell/frame/icons.js +75 -0
- package/dist/shell/frame/icons.js.map +1 -0
- package/dist/shell/frame/index.d.ts +34 -0
- package/dist/shell/frame/index.js +43 -0
- package/dist/shell/frame/index.js.map +1 -0
- package/dist/shell/frame/language.d.ts +58 -0
- package/dist/shell/frame/language.js +165 -0
- package/dist/shell/frame/language.js.map +1 -0
- package/dist/shell/frame/mediaModel.d.ts +34 -0
- package/dist/shell/frame/mediaModel.js +53 -0
- package/dist/shell/frame/mediaModel.js.map +1 -0
- package/dist/shell/frame/menuMessages.en.json +54 -0
- package/dist/shell/frame/menuModel.d.ts +277 -0
- package/dist/shell/frame/menuModel.js +293 -0
- package/dist/shell/frame/menuModel.js.map +1 -0
- package/dist/shell/frame/paletteModel.d.ts +139 -0
- package/dist/shell/frame/paletteModel.js +112 -0
- package/dist/shell/frame/paletteModel.js.map +1 -0
- package/dist/shell/frame/paneTheme.css +9 -0
- package/dist/shell/frame/pluginCommandStore.d.ts +23 -0
- package/dist/shell/frame/pluginCommandStore.js +70 -0
- package/dist/shell/frame/pluginCommandStore.js.map +1 -0
- package/dist/shell/frame/reportModel.d.ts +52 -0
- package/dist/shell/frame/reportModel.js +105 -0
- package/dist/shell/frame/reportModel.js.map +1 -0
- package/dist/shell/frame/safeStore.d.ts +7 -0
- package/dist/shell/frame/safeStore.js +40 -0
- package/dist/shell/frame/safeStore.js.map +1 -0
- package/dist/shell/frame/searchInput.d.ts +2 -0
- package/dist/shell/frame/searchInput.js +11 -0
- package/dist/shell/frame/searchInput.js.map +1 -0
- package/dist/shell/frame/shell.css +629 -0
- package/dist/shell/frame/site.d.ts +206 -0
- package/dist/shell/frame/site.js +22 -0
- package/dist/shell/frame/site.js.map +1 -0
- package/dist/shell/frame/state.d.ts +99 -0
- package/dist/shell/frame/state.js +284 -0
- package/dist/shell/frame/state.js.map +1 -0
- package/dist/shell/frame/syncGate.d.ts +10 -0
- package/dist/shell/frame/syncGate.js +36 -0
- package/dist/shell/frame/syncGate.js.map +1 -0
- package/dist/shell/frame/syncHost.d.ts +35 -0
- package/dist/shell/frame/syncHost.js +85 -0
- package/dist/shell/frame/syncHost.js.map +1 -0
- package/dist/shell/frame/tabStill.d.ts +2 -0
- package/dist/shell/frame/tabStill.js +62 -0
- package/dist/shell/frame/tabStill.js.map +1 -0
- package/dist/shell/frame/themeScopes.d.ts +29 -0
- package/dist/shell/frame/themeScopes.js +61 -0
- package/dist/shell/frame/themeScopes.js.map +1 -0
- package/dist/shell/frame/themeStore.d.ts +99 -0
- package/dist/shell/frame/themeStore.js +252 -0
- package/dist/shell/frame/themeStore.js.map +1 -0
- package/dist/shell/frame/windowBinding.d.ts +2 -0
- package/dist/shell/frame/windowBinding.js +7 -0
- package/dist/shell/frame/windowBinding.js.map +1 -0
- package/dist/shell/frame/workspaceModel.d.ts +82 -0
- package/dist/shell/frame/workspaceModel.js +250 -0
- package/dist/shell/frame/workspaceModel.js.map +1 -0
- package/dist/shell/frame/workspaces.css +84 -0
- package/dist/shell/frame/workspaces.d.ts +22 -0
- package/dist/shell/frame/workspaces.js +125 -0
- package/dist/shell/frame/workspaces.js.map +1 -0
- package/dist/shell/frame/zoomStore.d.ts +10 -0
- package/dist/shell/frame/zoomStore.js +65 -0
- package/dist/shell/frame/zoomStore.js.map +1 -0
- package/dist/shell/installController.d.ts +122 -0
- package/dist/shell/installController.js +146 -0
- package/dist/shell/installController.js.map +1 -0
- package/dist/shell/installerMessages.d.ts +30 -0
- package/dist/shell/installerMessages.js +36 -0
- package/dist/shell/installerMessages.js.map +1 -0
- package/dist/shell/linkDrop.js.map +1 -1
- package/dist/shell/messages.d.ts +16 -0
- package/dist/shell/messages.js +27 -0
- package/dist/shell/messages.js.map +1 -0
- package/dist/shell/palette.js.map +1 -1
- package/dist/shell/paneModel.d.ts +22 -0
- package/dist/shell/paneModel.js +24 -1
- package/dist/shell/paneModel.js.map +1 -1
- package/dist/shell/panel/Appearance.d.ts +8 -0
- package/dist/shell/panel/Appearance.js +256 -0
- package/dist/shell/panel/Appearance.js.map +1 -0
- package/dist/shell/panel/BackupPanel.d.ts +5 -0
- package/dist/shell/panel/BackupPanel.js +198 -0
- package/dist/shell/panel/BackupPanel.js.map +1 -0
- package/dist/shell/panel/DeveloperPanel.d.ts +4 -0
- package/dist/shell/panel/DeveloperPanel.js +51 -0
- package/dist/shell/panel/DeveloperPanel.js.map +1 -0
- package/dist/shell/panel/FeatureToggles.d.ts +13 -0
- package/dist/shell/panel/FeatureToggles.js +42 -0
- package/dist/shell/panel/FeatureToggles.js.map +1 -0
- package/dist/shell/panel/Home.d.ts +3 -0
- package/dist/shell/panel/Home.js +23 -0
- package/dist/shell/panel/Home.js.map +1 -0
- package/dist/shell/panel/IconPackInstall.d.ts +15 -0
- package/dist/shell/panel/IconPackInstall.js +41 -0
- package/dist/shell/panel/IconPackInstall.js.map +1 -0
- package/dist/shell/panel/LanguageSettings.d.ts +1 -0
- package/dist/shell/panel/LanguageSettings.js +54 -0
- package/dist/shell/panel/LanguageSettings.js.map +1 -0
- package/dist/shell/panel/MakePanel.d.ts +3 -0
- package/dist/shell/panel/MakePanel.js +237 -0
- package/dist/shell/panel/MakePanel.js.map +1 -0
- package/dist/shell/panel/MarkdownDoc.d.ts +6 -0
- package/dist/shell/panel/MarkdownDoc.js +35 -0
- package/dist/shell/panel/MarkdownDoc.js.map +1 -0
- package/dist/shell/panel/Modes.d.ts +40 -0
- package/dist/shell/panel/Modes.js +270 -0
- package/dist/shell/panel/Modes.js.map +1 -0
- package/dist/shell/panel/NavIcon.d.ts +4 -0
- package/dist/shell/panel/NavIcon.js +6 -0
- package/dist/shell/panel/NavIcon.js.map +1 -0
- package/dist/shell/panel/Panel.d.ts +7 -0
- package/dist/shell/panel/Panel.js +139 -0
- package/dist/shell/panel/Panel.js.map +1 -0
- package/dist/shell/panel/PluginFeatures.d.ts +24 -0
- package/dist/shell/panel/PluginFeatures.js +165 -0
- package/dist/shell/panel/PluginFeatures.js.map +1 -0
- package/dist/shell/panel/Plugins.d.ts +33 -0
- package/dist/shell/panel/Plugins.js +112 -0
- package/dist/shell/panel/Plugins.js.map +1 -0
- package/dist/shell/panel/PowerSettings.d.ts +4 -0
- package/dist/shell/panel/PowerSettings.js +52 -0
- package/dist/shell/panel/PowerSettings.js.map +1 -0
- package/dist/shell/panel/Settings.d.ts +23 -0
- package/dist/shell/panel/Settings.js +116 -0
- package/dist/shell/panel/Settings.js.map +1 -0
- package/dist/shell/panel/ShareSetup.d.ts +8 -0
- package/dist/shell/panel/ShareSetup.js +130 -0
- package/dist/shell/panel/ShareSetup.js.map +1 -0
- package/dist/shell/panel/StoreSection.d.ts +6 -0
- package/dist/shell/panel/StoreSection.js +48 -0
- package/dist/shell/panel/StoreSection.js.map +1 -0
- package/dist/shell/panel/StringPacks.d.ts +11 -0
- package/dist/shell/panel/StringPacks.js +106 -0
- package/dist/shell/panel/StringPacks.js.map +1 -0
- package/dist/shell/panel/ThemeBuilder.d.ts +5 -0
- package/dist/shell/panel/ThemeBuilder.js +205 -0
- package/dist/shell/panel/ThemeBuilder.js.map +1 -0
- package/dist/shell/panel/backup.css +34 -0
- package/dist/shell/panel/builder.css +232 -0
- package/dist/shell/panel/builderModel.d.ts +55 -0
- package/dist/shell/panel/builderModel.js +95 -0
- package/dist/shell/panel/builderModel.js.map +1 -0
- package/dist/shell/panel/compare.d.ts +10 -0
- package/dist/shell/panel/compare.js +51 -0
- package/dist/shell/panel/compare.js.map +1 -0
- package/dist/shell/panel/controls.d.ts +135 -0
- package/dist/shell/panel/controls.js +213 -0
- package/dist/shell/panel/controls.js.map +1 -0
- package/dist/shell/panel/featureModel.d.ts +69 -0
- package/dist/shell/panel/featureModel.js +79 -0
- package/dist/shell/panel/featureModel.js.map +1 -0
- package/dist/shell/panel/fonts/FontBrowser.d.ts +10 -0
- package/dist/shell/panel/fonts/FontBrowser.js +189 -0
- package/dist/shell/panel/fonts/FontBrowser.js.map +1 -0
- package/dist/shell/panel/fonts/FontRoles.d.ts +20 -0
- package/dist/shell/panel/fonts/FontRoles.js +77 -0
- package/dist/shell/panel/fonts/FontRoles.js.map +1 -0
- package/dist/shell/panel/fonts/catalog.d.ts +37 -0
- package/dist/shell/panel/fonts/catalog.js +68 -0
- package/dist/shell/panel/fonts/catalog.js.map +1 -0
- package/dist/shell/panel/fonts/googleFontsCatalog.json +1 -0
- package/dist/shell/panel/index.d.ts +20 -0
- package/dist/shell/panel/index.js +34 -0
- package/dist/shell/panel/index.js.map +1 -0
- package/dist/shell/panel/languageModel.d.ts +5 -0
- package/dist/shell/panel/languageModel.js +7 -0
- package/dist/shell/panel/languageModel.js.map +1 -0
- package/dist/shell/panel/make.css +72 -0
- package/dist/shell/panel/makeModel.d.ts +32 -0
- package/dist/shell/panel/makeModel.js +84 -0
- package/dist/shell/panel/makeModel.js.map +1 -0
- package/dist/shell/panel/markdown.d.ts +46 -0
- package/dist/shell/panel/markdown.js +100 -0
- package/dist/shell/panel/markdown.js.map +1 -0
- package/dist/shell/panel/nav.d.ts +12 -0
- package/dist/shell/panel/nav.js +50 -0
- package/dist/shell/panel/nav.js.map +1 -0
- package/dist/shell/panel/panel.css +401 -0
- package/dist/shell/panel/panelMessages.d.ts +763 -0
- package/dist/shell/panel/panelMessages.js +767 -0
- package/dist/shell/panel/panelMessages.js.map +1 -0
- package/dist/shell/panel/plugins.css +59 -0
- package/dist/shell/panel/setupModel.d.ts +87 -0
- package/dist/shell/panel/setupModel.js +152 -0
- package/dist/shell/panel/setupModel.js.map +1 -0
- package/dist/shell/panel/site.d.ts +259 -0
- package/dist/shell/panel/site.js +25 -0
- package/dist/shell/panel/site.js.map +1 -0
- package/dist/shell/panel/strings.css +7 -0
- package/dist/shell/panel/themes.d.ts +10 -0
- package/dist/shell/panel/themes.js +8 -0
- package/dist/shell/panel/themes.js.map +1 -0
- package/dist/shell/profileModel.d.ts +3 -2
- package/dist/shell/profileModel.js +7 -5
- package/dist/shell/profileModel.js.map +1 -1
- package/dist/shell/store.css +230 -0
- package/dist/shell/storeMessages.d.ts +169 -0
- package/dist/shell/storeMessages.js +172 -0
- package/dist/shell/storeMessages.js.map +1 -0
- package/dist/shell/storeModel.d.ts +181 -0
- package/dist/shell/storeModel.js +133 -0
- package/dist/shell/storeModel.js.map +1 -0
- package/dist/shell/stringPacksModel.d.ts +44 -0
- package/dist/shell/stringPacksModel.js +94 -0
- package/dist/shell/stringPacksModel.js.map +1 -0
- package/dist/shell/updateModel.d.ts +2 -1
- package/dist/shell/updateModel.js +5 -4
- package/dist/shell/updateModel.js.map +1 -1
- package/dist/shell/windowControls.d.ts +4 -0
- package/dist/shell/windowControls.js +5 -0
- package/dist/shell/windowControls.js.map +1 -1
- package/i18n-config.schema.json +29 -0
- package/i18n-meta.schema.json +26 -0
- package/i18n.schema.json +42 -0
- package/icons.schema.json +646 -0
- package/languages.schema.json +23 -0
- package/locales/ar-x-fm.json +11 -0
- package/locales/ar.json +1281 -0
- package/locales/bg.json +1280 -0
- package/locales/bn.json +1280 -0
- package/locales/ca.json +1280 -0
- package/locales/cs.json +1280 -0
- package/locales/da.json +1280 -0
- package/locales/de.json +1280 -0
- package/locales/el.json +1280 -0
- package/locales/en-GB.json +27 -0
- package/locales/en.json +1280 -0
- package/locales/en.meta.json +51 -0
- package/locales/es.json +1280 -0
- package/locales/eu.json +1280 -0
- package/locales/fa.json +1281 -0
- package/locales/fi.json +1280 -0
- package/locales/fil.json +1280 -0
- package/locales/fr.json +1280 -0
- package/locales/ga.json +1280 -0
- package/locales/gl.json +1280 -0
- package/locales/gu.json +1280 -0
- package/locales/ha.json +1280 -0
- package/locales/he.json +1281 -0
- package/locales/hi.json +1280 -0
- package/locales/hr.json +1280 -0
- package/locales/hu.json +1279 -0
- package/locales/id.json +1280 -0
- package/locales/ig.json +1280 -0
- package/locales/it.json +1280 -0
- package/locales/ja.json +1280 -0
- package/locales/kn.json +1280 -0
- package/locales/ko.json +1280 -0
- package/locales/mr.json +1280 -0
- package/locales/ms.json +1280 -0
- package/locales/nb.json +1280 -0
- package/locales/nl.json +1280 -0
- package/locales/pl.json +1280 -0
- package/locales/pt.json +1280 -0
- package/locales/ro.json +1280 -0
- package/locales/ru.json +1280 -0
- package/locales/sk.json +1280 -0
- package/locales/sr.json +1280 -0
- package/locales/sv.json +1280 -0
- package/locales/ta.json +1280 -0
- package/locales/th.json +1280 -0
- package/locales/tr.json +1280 -0
- package/locales/uk.json +1280 -0
- package/locales/ur.json +1281 -0
- package/locales/vi.json +1280 -0
- package/locales/yo.json +1280 -0
- package/locales/zh-Hans.json +1280 -0
- package/locales/zh-Hant.json +1280 -0
- package/package.json +139 -5
- package/store-catalog.schema.json +65 -0
- package/theme.schema.json +4659 -0
- package/windows/installer.nsi +926 -0
- package/windows/languages/Basque.nsh +28 -0
- package/windows/languages/Catalan.nsh +28 -0
- package/windows/languages/Croatian.nsh +28 -0
- package/windows/languages/Czech.nsh +28 -0
- package/windows/languages/Danish.nsh +28 -0
- package/windows/languages/Finnish.nsh +28 -0
- package/windows/languages/Galician.nsh +28 -0
- package/windows/languages/Greek.nsh +28 -0
- package/windows/languages/Hungarian.nsh +28 -0
- package/windows/languages/Indonesian.nsh +28 -0
- package/windows/languages/Irish.nsh +28 -0
- package/windows/languages/Malay.nsh +28 -0
- package/windows/languages/Polish.nsh +28 -0
- package/windows/languages/Romanian.nsh +28 -0
- package/windows/languages/Serbian.nsh +28 -0
- package/windows/languages/Slovak.nsh +28 -0
- package/windows/languages/Thai.nsh +28 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// A settings schema: what a feature (or a plugin) lets its owner adjust, as data. The same schema
|
|
2
|
+
// gives the stored values their shape (`normalizeSettings`: anything missing or of the wrong type
|
|
3
|
+
// takes the field's default, so an old or damaged store never breaks a feature) and draws the
|
|
4
|
+
// controls from the UI kit's form parts (`buildSettingsForm`: check boxes, number, text, select and
|
|
5
|
+
// list fields inside a kit dialog). Labels and hints are catalog keys the caller translates.
|
|
6
|
+
export const SETTINGS_LIMITS = Object.freeze({ fields: 64, text: 2000, listItems: 500, listItem: 500 });
|
|
7
|
+
const valueFields = (schema) => schema.filter((field) => field.type !== 'divider');
|
|
8
|
+
function fieldValue(field, value) {
|
|
9
|
+
switch (field.type) {
|
|
10
|
+
case 'toggle':
|
|
11
|
+
return typeof value === 'boolean' ? value : field.default;
|
|
12
|
+
case 'number': {
|
|
13
|
+
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
14
|
+
return field.default;
|
|
15
|
+
return Math.min(field.max ?? Infinity, Math.max(field.min ?? -Infinity, value));
|
|
16
|
+
}
|
|
17
|
+
case 'text':
|
|
18
|
+
return typeof value === 'string' ? value.slice(0, Math.min(field.maxLength ?? SETTINGS_LIMITS.text, SETTINGS_LIMITS.text)) : field.default;
|
|
19
|
+
case 'select':
|
|
20
|
+
return typeof value === 'string' && field.options.some(option => option.value === value) ? value : field.default;
|
|
21
|
+
case 'list': {
|
|
22
|
+
if (!Array.isArray(value))
|
|
23
|
+
return [...field.default];
|
|
24
|
+
const max = Math.min(field.maxLength ?? SETTINGS_LIMITS.listItem, SETTINGS_LIMITS.listItem);
|
|
25
|
+
return value.filter((item) => typeof item === 'string' && item.trim() !== '').map(item => item.slice(0, max)).slice(0, Math.min(field.maxItems ?? SETTINGS_LIMITS.listItems, SETTINGS_LIMITS.listItems));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** The values for `schema` from whatever was stored: every field present, every value of its type and in range. */
|
|
30
|
+
export function normalizeSettings(schema, stored) {
|
|
31
|
+
const source = stored && typeof stored === 'object' ? stored : {};
|
|
32
|
+
const out = {};
|
|
33
|
+
for (const field of valueFields(schema))
|
|
34
|
+
out[field.key] = fieldValue(field, source[field.key]);
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
/** Problems in a schema (an empty list: valid). */
|
|
38
|
+
export function validateSchema(schema) {
|
|
39
|
+
const problems = [];
|
|
40
|
+
const keys = new Set();
|
|
41
|
+
const fields = valueFields(schema);
|
|
42
|
+
if (fields.length > SETTINGS_LIMITS.fields)
|
|
43
|
+
problems.push(`at most ${SETTINGS_LIMITS.fields} fields`);
|
|
44
|
+
for (const field of fields) {
|
|
45
|
+
if (!/^[A-Za-z][A-Za-z0-9]{0,39}$/.test(field.key))
|
|
46
|
+
problems.push(`invalid key ${JSON.stringify(field.key)}`);
|
|
47
|
+
if (keys.has(field.key))
|
|
48
|
+
problems.push(`${field.key}: listed twice`);
|
|
49
|
+
keys.add(field.key);
|
|
50
|
+
if (!field.label)
|
|
51
|
+
problems.push(`${field.key}: a label is required`);
|
|
52
|
+
if (field.type === 'select' && !field.options.some(option => option.value === field.default))
|
|
53
|
+
problems.push(`${field.key}: the default is not an option`);
|
|
54
|
+
if (field.type === 'number' && (field.min ?? -Infinity) > (field.max ?? Infinity))
|
|
55
|
+
problems.push(`${field.key}: min is above max`);
|
|
56
|
+
}
|
|
57
|
+
return problems;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The controls for `schema` showing `values`, built with the kit's element builder and styled by the
|
|
61
|
+
* kit's form classes. `text(key)` translates a label, hint or option key.
|
|
62
|
+
*/
|
|
63
|
+
export function buildSettingsForm(h, schema, values, text) {
|
|
64
|
+
const readers = [];
|
|
65
|
+
const nodes = [];
|
|
66
|
+
for (const field of schema) {
|
|
67
|
+
if (field.type === 'divider') {
|
|
68
|
+
nodes.push(h('div', { class: 'wb-divider' }));
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const value = values[field.key];
|
|
72
|
+
const hint = field.hint ? text(field.hint) : '';
|
|
73
|
+
if (field.type === 'toggle') {
|
|
74
|
+
const input = h('input', { type: 'checkbox', checked: value === true });
|
|
75
|
+
nodes.push(h('label', { class: 'wb-check' }, input, h('span', null, text(field.label), hint ? h('small', null, hint) : null)));
|
|
76
|
+
readers.push([field, () => input.checked]);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
let control;
|
|
80
|
+
if (field.type === 'number') {
|
|
81
|
+
const input = h('input', { type: 'number', value: String(value), min: field.min, max: field.max, step: field.step ?? 1 });
|
|
82
|
+
readers.push([field, () => (input.value.trim() === '' ? NaN : Number(input.value))]);
|
|
83
|
+
control = input;
|
|
84
|
+
}
|
|
85
|
+
else if (field.type === 'select') {
|
|
86
|
+
const select = h('select', null, field.options.map(option => h('option', { value: option.value, selected: option.value === value }, text(option.label))));
|
|
87
|
+
readers.push([field, () => select.value]);
|
|
88
|
+
control = select;
|
|
89
|
+
}
|
|
90
|
+
else if (field.type === 'list') {
|
|
91
|
+
const area = h('textarea', { class: 'wb-mono', rows: 5, spellcheck: false, value: value.join('\n') });
|
|
92
|
+
readers.push([field, () => area.value.split(/\r?\n/).map(line => line.trim()).filter(Boolean)]);
|
|
93
|
+
control = area;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
const input = (field.multiline
|
|
97
|
+
? h('textarea', { rows: 4, value: String(value), maxLength: field.maxLength, placeholder: field.placeholder })
|
|
98
|
+
: h('input', { type: 'text', value: String(value), maxLength: field.maxLength, placeholder: field.placeholder }));
|
|
99
|
+
readers.push([field, () => input.value]);
|
|
100
|
+
control = input;
|
|
101
|
+
}
|
|
102
|
+
nodes.push(h('label', { class: 'wb-field' }, h('span', { class: 'wb-label' }, text(field.label)), control, hint ? h('p', { class: 'wb-hint' }, hint) : null));
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
nodes,
|
|
106
|
+
read() {
|
|
107
|
+
const raw = {};
|
|
108
|
+
for (const [field, read] of readers)
|
|
109
|
+
raw[field.key] = read();
|
|
110
|
+
return normalizeSettings(schema, raw);
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=settingsForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settingsForm.js","sourceRoot":"","sources":["../../../runtime/src/settingsForm.ts"],"names":[],"mappings":"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","sourcesContent":["// A settings schema: what a feature (or a plugin) lets its owner adjust, as data. The same schema\n// gives the stored values their shape (`normalizeSettings`: anything missing or of the wrong type\n// takes the field's default, so an old or damaged store never breaks a feature) and draws the\n// controls from the UI kit's form parts (`buildSettingsForm`: check boxes, number, text, select and\n// list fields inside a kit dialog). Labels and hints are catalog keys the caller translates.\n\nimport type { UiKit } from './ui.ts';\n\ntype FieldBase = {\n /** The key in the stored values. */\n key: string;\n /** Catalog key of the label. */\n label: string;\n /** Catalog key of a line under the label. */\n hint?: string;\n};\n\nexport type SettingField =\n | (FieldBase & { type: 'toggle'; default: boolean })\n | (FieldBase & { type: 'number'; default: number; min?: number; max?: number; step?: number })\n | (FieldBase & { type: 'text'; default: string; maxLength?: number; multiline?: boolean; placeholder?: string })\n | (FieldBase & { type: 'select'; default: string; options: ReadonlyArray<{ value: string; label: string }> })\n /** Lines of text (patterns, handles): one per line in the form. */\n | (FieldBase & { type: 'list'; default: readonly string[]; maxItems?: number; maxLength?: number })\n | { type: 'divider' };\n\nexport type SettingsSchema = readonly SettingField[];\nexport type SettingValue = boolean | number | string | string[];\nexport type SettingValues = Record<string, SettingValue>;\n\nexport const SETTINGS_LIMITS = Object.freeze({ fields: 64, text: 2000, listItems: 500, listItem: 500 });\n\ntype ValueField = Exclude<SettingField, { type: 'divider' }>;\nconst valueFields = (schema: SettingsSchema) => schema.filter((field): field is ValueField => field.type !== 'divider');\n\nfunction fieldValue(field: ValueField, value: unknown): SettingValue {\n switch (field.type) {\n case 'toggle':\n return typeof value === 'boolean' ? value : field.default;\n case 'number': {\n if (typeof value !== 'number' || !Number.isFinite(value)) return field.default;\n return Math.min(field.max ?? Infinity, Math.max(field.min ?? -Infinity, value));\n }\n case 'text':\n return typeof value === 'string' ? value.slice(0, Math.min(field.maxLength ?? SETTINGS_LIMITS.text, SETTINGS_LIMITS.text)) : field.default;\n case 'select':\n return typeof value === 'string' && field.options.some(option => option.value === value) ? value : field.default;\n case 'list': {\n if (!Array.isArray(value)) return [...field.default];\n const max = Math.min(field.maxLength ?? SETTINGS_LIMITS.listItem, SETTINGS_LIMITS.listItem);\n return value.filter((item): item is string => typeof item === 'string' && item.trim() !== '').map(item => item.slice(0, max)).slice(0, Math.min(field.maxItems ?? SETTINGS_LIMITS.listItems, SETTINGS_LIMITS.listItems));\n }\n }\n}\n\n/** The values for `schema` from whatever was stored: every field present, every value of its type and in range. */\nexport function normalizeSettings(schema: SettingsSchema, stored: unknown): SettingValues {\n const source = stored && typeof stored === 'object' ? stored as Record<string, unknown> : {};\n const out: SettingValues = {};\n for (const field of valueFields(schema)) out[field.key] = fieldValue(field, source[field.key]);\n return out;\n}\n\n/** Problems in a schema (an empty list: valid). */\nexport function validateSchema(schema: SettingsSchema): string[] {\n const problems: string[] = [];\n const keys = new Set<string>();\n const fields = valueFields(schema);\n if (fields.length > SETTINGS_LIMITS.fields) problems.push(`at most ${SETTINGS_LIMITS.fields} fields`);\n for (const field of fields) {\n if (!/^[A-Za-z][A-Za-z0-9]{0,39}$/.test(field.key)) problems.push(`invalid key ${JSON.stringify(field.key)}`);\n if (keys.has(field.key)) problems.push(`${field.key}: listed twice`);\n keys.add(field.key);\n if (!field.label) problems.push(`${field.key}: a label is required`);\n if (field.type === 'select' && !field.options.some(option => option.value === field.default)) problems.push(`${field.key}: the default is not an option`);\n if (field.type === 'number' && (field.min ?? -Infinity) > (field.max ?? Infinity)) problems.push(`${field.key}: min is above max`);\n }\n return problems;\n}\n\nexport type SettingsForm = {\n /** The controls, in schema order: append them to a dialog's body. */\n nodes: HTMLElement[];\n /** The values as the controls show them now (normalized). */\n read(): SettingValues;\n};\n\n/**\n * The controls for `schema` showing `values`, built with the kit's element builder and styled by the\n * kit's form classes. `text(key)` translates a label, hint or option key.\n */\nexport function buildSettingsForm(h: UiKit['h'], schema: SettingsSchema, values: SettingValues, text: (key: string) => string): SettingsForm {\n const readers: Array<[ValueField, () => unknown]> = [];\n const nodes: HTMLElement[] = [];\n for (const field of schema) {\n if (field.type === 'divider') { nodes.push(h('div', { class: 'wb-divider' })); continue; }\n const value = values[field.key];\n const hint = field.hint ? text(field.hint) : '';\n if (field.type === 'toggle') {\n const input = h('input', { type: 'checkbox', checked: value === true }) as HTMLInputElement;\n nodes.push(h('label', { class: 'wb-check' }, input, h('span', null, text(field.label), hint ? h('small', null, hint) : null)));\n readers.push([field, () => input.checked]);\n continue;\n }\n let control: HTMLElement;\n if (field.type === 'number') {\n const input = h('input', { type: 'number', value: String(value), min: field.min, max: field.max, step: field.step ?? 1 }) as HTMLInputElement;\n readers.push([field, () => (input.value.trim() === '' ? NaN : Number(input.value))]);\n control = input;\n } else if (field.type === 'select') {\n const select = h('select', null, field.options.map(option => h('option', { value: option.value, selected: option.value === value }, text(option.label)))) as HTMLSelectElement;\n readers.push([field, () => select.value]);\n control = select;\n } else if (field.type === 'list') {\n const area = h('textarea', { class: 'wb-mono', rows: 5, spellcheck: false, value: (value as string[]).join('\\n') }) as HTMLTextAreaElement;\n readers.push([field, () => area.value.split(/\\r?\\n/).map(line => line.trim()).filter(Boolean)]);\n control = area;\n } else {\n const input = (field.multiline\n ? h('textarea', { rows: 4, value: String(value), maxLength: field.maxLength, placeholder: field.placeholder })\n : h('input', { type: 'text', value: String(value), maxLength: field.maxLength, placeholder: field.placeholder })) as HTMLInputElement | HTMLTextAreaElement;\n readers.push([field, () => input.value]);\n control = input;\n }\n nodes.push(h('label', { class: 'wb-field' }, h('span', { class: 'wb-label' }, text(field.label)), control, hint ? h('p', { class: 'wb-hint' }, hint) : null));\n }\n return {\n nodes,\n read() {\n const raw: Record<string, unknown> = {};\n for (const [field, read] of readers) raw[field.key] = read();\n return normalizeSettings(schema, raw);\n },\n };\n}\n"]}
|
package/dist/runtime/site.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AccountSite } from './accountReport.ts';
|
|
2
|
+
import type { ColumnSite } from './column.ts';
|
|
2
3
|
import type { LinkSite } from './linkRouting.ts';
|
|
3
4
|
import type { RailSite } from './paneNav.ts';
|
|
4
5
|
import type { PluginApiSite } from './pluginApi.ts';
|
|
@@ -12,6 +13,8 @@ export type SiteAdapter = {
|
|
|
12
13
|
runtimeGlobal: string;
|
|
13
14
|
/** Pages where heavy-page-sensitive DOM features pause (e.g. a WASM chat); null = none. */
|
|
14
15
|
heavyPath: RegExp | null;
|
|
16
|
+
/** Hosts whose open shadow roots are part of the page (the DOM hub observes and searches them; `domRoots`). */
|
|
17
|
+
shadowHosts?: readonly string[];
|
|
15
18
|
/** Request URL substrings that are the site's API calls; only these reach the net hub stages. */
|
|
16
19
|
apiMarks: string[];
|
|
17
20
|
/** Extra URL substrings that reach XHR gates only. */
|
|
@@ -19,6 +22,8 @@ export type SiteAdapter = {
|
|
|
19
22
|
plugins: PluginApiSite;
|
|
20
23
|
/** Split-view rail hiding; omit when the site has no navigation rail. */
|
|
21
24
|
rail?: RailSite;
|
|
25
|
+
/** Power User Mode: how a site tab becomes a narrow deck column (runtime/column.ts); omit = no decks. */
|
|
26
|
+
column?: ColumnSite;
|
|
22
27
|
/** Signed-in account reader for the account switcher. */
|
|
23
28
|
account?: AccountSite;
|
|
24
29
|
/** Which in-page clicks the "links to site pages" setting may divert. */
|
package/dist/runtime/site.js
CHANGED
|
@@ -4,7 +4,7 @@ import { configureDomHub } from "./domHub.js";
|
|
|
4
4
|
import { configureNetHub } from "./netHub.js";
|
|
5
5
|
/** Applies the adapter's global knobs (DOM hub, net hub). Call once, before features start. */
|
|
6
6
|
export function configureRuntime(site) {
|
|
7
|
-
configureDomHub({ label: site.product, heavyPath: site.heavyPath });
|
|
7
|
+
configureDomHub({ label: site.product, heavyPath: site.heavyPath, shadowHosts: site.shadowHosts ?? [] });
|
|
8
8
|
configureNetHub({ apiMarks: site.apiMarks, xhrMarks: site.xhrMarks });
|
|
9
9
|
}
|
|
10
10
|
/** Whether `href` is on the site's origin (https, one of `hosts`). */
|
package/dist/runtime/site.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site.js","sourceRoot":"","sources":["../../../runtime/src/site.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,mGAAmG;AAEnG,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"site.js","sourceRoot":"","sources":["../../../runtime/src/site.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,mGAAmG;AAEnG,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAoC9C,+FAA+F;AAC/F,MAAM,UAAU,gBAAgB,CAAC,IAAiB;IAChD,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC;IACzG,eAAe,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,SAAS,CAAC,IAAgC,EAAE,IAAY;IACtE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC1G,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC","sourcesContent":["// The page side of a site adapter. A wayBetter app for one site is mostly this object (plus the\n// native `SiteSpec` in Rust and its Tauri capability files); every runtime module takes its piece.\n\nimport { configureDomHub } from './domHub.ts';\nimport { configureNetHub } from './netHub.ts';\nimport type { AccountSite } from './accountReport.ts';\nimport type { ColumnSite } from './column.ts';\nimport type { LinkSite } from './linkRouting.ts';\nimport type { RailSite } from './paneNav.ts';\nimport type { PluginApiSite } from './pluginApi.ts';\nimport type { SourceAxis } from './themeTokens.ts';\n\nexport type SiteAdapter = {\n /** e.g. \"wayBetter for X\"; console prefixes and toasts. */\n product: string;\n /** Exact hosts of the site's origin (must match the native `SiteSpec.hosts`). */\n hosts: readonly string[];\n /** The runtime's window global (`window.<runtimeGlobal>`), plugins included. */\n runtimeGlobal: string;\n /** Pages where heavy-page-sensitive DOM features pause (e.g. a WASM chat); null = none. */\n heavyPath: RegExp | null;\n /** Hosts whose open shadow roots are part of the page (the DOM hub observes and searches them; `domRoots`). */\n shadowHosts?: readonly string[];\n /** Request URL substrings that are the site's API calls; only these reach the net hub stages. */\n apiMarks: string[];\n /** Extra URL substrings that reach XHR gates only. */\n xhrMarks: string[];\n plugins: PluginApiSite;\n /** Split-view rail hiding; omit when the site has no navigation rail. */\n rail?: RailSite;\n /** Power User Mode: how a site tab becomes a narrow deck column (runtime/column.ts); omit = no decks. */\n column?: ColumnSite;\n /** Signed-in account reader for the account switcher. */\n account?: AccountSite;\n /** Which in-page clicks the \"links to site pages\" setting may divert. */\n links?: LinkSite;\n /** The site's own palette per color mode, the source the theme engine maps from. */\n themeSources?: Record<string, SourceAxis>;\n};\n\n/** Applies the adapter's global knobs (DOM hub, net hub). Call once, before features start. */\nexport function configureRuntime(site: SiteAdapter): void {\n configureDomHub({ label: site.product, heavyPath: site.heavyPath, shadowHosts: site.shadowHosts ?? [] });\n configureNetHub({ apiMarks: site.apiMarks, xhrMarks: site.xhrMarks });\n}\n\n/** Whether `href` is on the site's origin (https, one of `hosts`). */\nexport function isSiteUrl(site: Pick<SiteAdapter, 'hosts'>, href: string): boolean {\n try {\n const url = new URL(href);\n return url.protocol === 'https:' && site.hosts.includes(url.hostname) && !url.username && !url.password;\n } catch {\n return false;\n }\n}\n"]}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { PageStrings } from './pageStrings.ts';
|
|
2
|
+
import type { PluginContext } from './permissions.ts';
|
|
3
|
+
import type { Params } from './i18n.ts';
|
|
4
|
+
import type { SiteAdapter } from './site.ts';
|
|
5
|
+
export type PageInvoke = (command: string, args: Record<string, unknown>) => Promise<unknown>;
|
|
6
|
+
/**
|
|
7
|
+
* Native commands from the page. The IPC bridge is read at call time: a runtime installed at
|
|
8
|
+
* document start can run before Tauri has put `__TAURI_INTERNALS__` on the page. A runtime only
|
|
9
|
+
* ships inside the app's site tabs; automated test browsers (`navigator.webdriver`) have no
|
|
10
|
+
* bridge, and the features that need it stay off there (undefined).
|
|
11
|
+
*/
|
|
12
|
+
export declare function pageInvoke(win: Window, product: string): PageInvoke | undefined;
|
|
13
|
+
/** A flag-controlled part of the runtime, while it is installed. */
|
|
14
|
+
export type Installed = {
|
|
15
|
+
dispose(): void;
|
|
16
|
+
};
|
|
17
|
+
export type FlagInstaller<Flags> = readonly [flag: keyof Flags & string, install: () => Installed];
|
|
18
|
+
export type FeatureFlagsOptions<Flags extends Record<string, boolean>> = {
|
|
19
|
+
/** Every flag with its default; a flag not in here is ignored. */
|
|
20
|
+
defaults: Flags;
|
|
21
|
+
/** Console label (the app's name). */
|
|
22
|
+
label: string;
|
|
23
|
+
/** Parts that install when their flag turns on and dispose when it turns off, in install order. */
|
|
24
|
+
installers: ReadonlyArray<FlagInstaller<Flags>>;
|
|
25
|
+
/** Every applied config (the full map), before the installers (flags that are CSS, or that another part reads). */
|
|
26
|
+
apply?(config: Flags): void;
|
|
27
|
+
/**
|
|
28
|
+
* What owns what: given the delivered flags over the defaults, the flags that really run (an
|
|
29
|
+
* area whose switch is off turns its features off; featureTable `effectiveFlags`).
|
|
30
|
+
*/
|
|
31
|
+
resolve?(flags: Flags): Flags;
|
|
32
|
+
/** The page's document: a column's flags delivered at document start wait for `<html>` to exist. */
|
|
33
|
+
document?: Document;
|
|
34
|
+
};
|
|
35
|
+
export type FeatureFlags<Flags extends Record<string, boolean>> = {
|
|
36
|
+
/**
|
|
37
|
+
* The flags native code delivers (the owner's choices); a deck column's overrides stay on top.
|
|
38
|
+
* A delivery is the whole state, stored sparsely: a flag it does not name is at its default.
|
|
39
|
+
*/
|
|
40
|
+
apply(config: Partial<Flags>): void;
|
|
41
|
+
/**
|
|
42
|
+
* A deck column's flag overrides (allow-listed natively; unknown keys and non-booleans are
|
|
43
|
+
* dropped here too). Flags a column stops overriding go back to the global value, or the default
|
|
44
|
+
* when the global config never named them. Recorded at once; applied now, or once the document
|
|
45
|
+
* has its `<html>` (a new column webview gets its config at document start).
|
|
46
|
+
*/
|
|
47
|
+
setColumnFlags(flags: unknown): void;
|
|
48
|
+
/** Turns one installer on or off directly (a kill switch). */
|
|
49
|
+
set(flag: keyof Flags & string, enabled: boolean): void;
|
|
50
|
+
/** Whether a flag's installer is installed right now. */
|
|
51
|
+
installed(flag: keyof Flags & string): boolean;
|
|
52
|
+
/** Every flag as it runs right now (defaults, the delivery, ownership, the column). */
|
|
53
|
+
current(): Flags;
|
|
54
|
+
};
|
|
55
|
+
export declare function createFeatureFlags<Flags extends Record<string, boolean>>(options: FeatureFlagsOptions<Flags>): FeatureFlags<Flags>;
|
|
56
|
+
/** What native code and plugins reach through `window.<runtimeGlobal>`. */
|
|
57
|
+
export type SiteRuntime<Api extends object> = {
|
|
58
|
+
version: string;
|
|
59
|
+
/** Running plugins by file (native start/stop scripts manage this). */
|
|
60
|
+
plugins: Record<string, {
|
|
61
|
+
start?: () => void;
|
|
62
|
+
stop?: () => void;
|
|
63
|
+
}>;
|
|
64
|
+
/** Load errors by plugin file. */
|
|
65
|
+
errors: Record<string, string>;
|
|
66
|
+
/** Native code hands over the feature flags (`features_set`). */
|
|
67
|
+
features: {
|
|
68
|
+
apply(config: unknown): void;
|
|
69
|
+
};
|
|
70
|
+
/** Native code hands over the owner's language: `{ locale, dir, messages }` (pageStrings.ts). */
|
|
71
|
+
i18n: {
|
|
72
|
+
set(strings: unknown): void;
|
|
73
|
+
locale(): string;
|
|
74
|
+
t(key: string, params?: Params): string;
|
|
75
|
+
};
|
|
76
|
+
/** Native code hands over where clicked site pages open (`{ site: 'same' | 'pane' | 'tab' | 'browser' }`). */
|
|
77
|
+
links: {
|
|
78
|
+
configure(value: unknown): void;
|
|
79
|
+
};
|
|
80
|
+
/** Native code says whether this pane's navigation repeats another pane's (`{ redundantNav }`). */
|
|
81
|
+
pane: {
|
|
82
|
+
set(state: unknown): void;
|
|
83
|
+
};
|
|
84
|
+
/** Native code hands over downloaded Google Fonts (validated woff2 bytes) that this tab's theme uses. */
|
|
85
|
+
fonts: {
|
|
86
|
+
provide(fonts: unknown): void;
|
|
87
|
+
};
|
|
88
|
+
/** Power User Mode: native code hands a deck column its config (null = an ordinary tab again). */
|
|
89
|
+
column: {
|
|
90
|
+
set(config: unknown): void;
|
|
91
|
+
markRead(): void;
|
|
92
|
+
jumpToUnread(): void;
|
|
93
|
+
unread(): number;
|
|
94
|
+
};
|
|
95
|
+
/** Opens the app's panel in the shell (at a section). */
|
|
96
|
+
open(section?: string): void;
|
|
97
|
+
/**
|
|
98
|
+
* Helpers for `*.plugin.js` files. Read while a plugin's code runs (its module body, constructor,
|
|
99
|
+
* start() and stop()), this is that plugin's view for its declared `@permissions`; elsewhere it
|
|
100
|
+
* is the full API.
|
|
101
|
+
*/
|
|
102
|
+
readonly api: Api;
|
|
103
|
+
/** Runs `fn` as plugin `id` with `grants` (null = legacy, full API; undefined = as registered). Native start/stop scripts call it. */
|
|
104
|
+
withPlugin<R>(id: string, grants: readonly string[] | null | undefined, fn: () => R): R;
|
|
105
|
+
/** Developer mode: a reloaded plugin failed to start (native `dev_start_script`); shown as a toast. */
|
|
106
|
+
devError(file: unknown, error: unknown): void;
|
|
107
|
+
};
|
|
108
|
+
export type SiteRuntimeOptions<Api extends object, Extra extends object> = {
|
|
109
|
+
win: Window & typeof globalThis;
|
|
110
|
+
site: Pick<SiteAdapter, 'product' | 'runtimeGlobal'>;
|
|
111
|
+
version: string;
|
|
112
|
+
/** Other window names for the runtime, besides `wayBetter` and `site.runtimeGlobal` (names older plugins use). */
|
|
113
|
+
aliases?: readonly string[];
|
|
114
|
+
invoke?: PageInvoke;
|
|
115
|
+
/** Per-plugin API views (permissions.ts `createPluginContext`). */
|
|
116
|
+
plugins: PluginContext<Api>;
|
|
117
|
+
strings: PageStrings;
|
|
118
|
+
/** The toast for a plugin that failed to start in developer mode ("Plugin failed: {error}"). */
|
|
119
|
+
pluginFailed(error: string): string;
|
|
120
|
+
features?: {
|
|
121
|
+
apply(config: never): void;
|
|
122
|
+
};
|
|
123
|
+
/** The theme handle (themeRuntime.ts), exposed as `theme`. */
|
|
124
|
+
theme?: {
|
|
125
|
+
apply(choice: unknown): void;
|
|
126
|
+
};
|
|
127
|
+
fonts?(fonts: unknown): void;
|
|
128
|
+
pane?: {
|
|
129
|
+
set(state: unknown): void;
|
|
130
|
+
};
|
|
131
|
+
links?: {
|
|
132
|
+
configure(value: unknown): void;
|
|
133
|
+
};
|
|
134
|
+
column?: SiteRuntime<Api>['column'];
|
|
135
|
+
/** The app's own members (X: alerts, fixes). */
|
|
136
|
+
extra?: Extra;
|
|
137
|
+
/** Values native code may have delivered for the app's own members before the runtime existed: queue global and receiver. */
|
|
138
|
+
queues?: ReadonlyArray<readonly [queue: string, deliver: (value: unknown) => void]>;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Builds the runtime object, publishes it under its window names (not writable, not configurable),
|
|
142
|
+
* takes over what native code queued before it existed, and starts the palette command report.
|
|
143
|
+
*/
|
|
144
|
+
export declare function installSiteRuntime<Api extends object, Extra extends object = Record<never, never>>(options: SiteRuntimeOptions<Api, Extra>): SiteRuntime<Api> & Extra;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// The page runtime's composition helpers: what every app's runtime entry does the same way. An
|
|
2
|
+
// app's entry (injected at document start into its site's tabs) installs its features and then:
|
|
3
|
+
//
|
|
4
|
+
// const invoke = pageInvoke(window, SITE.product);
|
|
5
|
+
// const flags = createFeatureFlags({ defaults, label: SITE.product, installers, apply });
|
|
6
|
+
// const runtime = installSiteRuntime({ win: window, site: SITE, version, invoke, plugins, strings, features: flags, ... });
|
|
7
|
+
// installPanelButton(window, button, () => runtime.open()); // panelButton.ts
|
|
8
|
+
//
|
|
9
|
+
// - `pageInvoke`: the IPC bridge, read at call time.
|
|
10
|
+
// - `createFeatureFlags`: flag-controlled parts that install on enable and dispose on disable, the
|
|
11
|
+
// flags native code delivers (`features_set`) and a deck column's overrides on top of them.
|
|
12
|
+
// - `installSiteRuntime`: the runtime object under its window names (`window.wayBetter` and the
|
|
13
|
+
// app's own), the members native code calls (features, theme, fonts, pane, links, i18n, column),
|
|
14
|
+
// the plugin API views, developer-mode errors, the palette command report, and whatever native
|
|
15
|
+
// code delivered before the runtime existed (the `__bt*` / `__wb*` queues).
|
|
16
|
+
import { installCommandReport, devErrorReporter } from "./commandReport.js";
|
|
17
|
+
/**
|
|
18
|
+
* Native commands from the page. The IPC bridge is read at call time: a runtime installed at
|
|
19
|
+
* document start can run before Tauri has put `__TAURI_INTERNALS__` on the page. A runtime only
|
|
20
|
+
* ships inside the app's site tabs; automated test browsers (`navigator.webdriver`) have no
|
|
21
|
+
* bridge, and the features that need it stay off there (undefined).
|
|
22
|
+
*/
|
|
23
|
+
export function pageInvoke(win, product) {
|
|
24
|
+
const target = win;
|
|
25
|
+
const inApp = !!target.__TAURI_INTERNALS__ || !target.navigator.webdriver;
|
|
26
|
+
if (!inApp)
|
|
27
|
+
return undefined;
|
|
28
|
+
return (command, args) => {
|
|
29
|
+
const ipc = target.__TAURI_INTERNALS__;
|
|
30
|
+
return ipc ? ipc.invoke(command, args) : Promise.reject(new Error(`${product}: IPC bridge not ready`));
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function createFeatureFlags(options) {
|
|
34
|
+
const { defaults, label, installers } = options;
|
|
35
|
+
const active = new Map();
|
|
36
|
+
const installerOf = new Map(installers.map(([flag, install]) => [flag, install]));
|
|
37
|
+
const set = (flag, enabled) => {
|
|
38
|
+
const install = installerOf.get(flag);
|
|
39
|
+
if (!install)
|
|
40
|
+
return;
|
|
41
|
+
const current = active.get(flag);
|
|
42
|
+
if (enabled && !current) {
|
|
43
|
+
try {
|
|
44
|
+
active.set(flag, install());
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
console.error(`[${label}] ${flag} failed`, error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else if (!enabled && current) {
|
|
51
|
+
current.dispose();
|
|
52
|
+
active.delete(flag);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
// Installed at document start, before the site's bundle runs (request gates wrap its fetch).
|
|
56
|
+
for (const [flag] of installers)
|
|
57
|
+
set(flag, defaults[flag]);
|
|
58
|
+
let globalFlags = {};
|
|
59
|
+
let columnFlags = {};
|
|
60
|
+
const known = (input) => {
|
|
61
|
+
const out = {};
|
|
62
|
+
if (input && typeof input === 'object') {
|
|
63
|
+
for (const [key, value] of Object.entries(input))
|
|
64
|
+
if (key in defaults && typeof value === 'boolean')
|
|
65
|
+
out[key] = value;
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
};
|
|
69
|
+
// What runs: the defaults, the delivered flags over them, what owns what (`resolve`), and a
|
|
70
|
+
// column's own choices on top.
|
|
71
|
+
const current = () => {
|
|
72
|
+
const base = { ...defaults, ...globalFlags };
|
|
73
|
+
return { ...(options.resolve ? options.resolve(base) : base), ...columnFlags };
|
|
74
|
+
};
|
|
75
|
+
const applyAll = () => {
|
|
76
|
+
const config = current();
|
|
77
|
+
options.apply?.(config);
|
|
78
|
+
for (const [flag] of installers)
|
|
79
|
+
set(flag, config[flag]);
|
|
80
|
+
};
|
|
81
|
+
return {
|
|
82
|
+
apply(config) {
|
|
83
|
+
globalFlags = known(config);
|
|
84
|
+
applyAll();
|
|
85
|
+
},
|
|
86
|
+
setColumnFlags(flags) {
|
|
87
|
+
const next = known(flags);
|
|
88
|
+
const previous = columnFlags;
|
|
89
|
+
columnFlags = next;
|
|
90
|
+
if (!Object.keys(previous).length && !Object.keys(next).length)
|
|
91
|
+
return;
|
|
92
|
+
const apply = () => { try {
|
|
93
|
+
applyAll();
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.error(`[${label}] column flags failed`, error);
|
|
97
|
+
} };
|
|
98
|
+
const doc = options.document;
|
|
99
|
+
if (!doc || doc.documentElement)
|
|
100
|
+
apply();
|
|
101
|
+
else
|
|
102
|
+
doc.addEventListener('DOMContentLoaded', apply, { once: true });
|
|
103
|
+
},
|
|
104
|
+
set,
|
|
105
|
+
installed: flag => active.has(flag),
|
|
106
|
+
current,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Builds the runtime object, publishes it under its window names (not writable, not configurable),
|
|
111
|
+
* takes over what native code queued before it existed, and starts the palette command report.
|
|
112
|
+
*/
|
|
113
|
+
export function installSiteRuntime(options) {
|
|
114
|
+
const { win, site, plugins, strings } = options;
|
|
115
|
+
const label = site.product;
|
|
116
|
+
// A failure in one member never breaks native code's other deliveries (or the page).
|
|
117
|
+
const guarded = (what, fn) => (value) => {
|
|
118
|
+
try {
|
|
119
|
+
fn(value);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
console.error(`[${label}] ${what} failed`, error);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
const runtime = {
|
|
126
|
+
...(options.extra ?? {}),
|
|
127
|
+
version: options.version,
|
|
128
|
+
plugins: {},
|
|
129
|
+
errors: {},
|
|
130
|
+
features: { apply: (config) => options.features?.apply(config) },
|
|
131
|
+
...(options.theme ? { theme: options.theme } : {}),
|
|
132
|
+
fonts: { provide: guarded('fonts', (list) => options.fonts?.(list)) },
|
|
133
|
+
pane: { set: guarded('split navigation', (state) => options.pane?.set(state)) },
|
|
134
|
+
links: { configure: (value) => options.links?.configure(value) },
|
|
135
|
+
i18n: { set: guarded('language', (value) => strings.set(value)), locale: strings.locale, t: strings.t },
|
|
136
|
+
column: {
|
|
137
|
+
set: guarded('deck column', (config) => options.column?.set(config)),
|
|
138
|
+
markRead: () => options.column?.markRead(),
|
|
139
|
+
jumpToUnread: () => options.column?.jumpToUnread(),
|
|
140
|
+
unread: () => options.column?.unread() ?? 0,
|
|
141
|
+
},
|
|
142
|
+
open(section) {
|
|
143
|
+
win.__TAURI_INTERNALS__?.invoke('open_panel', { section: section ?? null }).catch(() => { });
|
|
144
|
+
},
|
|
145
|
+
withPlugin: (id, grants, fn) => plugins.run(id, grants, fn),
|
|
146
|
+
get api() { return plugins.current(); },
|
|
147
|
+
devError: devErrorReporter(() => {
|
|
148
|
+
const ui = plugins.current().ui;
|
|
149
|
+
return ui ? (message, toastOptions) => { ui.toast(message, toastOptions); } : undefined;
|
|
150
|
+
}, options.pluginFailed),
|
|
151
|
+
};
|
|
152
|
+
// `wayBetter` is the documented name; the app's own names stay for existing plugins.
|
|
153
|
+
const names = [...new Set(['wayBetter', site.runtimeGlobal, ...(options.aliases ?? [])])];
|
|
154
|
+
for (const name of names)
|
|
155
|
+
Object.defineProperty(win, name, { value: runtime, configurable: false, writable: false });
|
|
156
|
+
// Native code may deliver before this runtime exists.
|
|
157
|
+
const queued = win;
|
|
158
|
+
const take = (queue, deliver) => { if (queued[queue])
|
|
159
|
+
deliver(queued[queue]); };
|
|
160
|
+
take('__wbI18n', runtime.i18n.set);
|
|
161
|
+
take('__btFeatures', runtime.features.apply);
|
|
162
|
+
take('__wbFonts', runtime.fonts.provide);
|
|
163
|
+
take('__btTheme', value => runtime.theme?.apply(value));
|
|
164
|
+
take('__btPane', runtime.pane.set);
|
|
165
|
+
take('__btLinks', runtime.links.configure);
|
|
166
|
+
take('__btColumn', runtime.column.set);
|
|
167
|
+
for (const [queue, deliver] of options.queues ?? [])
|
|
168
|
+
take(queue, deliver);
|
|
169
|
+
// Plugin commands for the shell's command palette: ids, titles and keywords about this tab only.
|
|
170
|
+
const commands = plugins.current().commands;
|
|
171
|
+
if (commands)
|
|
172
|
+
installCommandReport(commands, options.invoke);
|
|
173
|
+
return runtime;
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=siteRuntime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"siteRuntime.js","sourceRoot":"","sources":["../../../runtime/src/siteRuntime.ts"],"names":[],"mappings":"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","sourcesContent":["// The page runtime's composition helpers: what every app's runtime entry does the same way. An\n// app's entry (injected at document start into its site's tabs) installs its features and then:\n//\n// const invoke = pageInvoke(window, SITE.product);\n// const flags = createFeatureFlags({ defaults, label: SITE.product, installers, apply });\n// const runtime = installSiteRuntime({ win: window, site: SITE, version, invoke, plugins, strings, features: flags, ... });\n// installPanelButton(window, button, () => runtime.open()); // panelButton.ts\n//\n// - `pageInvoke`: the IPC bridge, read at call time.\n// - `createFeatureFlags`: flag-controlled parts that install on enable and dispose on disable, the\n// flags native code delivers (`features_set`) and a deck column's overrides on top of them.\n// - `installSiteRuntime`: the runtime object under its window names (`window.wayBetter` and the\n// app's own), the members native code calls (features, theme, fonts, pane, links, i18n, column),\n// the plugin API views, developer-mode errors, the palette command report, and whatever native\n// code delivered before the runtime existed (the `__bt*` / `__wb*` queues).\n\nimport { installCommandReport, devErrorReporter } from './commandReport.ts';\nimport type { CommandInfo } from './commands.ts';\nimport type { PageStrings } from './pageStrings.ts';\nimport type { PluginContext } from './permissions.ts';\nimport type { Params } from './i18n.ts';\nimport type { SiteAdapter } from './site.ts';\n\nexport type PageInvoke = (command: string, args: Record<string, unknown>) => Promise<unknown>;\n\ntype BridgeWindow = { __TAURI_INTERNALS__?: { invoke(cmd: string, args?: Record<string, unknown>): Promise<unknown> }; navigator: { webdriver?: boolean } };\n\n/**\n * Native commands from the page. The IPC bridge is read at call time: a runtime installed at\n * document start can run before Tauri has put `__TAURI_INTERNALS__` on the page. A runtime only\n * ships inside the app's site tabs; automated test browsers (`navigator.webdriver`) have no\n * bridge, and the features that need it stay off there (undefined).\n */\nexport function pageInvoke(win: Window, product: string): PageInvoke | undefined {\n const target = win as unknown as BridgeWindow;\n const inApp = !!target.__TAURI_INTERNALS__ || !target.navigator.webdriver;\n if (!inApp) return undefined;\n return (command, args) => {\n const ipc = target.__TAURI_INTERNALS__;\n return ipc ? ipc.invoke(command, args) : Promise.reject(new Error(`${product}: IPC bridge not ready`));\n };\n}\n\n// ---------------------------------------------------------------------------------------------\n// Feature flags\n\n/** A flag-controlled part of the runtime, while it is installed. */\nexport type Installed = { dispose(): void };\nexport type FlagInstaller<Flags> = readonly [flag: keyof Flags & string, install: () => Installed];\n\nexport type FeatureFlagsOptions<Flags extends Record<string, boolean>> = {\n /** Every flag with its default; a flag not in here is ignored. */\n defaults: Flags;\n /** Console label (the app's name). */\n label: string;\n /** Parts that install when their flag turns on and dispose when it turns off, in install order. */\n installers: ReadonlyArray<FlagInstaller<Flags>>;\n /** Every applied config (the full map), before the installers (flags that are CSS, or that another part reads). */\n apply?(config: Flags): void;\n /**\n * What owns what: given the delivered flags over the defaults, the flags that really run (an\n * area whose switch is off turns its features off; featureTable `effectiveFlags`).\n */\n resolve?(flags: Flags): Flags;\n /** The page's document: a column's flags delivered at document start wait for `<html>` to exist. */\n document?: Document;\n};\n\nexport type FeatureFlags<Flags extends Record<string, boolean>> = {\n /**\n * The flags native code delivers (the owner's choices); a deck column's overrides stay on top.\n * A delivery is the whole state, stored sparsely: a flag it does not name is at its default.\n */\n apply(config: Partial<Flags>): void;\n /**\n * A deck column's flag overrides (allow-listed natively; unknown keys and non-booleans are\n * dropped here too). Flags a column stops overriding go back to the global value, or the default\n * when the global config never named them. Recorded at once; applied now, or once the document\n * has its `<html>` (a new column webview gets its config at document start).\n */\n setColumnFlags(flags: unknown): void;\n /** Turns one installer on or off directly (a kill switch). */\n set(flag: keyof Flags & string, enabled: boolean): void;\n /** Whether a flag's installer is installed right now. */\n installed(flag: keyof Flags & string): boolean;\n /** Every flag as it runs right now (defaults, the delivery, ownership, the column). */\n current(): Flags;\n};\n\nexport function createFeatureFlags<Flags extends Record<string, boolean>>(options: FeatureFlagsOptions<Flags>): FeatureFlags<Flags> {\n const { defaults, label, installers } = options;\n const active = new Map<string, Installed>();\n const installerOf = new Map(installers.map(([flag, install]) => [flag as string, install]));\n\n const set = (flag: string, enabled: boolean) => {\n const install = installerOf.get(flag);\n if (!install) return;\n const current = active.get(flag);\n if (enabled && !current) {\n try { active.set(flag, install()); }\n catch (error) { console.error(`[${label}] ${flag} failed`, error); }\n } else if (!enabled && current) {\n current.dispose();\n active.delete(flag);\n }\n };\n // Installed at document start, before the site's bundle runs (request gates wrap its fetch).\n for (const [flag] of installers) set(flag, defaults[flag]);\n\n let globalFlags: Partial<Flags> = {};\n let columnFlags: Partial<Flags> = {};\n const known = (input: unknown): Partial<Flags> => {\n const out: Record<string, boolean> = {};\n if (input && typeof input === 'object') {\n for (const [key, value] of Object.entries(input)) if (key in defaults && typeof value === 'boolean') out[key] = value;\n }\n return out as Partial<Flags>;\n };\n // What runs: the defaults, the delivered flags over them, what owns what (`resolve`), and a\n // column's own choices on top.\n const current = (): Flags => {\n const base = { ...defaults, ...globalFlags } as Flags;\n return { ...(options.resolve ? options.resolve(base) : base), ...columnFlags };\n };\n const applyAll = () => {\n const config = current();\n options.apply?.(config);\n for (const [flag] of installers) set(flag, config[flag]);\n };\n\n return {\n apply(config) {\n globalFlags = known(config);\n applyAll();\n },\n setColumnFlags(flags) {\n const next = known(flags);\n const previous = columnFlags;\n columnFlags = next;\n if (!Object.keys(previous).length && !Object.keys(next).length) return;\n const apply = () => { try { applyAll(); } catch (error) { console.error(`[${label}] column flags failed`, error); } };\n const doc = options.document;\n if (!doc || doc.documentElement) apply();\n else doc.addEventListener('DOMContentLoaded', apply, { once: true });\n },\n set,\n installed: flag => active.has(flag),\n current,\n };\n}\n\n// ---------------------------------------------------------------------------------------------\n// The runtime object\n\n/** What native code and plugins reach through `window.<runtimeGlobal>`. */\nexport type SiteRuntime<Api extends object> = {\n version: string;\n /** Running plugins by file (native start/stop scripts manage this). */\n plugins: Record<string, { start?: () => void; stop?: () => void }>;\n /** Load errors by plugin file. */\n errors: Record<string, string>;\n /** Native code hands over the feature flags (`features_set`). */\n features: { apply(config: unknown): void };\n /** Native code hands over the owner's language: `{ locale, dir, messages }` (pageStrings.ts). */\n i18n: { set(strings: unknown): void; locale(): string; t(key: string, params?: Params): string };\n /** Native code hands over where clicked site pages open (`{ site: 'same' | 'pane' | 'tab' | 'browser' }`). */\n links: { configure(value: unknown): void };\n /** Native code says whether this pane's navigation repeats another pane's (`{ redundantNav }`). */\n pane: { set(state: unknown): void };\n /** Native code hands over downloaded Google Fonts (validated woff2 bytes) that this tab's theme uses. */\n fonts: { provide(fonts: unknown): void };\n /** Power User Mode: native code hands a deck column its config (null = an ordinary tab again). */\n column: { set(config: unknown): void; markRead(): void; jumpToUnread(): void; unread(): number };\n /** Opens the app's panel in the shell (at a section). */\n open(section?: string): void;\n /**\n * Helpers for `*.plugin.js` files. Read while a plugin's code runs (its module body, constructor,\n * start() and stop()), this is that plugin's view for its declared `@permissions`; elsewhere it\n * is the full API.\n */\n readonly api: Api;\n /** Runs `fn` as plugin `id` with `grants` (null = legacy, full API; undefined = as registered). Native start/stop scripts call it. */\n withPlugin<R>(id: string, grants: readonly string[] | null | undefined, fn: () => R): R;\n /** Developer mode: a reloaded plugin failed to start (native `dev_start_script`); shown as a toast. */\n devError(file: unknown, error: unknown): void;\n};\n\ntype ApiWithUi = { ui?: { toast(message: string, options: { tone: 'danger'; duration: number }): unknown }; commands?: { list(): CommandInfo[]; onChange(callback: (list: CommandInfo[]) => void): () => void } };\n\nexport type SiteRuntimeOptions<Api extends object, Extra extends object> = {\n win: Window & typeof globalThis;\n site: Pick<SiteAdapter, 'product' | 'runtimeGlobal'>;\n version: string;\n /** Other window names for the runtime, besides `wayBetter` and `site.runtimeGlobal` (names older plugins use). */\n aliases?: readonly string[];\n invoke?: PageInvoke;\n /** Per-plugin API views (permissions.ts `createPluginContext`). */\n plugins: PluginContext<Api>;\n strings: PageStrings;\n /** The toast for a plugin that failed to start in developer mode (\"Plugin failed: {error}\"). */\n pluginFailed(error: string): string;\n features?: { apply(config: never): void };\n /** The theme handle (themeRuntime.ts), exposed as `theme`. */\n theme?: { apply(choice: unknown): void };\n fonts?(fonts: unknown): void;\n pane?: { set(state: unknown): void };\n links?: { configure(value: unknown): void };\n column?: SiteRuntime<Api>['column'];\n /** The app's own members (X: alerts, fixes). */\n extra?: Extra;\n /** Values native code may have delivered for the app's own members before the runtime existed: queue global and receiver. */\n queues?: ReadonlyArray<readonly [queue: string, deliver: (value: unknown) => void]>;\n};\n\n/**\n * Builds the runtime object, publishes it under its window names (not writable, not configurable),\n * takes over what native code queued before it existed, and starts the palette command report.\n */\nexport function installSiteRuntime<Api extends object, Extra extends object = Record<never, never>>(options: SiteRuntimeOptions<Api, Extra>): SiteRuntime<Api> & Extra {\n const { win, site, plugins, strings } = options;\n const label = site.product;\n // A failure in one member never breaks native code's other deliveries (or the page).\n const guarded = <T>(what: string, fn: (value: T) => void) => (value: T) => {\n try { fn(value); } catch (error) { console.error(`[${label}] ${what} failed`, error); }\n };\n const runtime = {\n ...(options.extra ?? {}),\n version: options.version,\n plugins: {},\n errors: {},\n features: { apply: (config: unknown) => (options.features as { apply(config: unknown): void } | undefined)?.apply(config) },\n ...(options.theme ? { theme: options.theme } : {}),\n fonts: { provide: guarded('fonts', (list: unknown) => options.fonts?.(list)) },\n pane: { set: guarded('split navigation', (state: unknown) => options.pane?.set(state)) },\n links: { configure: (value: unknown) => options.links?.configure(value) },\n i18n: { set: guarded('language', (value: unknown) => strings.set(value)), locale: strings.locale, t: strings.t },\n column: {\n set: guarded('deck column', (config: unknown) => options.column?.set(config)),\n markRead: () => options.column?.markRead(),\n jumpToUnread: () => options.column?.jumpToUnread(),\n unread: () => options.column?.unread() ?? 0,\n },\n open(section?: string) {\n (win as unknown as BridgeWindow).__TAURI_INTERNALS__?.invoke('open_panel', { section: section ?? null }).catch(() => {});\n },\n withPlugin: <R>(id: string, grants: readonly string[] | null | undefined, fn: () => R) => plugins.run(id, grants, fn),\n get api() { return plugins.current(); },\n devError: devErrorReporter(() => {\n const ui = (plugins.current() as ApiWithUi).ui;\n return ui ? (message, toastOptions) => { ui.toast(message, toastOptions); } : undefined;\n }, options.pluginFailed),\n } as unknown as SiteRuntime<Api> & Extra & { theme?: { apply(choice: unknown): void } };\n\n // `wayBetter` is the documented name; the app's own names stay for existing plugins.\n const names = [...new Set(['wayBetter', site.runtimeGlobal, ...(options.aliases ?? [])])];\n for (const name of names) Object.defineProperty(win, name, { value: runtime, configurable: false, writable: false });\n\n // Native code may deliver before this runtime exists.\n const queued = win as unknown as Record<string, unknown>;\n const take = (queue: string, deliver: (value: unknown) => void) => { if (queued[queue]) deliver(queued[queue]); };\n take('__wbI18n', runtime.i18n.set);\n take('__btFeatures', runtime.features.apply);\n take('__wbFonts', runtime.fonts.provide);\n take('__btTheme', value => runtime.theme?.apply(value));\n take('__btPane', runtime.pane.set);\n take('__btLinks', runtime.links.configure);\n take('__btColumn', runtime.column.set);\n for (const [queue, deliver] of options.queues ?? []) take(queue, deliver);\n\n // Plugin commands for the shell's command palette: ids, titles and keywords about this tab only.\n const commands = (plugins.current() as ApiWithUi).commands;\n if (commands) installCommandReport(commands, options.invoke);\n return runtime;\n}\n"]}
|