rune-lab 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitignore +12 -0
- package/README.md +3 -3
- package/deno.json +50 -0
- package/justfile +5 -0
- package/package.json +2 -79
- package/scripts/build_pkg.ts +51 -0
- package/scripts/ci.just +26 -0
- package/scripts/deploy.just +21 -0
- package/scripts/dev.just +4 -0
- package/scripts/inject.just +72 -0
- package/src/RuneProvider.svelte +105 -0
- package/src/i18n/message-resolver.test.ts +103 -0
- package/src/i18n/message-resolver.ts +89 -0
- package/src/i18n/project.inlang/settings.json +26 -0
- package/src/i18n/translations/ar.json +89 -0
- package/src/i18n/translations/de.json +89 -0
- package/src/i18n/translations/en.json +89 -0
- package/src/i18n/translations/es.json +89 -0
- package/src/i18n/translations/fr.json +89 -0
- package/src/i18n/translations/hi.json +89 -0
- package/src/i18n/translations/it.json +89 -0
- package/src/i18n/translations/ja.json +89 -0
- package/src/i18n/translations/ko.json +89 -0
- package/src/i18n/translations/pt.json +89 -0
- package/src/i18n/translations/ru.json +89 -0
- package/src/i18n/translations/vi.json +89 -0
- package/src/i18n/translations/zh.json +89 -0
- package/src/kernel/deno.json +5 -0
- package/src/kernel/src/actions/portal.ts +41 -0
- package/src/kernel/src/actions/shortcut-listener.ts +50 -0
- package/src/kernel/src/context/app.svelte.ts +98 -0
- package/src/kernel/src/context/context.ts +31 -0
- package/src/kernel/src/context/stores.svelte.ts +96 -0
- package/src/kernel/src/context/types.ts +110 -0
- package/src/kernel/src/context/useRuneLab.ts +38 -0
- package/src/kernel/src/mod.ts +13 -0
- package/src/kernel/src/persistence/createConfigStore.svelte.ts +120 -0
- package/src/kernel/src/persistence/drivers.test.ts +95 -0
- package/src/kernel/src/persistence/drivers.ts +77 -0
- package/src/kernel/src/persistence/provider.test.ts +58 -0
- package/{dist/state/persistence/provider.js → src/kernel/src/persistence/provider.ts} +29 -14
- package/src/kernel/src/persistence/types.ts +19 -0
- package/src/kernel/src/persistence/usePersistence.ts +9 -0
- package/src/kernel/src/registry/mod.ts +221 -0
- package/src/kernel/src/registry/registry.test.ts +162 -0
- package/src/kernel/src/tokens/props.ts +94 -0
- package/src/mod.ts +10 -0
- package/src/runes/layout/deno.json +5 -0
- package/src/runes/layout/src/APP_CONFIGURATIONS.ts +56 -0
- package/{dist/ui/features/config → src/runes/layout/src}/AppSettingSelector.svelte +1 -1
- package/{dist/ui/layout → src/runes/layout/src}/ConnectedNavigationPanel.svelte +1 -1
- package/{dist/ui/layout → src/runes/layout/src}/ConnectedWorkspaceStrip.svelte +1 -1
- package/src/runes/layout/src/Icon.svelte +7 -0
- package/{dist/ui/features/config → src/runes/layout/src}/LanguageSelector.svelte +7 -5
- package/{dist/ui/layout → src/runes/layout/src}/NavigationPanel.svelte +1 -4
- package/{dist/ui/features/config → src/runes/layout/src}/ResourceSelector.svelte +3 -5
- package/{dist/ui/features/config → src/runes/layout/src}/ThemeSelector.svelte +2 -2
- package/{dist/ui/layout → src/runes/layout/src}/WorkspaceLayout.svelte +6 -4
- package/{dist/ui/layout → src/runes/layout/src}/WorkspaceStrip.svelte +1 -1
- package/src/runes/layout/src/connection-factory.ts +95 -0
- package/src/runes/layout/src/language.svelte.ts +44 -0
- package/src/runes/layout/src/mod.ts +71 -0
- package/src/runes/layout/src/store.svelte.ts +142 -0
- package/src/runes/layout/src/theme.svelte.ts +73 -0
- package/src/runes/layout/src/types.ts +11 -0
- package/src/runes/palettes/deno.json +8 -0
- package/{dist/ui/features/command-palette → src/runes/palettes/src/commands}/CommandPalette.svelte +4 -4
- package/src/runes/palettes/src/commands/mod.ts +2 -0
- package/src/runes/palettes/src/commands/store.svelte.ts +80 -0
- package/src/runes/palettes/src/mod.ts +51 -0
- package/{dist/ui/components → src/runes/palettes/src/notifications}/Toaster.svelte +1 -2
- package/src/runes/palettes/src/notifications/bridge.ts +56 -0
- package/src/runes/palettes/src/notifications/mod.ts +4 -0
- package/src/runes/palettes/src/notifications/store.svelte.ts +58 -0
- package/{dist/ui/features → src/runes/palettes/src}/shortcuts/ShortcutPalette.svelte +4 -4
- package/src/runes/palettes/src/shortcuts/mod.ts +4 -0
- package/src/runes/palettes/src/shortcuts/store.svelte.ts +85 -0
- package/src/runes/palettes/src/shortcuts/types.ts +4 -0
- package/src/runes/palettes/src/shortcuts/useShortcuts.ts +85 -0
- package/src/runes/plugins/money/deno.json +8 -0
- package/{dist/ui/features/config → src/runes/plugins/money/src}/CurrencySelector.svelte +2 -2
- package/{dist/ui/components/money → src/runes/plugins/money/src}/MoneyDisplay.svelte +2 -2
- package/{dist/ui/components/money → src/runes/plugins/money/src}/MoneyInput.svelte +4 -8
- package/src/runes/plugins/money/src/currency.svelte.ts +95 -0
- package/src/runes/plugins/money/src/currency.test.ts +40 -0
- package/src/runes/plugins/money/src/exchange-rate.svelte.ts +176 -0
- package/src/runes/plugins/money/src/exchange-rate.test.ts +95 -0
- package/src/runes/plugins/money/src/mod.ts +79 -0
- package/src/runes/plugins/money/src/money-primitive.test.ts +217 -0
- package/src/runes/plugins/money/src/money-primitive.ts +220 -0
- package/src/runes/plugins/money/src/money.test.ts +183 -0
- package/src/runes/plugins/money/src/money.ts +382 -0
- package/src/runes/plugins/money/src/strategies.test.ts +143 -0
- package/{dist/core/exchange-rate/strategies.js → src/runes/plugins/money/src/strategies.ts} +45 -22
- package/src/runes/plugins/money/src/types.ts +27 -0
- package/src/runes/plugins/money/src/useMoney.ts +261 -0
- package/src/runes/plugins/money/src/useMoneyFilter.ts +132 -0
- package/tsconfig.json +41 -0
- package/vite.config.ts +44 -0
- package/dist/core/design-tokens/props.d.ts +0 -52
- package/dist/core/design-tokens/props.d.ts.map +0 -1
- package/dist/core/design-tokens/props.js +0 -34
- package/dist/core/exchange-rate/strategies.d.ts +0 -52
- package/dist/core/exchange-rate/strategies.d.ts.map +0 -1
- package/dist/core/index.d.ts +0 -9
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -8
- package/dist/core/internal/message-resolver.d.ts +0 -42
- package/dist/core/internal/message-resolver.d.ts.map +0 -1
- package/dist/core/internal/message-resolver.js +0 -47
- package/dist/core/layout/types.d.ts +0 -60
- package/dist/core/layout/types.d.ts.map +0 -1
- package/dist/core/layout/types.js +0 -4
- package/dist/core/money/index.d.ts +0 -2
- package/dist/core/money/index.d.ts.map +0 -1
- package/dist/core/money/index.js +0 -2
- package/dist/core/money/money-primitive.d.ts +0 -101
- package/dist/core/money/money-primitive.d.ts.map +0 -1
- package/dist/core/money/money-primitive.js +0 -161
- package/dist/core/money/money.d.ts +0 -129
- package/dist/core/money/money.d.ts.map +0 -1
- package/dist/core/money/money.js +0 -250
- package/dist/core/persistence/types.d.ts +0 -18
- package/dist/core/persistence/types.d.ts.map +0 -1
- package/dist/core/persistence/types.js +0 -2
- package/dist/core/shortcuts/types.d.ts +0 -60
- package/dist/core/shortcuts/types.d.ts.map +0 -1
- package/dist/core/shortcuts/types.js +0 -4
- package/dist/index.d.ts +0 -6
- package/dist/index.js +0 -7
- package/dist/state/api.svelte.d.ts +0 -26
- package/dist/state/api.svelte.js +0 -65
- package/dist/state/app.svelte.d.ts +0 -48
- package/dist/state/app.svelte.js +0 -82
- package/dist/state/auth/index.d.ts +0 -2
- package/dist/state/auth/index.js +0 -2
- package/dist/state/auth/session.svelte.d.ts +0 -40
- package/dist/state/auth/session.svelte.js +0 -59
- package/dist/state/auth/types.d.ts +0 -30
- package/dist/state/auth/types.js +0 -3
- package/dist/state/cart.svelte.d.ts +0 -64
- package/dist/state/cart.svelte.js +0 -122
- package/dist/state/commands.svelte.d.ts +0 -46
- package/dist/state/commands.svelte.js +0 -62
- package/dist/state/composables/useMoney.d.ts +0 -31
- package/dist/state/composables/useMoney.js +0 -126
- package/dist/state/composables/useMoneyFilter.d.ts +0 -20
- package/dist/state/composables/useMoneyFilter.js +0 -81
- package/dist/state/composables/usePersistence.d.ts +0 -2
- package/dist/state/composables/usePersistence.js +0 -5
- package/dist/state/composables/useRuneLab.d.ts +0 -19
- package/dist/state/composables/useRuneLab.js +0 -30
- package/dist/state/composables/useShortcuts.d.ts +0 -33
- package/dist/state/composables/useShortcuts.js +0 -75
- package/dist/state/context.d.ts +0 -15
- package/dist/state/context.js +0 -16
- package/dist/state/createConfigStore.svelte.d.ts +0 -28
- package/dist/state/createConfigStore.svelte.js +0 -72
- package/dist/state/currency.svelte.d.ts +0 -32
- package/dist/state/currency.svelte.js +0 -96
- package/dist/state/currency.test.d.ts +0 -1
- package/dist/state/currency.test.js +0 -35
- package/dist/state/exchange-rate.svelte.d.ts +0 -43
- package/dist/state/exchange-rate.svelte.js +0 -145
- package/dist/state/exchange-rate.test.d.ts +0 -1
- package/dist/state/exchange-rate.test.js +0 -75
- package/dist/state/index.d.ts +0 -26
- package/dist/state/index.js +0 -32
- package/dist/state/language.svelte.d.ts +0 -57
- package/dist/state/language.svelte.js +0 -43
- package/dist/state/layout.svelte.d.ts +0 -49
- package/dist/state/layout.svelte.js +0 -108
- package/dist/state/persistence/drivers.d.ts +0 -12
- package/dist/state/persistence/drivers.js +0 -75
- package/dist/state/persistence/drivers.test.d.ts +0 -1
- package/dist/state/persistence/drivers.test.js +0 -79
- package/dist/state/persistence/provider.d.ts +0 -23
- package/dist/state/persistence/provider.test.d.ts +0 -1
- package/dist/state/persistence/provider.test.js +0 -51
- package/dist/state/registry/index.d.ts +0 -44
- package/dist/state/registry/index.js +0 -58
- package/dist/state/registry/registry.test.d.ts +0 -1
- package/dist/state/registry/registry.test.js +0 -112
- package/dist/state/registry/types.d.ts +0 -20
- package/dist/state/registry/types.js +0 -3
- package/dist/state/shortcuts.svelte.d.ts +0 -121
- package/dist/state/shortcuts.svelte.js +0 -222
- package/dist/state/theme.svelte.d.ts +0 -15
- package/dist/state/theme.svelte.js +0 -92
- package/dist/state/toast-bridge.d.ts +0 -29
- package/dist/state/toast-bridge.js +0 -43
- package/dist/state/toast.svelte.d.ts +0 -27
- package/dist/state/toast.svelte.js +0 -43
- package/dist/ui/actions/portal.d.ts +0 -7
- package/dist/ui/actions/portal.js +0 -32
- package/dist/ui/components/ApiMonitor.svelte +0 -162
- package/dist/ui/components/ApiMonitor.svelte.d.ts +0 -3
- package/dist/ui/components/Icon.svelte +0 -108
- package/dist/ui/components/Icon.svelte.d.ts +0 -14
- package/dist/ui/components/Kyntharil.svelte +0 -48
- package/dist/ui/components/Kyntharil.svelte.d.ts +0 -6
- package/dist/ui/components/RuneProvider.svelte +0 -218
- package/dist/ui/components/RuneProvider.svelte.d.ts +0 -49
- package/dist/ui/components/Toaster.svelte.d.ts +0 -18
- package/dist/ui/components/money/MoneyDisplay.svelte.d.ts +0 -33
- package/dist/ui/components/money/MoneyDisplay.svelte.test.d.ts +0 -1
- package/dist/ui/components/money/MoneyDisplay.svelte.test.js +0 -117
- package/dist/ui/components/money/MoneyInput.svelte.d.ts +0 -34
- package/dist/ui/components/money/index.d.ts +0 -2
- package/dist/ui/components/money/index.js +0 -3
- package/dist/ui/components/user/UserAvatar.svelte +0 -66
- package/dist/ui/components/user/UserAvatar.svelte.d.ts +0 -13
- package/dist/ui/components/user/UserProfile.svelte +0 -79
- package/dist/ui/components/user/UserProfile.svelte.d.ts +0 -17
- package/dist/ui/components/user/index.d.ts +0 -2
- package/dist/ui/components/user/index.js +0 -3
- package/dist/ui/features/command-palette/CommandPalette.svelte.d.ts +0 -6
- package/dist/ui/features/config/APP_CONFIGURATIONS.d.ts +0 -29
- package/dist/ui/features/config/APP_CONFIGURATIONS.js +0 -38
- package/dist/ui/features/config/AppSettingSelector.svelte.d.ts +0 -13
- package/dist/ui/features/config/CurrencySelector.svelte.d.ts +0 -8
- package/dist/ui/features/config/LanguageSelector.svelte.d.ts +0 -8
- package/dist/ui/features/config/ResourceSelector.svelte.d.ts +0 -25
- package/dist/ui/features/config/ThemeSelector.svelte.d.ts +0 -8
- package/dist/ui/features/notifications/NotificationBell.svelte.d.ts +0 -11
- package/dist/ui/features/notifications/index.d.ts +0 -1
- package/dist/ui/features/notifications/index.js +0 -2
- package/dist/ui/features/shortcuts/ShortcutBinder.svelte +0 -17
- package/dist/ui/features/shortcuts/ShortcutBinder.svelte.d.ts +0 -7
- package/dist/ui/features/shortcuts/ShortcutPalette.svelte.d.ts +0 -6
- package/dist/ui/index.d.ts +0 -30
- package/dist/ui/index.js +0 -46
- package/dist/ui/layout/ConnectedNavigationPanel.svelte.d.ts +0 -10
- package/dist/ui/layout/ConnectedWorkspaceStrip.svelte.d.ts +0 -9
- package/dist/ui/layout/ContentArea.svelte.d.ts +0 -8
- package/dist/ui/layout/DetailPanel.svelte.d.ts +0 -7
- package/dist/ui/layout/NavigationPanel.svelte.d.ts +0 -14
- package/dist/ui/layout/WorkspaceLayout.svelte.d.ts +0 -32
- package/dist/ui/layout/WorkspaceStrip.svelte.d.ts +0 -11
- package/dist/ui/layout/connection-factory.d.ts +0 -50
- package/dist/ui/layout/connection-factory.js +0 -58
- package/dist/ui/layout/index.d.ts +0 -7
- package/dist/ui/layout/index.js +0 -7
- package/dist/ui/paraglide/README.md +0 -147
- package/dist/ui/paraglide/messages/_index.d.ts +0 -87
- package/dist/ui/paraglide/messages/_index.js +0 -88
- package/dist/ui/paraglide/messages/abyss.d.ts +0 -16
- package/dist/ui/paraglide/messages/abyss.js +0 -84
- package/dist/ui/paraglide/messages/acid.d.ts +0 -16
- package/dist/ui/paraglide/messages/acid.js +0 -84
- package/dist/ui/paraglide/messages/active_toasts.d.ts +0 -16
- package/dist/ui/paraglide/messages/active_toasts.js +0 -84
- package/dist/ui/paraglide/messages/aed3.d.ts +0 -17
- package/dist/ui/paraglide/messages/aed3.js +0 -85
- package/dist/ui/paraglide/messages/all_currencies.d.ts +0 -16
- package/dist/ui/paraglide/messages/all_currencies.js +0 -84
- package/dist/ui/paraglide/messages/all_languages.d.ts +0 -16
- package/dist/ui/paraglide/messages/all_languages.js +0 -84
- package/dist/ui/paraglide/messages/all_themes.d.ts +0 -16
- package/dist/ui/paraglide/messages/all_themes.js +0 -84
- package/dist/ui/paraglide/messages/api_status.d.ts +0 -16
- package/dist/ui/paraglide/messages/api_status.js +0 -84
- package/dist/ui/paraglide/messages/app_info.d.ts +0 -16
- package/dist/ui/paraglide/messages/app_info.js +0 -84
- package/dist/ui/paraglide/messages/appearance.d.ts +0 -16
- package/dist/ui/paraglide/messages/appearance.js +0 -84
- package/dist/ui/paraglide/messages/aqua.d.ts +0 -16
- package/dist/ui/paraglide/messages/aqua.js +0 -84
- package/dist/ui/paraglide/messages/ar.d.ts +0 -16
- package/dist/ui/paraglide/messages/ar.js +0 -84
- package/dist/ui/paraglide/messages/autumn.d.ts +0 -16
- package/dist/ui/paraglide/messages/autumn.js +0 -84
- package/dist/ui/paraglide/messages/black.d.ts +0 -16
- package/dist/ui/paraglide/messages/black.js +0 -84
- package/dist/ui/paraglide/messages/brl3.d.ts +0 -17
- package/dist/ui/paraglide/messages/brl3.js +0 -85
- package/dist/ui/paraglide/messages/bumblebee.d.ts +0 -16
- package/dist/ui/paraglide/messages/bumblebee.js +0 -84
- package/dist/ui/paraglide/messages/business.d.ts +0 -16
- package/dist/ui/paraglide/messages/business.js +0 -84
- package/dist/ui/paraglide/messages/cad3.d.ts +0 -17
- package/dist/ui/paraglide/messages/cad3.js +0 -85
- package/dist/ui/paraglide/messages/caramellatte.d.ts +0 -16
- package/dist/ui/paraglide/messages/caramellatte.js +0 -84
- package/dist/ui/paraglide/messages/cmyk.d.ts +0 -16
- package/dist/ui/paraglide/messages/cmyk.js +0 -84
- package/dist/ui/paraglide/messages/cny3.d.ts +0 -17
- package/dist/ui/paraglide/messages/cny3.js +0 -85
- package/dist/ui/paraglide/messages/coffee.d.ts +0 -16
- package/dist/ui/paraglide/messages/coffee.js +0 -84
- package/dist/ui/paraglide/messages/commands_label.d.ts +0 -16
- package/dist/ui/paraglide/messages/commands_label.js +0 -84
- package/dist/ui/paraglide/messages/corporate.d.ts +0 -16
- package/dist/ui/paraglide/messages/corporate.js +0 -84
- package/dist/ui/paraglide/messages/cupcake.d.ts +0 -16
- package/dist/ui/paraglide/messages/cupcake.js +0 -84
- package/dist/ui/paraglide/messages/currency.d.ts +0 -16
- package/dist/ui/paraglide/messages/currency.js +0 -84
- package/dist/ui/paraglide/messages/current_currency.d.ts +0 -16
- package/dist/ui/paraglide/messages/current_currency.js +0 -84
- package/dist/ui/paraglide/messages/current_language.d.ts +0 -16
- package/dist/ui/paraglide/messages/current_language.js +0 -84
- package/dist/ui/paraglide/messages/current_theme.d.ts +0 -16
- package/dist/ui/paraglide/messages/current_theme.js +0 -84
- package/dist/ui/paraglide/messages/currently_in_queue.d.ts +0 -16
- package/dist/ui/paraglide/messages/currently_in_queue.js +0 -84
- package/dist/ui/paraglide/messages/cyberpunk.d.ts +0 -16
- package/dist/ui/paraglide/messages/cyberpunk.js +0 -84
- package/dist/ui/paraglide/messages/dark.d.ts +0 -16
- package/dist/ui/paraglide/messages/dark.js +0 -84
- package/dist/ui/paraglide/messages/de.d.ts +0 -16
- package/dist/ui/paraglide/messages/de.js +0 -84
- package/dist/ui/paraglide/messages/dim.d.ts +0 -16
- package/dist/ui/paraglide/messages/dim.js +0 -84
- package/dist/ui/paraglide/messages/dracula.d.ts +0 -16
- package/dist/ui/paraglide/messages/dracula.js +0 -84
- package/dist/ui/paraglide/messages/emerald.d.ts +0 -16
- package/dist/ui/paraglide/messages/emerald.js +0 -84
- package/dist/ui/paraglide/messages/en.d.ts +0 -16
- package/dist/ui/paraglide/messages/en.js +0 -84
- package/dist/ui/paraglide/messages/es.d.ts +0 -16
- package/dist/ui/paraglide/messages/es.js +0 -84
- package/dist/ui/paraglide/messages/eur3.d.ts +0 -17
- package/dist/ui/paraglide/messages/eur3.js +0 -85
- package/dist/ui/paraglide/messages/extended_controls.d.ts +0 -16
- package/dist/ui/paraglide/messages/extended_controls.js +0 -84
- package/dist/ui/paraglide/messages/fantasy.d.ts +0 -16
- package/dist/ui/paraglide/messages/fantasy.js +0 -84
- package/dist/ui/paraglide/messages/forest.d.ts +0 -16
- package/dist/ui/paraglide/messages/forest.js +0 -84
- package/dist/ui/paraglide/messages/fr.d.ts +0 -16
- package/dist/ui/paraglide/messages/fr.js +0 -84
- package/dist/ui/paraglide/messages/garden.d.ts +0 -16
- package/dist/ui/paraglide/messages/garden.js +0 -84
- package/dist/ui/paraglide/messages/gbp3.d.ts +0 -17
- package/dist/ui/paraglide/messages/gbp3.js +0 -85
- package/dist/ui/paraglide/messages/halloween.d.ts +0 -16
- package/dist/ui/paraglide/messages/halloween.js +0 -84
- package/dist/ui/paraglide/messages/hello_world.d.ts +0 -18
- package/dist/ui/paraglide/messages/hello_world.js +0 -84
- package/dist/ui/paraglide/messages/hi.d.ts +0 -16
- package/dist/ui/paraglide/messages/hi.js +0 -84
- package/dist/ui/paraglide/messages/inr3.d.ts +0 -17
- package/dist/ui/paraglide/messages/inr3.js +0 -85
- package/dist/ui/paraglide/messages/it.d.ts +0 -16
- package/dist/ui/paraglide/messages/it.js +0 -84
- package/dist/ui/paraglide/messages/ja.d.ts +0 -16
- package/dist/ui/paraglide/messages/ja.js +0 -84
- package/dist/ui/paraglide/messages/jpy3.d.ts +0 -17
- package/dist/ui/paraglide/messages/jpy3.js +0 -85
- package/dist/ui/paraglide/messages/ko.d.ts +0 -16
- package/dist/ui/paraglide/messages/ko.js +0 -84
- package/dist/ui/paraglide/messages/krw3.d.ts +0 -17
- package/dist/ui/paraglide/messages/krw3.js +0 -85
- package/dist/ui/paraglide/messages/languages.d.ts +0 -16
- package/dist/ui/paraglide/messages/languages.js +0 -84
- package/dist/ui/paraglide/messages/lemonade.d.ts +0 -16
- package/dist/ui/paraglide/messages/lemonade.js +0 -84
- package/dist/ui/paraglide/messages/light.d.ts +0 -16
- package/dist/ui/paraglide/messages/light.js +0 -84
- package/dist/ui/paraglide/messages/live_store_dashboard.d.ts +0 -16
- package/dist/ui/paraglide/messages/live_store_dashboard.js +0 -84
- package/dist/ui/paraglide/messages/localization.d.ts +0 -16
- package/dist/ui/paraglide/messages/localization.js +0 -84
- package/dist/ui/paraglide/messages/lofi.d.ts +0 -16
- package/dist/ui/paraglide/messages/lofi.js +0 -84
- package/dist/ui/paraglide/messages/luxury.d.ts +0 -16
- package/dist/ui/paraglide/messages/luxury.js +0 -84
- package/dist/ui/paraglide/messages/mxn3.d.ts +0 -17
- package/dist/ui/paraglide/messages/mxn3.js +0 -85
- package/dist/ui/paraglide/messages/name_label.d.ts +0 -16
- package/dist/ui/paraglide/messages/name_label.js +0 -84
- package/dist/ui/paraglide/messages/night.d.ts +0 -16
- package/dist/ui/paraglide/messages/night.js +0 -84
- package/dist/ui/paraglide/messages/nord.d.ts +0 -16
- package/dist/ui/paraglide/messages/nord.js +0 -84
- package/dist/ui/paraglide/messages/pastel.d.ts +0 -16
- package/dist/ui/paraglide/messages/pastel.js +0 -84
- package/dist/ui/paraglide/messages/pt.d.ts +0 -16
- package/dist/ui/paraglide/messages/pt.js +0 -84
- package/dist/ui/paraglide/messages/real_time_monitor_desc.d.ts +0 -16
- package/dist/ui/paraglide/messages/real_time_monitor_desc.js +0 -84
- package/dist/ui/paraglide/messages/registered_in_registry.d.ts +0 -16
- package/dist/ui/paraglide/messages/registered_in_registry.js +0 -84
- package/dist/ui/paraglide/messages/retro.d.ts +0 -16
- package/dist/ui/paraglide/messages/retro.js +0 -84
- package/dist/ui/paraglide/messages/ru.d.ts +0 -16
- package/dist/ui/paraglide/messages/ru.js +0 -84
- package/dist/ui/paraglide/messages/silk.d.ts +0 -16
- package/dist/ui/paraglide/messages/silk.js +0 -84
- package/dist/ui/paraglide/messages/state_label.d.ts +0 -16
- package/dist/ui/paraglide/messages/state_label.js +0 -84
- package/dist/ui/paraglide/messages/sunset.d.ts +0 -16
- package/dist/ui/paraglide/messages/sunset.js +0 -84
- package/dist/ui/paraglide/messages/synthwave.d.ts +0 -16
- package/dist/ui/paraglide/messages/synthwave.js +0 -84
- package/dist/ui/paraglide/messages/system.d.ts +0 -16
- package/dist/ui/paraglide/messages/system.js +0 -84
- package/dist/ui/paraglide/messages/theme.d.ts +0 -16
- package/dist/ui/paraglide/messages/theme.js +0 -84
- package/dist/ui/paraglide/messages/themes.d.ts +0 -16
- package/dist/ui/paraglide/messages/themes.js +0 -84
- package/dist/ui/paraglide/messages/url_label.d.ts +0 -16
- package/dist/ui/paraglide/messages/url_label.js +0 -84
- package/dist/ui/paraglide/messages/usd3.d.ts +0 -17
- package/dist/ui/paraglide/messages/usd3.js +0 -85
- package/dist/ui/paraglide/messages/valentine.d.ts +0 -16
- package/dist/ui/paraglide/messages/valentine.js +0 -84
- package/dist/ui/paraglide/messages/version_label.d.ts +0 -16
- package/dist/ui/paraglide/messages/version_label.js +0 -84
- package/dist/ui/paraglide/messages/vi.d.ts +0 -16
- package/dist/ui/paraglide/messages/vi.js +0 -84
- package/dist/ui/paraglide/messages/winter.d.ts +0 -16
- package/dist/ui/paraglide/messages/winter.js +0 -84
- package/dist/ui/paraglide/messages/wireframe.d.ts +0 -16
- package/dist/ui/paraglide/messages/wireframe.js +0 -84
- package/dist/ui/paraglide/messages/zh.d.ts +0 -16
- package/dist/ui/paraglide/messages/zh.js +0 -84
- package/dist/ui/paraglide/messages.d.ts +0 -2
- package/dist/ui/paraglide/messages.js +0 -4
- package/dist/ui/paraglide/registry.d.ts +0 -21
- package/dist/ui/paraglide/registry.js +0 -31
- package/dist/ui/paraglide/runtime.d.ts +0 -730
- package/dist/ui/paraglide/runtime.js +0 -1812
- package/dist/ui/paraglide/server.d.ts +0 -92
- package/dist/ui/paraglide/server.js +0 -239
- package/dist/ui/primitives/DatePicker.svelte +0 -257
- package/dist/ui/primitives/DatePicker.svelte.d.ts +0 -17
- package/dist/ui/primitives/index.d.ts +0 -1
- package/dist/ui/primitives/index.js +0 -3
- /package/{dist/ui/layout → src/runes/layout/src}/ContentArea.svelte +0 -0
- /package/{dist/ui/layout → src/runes/layout/src}/DetailPanel.svelte +0 -0
- /package/{dist/ui/features → src/runes/palettes/src}/notifications/NotificationBell.svelte +0 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// src/kernel/src/context/app.svelte.ts
|
|
2
|
+
import { getContext } from "svelte";
|
|
3
|
+
import { RUNE_LAB_CONTEXT } from "./context.ts";
|
|
4
|
+
import { DEV } from "esm-env";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Application metadata interface
|
|
8
|
+
*/
|
|
9
|
+
export interface AppData {
|
|
10
|
+
name: string;
|
|
11
|
+
version: string;
|
|
12
|
+
description: string;
|
|
13
|
+
author: string;
|
|
14
|
+
repository?: string;
|
|
15
|
+
license?: string;
|
|
16
|
+
homepage?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* App Store
|
|
21
|
+
* Manages application metadata and identity
|
|
22
|
+
*/
|
|
23
|
+
export class AppStore {
|
|
24
|
+
// State
|
|
25
|
+
name: string = $state("Rune Lab");
|
|
26
|
+
version: string = $state("0.0.1");
|
|
27
|
+
description: string = $state("Modern toolkit for Svelte 5 Runes");
|
|
28
|
+
author: string = $state("Yrrrrrf");
|
|
29
|
+
repository: string = $state("https://github.com/Yrrrrrf/rune-lab");
|
|
30
|
+
license: string = $state("MIT");
|
|
31
|
+
homepage: string = $state("https://jsr.io/@yrrrrrf/rune-lab");
|
|
32
|
+
customIcons: Record<string, string> = $state<Record<string, string>>({});
|
|
33
|
+
|
|
34
|
+
#initialized = false;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Initialize app store with metadata.
|
|
38
|
+
*/
|
|
39
|
+
init(data: Partial<AppData>): void {
|
|
40
|
+
if (this.#initialized) {
|
|
41
|
+
if (DEV) {
|
|
42
|
+
console.warn(
|
|
43
|
+
"AppStore.init() called multiple times. Ignoring subsequent calls.",
|
|
44
|
+
"Overwritten properties would have been:",
|
|
45
|
+
data,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (data.name) this.name = data.name;
|
|
52
|
+
if (data.version) this.version = data.version;
|
|
53
|
+
if (data.description) this.description = data.description;
|
|
54
|
+
if (data.author) this.author = data.author;
|
|
55
|
+
if (data.repository) this.repository = data.repository;
|
|
56
|
+
if (data.license) this.license = data.license;
|
|
57
|
+
if (data.homepage) this.homepage = data.homepage;
|
|
58
|
+
|
|
59
|
+
this.#initialized = true;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @internal Test-only. Resets initialization guard.
|
|
64
|
+
*/
|
|
65
|
+
__reset(): void {
|
|
66
|
+
this.#initialized = false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get full app information object
|
|
71
|
+
*/
|
|
72
|
+
get info(): AppData {
|
|
73
|
+
return {
|
|
74
|
+
name: this.name,
|
|
75
|
+
version: this.version,
|
|
76
|
+
description: this.description,
|
|
77
|
+
author: this.author,
|
|
78
|
+
repository: this.repository,
|
|
79
|
+
license: this.license,
|
|
80
|
+
homepage: this.homepage,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Registers custom SVG icons to be available globally in the Icon component
|
|
86
|
+
*/
|
|
87
|
+
registerIcons(icons: Record<string, string>) {
|
|
88
|
+
this.customIcons = { ...this.customIcons, ...icons };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function createAppStore(): AppStore {
|
|
93
|
+
return new AppStore();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function getAppStore(): AppStore {
|
|
97
|
+
return getContext<AppStore>(RUNE_LAB_CONTEXT.app);
|
|
98
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// src/lib/context.ts
|
|
2
|
+
|
|
3
|
+
export const RUNE_LAB_CONTEXT: {
|
|
4
|
+
app: symbol;
|
|
5
|
+
api: symbol;
|
|
6
|
+
toast: symbol;
|
|
7
|
+
theme: symbol;
|
|
8
|
+
language: symbol;
|
|
9
|
+
currency: symbol;
|
|
10
|
+
shortcut: symbol;
|
|
11
|
+
layout: symbol;
|
|
12
|
+
commands: symbol;
|
|
13
|
+
persistence: symbol;
|
|
14
|
+
cart: symbol;
|
|
15
|
+
session: symbol;
|
|
16
|
+
exchangeRate: symbol;
|
|
17
|
+
} = {
|
|
18
|
+
app: Symbol("rl:app"),
|
|
19
|
+
api: Symbol("rl:api"),
|
|
20
|
+
toast: Symbol("rl:toast"),
|
|
21
|
+
theme: Symbol("rl:theme"),
|
|
22
|
+
language: Symbol("rl:language"),
|
|
23
|
+
currency: Symbol("rl:currency"),
|
|
24
|
+
shortcut: Symbol("rl:shortcut"),
|
|
25
|
+
layout: Symbol("rl:layout"),
|
|
26
|
+
commands: Symbol("rl:commands"),
|
|
27
|
+
persistence: Symbol("rl:persistence"),
|
|
28
|
+
cart: Symbol("rl:cart"),
|
|
29
|
+
session: Symbol("rl:session"),
|
|
30
|
+
exchangeRate: Symbol("rl:exchange-rate"),
|
|
31
|
+
} as const;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { getContext } from "svelte";
|
|
2
|
+
import { RUNE_LAB_CONTEXT } from "./context.ts";
|
|
3
|
+
import type { ConfigStore } from "../persistence/createConfigStore.svelte.ts";
|
|
4
|
+
import type {
|
|
5
|
+
Command,
|
|
6
|
+
Currency,
|
|
7
|
+
Language,
|
|
8
|
+
Theme,
|
|
9
|
+
Toast,
|
|
10
|
+
ToastType,
|
|
11
|
+
} from "./types.ts";
|
|
12
|
+
import type { LayoutStore } from "../../../runes/layout/src/store.svelte.ts";
|
|
13
|
+
import type { ShortcutStore } from "../../../runes/palettes/src/shortcuts/store.svelte.ts";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Common store interfaces
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export interface ICommandStore {
|
|
20
|
+
commands: Command[];
|
|
21
|
+
register(command: Command): void;
|
|
22
|
+
unregister(id: string): void;
|
|
23
|
+
search(query: string, parentId?: string): Command[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface IToastStore {
|
|
27
|
+
toasts: Toast[];
|
|
28
|
+
send(message: string, type?: ToastType, duration?: number): void;
|
|
29
|
+
success(msg: string): void;
|
|
30
|
+
error(msg: string): void;
|
|
31
|
+
warn(msg: string): void;
|
|
32
|
+
info(msg: string): void;
|
|
33
|
+
dismiss(id: string): void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ICurrencyStore extends ConfigStore<Currency> {
|
|
37
|
+
canConvert: boolean;
|
|
38
|
+
convertAmount(amount: number, fromCode: string, toCode?: string): number;
|
|
39
|
+
addCurrency(meta: Currency, dineroDef?: unknown): void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Store context accessors
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
export function getLayoutStore(): LayoutStore {
|
|
47
|
+
return getContext<LayoutStore>(RUNE_LAB_CONTEXT.layout);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function getLanguageStore(): ConfigStore<Language> {
|
|
51
|
+
return getContext<ConfigStore<Language>>(RUNE_LAB_CONTEXT.language);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function getThemeStore(): ConfigStore<Theme> {
|
|
55
|
+
return getContext<ConfigStore<Theme>>(RUNE_LAB_CONTEXT.theme);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function getShortcutStore(): ShortcutStore {
|
|
59
|
+
return getContext<ShortcutStore>(RUNE_LAB_CONTEXT.shortcut);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function getCommandStore(): ICommandStore {
|
|
63
|
+
return getContext<ICommandStore>(RUNE_LAB_CONTEXT.commands);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function getToastStore(): IToastStore {
|
|
67
|
+
return getContext<IToastStore>(RUNE_LAB_CONTEXT.toast);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function getCurrencyStore(): ICurrencyStore {
|
|
71
|
+
return getContext<ICurrencyStore>(RUNE_LAB_CONTEXT.currency);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Standard layout shortcuts
|
|
76
|
+
*/
|
|
77
|
+
export const LAYOUT_SHORTCUTS = {
|
|
78
|
+
TOGGLE_NAV: {
|
|
79
|
+
id: "layout:toggle-nav",
|
|
80
|
+
keys: "ctrl+b",
|
|
81
|
+
label: "Toggle Sidebar",
|
|
82
|
+
category: "Layout",
|
|
83
|
+
},
|
|
84
|
+
TOGGLE_DETAIL: {
|
|
85
|
+
id: "layout:toggle-detail",
|
|
86
|
+
keys: "ctrl+alt+b",
|
|
87
|
+
label: "Toggle Detail Panel",
|
|
88
|
+
category: "Layout",
|
|
89
|
+
},
|
|
90
|
+
OPEN_SHORTCUTS: {
|
|
91
|
+
id: "layout:open-shortcuts",
|
|
92
|
+
keys: "ctrl+/",
|
|
93
|
+
label: "Show Shortcuts",
|
|
94
|
+
category: "Layout",
|
|
95
|
+
},
|
|
96
|
+
} as const;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layout configuration
|
|
3
|
+
*/
|
|
4
|
+
export interface LayoutZone {
|
|
5
|
+
id: string;
|
|
6
|
+
component?: unknown;
|
|
7
|
+
storeKey?: string;
|
|
8
|
+
width?: string;
|
|
9
|
+
collapsible?: boolean;
|
|
10
|
+
conditional?: string;
|
|
11
|
+
minWidth?: string;
|
|
12
|
+
position?: "start" | "end";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type LayoutConfig = LayoutZone[];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Currency
|
|
19
|
+
*/
|
|
20
|
+
export interface Currency {
|
|
21
|
+
code: string;
|
|
22
|
+
symbol: string;
|
|
23
|
+
decimals: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Navigation & Workspace items
|
|
28
|
+
*/
|
|
29
|
+
export interface WorkspaceItem {
|
|
30
|
+
id: string;
|
|
31
|
+
icon: string;
|
|
32
|
+
label: string;
|
|
33
|
+
badge?: string | number;
|
|
34
|
+
href?: string;
|
|
35
|
+
onClick?: () => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface NavigationItem {
|
|
39
|
+
id: string;
|
|
40
|
+
label: string;
|
|
41
|
+
icon?: string;
|
|
42
|
+
href?: string;
|
|
43
|
+
badge?: string | number;
|
|
44
|
+
isActive?: boolean;
|
|
45
|
+
onClick?: () => void;
|
|
46
|
+
children?: NavigationItem[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface NavigationSection {
|
|
50
|
+
id: string;
|
|
51
|
+
title: string;
|
|
52
|
+
items: NavigationItem[];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* i18n
|
|
57
|
+
*/
|
|
58
|
+
export interface Language {
|
|
59
|
+
code: string;
|
|
60
|
+
flag?: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Theme
|
|
65
|
+
*/
|
|
66
|
+
export interface Theme {
|
|
67
|
+
name: string;
|
|
68
|
+
icon?: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Shortcuts
|
|
73
|
+
*/
|
|
74
|
+
export interface ShortcutConfig {
|
|
75
|
+
id: string;
|
|
76
|
+
keys: string;
|
|
77
|
+
handler: (event: KeyboardEvent) => void;
|
|
78
|
+
when?: () => boolean;
|
|
79
|
+
label?: string;
|
|
80
|
+
category?: string;
|
|
81
|
+
scope?: "global" | "layout" | `panel:${string}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface ShortcutEntry extends ShortcutConfig {
|
|
85
|
+
enabled?: boolean;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Commands
|
|
90
|
+
*/
|
|
91
|
+
export interface Command {
|
|
92
|
+
id: string;
|
|
93
|
+
label: string;
|
|
94
|
+
category?: string;
|
|
95
|
+
icon?: string;
|
|
96
|
+
action?: () => void;
|
|
97
|
+
children?: Command[];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Toasts
|
|
102
|
+
*/
|
|
103
|
+
export type ToastType = "info" | "success" | "warning" | "error";
|
|
104
|
+
|
|
105
|
+
export interface Toast {
|
|
106
|
+
id: string;
|
|
107
|
+
message: string;
|
|
108
|
+
type: ToastType;
|
|
109
|
+
duration?: number;
|
|
110
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getAppStore,
|
|
3
|
+
getCommandStore,
|
|
4
|
+
getCurrencyStore,
|
|
5
|
+
getLanguageStore,
|
|
6
|
+
getLayoutStore,
|
|
7
|
+
getShortcutStore,
|
|
8
|
+
getThemeStore,
|
|
9
|
+
getToastStore,
|
|
10
|
+
} from "../../../mod.ts";
|
|
11
|
+
|
|
12
|
+
export interface RuneLabContext {
|
|
13
|
+
app: ReturnType<typeof getAppStore>;
|
|
14
|
+
toast: ReturnType<typeof getToastStore>;
|
|
15
|
+
theme: ReturnType<typeof getThemeStore>;
|
|
16
|
+
language: ReturnType<typeof getLanguageStore>;
|
|
17
|
+
currency: ReturnType<typeof getCurrencyStore>;
|
|
18
|
+
shortcut: ReturnType<typeof getShortcutStore>;
|
|
19
|
+
layout: ReturnType<typeof getLayoutStore>;
|
|
20
|
+
commands: ReturnType<typeof getCommandStore>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Retrieves all Rune Lab stores from the Svelte context tree.
|
|
25
|
+
* Must be called during component initialization (in the `<script>` block).
|
|
26
|
+
*/
|
|
27
|
+
export function useRuneLab(): RuneLabContext {
|
|
28
|
+
return {
|
|
29
|
+
app: getAppStore(),
|
|
30
|
+
toast: getToastStore(),
|
|
31
|
+
theme: getThemeStore(),
|
|
32
|
+
language: getLanguageStore(),
|
|
33
|
+
currency: getCurrencyStore(),
|
|
34
|
+
shortcut: getShortcutStore(),
|
|
35
|
+
layout: getLayoutStore(),
|
|
36
|
+
commands: getCommandStore(),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from "./context/context.ts";
|
|
2
|
+
export * from "./context/types.ts";
|
|
3
|
+
export * from "./context/app.svelte.ts";
|
|
4
|
+
export * from "./context/stores.svelte.ts";
|
|
5
|
+
export * from "./persistence/types.ts";
|
|
6
|
+
export * from "./persistence/drivers.ts";
|
|
7
|
+
export * from "./persistence/provider.ts";
|
|
8
|
+
export * from "./persistence/usePersistence.ts";
|
|
9
|
+
export * from "./persistence/createConfigStore.svelte.ts";
|
|
10
|
+
export * from "./registry/mod.ts";
|
|
11
|
+
export * from "./tokens/props.ts";
|
|
12
|
+
export * from "./actions/portal.ts";
|
|
13
|
+
export * from "./actions/shortcut-listener.ts";
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { PersistenceDriver } from "@rune-lab/kernel";
|
|
2
|
+
import { createInMemoryDriver } from "./drivers.ts";
|
|
3
|
+
import { DEV } from "esm-env";
|
|
4
|
+
|
|
5
|
+
export type ConfigStore<T = unknown> = {
|
|
6
|
+
current: unknown;
|
|
7
|
+
available: T[];
|
|
8
|
+
set: (id: unknown) => void;
|
|
9
|
+
get: (id: unknown) => T | undefined;
|
|
10
|
+
getProp: <K extends keyof T>(prop: K, id?: unknown) => T[K] | undefined;
|
|
11
|
+
/** Append additional items (e.g. custom themes/currencies from the consuming app) */
|
|
12
|
+
addItems: (newItems: T[]) => void;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export interface ConfigStoreOptions<T = unknown> {
|
|
16
|
+
/** Array of available items */
|
|
17
|
+
items: readonly T[];
|
|
18
|
+
/** Storage key used by the persistence driver */
|
|
19
|
+
storageKey: string;
|
|
20
|
+
/** Display name for logging (e.g., "Theme", "Language") */
|
|
21
|
+
displayName: string;
|
|
22
|
+
/** Key to use as identifier (e.g., "code", "name") */
|
|
23
|
+
idKey: keyof T;
|
|
24
|
+
/** Icon for logs */
|
|
25
|
+
icon?: string;
|
|
26
|
+
/** Persistence driver */
|
|
27
|
+
driver?: PersistenceDriver;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Internal class implementation for configuration stores.
|
|
32
|
+
* Stable class definition avoids potential issues with multiple definitions in SSR.
|
|
33
|
+
*/
|
|
34
|
+
class ConfigStoreImpl<T = unknown> {
|
|
35
|
+
current: unknown = $state(null);
|
|
36
|
+
available: T[] = $state([]);
|
|
37
|
+
|
|
38
|
+
#options: ConfigStoreOptions<T>;
|
|
39
|
+
#driver: PersistenceDriver;
|
|
40
|
+
|
|
41
|
+
constructor(options: ConfigStoreOptions<T>) {
|
|
42
|
+
this.#options = options;
|
|
43
|
+
const { items, idKey, storageKey, driver = createInMemoryDriver() } =
|
|
44
|
+
options;
|
|
45
|
+
this.#driver = driver;
|
|
46
|
+
|
|
47
|
+
this.available = [...items] as T[];
|
|
48
|
+
this.current = items[0]?.[idKey] ?? "";
|
|
49
|
+
|
|
50
|
+
const saved = this.#driver.get(storageKey);
|
|
51
|
+
// Only load saved if it actually exists in our available items
|
|
52
|
+
if (saved && this.get(saved)) {
|
|
53
|
+
this.current = saved;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (DEV) {
|
|
57
|
+
console.log(
|
|
58
|
+
`${options.icon ?? "⚙️"} ${options.displayName} configured:`,
|
|
59
|
+
{
|
|
60
|
+
current: this.current,
|
|
61
|
+
},
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Set current item with validation
|
|
68
|
+
*/
|
|
69
|
+
set(id: unknown): void {
|
|
70
|
+
const item = this.get(id);
|
|
71
|
+
if (!item) {
|
|
72
|
+
console.warn(`${this.#options.displayName} "${id}" not found`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
this.current = id;
|
|
76
|
+
this.#driver.set(this.#options.storageKey, String(id));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get item by id
|
|
81
|
+
*/
|
|
82
|
+
get(id: unknown): T | undefined {
|
|
83
|
+
const idKey = this.#options.idKey;
|
|
84
|
+
return this.available.find(
|
|
85
|
+
(item: T) => (item as Record<string, unknown>)[idKey as string] === id,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get property from current or specified item
|
|
91
|
+
*/
|
|
92
|
+
getProp<K extends keyof T>(prop: K, id?: unknown): T[K] | undefined {
|
|
93
|
+
const targetId = id ?? this.current;
|
|
94
|
+
return (this.get(targetId) as Record<string, unknown> | undefined)
|
|
95
|
+
?.[prop as string] as
|
|
96
|
+
| T[K]
|
|
97
|
+
| undefined;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Append additional items (deduplicates by idKey)
|
|
102
|
+
*/
|
|
103
|
+
addItems(newItems: T[]): void {
|
|
104
|
+
const idKey = this.#options.idKey;
|
|
105
|
+
for (const item of newItems) {
|
|
106
|
+
if (!this.get((item as Record<string, unknown>)[idKey as string])) {
|
|
107
|
+
this.available.push(item);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Creates a reactive configuration store with persistence
|
|
115
|
+
*/
|
|
116
|
+
export function createConfigStore<T = unknown>(
|
|
117
|
+
options: ConfigStoreOptions<T>,
|
|
118
|
+
): ConfigStore<T> {
|
|
119
|
+
return new ConfigStoreImpl(options) as unknown as ConfigStore<T>;
|
|
120
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { describe, expect, it } from "vite-plus/test";
|
|
2
|
+
import { createInMemoryDriver, inMemoryDriver } from "./drivers.ts";
|
|
3
|
+
|
|
4
|
+
describe("PersistenceDriver Contract Tests", () => {
|
|
5
|
+
describe("createInMemoryDriver (factory)", () => {
|
|
6
|
+
it("should return null for missing keys", () => {
|
|
7
|
+
const driver = createInMemoryDriver();
|
|
8
|
+
expect(driver.get("nonexistent")).toBeNull();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("should set and get a value", () => {
|
|
12
|
+
const driver = createInMemoryDriver();
|
|
13
|
+
driver.set("key", "value");
|
|
14
|
+
expect(driver.get("key")).toBe("value");
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("should overwrite existing values", () => {
|
|
18
|
+
const driver = createInMemoryDriver();
|
|
19
|
+
driver.set("key", "v1");
|
|
20
|
+
driver.set("key", "v2");
|
|
21
|
+
expect(driver.get("key")).toBe("v2");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("should remove a key", () => {
|
|
25
|
+
const driver = createInMemoryDriver();
|
|
26
|
+
driver.set("key", "value");
|
|
27
|
+
driver.remove("key");
|
|
28
|
+
expect(driver.get("key")).toBeNull();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("should not throw when removing a nonexistent key", () => {
|
|
32
|
+
const driver = createInMemoryDriver();
|
|
33
|
+
expect(() => driver.remove("nonexistent")).not.toThrow();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("should handle empty string values", () => {
|
|
37
|
+
const driver = createInMemoryDriver();
|
|
38
|
+
driver.set("key", "");
|
|
39
|
+
expect(driver.get("key")).toBe("");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("should handle JSON string values", () => {
|
|
43
|
+
const driver = createInMemoryDriver();
|
|
44
|
+
const json = JSON.stringify({ theme: "dark", fontSize: 14 });
|
|
45
|
+
driver.set("settings", json);
|
|
46
|
+
expect(JSON.parse(driver.get("settings")!)).toEqual({
|
|
47
|
+
theme: "dark",
|
|
48
|
+
fontSize: 14,
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe("Factory isolation", () => {
|
|
54
|
+
it("should create isolated instances (no cross-contamination)", () => {
|
|
55
|
+
const driverA = createInMemoryDriver();
|
|
56
|
+
const driverB = createInMemoryDriver();
|
|
57
|
+
|
|
58
|
+
driverA.set("shared-key", "fromA");
|
|
59
|
+
driverB.set("shared-key", "fromB");
|
|
60
|
+
|
|
61
|
+
expect(driverA.get("shared-key")).toBe("fromA");
|
|
62
|
+
expect(driverB.get("shared-key")).toBe("fromB");
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("remove on one instance does not affect another", () => {
|
|
66
|
+
const driverA = createInMemoryDriver();
|
|
67
|
+
const driverB = createInMemoryDriver();
|
|
68
|
+
|
|
69
|
+
driverA.set("key", "valueA");
|
|
70
|
+
driverB.set("key", "valueB");
|
|
71
|
+
|
|
72
|
+
driverA.remove("key");
|
|
73
|
+
|
|
74
|
+
expect(driverA.get("key")).toBeNull();
|
|
75
|
+
expect(driverB.get("key")).toBe("valueB");
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe("inMemoryDriver singleton", () => {
|
|
80
|
+
it("should implement the full PersistenceDriver interface", () => {
|
|
81
|
+
expect(typeof inMemoryDriver.get).toBe("function");
|
|
82
|
+
expect(typeof inMemoryDriver.set).toBe("function");
|
|
83
|
+
expect(typeof inMemoryDriver.remove).toBe("function");
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("should function as a working driver", () => {
|
|
87
|
+
// Use unique keys to avoid test interference
|
|
88
|
+
const key = `test-${Date.now()}`;
|
|
89
|
+
inMemoryDriver.set(key, "singleton-value");
|
|
90
|
+
expect(inMemoryDriver.get(key)).toBe("singleton-value");
|
|
91
|
+
inMemoryDriver.remove(key);
|
|
92
|
+
expect(inMemoryDriver.get(key)).toBeNull();
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// sdk/state/src/persistence/drivers.ts
|
|
2
|
+
import type { PersistenceDriver } from "@rune-lab/kernel";
|
|
3
|
+
import { BROWSER as browser } from "esm-env";
|
|
4
|
+
|
|
5
|
+
export function createInMemoryDriver(): PersistenceDriver {
|
|
6
|
+
const store = new Map<string, string>();
|
|
7
|
+
return {
|
|
8
|
+
get: (key: string) => store.get(key) ?? null,
|
|
9
|
+
set: (key: string, value: string) => store.set(key, value),
|
|
10
|
+
remove: (key: string) => {
|
|
11
|
+
store.delete(key);
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const inMemoryDriver: PersistenceDriver = createInMemoryDriver();
|
|
17
|
+
|
|
18
|
+
export const localStorageDriver: PersistenceDriver = {
|
|
19
|
+
get: (key: string) => {
|
|
20
|
+
if (!browser) return null;
|
|
21
|
+
return globalThis.localStorage.getItem(key);
|
|
22
|
+
},
|
|
23
|
+
set: (key: string, value: string) => {
|
|
24
|
+
if (!browser) return;
|
|
25
|
+
globalThis.localStorage.setItem(key, value);
|
|
26
|
+
},
|
|
27
|
+
remove: (key: string) => {
|
|
28
|
+
if (!browser) return;
|
|
29
|
+
globalThis.localStorage.removeItem(key);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const sessionStorageDriver: PersistenceDriver = {
|
|
34
|
+
get: (key: string) => {
|
|
35
|
+
if (!browser) return null;
|
|
36
|
+
return globalThis.sessionStorage.getItem(key);
|
|
37
|
+
},
|
|
38
|
+
set: (key: string, value: string) => {
|
|
39
|
+
if (!browser) return;
|
|
40
|
+
globalThis.sessionStorage.setItem(key, value);
|
|
41
|
+
},
|
|
42
|
+
remove: (key: string) => {
|
|
43
|
+
if (!browser) return;
|
|
44
|
+
globalThis.sessionStorage.removeItem(key);
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const createCookieDriver = (
|
|
49
|
+
options: {
|
|
50
|
+
path?: string;
|
|
51
|
+
maxAge?: number;
|
|
52
|
+
sameSite?: "Lax" | "Strict" | "None";
|
|
53
|
+
} = {},
|
|
54
|
+
): PersistenceDriver => ({
|
|
55
|
+
get: (key: string) => {
|
|
56
|
+
if (!browser) return null;
|
|
57
|
+
const match = document.cookie.match(new RegExp(`(^| )${key}=([^;]+)`));
|
|
58
|
+
return match ? decodeURIComponent(match[2]) : null;
|
|
59
|
+
},
|
|
60
|
+
set: (key: string, value: string) => {
|
|
61
|
+
if (!browser) return;
|
|
62
|
+
let cookie = `${key}=${encodeURIComponent(value)}`;
|
|
63
|
+
if (options.path) cookie += `; path=${options.path}`;
|
|
64
|
+
if (options.maxAge) cookie += `; max-age=${options.maxAge}`;
|
|
65
|
+
if (options.sameSite) cookie += `; samesite=${options.sameSite}`;
|
|
66
|
+
document.cookie = cookie;
|
|
67
|
+
},
|
|
68
|
+
remove: (key: string) => {
|
|
69
|
+
if (!browser) return;
|
|
70
|
+
document.cookie = `${key}=; max-age=0; path=${options.path || "/"}`;
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
/** Default cookie driver singleton (path='/') */
|
|
75
|
+
export const cookieDriver: PersistenceDriver = createCookieDriver({
|
|
76
|
+
path: "/",
|
|
77
|
+
});
|