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,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
+ });