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.
Files changed (433) hide show
  1. package/.gitignore +12 -0
  2. package/README.md +3 -3
  3. package/deno.json +50 -0
  4. package/justfile +5 -0
  5. package/package.json +2 -79
  6. package/scripts/build_pkg.ts +51 -0
  7. package/scripts/ci.just +26 -0
  8. package/scripts/deploy.just +21 -0
  9. package/scripts/dev.just +4 -0
  10. package/scripts/inject.just +72 -0
  11. package/src/RuneProvider.svelte +105 -0
  12. package/src/i18n/message-resolver.test.ts +103 -0
  13. package/src/i18n/message-resolver.ts +89 -0
  14. package/src/i18n/project.inlang/settings.json +26 -0
  15. package/src/i18n/translations/ar.json +89 -0
  16. package/src/i18n/translations/de.json +89 -0
  17. package/src/i18n/translations/en.json +89 -0
  18. package/src/i18n/translations/es.json +89 -0
  19. package/src/i18n/translations/fr.json +89 -0
  20. package/src/i18n/translations/hi.json +89 -0
  21. package/src/i18n/translations/it.json +89 -0
  22. package/src/i18n/translations/ja.json +89 -0
  23. package/src/i18n/translations/ko.json +89 -0
  24. package/src/i18n/translations/pt.json +89 -0
  25. package/src/i18n/translations/ru.json +89 -0
  26. package/src/i18n/translations/vi.json +89 -0
  27. package/src/i18n/translations/zh.json +89 -0
  28. package/src/kernel/deno.json +5 -0
  29. package/src/kernel/src/actions/portal.ts +41 -0
  30. package/src/kernel/src/actions/shortcut-listener.ts +50 -0
  31. package/src/kernel/src/context/app.svelte.ts +98 -0
  32. package/src/kernel/src/context/context.ts +31 -0
  33. package/src/kernel/src/context/stores.svelte.ts +96 -0
  34. package/src/kernel/src/context/types.ts +110 -0
  35. package/src/kernel/src/context/useRuneLab.ts +38 -0
  36. package/src/kernel/src/mod.ts +13 -0
  37. package/src/kernel/src/persistence/createConfigStore.svelte.ts +120 -0
  38. package/src/kernel/src/persistence/drivers.test.ts +95 -0
  39. package/src/kernel/src/persistence/drivers.ts +77 -0
  40. package/src/kernel/src/persistence/provider.test.ts +58 -0
  41. package/{dist/state/persistence/provider.js → src/kernel/src/persistence/provider.ts} +29 -14
  42. package/src/kernel/src/persistence/types.ts +19 -0
  43. package/src/kernel/src/persistence/usePersistence.ts +9 -0
  44. package/src/kernel/src/registry/mod.ts +221 -0
  45. package/src/kernel/src/registry/registry.test.ts +162 -0
  46. package/src/kernel/src/tokens/props.ts +94 -0
  47. package/src/mod.ts +10 -0
  48. package/src/runes/layout/deno.json +5 -0
  49. package/src/runes/layout/src/APP_CONFIGURATIONS.ts +56 -0
  50. package/{dist/ui/features/config → src/runes/layout/src}/AppSettingSelector.svelte +1 -1
  51. package/{dist/ui/layout → src/runes/layout/src}/ConnectedNavigationPanel.svelte +1 -1
  52. package/{dist/ui/layout → src/runes/layout/src}/ConnectedWorkspaceStrip.svelte +1 -1
  53. package/src/runes/layout/src/Icon.svelte +7 -0
  54. package/{dist/ui/features/config → src/runes/layout/src}/LanguageSelector.svelte +7 -5
  55. package/{dist/ui/layout → src/runes/layout/src}/NavigationPanel.svelte +1 -4
  56. package/{dist/ui/features/config → src/runes/layout/src}/ResourceSelector.svelte +3 -5
  57. package/{dist/ui/features/config → src/runes/layout/src}/ThemeSelector.svelte +2 -2
  58. package/{dist/ui/layout → src/runes/layout/src}/WorkspaceLayout.svelte +6 -4
  59. package/{dist/ui/layout → src/runes/layout/src}/WorkspaceStrip.svelte +1 -1
  60. package/src/runes/layout/src/connection-factory.ts +95 -0
  61. package/src/runes/layout/src/language.svelte.ts +44 -0
  62. package/src/runes/layout/src/mod.ts +71 -0
  63. package/src/runes/layout/src/store.svelte.ts +142 -0
  64. package/src/runes/layout/src/theme.svelte.ts +73 -0
  65. package/src/runes/layout/src/types.ts +11 -0
  66. package/src/runes/palettes/deno.json +8 -0
  67. package/{dist/ui/features/command-palette → src/runes/palettes/src/commands}/CommandPalette.svelte +4 -4
  68. package/src/runes/palettes/src/commands/mod.ts +2 -0
  69. package/src/runes/palettes/src/commands/store.svelte.ts +80 -0
  70. package/src/runes/palettes/src/mod.ts +51 -0
  71. package/{dist/ui/components → src/runes/palettes/src/notifications}/Toaster.svelte +1 -2
  72. package/src/runes/palettes/src/notifications/bridge.ts +56 -0
  73. package/src/runes/palettes/src/notifications/mod.ts +4 -0
  74. package/src/runes/palettes/src/notifications/store.svelte.ts +58 -0
  75. package/{dist/ui/features → src/runes/palettes/src}/shortcuts/ShortcutPalette.svelte +4 -4
  76. package/src/runes/palettes/src/shortcuts/mod.ts +4 -0
  77. package/src/runes/palettes/src/shortcuts/store.svelte.ts +85 -0
  78. package/src/runes/palettes/src/shortcuts/types.ts +4 -0
  79. package/src/runes/palettes/src/shortcuts/useShortcuts.ts +85 -0
  80. package/src/runes/plugins/money/deno.json +8 -0
  81. package/{dist/ui/features/config → src/runes/plugins/money/src}/CurrencySelector.svelte +2 -2
  82. package/{dist/ui/components/money → src/runes/plugins/money/src}/MoneyDisplay.svelte +2 -2
  83. package/{dist/ui/components/money → src/runes/plugins/money/src}/MoneyInput.svelte +4 -8
  84. package/src/runes/plugins/money/src/currency.svelte.ts +95 -0
  85. package/src/runes/plugins/money/src/currency.test.ts +40 -0
  86. package/src/runes/plugins/money/src/exchange-rate.svelte.ts +176 -0
  87. package/src/runes/plugins/money/src/exchange-rate.test.ts +95 -0
  88. package/src/runes/plugins/money/src/mod.ts +79 -0
  89. package/src/runes/plugins/money/src/money-primitive.test.ts +217 -0
  90. package/src/runes/plugins/money/src/money-primitive.ts +220 -0
  91. package/src/runes/plugins/money/src/money.test.ts +183 -0
  92. package/src/runes/plugins/money/src/money.ts +382 -0
  93. package/src/runes/plugins/money/src/strategies.test.ts +143 -0
  94. package/{dist/core/exchange-rate/strategies.js → src/runes/plugins/money/src/strategies.ts} +45 -22
  95. package/src/runes/plugins/money/src/types.ts +27 -0
  96. package/src/runes/plugins/money/src/useMoney.ts +261 -0
  97. package/src/runes/plugins/money/src/useMoneyFilter.ts +132 -0
  98. package/tsconfig.json +41 -0
  99. package/vite.config.ts +44 -0
  100. package/dist/core/design-tokens/props.d.ts +0 -52
  101. package/dist/core/design-tokens/props.d.ts.map +0 -1
  102. package/dist/core/design-tokens/props.js +0 -34
  103. package/dist/core/exchange-rate/strategies.d.ts +0 -52
  104. package/dist/core/exchange-rate/strategies.d.ts.map +0 -1
  105. package/dist/core/index.d.ts +0 -9
  106. package/dist/core/index.d.ts.map +0 -1
  107. package/dist/core/index.js +0 -8
  108. package/dist/core/internal/message-resolver.d.ts +0 -42
  109. package/dist/core/internal/message-resolver.d.ts.map +0 -1
  110. package/dist/core/internal/message-resolver.js +0 -47
  111. package/dist/core/layout/types.d.ts +0 -60
  112. package/dist/core/layout/types.d.ts.map +0 -1
  113. package/dist/core/layout/types.js +0 -4
  114. package/dist/core/money/index.d.ts +0 -2
  115. package/dist/core/money/index.d.ts.map +0 -1
  116. package/dist/core/money/index.js +0 -2
  117. package/dist/core/money/money-primitive.d.ts +0 -101
  118. package/dist/core/money/money-primitive.d.ts.map +0 -1
  119. package/dist/core/money/money-primitive.js +0 -161
  120. package/dist/core/money/money.d.ts +0 -129
  121. package/dist/core/money/money.d.ts.map +0 -1
  122. package/dist/core/money/money.js +0 -250
  123. package/dist/core/persistence/types.d.ts +0 -18
  124. package/dist/core/persistence/types.d.ts.map +0 -1
  125. package/dist/core/persistence/types.js +0 -2
  126. package/dist/core/shortcuts/types.d.ts +0 -60
  127. package/dist/core/shortcuts/types.d.ts.map +0 -1
  128. package/dist/core/shortcuts/types.js +0 -4
  129. package/dist/index.d.ts +0 -6
  130. package/dist/index.js +0 -7
  131. package/dist/state/api.svelte.d.ts +0 -26
  132. package/dist/state/api.svelte.js +0 -65
  133. package/dist/state/app.svelte.d.ts +0 -48
  134. package/dist/state/app.svelte.js +0 -82
  135. package/dist/state/auth/index.d.ts +0 -2
  136. package/dist/state/auth/index.js +0 -2
  137. package/dist/state/auth/session.svelte.d.ts +0 -40
  138. package/dist/state/auth/session.svelte.js +0 -59
  139. package/dist/state/auth/types.d.ts +0 -30
  140. package/dist/state/auth/types.js +0 -3
  141. package/dist/state/cart.svelte.d.ts +0 -64
  142. package/dist/state/cart.svelte.js +0 -122
  143. package/dist/state/commands.svelte.d.ts +0 -46
  144. package/dist/state/commands.svelte.js +0 -62
  145. package/dist/state/composables/useMoney.d.ts +0 -31
  146. package/dist/state/composables/useMoney.js +0 -126
  147. package/dist/state/composables/useMoneyFilter.d.ts +0 -20
  148. package/dist/state/composables/useMoneyFilter.js +0 -81
  149. package/dist/state/composables/usePersistence.d.ts +0 -2
  150. package/dist/state/composables/usePersistence.js +0 -5
  151. package/dist/state/composables/useRuneLab.d.ts +0 -19
  152. package/dist/state/composables/useRuneLab.js +0 -30
  153. package/dist/state/composables/useShortcuts.d.ts +0 -33
  154. package/dist/state/composables/useShortcuts.js +0 -75
  155. package/dist/state/context.d.ts +0 -15
  156. package/dist/state/context.js +0 -16
  157. package/dist/state/createConfigStore.svelte.d.ts +0 -28
  158. package/dist/state/createConfigStore.svelte.js +0 -72
  159. package/dist/state/currency.svelte.d.ts +0 -32
  160. package/dist/state/currency.svelte.js +0 -96
  161. package/dist/state/currency.test.d.ts +0 -1
  162. package/dist/state/currency.test.js +0 -35
  163. package/dist/state/exchange-rate.svelte.d.ts +0 -43
  164. package/dist/state/exchange-rate.svelte.js +0 -145
  165. package/dist/state/exchange-rate.test.d.ts +0 -1
  166. package/dist/state/exchange-rate.test.js +0 -75
  167. package/dist/state/index.d.ts +0 -26
  168. package/dist/state/index.js +0 -32
  169. package/dist/state/language.svelte.d.ts +0 -57
  170. package/dist/state/language.svelte.js +0 -43
  171. package/dist/state/layout.svelte.d.ts +0 -49
  172. package/dist/state/layout.svelte.js +0 -108
  173. package/dist/state/persistence/drivers.d.ts +0 -12
  174. package/dist/state/persistence/drivers.js +0 -75
  175. package/dist/state/persistence/drivers.test.d.ts +0 -1
  176. package/dist/state/persistence/drivers.test.js +0 -79
  177. package/dist/state/persistence/provider.d.ts +0 -23
  178. package/dist/state/persistence/provider.test.d.ts +0 -1
  179. package/dist/state/persistence/provider.test.js +0 -51
  180. package/dist/state/registry/index.d.ts +0 -44
  181. package/dist/state/registry/index.js +0 -58
  182. package/dist/state/registry/registry.test.d.ts +0 -1
  183. package/dist/state/registry/registry.test.js +0 -112
  184. package/dist/state/registry/types.d.ts +0 -20
  185. package/dist/state/registry/types.js +0 -3
  186. package/dist/state/shortcuts.svelte.d.ts +0 -121
  187. package/dist/state/shortcuts.svelte.js +0 -222
  188. package/dist/state/theme.svelte.d.ts +0 -15
  189. package/dist/state/theme.svelte.js +0 -92
  190. package/dist/state/toast-bridge.d.ts +0 -29
  191. package/dist/state/toast-bridge.js +0 -43
  192. package/dist/state/toast.svelte.d.ts +0 -27
  193. package/dist/state/toast.svelte.js +0 -43
  194. package/dist/ui/actions/portal.d.ts +0 -7
  195. package/dist/ui/actions/portal.js +0 -32
  196. package/dist/ui/components/ApiMonitor.svelte +0 -162
  197. package/dist/ui/components/ApiMonitor.svelte.d.ts +0 -3
  198. package/dist/ui/components/Icon.svelte +0 -108
  199. package/dist/ui/components/Icon.svelte.d.ts +0 -14
  200. package/dist/ui/components/Kyntharil.svelte +0 -48
  201. package/dist/ui/components/Kyntharil.svelte.d.ts +0 -6
  202. package/dist/ui/components/RuneProvider.svelte +0 -218
  203. package/dist/ui/components/RuneProvider.svelte.d.ts +0 -49
  204. package/dist/ui/components/Toaster.svelte.d.ts +0 -18
  205. package/dist/ui/components/money/MoneyDisplay.svelte.d.ts +0 -33
  206. package/dist/ui/components/money/MoneyDisplay.svelte.test.d.ts +0 -1
  207. package/dist/ui/components/money/MoneyDisplay.svelte.test.js +0 -117
  208. package/dist/ui/components/money/MoneyInput.svelte.d.ts +0 -34
  209. package/dist/ui/components/money/index.d.ts +0 -2
  210. package/dist/ui/components/money/index.js +0 -3
  211. package/dist/ui/components/user/UserAvatar.svelte +0 -66
  212. package/dist/ui/components/user/UserAvatar.svelte.d.ts +0 -13
  213. package/dist/ui/components/user/UserProfile.svelte +0 -79
  214. package/dist/ui/components/user/UserProfile.svelte.d.ts +0 -17
  215. package/dist/ui/components/user/index.d.ts +0 -2
  216. package/dist/ui/components/user/index.js +0 -3
  217. package/dist/ui/features/command-palette/CommandPalette.svelte.d.ts +0 -6
  218. package/dist/ui/features/config/APP_CONFIGURATIONS.d.ts +0 -29
  219. package/dist/ui/features/config/APP_CONFIGURATIONS.js +0 -38
  220. package/dist/ui/features/config/AppSettingSelector.svelte.d.ts +0 -13
  221. package/dist/ui/features/config/CurrencySelector.svelte.d.ts +0 -8
  222. package/dist/ui/features/config/LanguageSelector.svelte.d.ts +0 -8
  223. package/dist/ui/features/config/ResourceSelector.svelte.d.ts +0 -25
  224. package/dist/ui/features/config/ThemeSelector.svelte.d.ts +0 -8
  225. package/dist/ui/features/notifications/NotificationBell.svelte.d.ts +0 -11
  226. package/dist/ui/features/notifications/index.d.ts +0 -1
  227. package/dist/ui/features/notifications/index.js +0 -2
  228. package/dist/ui/features/shortcuts/ShortcutBinder.svelte +0 -17
  229. package/dist/ui/features/shortcuts/ShortcutBinder.svelte.d.ts +0 -7
  230. package/dist/ui/features/shortcuts/ShortcutPalette.svelte.d.ts +0 -6
  231. package/dist/ui/index.d.ts +0 -30
  232. package/dist/ui/index.js +0 -46
  233. package/dist/ui/layout/ConnectedNavigationPanel.svelte.d.ts +0 -10
  234. package/dist/ui/layout/ConnectedWorkspaceStrip.svelte.d.ts +0 -9
  235. package/dist/ui/layout/ContentArea.svelte.d.ts +0 -8
  236. package/dist/ui/layout/DetailPanel.svelte.d.ts +0 -7
  237. package/dist/ui/layout/NavigationPanel.svelte.d.ts +0 -14
  238. package/dist/ui/layout/WorkspaceLayout.svelte.d.ts +0 -32
  239. package/dist/ui/layout/WorkspaceStrip.svelte.d.ts +0 -11
  240. package/dist/ui/layout/connection-factory.d.ts +0 -50
  241. package/dist/ui/layout/connection-factory.js +0 -58
  242. package/dist/ui/layout/index.d.ts +0 -7
  243. package/dist/ui/layout/index.js +0 -7
  244. package/dist/ui/paraglide/README.md +0 -147
  245. package/dist/ui/paraglide/messages/_index.d.ts +0 -87
  246. package/dist/ui/paraglide/messages/_index.js +0 -88
  247. package/dist/ui/paraglide/messages/abyss.d.ts +0 -16
  248. package/dist/ui/paraglide/messages/abyss.js +0 -84
  249. package/dist/ui/paraglide/messages/acid.d.ts +0 -16
  250. package/dist/ui/paraglide/messages/acid.js +0 -84
  251. package/dist/ui/paraglide/messages/active_toasts.d.ts +0 -16
  252. package/dist/ui/paraglide/messages/active_toasts.js +0 -84
  253. package/dist/ui/paraglide/messages/aed3.d.ts +0 -17
  254. package/dist/ui/paraglide/messages/aed3.js +0 -85
  255. package/dist/ui/paraglide/messages/all_currencies.d.ts +0 -16
  256. package/dist/ui/paraglide/messages/all_currencies.js +0 -84
  257. package/dist/ui/paraglide/messages/all_languages.d.ts +0 -16
  258. package/dist/ui/paraglide/messages/all_languages.js +0 -84
  259. package/dist/ui/paraglide/messages/all_themes.d.ts +0 -16
  260. package/dist/ui/paraglide/messages/all_themes.js +0 -84
  261. package/dist/ui/paraglide/messages/api_status.d.ts +0 -16
  262. package/dist/ui/paraglide/messages/api_status.js +0 -84
  263. package/dist/ui/paraglide/messages/app_info.d.ts +0 -16
  264. package/dist/ui/paraglide/messages/app_info.js +0 -84
  265. package/dist/ui/paraglide/messages/appearance.d.ts +0 -16
  266. package/dist/ui/paraglide/messages/appearance.js +0 -84
  267. package/dist/ui/paraglide/messages/aqua.d.ts +0 -16
  268. package/dist/ui/paraglide/messages/aqua.js +0 -84
  269. package/dist/ui/paraglide/messages/ar.d.ts +0 -16
  270. package/dist/ui/paraglide/messages/ar.js +0 -84
  271. package/dist/ui/paraglide/messages/autumn.d.ts +0 -16
  272. package/dist/ui/paraglide/messages/autumn.js +0 -84
  273. package/dist/ui/paraglide/messages/black.d.ts +0 -16
  274. package/dist/ui/paraglide/messages/black.js +0 -84
  275. package/dist/ui/paraglide/messages/brl3.d.ts +0 -17
  276. package/dist/ui/paraglide/messages/brl3.js +0 -85
  277. package/dist/ui/paraglide/messages/bumblebee.d.ts +0 -16
  278. package/dist/ui/paraglide/messages/bumblebee.js +0 -84
  279. package/dist/ui/paraglide/messages/business.d.ts +0 -16
  280. package/dist/ui/paraglide/messages/business.js +0 -84
  281. package/dist/ui/paraglide/messages/cad3.d.ts +0 -17
  282. package/dist/ui/paraglide/messages/cad3.js +0 -85
  283. package/dist/ui/paraglide/messages/caramellatte.d.ts +0 -16
  284. package/dist/ui/paraglide/messages/caramellatte.js +0 -84
  285. package/dist/ui/paraglide/messages/cmyk.d.ts +0 -16
  286. package/dist/ui/paraglide/messages/cmyk.js +0 -84
  287. package/dist/ui/paraglide/messages/cny3.d.ts +0 -17
  288. package/dist/ui/paraglide/messages/cny3.js +0 -85
  289. package/dist/ui/paraglide/messages/coffee.d.ts +0 -16
  290. package/dist/ui/paraglide/messages/coffee.js +0 -84
  291. package/dist/ui/paraglide/messages/commands_label.d.ts +0 -16
  292. package/dist/ui/paraglide/messages/commands_label.js +0 -84
  293. package/dist/ui/paraglide/messages/corporate.d.ts +0 -16
  294. package/dist/ui/paraglide/messages/corporate.js +0 -84
  295. package/dist/ui/paraglide/messages/cupcake.d.ts +0 -16
  296. package/dist/ui/paraglide/messages/cupcake.js +0 -84
  297. package/dist/ui/paraglide/messages/currency.d.ts +0 -16
  298. package/dist/ui/paraglide/messages/currency.js +0 -84
  299. package/dist/ui/paraglide/messages/current_currency.d.ts +0 -16
  300. package/dist/ui/paraglide/messages/current_currency.js +0 -84
  301. package/dist/ui/paraglide/messages/current_language.d.ts +0 -16
  302. package/dist/ui/paraglide/messages/current_language.js +0 -84
  303. package/dist/ui/paraglide/messages/current_theme.d.ts +0 -16
  304. package/dist/ui/paraglide/messages/current_theme.js +0 -84
  305. package/dist/ui/paraglide/messages/currently_in_queue.d.ts +0 -16
  306. package/dist/ui/paraglide/messages/currently_in_queue.js +0 -84
  307. package/dist/ui/paraglide/messages/cyberpunk.d.ts +0 -16
  308. package/dist/ui/paraglide/messages/cyberpunk.js +0 -84
  309. package/dist/ui/paraglide/messages/dark.d.ts +0 -16
  310. package/dist/ui/paraglide/messages/dark.js +0 -84
  311. package/dist/ui/paraglide/messages/de.d.ts +0 -16
  312. package/dist/ui/paraglide/messages/de.js +0 -84
  313. package/dist/ui/paraglide/messages/dim.d.ts +0 -16
  314. package/dist/ui/paraglide/messages/dim.js +0 -84
  315. package/dist/ui/paraglide/messages/dracula.d.ts +0 -16
  316. package/dist/ui/paraglide/messages/dracula.js +0 -84
  317. package/dist/ui/paraglide/messages/emerald.d.ts +0 -16
  318. package/dist/ui/paraglide/messages/emerald.js +0 -84
  319. package/dist/ui/paraglide/messages/en.d.ts +0 -16
  320. package/dist/ui/paraglide/messages/en.js +0 -84
  321. package/dist/ui/paraglide/messages/es.d.ts +0 -16
  322. package/dist/ui/paraglide/messages/es.js +0 -84
  323. package/dist/ui/paraglide/messages/eur3.d.ts +0 -17
  324. package/dist/ui/paraglide/messages/eur3.js +0 -85
  325. package/dist/ui/paraglide/messages/extended_controls.d.ts +0 -16
  326. package/dist/ui/paraglide/messages/extended_controls.js +0 -84
  327. package/dist/ui/paraglide/messages/fantasy.d.ts +0 -16
  328. package/dist/ui/paraglide/messages/fantasy.js +0 -84
  329. package/dist/ui/paraglide/messages/forest.d.ts +0 -16
  330. package/dist/ui/paraglide/messages/forest.js +0 -84
  331. package/dist/ui/paraglide/messages/fr.d.ts +0 -16
  332. package/dist/ui/paraglide/messages/fr.js +0 -84
  333. package/dist/ui/paraglide/messages/garden.d.ts +0 -16
  334. package/dist/ui/paraglide/messages/garden.js +0 -84
  335. package/dist/ui/paraglide/messages/gbp3.d.ts +0 -17
  336. package/dist/ui/paraglide/messages/gbp3.js +0 -85
  337. package/dist/ui/paraglide/messages/halloween.d.ts +0 -16
  338. package/dist/ui/paraglide/messages/halloween.js +0 -84
  339. package/dist/ui/paraglide/messages/hello_world.d.ts +0 -18
  340. package/dist/ui/paraglide/messages/hello_world.js +0 -84
  341. package/dist/ui/paraglide/messages/hi.d.ts +0 -16
  342. package/dist/ui/paraglide/messages/hi.js +0 -84
  343. package/dist/ui/paraglide/messages/inr3.d.ts +0 -17
  344. package/dist/ui/paraglide/messages/inr3.js +0 -85
  345. package/dist/ui/paraglide/messages/it.d.ts +0 -16
  346. package/dist/ui/paraglide/messages/it.js +0 -84
  347. package/dist/ui/paraglide/messages/ja.d.ts +0 -16
  348. package/dist/ui/paraglide/messages/ja.js +0 -84
  349. package/dist/ui/paraglide/messages/jpy3.d.ts +0 -17
  350. package/dist/ui/paraglide/messages/jpy3.js +0 -85
  351. package/dist/ui/paraglide/messages/ko.d.ts +0 -16
  352. package/dist/ui/paraglide/messages/ko.js +0 -84
  353. package/dist/ui/paraglide/messages/krw3.d.ts +0 -17
  354. package/dist/ui/paraglide/messages/krw3.js +0 -85
  355. package/dist/ui/paraglide/messages/languages.d.ts +0 -16
  356. package/dist/ui/paraglide/messages/languages.js +0 -84
  357. package/dist/ui/paraglide/messages/lemonade.d.ts +0 -16
  358. package/dist/ui/paraglide/messages/lemonade.js +0 -84
  359. package/dist/ui/paraglide/messages/light.d.ts +0 -16
  360. package/dist/ui/paraglide/messages/light.js +0 -84
  361. package/dist/ui/paraglide/messages/live_store_dashboard.d.ts +0 -16
  362. package/dist/ui/paraglide/messages/live_store_dashboard.js +0 -84
  363. package/dist/ui/paraglide/messages/localization.d.ts +0 -16
  364. package/dist/ui/paraglide/messages/localization.js +0 -84
  365. package/dist/ui/paraglide/messages/lofi.d.ts +0 -16
  366. package/dist/ui/paraglide/messages/lofi.js +0 -84
  367. package/dist/ui/paraglide/messages/luxury.d.ts +0 -16
  368. package/dist/ui/paraglide/messages/luxury.js +0 -84
  369. package/dist/ui/paraglide/messages/mxn3.d.ts +0 -17
  370. package/dist/ui/paraglide/messages/mxn3.js +0 -85
  371. package/dist/ui/paraglide/messages/name_label.d.ts +0 -16
  372. package/dist/ui/paraglide/messages/name_label.js +0 -84
  373. package/dist/ui/paraglide/messages/night.d.ts +0 -16
  374. package/dist/ui/paraglide/messages/night.js +0 -84
  375. package/dist/ui/paraglide/messages/nord.d.ts +0 -16
  376. package/dist/ui/paraglide/messages/nord.js +0 -84
  377. package/dist/ui/paraglide/messages/pastel.d.ts +0 -16
  378. package/dist/ui/paraglide/messages/pastel.js +0 -84
  379. package/dist/ui/paraglide/messages/pt.d.ts +0 -16
  380. package/dist/ui/paraglide/messages/pt.js +0 -84
  381. package/dist/ui/paraglide/messages/real_time_monitor_desc.d.ts +0 -16
  382. package/dist/ui/paraglide/messages/real_time_monitor_desc.js +0 -84
  383. package/dist/ui/paraglide/messages/registered_in_registry.d.ts +0 -16
  384. package/dist/ui/paraglide/messages/registered_in_registry.js +0 -84
  385. package/dist/ui/paraglide/messages/retro.d.ts +0 -16
  386. package/dist/ui/paraglide/messages/retro.js +0 -84
  387. package/dist/ui/paraglide/messages/ru.d.ts +0 -16
  388. package/dist/ui/paraglide/messages/ru.js +0 -84
  389. package/dist/ui/paraglide/messages/silk.d.ts +0 -16
  390. package/dist/ui/paraglide/messages/silk.js +0 -84
  391. package/dist/ui/paraglide/messages/state_label.d.ts +0 -16
  392. package/dist/ui/paraglide/messages/state_label.js +0 -84
  393. package/dist/ui/paraglide/messages/sunset.d.ts +0 -16
  394. package/dist/ui/paraglide/messages/sunset.js +0 -84
  395. package/dist/ui/paraglide/messages/synthwave.d.ts +0 -16
  396. package/dist/ui/paraglide/messages/synthwave.js +0 -84
  397. package/dist/ui/paraglide/messages/system.d.ts +0 -16
  398. package/dist/ui/paraglide/messages/system.js +0 -84
  399. package/dist/ui/paraglide/messages/theme.d.ts +0 -16
  400. package/dist/ui/paraglide/messages/theme.js +0 -84
  401. package/dist/ui/paraglide/messages/themes.d.ts +0 -16
  402. package/dist/ui/paraglide/messages/themes.js +0 -84
  403. package/dist/ui/paraglide/messages/url_label.d.ts +0 -16
  404. package/dist/ui/paraglide/messages/url_label.js +0 -84
  405. package/dist/ui/paraglide/messages/usd3.d.ts +0 -17
  406. package/dist/ui/paraglide/messages/usd3.js +0 -85
  407. package/dist/ui/paraglide/messages/valentine.d.ts +0 -16
  408. package/dist/ui/paraglide/messages/valentine.js +0 -84
  409. package/dist/ui/paraglide/messages/version_label.d.ts +0 -16
  410. package/dist/ui/paraglide/messages/version_label.js +0 -84
  411. package/dist/ui/paraglide/messages/vi.d.ts +0 -16
  412. package/dist/ui/paraglide/messages/vi.js +0 -84
  413. package/dist/ui/paraglide/messages/winter.d.ts +0 -16
  414. package/dist/ui/paraglide/messages/winter.js +0 -84
  415. package/dist/ui/paraglide/messages/wireframe.d.ts +0 -16
  416. package/dist/ui/paraglide/messages/wireframe.js +0 -84
  417. package/dist/ui/paraglide/messages/zh.d.ts +0 -16
  418. package/dist/ui/paraglide/messages/zh.js +0 -84
  419. package/dist/ui/paraglide/messages.d.ts +0 -2
  420. package/dist/ui/paraglide/messages.js +0 -4
  421. package/dist/ui/paraglide/registry.d.ts +0 -21
  422. package/dist/ui/paraglide/registry.js +0 -31
  423. package/dist/ui/paraglide/runtime.d.ts +0 -730
  424. package/dist/ui/paraglide/runtime.js +0 -1812
  425. package/dist/ui/paraglide/server.d.ts +0 -92
  426. package/dist/ui/paraglide/server.js +0 -239
  427. package/dist/ui/primitives/DatePicker.svelte +0 -257
  428. package/dist/ui/primitives/DatePicker.svelte.d.ts +0 -17
  429. package/dist/ui/primitives/index.d.ts +0 -1
  430. package/dist/ui/primitives/index.js +0 -3
  431. /package/{dist/ui/layout → src/runes/layout/src}/ContentArea.svelte +0 -0
  432. /package/{dist/ui/layout → src/runes/layout/src}/DetailPanel.svelte +0 -0
  433. /package/{dist/ui/features → src/runes/palettes/src}/notifications/NotificationBell.svelte +0 -0
@@ -0,0 +1,58 @@
1
+ import { describe, expect, it } from "vite-plus/test";
2
+ import { resolveDriver } from "./provider.ts";
3
+ import type { PersistenceDriver } from "./types.ts";
4
+
5
+ describe("DriverProvider", () => {
6
+ describe("resolveDriver", () => {
7
+ it("should return inMemoryDriver when given undefined", () => {
8
+ const driver = resolveDriver(undefined);
9
+ expect(driver).toBeDefined();
10
+ expect(typeof driver.get).toBe("function");
11
+ expect(typeof driver.set).toBe("function");
12
+ expect(typeof driver.remove).toBe("function");
13
+ });
14
+
15
+ it("should pass through a concrete PersistenceDriver", () => {
16
+ const mockDriver: PersistenceDriver = {
17
+ get: () => null,
18
+ set: () => {},
19
+ remove: () => {},
20
+ };
21
+ const driver = resolveDriver(mockDriver);
22
+ expect(driver).toBe(mockDriver);
23
+ });
24
+
25
+ it("should resolve a factory function to a concrete driver", () => {
26
+ const mockDriver: PersistenceDriver = {
27
+ get: () => null,
28
+ set: () => {},
29
+ remove: () => {},
30
+ };
31
+ const driver = resolveDriver(() => mockDriver);
32
+ expect(driver).toBe(mockDriver);
33
+ });
34
+
35
+ it("should fall back to inMemoryDriver when factory returns undefined", () => {
36
+ const driver = resolveDriver(() => undefined);
37
+ expect(driver).toBeDefined();
38
+ expect(typeof driver.get).toBe("function");
39
+ });
40
+
41
+ it("inMemoryDriver fallback should be functional", () => {
42
+ const driver = resolveDriver(undefined);
43
+ driver.set("test-key", "test-value");
44
+ expect(driver.get("test-key")).toBe("test-value");
45
+ driver.remove("test-key");
46
+ expect(driver.get("test-key")).toBeNull();
47
+ });
48
+
49
+ it("should create isolated inMemoryDriver instances per call", () => {
50
+ const driverA = resolveDriver(undefined);
51
+ const driverB = resolveDriver(undefined);
52
+ driverA.set("key", "A");
53
+ driverB.set("key", "B");
54
+ expect(driverA.get("key")).toBe("A");
55
+ expect(driverB.get("key")).toBe("B");
56
+ });
57
+ });
58
+ });
@@ -2,19 +2,29 @@
2
2
  // Context-based persistence driver injection.
3
3
  // Resolves the driver once (handling function-vs-instance duality)
4
4
  // and guarantees a concrete PersistenceDriver is always available.
5
+
5
6
  import { getContext, setContext } from "svelte";
7
+ import type { PersistenceDriver } from "../mod.ts";
6
8
  import { createInMemoryDriver } from "./drivers.ts";
9
+
7
10
  const DRIVER_CONTEXT_KEY = Symbol("rl:driver-provider");
11
+
8
12
  /**
9
13
  * Resolves a driver input (function or instance) into a concrete PersistenceDriver.
10
14
  * If the input is null/undefined, returns an inMemoryDriver as the Null Object.
11
15
  *
12
16
  * This is the single place where function-form drivers are unwrapped.
13
17
  */
14
- export function resolveDriver(driver) {
15
- const resolved = typeof driver === "function" ? driver() : driver;
16
- return resolved ?? createInMemoryDriver();
18
+ export function resolveDriver(
19
+ driver?:
20
+ | PersistenceDriver
21
+ | (() => PersistenceDriver | undefined)
22
+ | undefined,
23
+ ): PersistenceDriver {
24
+ const resolved = typeof driver === "function" ? driver() : driver;
25
+ return resolved ?? createInMemoryDriver();
17
26
  }
27
+
18
28
  /**
19
29
  * Sets the persistence driver context at the RuneProvider root.
20
30
  * Should be called exactly once, before any store factories run.
@@ -22,22 +32,27 @@ export function resolveDriver(driver) {
22
32
  * @param driver - A PersistenceDriver instance, a factory function, or undefined.
23
33
  * Undefined falls back to inMemoryDriver.
24
34
  */
25
- export function setDriverContext(driver) {
26
- const resolved = resolveDriver(driver);
27
- setContext(DRIVER_CONTEXT_KEY, resolved);
28
- return resolved;
35
+ export function setDriverContext(
36
+ driver?: PersistenceDriver | (() => PersistenceDriver | undefined),
37
+ ): PersistenceDriver {
38
+ const resolved = resolveDriver(driver);
39
+ setContext(DRIVER_CONTEXT_KEY, resolved);
40
+ return resolved;
29
41
  }
42
+
30
43
  /**
31
44
  * Retrieves the persistence driver from context.
32
45
  * Always returns a concrete PersistenceDriver — never null or undefined.
33
46
  *
34
47
  * @throws Error if called outside a RuneProvider tree (no context set).
35
48
  */
36
- export function getDriverContext() {
37
- const driver = getContext(DRIVER_CONTEXT_KEY);
38
- if (!driver) {
39
- throw new Error("[DriverProvider] getDriverContext() called outside a <RuneProvider> tree. " +
40
- "Wrap your application in <RuneProvider> to provide persistence.");
41
- }
42
- return driver;
49
+ export function getDriverContext(): PersistenceDriver {
50
+ const driver = getContext<PersistenceDriver | undefined>(DRIVER_CONTEXT_KEY);
51
+ if (!driver) {
52
+ throw new Error(
53
+ "[DriverProvider] getDriverContext() called outside a <RuneProvider> tree. " +
54
+ "Wrap your application in <RuneProvider> to provide persistence.",
55
+ );
56
+ }
57
+ return driver;
43
58
  }
@@ -0,0 +1,19 @@
1
+ // src/lib/persistence/types.ts
2
+
3
+ /**
4
+ * Synchronous persistence driver interface for Svelte stores
5
+ */
6
+ export interface PersistenceDriver {
7
+ /**
8
+ * Get a value by key. Should return null if not found.
9
+ */
10
+ get(key: string): string | null;
11
+ /**
12
+ * Set a value by key.
13
+ */
14
+ set(key: string, value: string): void;
15
+ /**
16
+ * Remove a value by key.
17
+ */
18
+ remove(key: string): void;
19
+ }
@@ -0,0 +1,9 @@
1
+ import { getContext } from "svelte";
2
+ import { RUNE_LAB_CONTEXT } from "../mod.ts";
3
+ import type { PersistenceDriver } from "../mod.ts";
4
+
5
+ export function usePersistence(): PersistenceDriver | undefined {
6
+ return getContext<PersistenceDriver | undefined>(
7
+ RUNE_LAB_CONTEXT.persistence,
8
+ );
9
+ }
@@ -0,0 +1,221 @@
1
+ import type { PersistenceDriver } from "@rune-lab/kernel";
2
+ import type { Component } from "svelte";
3
+
4
+ /**
5
+ * Factory function signature for creating a store.
6
+ * Receives the resolved config, driver, and a map of already-created store instances.
7
+ * The `stores` map enables dependency injection between stores.
8
+ */
9
+ export type StoreFactory<TConfig = unknown, TStore = unknown> = (
10
+ config: TConfig,
11
+ driver: PersistenceDriver,
12
+ stores: Map<string, unknown>,
13
+ ) => TStore | null;
14
+
15
+ /**
16
+ * An entry in the Store Registry.
17
+ * Maps a context key to its factory function and metadata.
18
+ */
19
+ export interface StoreRegistryEntry<TConfig = unknown, TStore = unknown> {
20
+ /** Unique id (previously key) matching the RUNE_LAB_CONTEXT key */
21
+ id: string;
22
+ /** The symbol used for Svelte context (e.g., RUNE_LAB_CONTEXT.theme) */
23
+ contextKey?: symbol;
24
+ /** The ID of the plugin that registered this store */
25
+ pluginId?: string;
26
+ /** Factory function that creates the store */
27
+ factory: StoreFactory<TConfig, TStore>;
28
+ /** If true, the store is optional — null return from factory means "skip" */
29
+ optional?: boolean;
30
+ /** If true, the store does not use persistence at all */
31
+ noPersistence?: boolean;
32
+ /**
33
+ * Keys of other stores that must be created before this one.
34
+ * The registry initializer topologically sorts entries by this field.
35
+ */
36
+ dependsOn?: string[];
37
+ /**
38
+ * Config key that must be present for this store to be created.
39
+ * Used for opt-in stores (e.g., "cart", "auth").
40
+ * When undefined, the store is always created.
41
+ */
42
+ conditional?: string;
43
+ }
44
+
45
+ /**
46
+ * A RunePlugin is a collection of stores and overlays.
47
+ */
48
+ export interface RunePlugin {
49
+ /** dot-namespaced: "rune-lab.layout" */
50
+ id: string;
51
+ /** one or more store slots */
52
+ stores: StoreRegistryEntry[];
53
+ /** Svelte components, no required props */
54
+ overlays?: Component<Record<never, never>>[];
55
+ }
56
+
57
+ /**
58
+ * The global store registry.
59
+ * Pre-populated with built-in stores by RuneProvider.
60
+ * Third-party plugins can register additional entries before mounting.
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * // Plugin registration (before RuneProvider mounts)
65
+ * registerStore({
66
+ * id: "analytics",
67
+ * factory: (config, driver) => createAnalyticsStore(config),
68
+ * optional: true,
69
+ * noPersistence: true,
70
+ * });
71
+ * ```
72
+ */
73
+ const STORE_REGISTRY: Map<string, StoreRegistryEntry> = new Map<
74
+ string,
75
+ StoreRegistryEntry
76
+ >();
77
+
78
+ /**
79
+ * Register a store entry in the global registry.
80
+ * Must be called before RuneProvider mounts for the store to be auto-wired.
81
+ *
82
+ * @param entry - Store registry entry with id, factory, and options.
83
+ * @throws Error if a store with the same id is already registered.
84
+ */
85
+ export function registerStore<TConfig = unknown, TStore = unknown>(
86
+ entry: StoreRegistryEntry<TConfig, TStore>,
87
+ ): void {
88
+ if (STORE_REGISTRY.has(entry.id)) {
89
+ console.warn(
90
+ `[StoreRegistry] Overwriting existing store registration for id "${entry.id}"`,
91
+ );
92
+ }
93
+ STORE_REGISTRY.set(entry.id, entry as StoreRegistryEntry);
94
+ }
95
+
96
+ /**
97
+ * Define a Rune plugin and register its stores.
98
+ */
99
+ export function defineRune(plugin: RunePlugin): RunePlugin {
100
+ for (const slot of plugin.stores) {
101
+ if (!slot.pluginId) {
102
+ slot.pluginId = plugin.id;
103
+ }
104
+ registerStore(slot);
105
+ }
106
+ return plugin;
107
+ }
108
+
109
+ /**
110
+ * Get a registered store entry by key.
111
+ */
112
+ export function getRegisteredStore(
113
+ key: string,
114
+ ): StoreRegistryEntry | undefined {
115
+ return STORE_REGISTRY.get(key);
116
+ }
117
+
118
+ /**
119
+ * Get all registered store entries.
120
+ */
121
+ export function getAllRegisteredStores(): Map<string, StoreRegistryEntry> {
122
+ return STORE_REGISTRY;
123
+ }
124
+
125
+ /**
126
+ * Remove a store registration (primarily useful for testing).
127
+ */
128
+ export function unregisterStore(key: string): boolean {
129
+ return STORE_REGISTRY.delete(key);
130
+ }
131
+
132
+ /**
133
+ * Clear all store registrations (primarily useful for testing).
134
+ */
135
+ export function clearRegistry(): void {
136
+ STORE_REGISTRY.clear();
137
+ }
138
+
139
+ /**
140
+ * Topologically sort registry entries by `dependsOn` to ensure correct creation order.
141
+ * Entries with no dependencies come first; entries depending on others come after.
142
+ */
143
+ function topologicalSort(entries: StoreRegistryEntry[]): StoreRegistryEntry[] {
144
+ const sorted: StoreRegistryEntry[] = [];
145
+ const visited = new Set<string>();
146
+ const visiting = new Set<string>(); // cycle detection
147
+
148
+ const entryMap = new Map(entries.map((e) => [e.id, e]));
149
+
150
+ function visit(entry: StoreRegistryEntry) {
151
+ if (visited.has(entry.id)) return;
152
+ if (visiting.has(entry.id)) {
153
+ throw new Error(
154
+ `[StoreRegistry] Circular dependency detected involving "${entry.id}"`,
155
+ );
156
+ }
157
+
158
+ visiting.add(entry.id);
159
+
160
+ for (const depKey of entry.dependsOn ?? []) {
161
+ const dep = entryMap.get(depKey);
162
+ if (dep) visit(dep);
163
+ }
164
+
165
+ visiting.delete(entry.id);
166
+ visited.add(entry.id);
167
+ sorted.push(entry);
168
+ }
169
+
170
+ for (const entry of entries) {
171
+ visit(entry);
172
+ }
173
+
174
+ return sorted;
175
+ }
176
+
177
+ /**
178
+ * Initialize all registered stores using the provided plugins, config, and driver.
179
+ * Resolves dependencies via topological sort and returns a map of key → store instance.
180
+ *
181
+ * @param _plugins - The list of active RunePlugins (unused but kept for API stability)
182
+ * @param config - The RuneLabConfig (Record<string, unknown>)
183
+ * @param driver - The resolved PersistenceDriver
184
+ * @returns Map of store key → created store instance
185
+ */
186
+ export function initializeStores(
187
+ _plugins: unknown[], // RunePlugin[] - avoid circular import if possible
188
+ config: Record<string, unknown>,
189
+ driver: PersistenceDriver,
190
+ ): Map<string, unknown> {
191
+ const entries = Array.from(STORE_REGISTRY.values());
192
+ const sorted = topologicalSort(entries);
193
+ const stores = new Map<string, unknown>();
194
+
195
+ for (const entry of sorted) {
196
+ // Extract plugin-specific config slice if pluginId is present
197
+ // Fallback to root config for backward compat with top-level props
198
+ const pluginConfig = entry.pluginId && config[entry.pluginId]
199
+ ? (config[entry.pluginId] as Record<string, unknown>)
200
+ : config;
201
+
202
+ // Skip conditional stores when their config key is absent
203
+ if (entry.conditional && !(entry.conditional in pluginConfig)) {
204
+ continue;
205
+ }
206
+
207
+ const store = entry.factory(pluginConfig, driver, stores);
208
+
209
+ if (store === null && entry.optional) {
210
+ continue; // Optional store chose not to create
211
+ }
212
+
213
+ if (store !== null && store !== undefined) {
214
+ stores.set(entry.id, store);
215
+ }
216
+ }
217
+
218
+ return stores;
219
+ }
220
+
221
+ export { STORE_REGISTRY };
@@ -0,0 +1,162 @@
1
+ import { beforeEach, describe, expect, it } from "vite-plus/test";
2
+ import type { PersistenceDriver } from "../persistence/types.ts";
3
+ import {
4
+ clearRegistry,
5
+ getAllRegisteredStores,
6
+ getRegisteredStore,
7
+ registerStore,
8
+ STORE_REGISTRY,
9
+ unregisterStore,
10
+ } from "./mod.ts";
11
+
12
+ describe("StoreRegistry", () => {
13
+ // Clean slate for each test
14
+ beforeEach(() => {
15
+ clearRegistry();
16
+ });
17
+
18
+ describe("registerStore", () => {
19
+ it("should register a store entry", () => {
20
+ registerStore({
21
+ id: "test",
22
+ factory: () => ({ value: 42 }),
23
+ });
24
+
25
+ expect(STORE_REGISTRY.size).toBe(1);
26
+ expect(STORE_REGISTRY.has("test")).toBe(true);
27
+ });
28
+
29
+ it("should allow overwriting with a warning", () => {
30
+ registerStore({ id: "test", factory: () => "v1" });
31
+ registerStore({ id: "test", factory: () => "v2" });
32
+
33
+ expect(STORE_REGISTRY.size).toBe(1);
34
+ const entry = getRegisteredStore("test");
35
+ // Factory should be the second one
36
+ expect(
37
+ entry?.factory(
38
+ {} as Record<string, unknown>,
39
+ {} as PersistenceDriver,
40
+ new Map(),
41
+ ),
42
+ ).toBe("v2");
43
+ });
44
+
45
+ it("should register multiple entries", () => {
46
+ registerStore({ id: "a", factory: () => "A" });
47
+ registerStore({ id: "b", factory: () => "B" });
48
+ registerStore({ id: "c", factory: () => "C" });
49
+
50
+ expect(STORE_REGISTRY.size).toBe(3);
51
+ });
52
+ });
53
+
54
+ describe("getRegisteredStore", () => {
55
+ it("should return the entry for a registered key", () => {
56
+ registerStore({
57
+ id: "theme",
58
+ factory: () => "theme-store",
59
+ optional: false,
60
+ });
61
+
62
+ const entry = getRegisteredStore("theme");
63
+ expect(entry).toBeDefined();
64
+ expect(entry!.id).toBe("theme");
65
+ expect(entry!.optional).toBe(false);
66
+ });
67
+
68
+ it("should return undefined for unregistered keys", () => {
69
+ expect(getRegisteredStore("nonexistent")).toBeUndefined();
70
+ });
71
+ });
72
+
73
+ describe("getAllRegisteredStores", () => {
74
+ it("should return all registered stores", () => {
75
+ registerStore({ id: "a", factory: () => "A" });
76
+ registerStore({ id: "b", factory: () => "B" });
77
+
78
+ const all = getAllRegisteredStores();
79
+ expect(all.size).toBe(2);
80
+ expect(all.has("a")).toBe(true);
81
+ expect(all.has("b")).toBe(true);
82
+ });
83
+ });
84
+
85
+ describe("unregisterStore", () => {
86
+ it("should remove a registered store", () => {
87
+ registerStore({ id: "test", factory: () => "val" });
88
+ expect(STORE_REGISTRY.has("test")).toBe(true);
89
+
90
+ const result = unregisterStore("test");
91
+ expect(result).toBe(true);
92
+ expect(STORE_REGISTRY.has("test")).toBe(false);
93
+ });
94
+
95
+ it("should return false for non-existent keys", () => {
96
+ expect(unregisterStore("nope")).toBe(false);
97
+ });
98
+ });
99
+
100
+ describe("clearRegistry", () => {
101
+ it("should remove all entries", () => {
102
+ registerStore({ id: "a", factory: () => "A" });
103
+ registerStore({ id: "b", factory: () => "B" });
104
+ expect(STORE_REGISTRY.size).toBe(2);
105
+
106
+ clearRegistry();
107
+ expect(STORE_REGISTRY.size).toBe(0);
108
+ });
109
+ });
110
+
111
+ describe("StoreFactory contract", () => {
112
+ it("factory receives config and driver, returns store", () => {
113
+ const mockDriver: PersistenceDriver = {
114
+ get: () => null,
115
+ set: () => {},
116
+ remove: () => {},
117
+ };
118
+
119
+ registerStore<
120
+ Record<string, unknown>,
121
+ { type: string; hasDriver: boolean; apiUrl: unknown }
122
+ >(
123
+ {
124
+ id: "analytics",
125
+ factory: (config, driver) => ({
126
+ type: "analytics",
127
+ hasDriver: !!driver,
128
+ apiUrl: config.apiUrl,
129
+ }),
130
+ optional: true,
131
+ noPersistence: true,
132
+ },
133
+ );
134
+
135
+ const entry = getRegisteredStore("analytics")!;
136
+ const store = entry.factory({ apiUrl: "test" }, mockDriver, new Map());
137
+
138
+ expect(store).toEqual({
139
+ type: "analytics",
140
+ hasDriver: true,
141
+ apiUrl: "test",
142
+ });
143
+ });
144
+
145
+ it("optional factory can return null", () => {
146
+ registerStore({
147
+ id: "optional-feature",
148
+ factory: () => null,
149
+ optional: true,
150
+ });
151
+
152
+ const entry = getRegisteredStore("optional-feature")!;
153
+ expect(
154
+ entry.factory(
155
+ {} as Record<string, unknown>,
156
+ {} as PersistenceDriver,
157
+ new Map(),
158
+ ),
159
+ ).toBeNull();
160
+ });
161
+ });
162
+ });
@@ -0,0 +1,94 @@
1
+ // sdk/core/src/design-tokens/props.ts
2
+ // Canonical shared prop interfaces for design tokens.
3
+ // No CSS-framework-specific logic here — class maps live in sdk/ui.
4
+
5
+ // ── Size Tokens ────────────────────────────────────────────────────────────────
6
+
7
+ /** Standard size scale used across all components. */
8
+ export type SizeToken = "xs" | "sm" | "md" | "lg" | "xl";
9
+
10
+ /** Mixin interface for components that accept a size prop. */
11
+ export interface WithSizing {
12
+ /** Visual size variant. Defaults to "md" if omitted. */
13
+ size?: SizeToken;
14
+ }
15
+
16
+ // ── Variant Tokens ─────────────────────────────────────────────────────────────
17
+
18
+ /**
19
+ * Semantic variant tokens aligned with DaisyUI's theme system.
20
+ * Kept as a union type for TypeScript inference; consumers can extend via
21
+ * `string & {}` if they need custom variants.
22
+ */
23
+ export type VariantToken =
24
+ | "primary"
25
+ | "secondary"
26
+ | "accent"
27
+ | "neutral"
28
+ | "ghost"
29
+ | "info"
30
+ | "success"
31
+ | "warning"
32
+ | "error";
33
+
34
+ /** Mixin interface for components that accept a variant prop. */
35
+ export interface WithVariant {
36
+ /** Semantic color variant. */
37
+ variant?: VariantToken;
38
+ }
39
+
40
+ // ── Class Passthrough ──────────────────────────────────────────────────────────
41
+
42
+ /** Mixin interface for components that accept a custom CSS class. */
43
+ export interface WithClass {
44
+ /** Additional CSS class string to merge with component classes. */
45
+ class?: string;
46
+ }
47
+
48
+ // ── Combined ───────────────────────────────────────────────────────────────────
49
+
50
+ /**
51
+ * Convenience intersection of all design-token mixins.
52
+ * Use when a component supports size, variant, and custom class.
53
+ */
54
+ export type WithDesignTokens = WithSizing & WithVariant & WithClass;
55
+
56
+ // ── Resolution Utilities ───────────────────────────────────────────────────────
57
+
58
+ /**
59
+ * Maps a size token to a CSS class string using a component-specific map.
60
+ * Returns the mapped class or an empty string for unknown tokens.
61
+ *
62
+ * @param size - The size token to resolve
63
+ * @param classMap - Component-specific mapping of tokens to CSS classes
64
+ * @param fallback - Fallback size if `size` is undefined (default: "md")
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * const btnSizeMap = { xs: "btn-xs", sm: "btn-sm", md: "btn-md", lg: "btn-lg", xl: "btn-xl" };
69
+ * resolveSize("lg", btnSizeMap); // "btn-lg"
70
+ * resolveSize(undefined, btnSizeMap); // "btn-md"
71
+ * ```
72
+ */
73
+ export function resolveSize(
74
+ size: SizeToken | undefined,
75
+ classMap: Partial<Record<SizeToken, string>>,
76
+ fallback: SizeToken = "md",
77
+ ): string {
78
+ const token = size ?? fallback;
79
+ return classMap[token] ?? "";
80
+ }
81
+
82
+ /**
83
+ * Maps a variant token to a CSS class string using a component-specific map.
84
+ *
85
+ * @param variant - The variant token to resolve
86
+ * @param classMap - Component-specific mapping of tokens to CSS classes
87
+ */
88
+ export function resolveVariant(
89
+ variant: VariantToken | undefined,
90
+ classMap: Partial<Record<VariantToken, string>>,
91
+ ): string {
92
+ if (!variant) return "";
93
+ return classMap[variant] ?? "";
94
+ }
package/src/mod.ts ADDED
@@ -0,0 +1,10 @@
1
+ export { default as RuneProvider } from "./RuneProvider.svelte";
2
+ // export { default as Icon } from "./Icon.svelte";
3
+
4
+ export * from "./kernel/src/mod.ts";
5
+ export * from "./runes/layout/src/mod.ts";
6
+ export * from "./runes/palettes/src/mod.ts";
7
+ export * from "./runes/plugins/money/src/mod.ts";
8
+
9
+ import denoConfig from "../deno.json" with { type: "json" };
10
+ export const version = (): string => denoConfig.version;
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "@rune-lab/layout",
3
+ "version": "0.1.0",
4
+ "exports": "./mod.ts"
5
+ }