rune-lab 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/README.md +1 -1
  2. package/dist/core/design-tokens/props.d.ts +52 -0
  3. package/dist/core/design-tokens/props.d.ts.map +1 -0
  4. package/dist/core/design-tokens/props.js +34 -0
  5. package/dist/core/exchange-rate/strategies.d.ts +52 -0
  6. package/dist/core/exchange-rate/strategies.d.ts.map +1 -0
  7. package/dist/core/exchange-rate/strategies.js +72 -0
  8. package/dist/core/index.d.ts +8 -3
  9. package/dist/core/index.d.ts.map +1 -1
  10. package/dist/core/index.js +8 -3
  11. package/dist/core/internal/message-resolver.d.ts +1 -1
  12. package/dist/core/internal/message-resolver.d.ts.map +1 -1
  13. package/dist/core/layout/types.d.ts +60 -0
  14. package/dist/core/layout/types.d.ts.map +1 -0
  15. package/dist/core/layout/types.js +4 -0
  16. package/dist/core/money/index.d.ts +1 -1
  17. package/dist/core/money/index.d.ts.map +1 -1
  18. package/dist/core/money/index.js +1 -1
  19. package/dist/core/money/money-primitive.d.ts +101 -0
  20. package/dist/core/money/money-primitive.d.ts.map +1 -0
  21. package/dist/core/money/money-primitive.js +161 -0
  22. package/dist/core/money/money.d.ts +74 -2
  23. package/dist/core/money/money.d.ts.map +1 -1
  24. package/dist/core/money/money.js +120 -2
  25. package/dist/core/shortcuts/types.d.ts +60 -0
  26. package/dist/core/shortcuts/types.d.ts.map +1 -0
  27. package/dist/core/shortcuts/types.js +4 -0
  28. package/dist/index.d.ts +4 -3
  29. package/dist/index.js +6 -4
  30. package/dist/state/api.svelte.js +2 -2
  31. package/dist/state/app.svelte.js +1 -1
  32. package/dist/state/auth/index.d.ts +2 -2
  33. package/dist/state/auth/index.js +1 -1
  34. package/dist/state/auth/session.svelte.d.ts +1 -1
  35. package/dist/state/auth/session.svelte.js +7 -5
  36. package/dist/state/auth/types.d.ts +1 -1
  37. package/dist/state/cart.svelte.d.ts +1 -1
  38. package/dist/state/cart.svelte.js +1 -1
  39. package/dist/state/commands.svelte.d.ts +7 -7
  40. package/dist/state/commands.svelte.js +1 -1
  41. package/dist/state/composables/useMoney.d.ts +19 -3
  42. package/dist/state/composables/useMoney.js +70 -6
  43. package/dist/state/composables/useMoneyFilter.d.ts +20 -0
  44. package/dist/state/composables/useMoneyFilter.js +81 -0
  45. package/dist/state/composables/usePersistence.d.ts +1 -1
  46. package/dist/state/composables/usePersistence.js +1 -1
  47. package/dist/state/composables/useRuneLab.d.ts +1 -1
  48. package/dist/state/composables/useRuneLab.js +2 -2
  49. package/dist/state/composables/useShortcuts.d.ts +33 -0
  50. package/dist/state/composables/useShortcuts.js +75 -0
  51. package/dist/state/context.d.ts +1 -0
  52. package/dist/state/context.js +1 -0
  53. package/dist/state/createConfigStore.svelte.d.ts +4 -31
  54. package/dist/state/createConfigStore.svelte.js +62 -51
  55. package/dist/state/currency.svelte.d.ts +13 -9
  56. package/dist/state/currency.svelte.js +26 -10
  57. package/dist/state/currency.test.d.ts +1 -0
  58. package/dist/state/currency.test.js +35 -0
  59. package/dist/state/exchange-rate.svelte.d.ts +43 -0
  60. package/dist/state/exchange-rate.svelte.js +145 -0
  61. package/dist/state/exchange-rate.test.d.ts +1 -0
  62. package/dist/state/exchange-rate.test.js +75 -0
  63. package/dist/state/index.d.ts +26 -19
  64. package/dist/state/index.js +25 -18
  65. package/dist/state/language.svelte.d.ts +3 -10
  66. package/dist/state/language.svelte.js +4 -5
  67. package/dist/state/layout.svelte.d.ts +1 -1
  68. package/dist/state/layout.svelte.js +4 -4
  69. package/dist/state/persistence/drivers.d.ts +1 -1
  70. package/dist/state/persistence/drivers.js +9 -7
  71. package/dist/state/persistence/drivers.test.d.ts +1 -0
  72. package/dist/state/persistence/drivers.test.js +79 -0
  73. package/dist/state/persistence/provider.d.ts +23 -0
  74. package/dist/state/persistence/provider.js +43 -0
  75. package/dist/state/persistence/provider.test.d.ts +1 -0
  76. package/dist/state/persistence/provider.test.js +51 -0
  77. package/dist/state/registry/index.d.ts +44 -0
  78. package/dist/state/registry/index.js +58 -0
  79. package/dist/state/registry/registry.test.d.ts +1 -0
  80. package/dist/state/registry/registry.test.js +112 -0
  81. package/dist/state/registry/types.d.ts +20 -0
  82. package/dist/state/registry/types.js +3 -0
  83. package/dist/state/shortcuts.svelte.js +4 -4
  84. package/dist/state/theme.svelte.d.ts +3 -10
  85. package/dist/state/theme.svelte.js +8 -8
  86. package/dist/state/toast-bridge.d.ts +1 -1
  87. package/dist/state/toast.svelte.js +1 -1
  88. package/dist/ui/components/ApiMonitor.svelte +2 -2
  89. package/dist/ui/components/Icon.svelte +1 -1
  90. package/dist/ui/components/RuneProvider.svelte +28 -8
  91. package/dist/ui/components/RuneProvider.svelte.d.ts +12 -5
  92. package/dist/ui/components/Toaster.svelte +1 -1
  93. package/dist/ui/components/money/MoneyDisplay.svelte +91 -18
  94. package/dist/ui/components/money/MoneyDisplay.svelte.d.ts +15 -3
  95. package/dist/ui/components/money/MoneyDisplay.svelte.test.d.ts +1 -1
  96. package/dist/ui/components/money/MoneyDisplay.svelte.test.js +45 -2
  97. package/dist/ui/components/money/MoneyInput.svelte +123 -42
  98. package/dist/ui/components/money/MoneyInput.svelte.d.ts +14 -5
  99. package/dist/ui/features/command-palette/CommandPalette.svelte +3 -3
  100. package/dist/ui/features/config/APP_CONFIGURATIONS.d.ts +29 -0
  101. package/dist/ui/features/config/APP_CONFIGURATIONS.js +38 -0
  102. package/dist/ui/features/config/CurrencySelector.svelte +10 -36
  103. package/dist/ui/features/config/LanguageSelector.svelte +10 -33
  104. package/dist/ui/features/config/ResourceSelector.svelte +92 -0
  105. package/dist/ui/features/config/ResourceSelector.svelte.d.ts +25 -0
  106. package/dist/ui/features/config/ThemeSelector.svelte +11 -34
  107. package/dist/ui/features/shortcuts/ShortcutBinder.svelte +17 -0
  108. package/dist/ui/features/shortcuts/ShortcutBinder.svelte.d.ts +7 -0
  109. package/dist/ui/features/shortcuts/ShortcutPalette.svelte +3 -3
  110. package/dist/ui/index.d.ts +5 -1
  111. package/dist/ui/index.js +8 -3
  112. package/dist/ui/layout/ConnectedNavigationPanel.svelte +7 -8
  113. package/dist/ui/layout/ConnectedNavigationPanel.svelte.d.ts +1 -1
  114. package/dist/ui/layout/ConnectedWorkspaceStrip.svelte +5 -3
  115. package/dist/ui/layout/ConnectedWorkspaceStrip.svelte.d.ts +1 -1
  116. package/dist/ui/layout/NavigationPanel.svelte +1 -1
  117. package/dist/ui/layout/NavigationPanel.svelte.d.ts +1 -1
  118. package/dist/ui/layout/WorkspaceLayout.svelte +9 -1
  119. package/dist/ui/layout/WorkspaceLayout.svelte.d.ts +7 -0
  120. package/dist/ui/layout/WorkspaceStrip.svelte +1 -1
  121. package/dist/ui/layout/WorkspaceStrip.svelte.d.ts +1 -1
  122. package/dist/ui/layout/connection-factory.d.ts +50 -0
  123. package/dist/ui/layout/connection-factory.js +58 -0
  124. package/dist/ui/layout/index.d.ts +2 -2
  125. package/dist/ui/layout/index.js +1 -1
  126. package/dist/ui/paraglide/README.md +53 -0
  127. package/dist/ui/paraglide/runtime.d.ts +105 -124
  128. package/dist/ui/paraglide/runtime.js +162 -127
  129. package/dist/ui/paraglide/server.d.ts +6 -17
  130. package/dist/ui/paraglide/server.js +11 -20
  131. package/dist/ui/primitives/DatePicker.svelte +1 -1
  132. package/package.json +8 -8
  133. package/dist/state/daisyui.d.ts +0 -4
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <h1 align="center">
2
- <img src="https://raw.githubusercontent.com/Yrrrrrf/rune-lab/main/static/img/rune.png" alt="Rune Lab Icon" width="128" height="128" description="Icon representing the Svelte Runes system">
2
+ <img src="https://raw.githubusercontent.com/Yrrrrrf/rune-lab/main/src/sdk/ui/static/img/rune.png" alt="Rune Lab Icon" width="128" height="128" descripti``on="Icon representing the Svelte Runes system">
3
3
  <div align="center">Rune Lab</div>
4
4
  </h1>
5
5
 
@@ -0,0 +1,52 @@
1
+ /** Standard size scale used across all components. */
2
+ export type SizeToken = "xs" | "sm" | "md" | "lg" | "xl";
3
+ /** Mixin interface for components that accept a size prop. */
4
+ export interface WithSizing {
5
+ /** Visual size variant. Defaults to "md" if omitted. */
6
+ size?: SizeToken;
7
+ }
8
+ /**
9
+ * Semantic variant tokens aligned with DaisyUI's theme system.
10
+ * Kept as a union type for TypeScript inference; consumers can extend via
11
+ * `string & {}` if they need custom variants.
12
+ */
13
+ export type VariantToken = "primary" | "secondary" | "accent" | "neutral" | "ghost" | "info" | "success" | "warning" | "error";
14
+ /** Mixin interface for components that accept a variant prop. */
15
+ export interface WithVariant {
16
+ /** Semantic color variant. */
17
+ variant?: VariantToken;
18
+ }
19
+ /** Mixin interface for components that accept a custom CSS class. */
20
+ export interface WithClass {
21
+ /** Additional CSS class string to merge with component classes. */
22
+ class?: string;
23
+ }
24
+ /**
25
+ * Convenience intersection of all design-token mixins.
26
+ * Use when a component supports size, variant, and custom class.
27
+ */
28
+ export type WithDesignTokens = WithSizing & WithVariant & WithClass;
29
+ /**
30
+ * Maps a size token to a CSS class string using a component-specific map.
31
+ * Returns the mapped class or an empty string for unknown tokens.
32
+ *
33
+ * @param size - The size token to resolve
34
+ * @param classMap - Component-specific mapping of tokens to CSS classes
35
+ * @param fallback - Fallback size if `size` is undefined (default: "md")
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * const btnSizeMap = { xs: "btn-xs", sm: "btn-sm", md: "btn-md", lg: "btn-lg", xl: "btn-xl" };
40
+ * resolveSize("lg", btnSizeMap); // "btn-lg"
41
+ * resolveSize(undefined, btnSizeMap); // "btn-md"
42
+ * ```
43
+ */
44
+ export declare function resolveSize(size: SizeToken | undefined, classMap: Partial<Record<SizeToken, string>>, fallback?: SizeToken): string;
45
+ /**
46
+ * Maps a variant token to a CSS class string using a component-specific map.
47
+ *
48
+ * @param variant - The variant token to resolve
49
+ * @param classMap - Component-specific mapping of tokens to CSS classes
50
+ */
51
+ export declare function resolveVariant(variant: VariantToken | undefined, classMap: Partial<Record<VariantToken, string>>): string;
52
+ //# sourceMappingURL=props.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../../src/sdk/core/src/design-tokens/props.ts"],"names":[],"mappings":"AAMA,sDAAsD;AACtD,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEzD,8DAA8D;AAC9D,MAAM,WAAW,UAAU;IACzB,wDAAwD;IACxD,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAID;;;;GAIG;AACH,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,WAAW,GACX,QAAQ,GACR,SAAS,GACT,OAAO,GACP,MAAM,GACN,SAAS,GACT,SAAS,GACT,OAAO,CAAC;AAEZ,iEAAiE;AACjE,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAID,qEAAqE;AACrE,MAAM,WAAW,SAAS;IACxB,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,CAAC;AAIpE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,SAAS,GAAG,SAAS,EAC3B,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,EAC5C,QAAQ,GAAE,SAAgB,GACzB,MAAM,CAGR;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,GAC9C,MAAM,CAGR"}
@@ -0,0 +1,34 @@
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
+ // ── Resolution Utilities ───────────────────────────────────────────────────────
5
+ /**
6
+ * Maps a size token to a CSS class string using a component-specific map.
7
+ * Returns the mapped class or an empty string for unknown tokens.
8
+ *
9
+ * @param size - The size token to resolve
10
+ * @param classMap - Component-specific mapping of tokens to CSS classes
11
+ * @param fallback - Fallback size if `size` is undefined (default: "md")
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const btnSizeMap = { xs: "btn-xs", sm: "btn-sm", md: "btn-md", lg: "btn-lg", xl: "btn-xl" };
16
+ * resolveSize("lg", btnSizeMap); // "btn-lg"
17
+ * resolveSize(undefined, btnSizeMap); // "btn-md"
18
+ * ```
19
+ */
20
+ export function resolveSize(size, classMap, fallback = "md") {
21
+ const token = size ?? fallback;
22
+ return classMap[token] ?? "";
23
+ }
24
+ /**
25
+ * Maps a variant token to a CSS class string using a component-specific map.
26
+ *
27
+ * @param variant - The variant token to resolve
28
+ * @param classMap - Component-specific mapping of tokens to CSS classes
29
+ */
30
+ export function resolveVariant(variant, classMap) {
31
+ if (!variant)
32
+ return "";
33
+ return classMap[variant] ?? "";
34
+ }
@@ -0,0 +1,52 @@
1
+ import type { ScaledRate } from "../money/money.ts";
2
+ /**
3
+ * A pure function that converts a minor-unit amount using a rate.
4
+ * All strategy functions must be deterministic and side-effect-free.
5
+ */
6
+ export type ConversionFn = (amount: number, ...rates: number[]) => number;
7
+ /**
8
+ * Resolves a ScaledRate or plain number into a float rate value.
9
+ */
10
+ export declare function resolveRate(rate: ScaledRate | number): number;
11
+ /**
12
+ * Direct conversion: base currency → target currency.
13
+ * Multiplies the amount by the rate.
14
+ *
15
+ * @param amount - Minor-unit amount in the source currency
16
+ * @param rate - Conversion rate (1 source = `rate` target)
17
+ * @returns Minor-unit amount in the target currency
18
+ */
19
+ export declare function directConversion(amount: number, rate: number): number;
20
+ /**
21
+ * Inverse conversion: target currency → base currency.
22
+ * Divides the amount by the rate.
23
+ *
24
+ * @param amount - Minor-unit amount in the source currency
25
+ * @param rate - Conversion rate of source relative to base (1 base = `rate` source)
26
+ * @returns Minor-unit amount in the base currency
27
+ */
28
+ export declare function inverseConversion(amount: number, rate: number): number;
29
+ /**
30
+ * Triangular conversion: source → base → target (cross-rate).
31
+ * First divides by the source-to-base rate, then multiplies by the base-to-target rate.
32
+ *
33
+ * @param amount - Minor-unit amount in the source currency
34
+ * @param rateSourceToBase - Rate of source relative to base (1 base = `rate` source)
35
+ * @param rateBaseToTarget - Rate of base to target (1 base = `rate` target)
36
+ * @returns Minor-unit amount in the target currency
37
+ */
38
+ export declare function triangularConversion(amount: number, rateSourceToBase: number, rateBaseToTarget: number): number;
39
+ /**
40
+ * Named map of conversion strategies.
41
+ * Consumer code and the ExchangeRateStore can select a strategy by name.
42
+ * Extensible: register additional strategies before store initialization.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * CONVERSION_STRATEGIES["crypto"] = (amount, rate) => {
47
+ * // 18-decimal precision logic
48
+ * };
49
+ * ```
50
+ */
51
+ export declare const CONVERSION_STRATEGIES: Record<string, ConversionFn>;
52
+ //# sourceMappingURL=strategies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategies.d.ts","sourceRoot":"","sources":["../../../src/sdk/core/src/exchange-rate/strategies.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC;AAE1E;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAG7D;AAID;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKtE;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,EACxB,gBAAgB,EAAE,MAAM,GACvB,MAAM,CAQR;AAID;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAM9D,CAAC"}
@@ -0,0 +1,72 @@
1
+ // sdk/core/src/exchange-rate/strategies.ts
2
+ // Pure conversion strategy functions — no store or context dependencies.
3
+ // Extracted from ExchangeRateStore to enable independent testing and extensibility.
4
+ /**
5
+ * Resolves a ScaledRate or plain number into a float rate value.
6
+ */
7
+ export function resolveRate(rate) {
8
+ if (typeof rate === "number")
9
+ return rate;
10
+ return rate.amount / Math.pow(10, rate.scale);
11
+ }
12
+ // ── Strategy Functions ─────────────────────────────────────────────────────────
13
+ /**
14
+ * Direct conversion: base currency → target currency.
15
+ * Multiplies the amount by the rate.
16
+ *
17
+ * @param amount - Minor-unit amount in the source currency
18
+ * @param rate - Conversion rate (1 source = `rate` target)
19
+ * @returns Minor-unit amount in the target currency
20
+ */
21
+ export function directConversion(amount, rate) {
22
+ return Math.round(amount * rate);
23
+ }
24
+ /**
25
+ * Inverse conversion: target currency → base currency.
26
+ * Divides the amount by the rate.
27
+ *
28
+ * @param amount - Minor-unit amount in the source currency
29
+ * @param rate - Conversion rate of source relative to base (1 base = `rate` source)
30
+ * @returns Minor-unit amount in the base currency
31
+ */
32
+ export function inverseConversion(amount, rate) {
33
+ if (rate === 0) {
34
+ throw new Error("Cannot perform inverse conversion with a rate of zero.");
35
+ }
36
+ return Math.round(amount / rate);
37
+ }
38
+ /**
39
+ * Triangular conversion: source → base → target (cross-rate).
40
+ * First divides by the source-to-base rate, then multiplies by the base-to-target rate.
41
+ *
42
+ * @param amount - Minor-unit amount in the source currency
43
+ * @param rateSourceToBase - Rate of source relative to base (1 base = `rate` source)
44
+ * @param rateBaseToTarget - Rate of base to target (1 base = `rate` target)
45
+ * @returns Minor-unit amount in the target currency
46
+ */
47
+ export function triangularConversion(amount, rateSourceToBase, rateBaseToTarget) {
48
+ if (rateSourceToBase === 0) {
49
+ throw new Error("Cannot perform triangular conversion: source-to-base rate is zero.");
50
+ }
51
+ const amountInBase = amount / rateSourceToBase;
52
+ return Math.round(amountInBase * rateBaseToTarget);
53
+ }
54
+ // ── Strategy Registry ──────────────────────────────────────────────────────────
55
+ /**
56
+ * Named map of conversion strategies.
57
+ * Consumer code and the ExchangeRateStore can select a strategy by name.
58
+ * Extensible: register additional strategies before store initialization.
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * CONVERSION_STRATEGIES["crypto"] = (amount, rate) => {
63
+ * // 18-decimal precision logic
64
+ * };
65
+ * ```
66
+ */
67
+ export const CONVERSION_STRATEGIES = {
68
+ direct: directConversion,
69
+ inverse: inverseConversion,
70
+ // triangularConversion takes 2 rates — wrapped for the registry signature
71
+ triangular: (amount, ...rates) => triangularConversion(amount, rates[0], rates[1]),
72
+ };
@@ -1,4 +1,9 @@
1
- export * from "./internal/message-resolver";
2
- export * from "./persistence/types";
3
- export * from "./money/index";
1
+ export * from "./internal/message-resolver.ts";
2
+ export * from "./persistence/types.ts";
3
+ export * from "./money/index.ts";
4
+ export { type MoneyJSON, MoneyPrimitive } from "./money/money-primitive.ts";
5
+ export * from "./exchange-rate/strategies.ts";
6
+ export * from "./design-tokens/props.ts";
7
+ export * from "./layout/types.ts";
8
+ export * from "./shortcuts/types.ts";
4
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sdk/core/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAE5C,cAAc,qBAAqB,CAAC;AAEpC,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sdk/core/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC;AAE/C,cAAc,wBAAwB,CAAC;AAEvC,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,KAAK,SAAS,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5E,cAAc,+BAA+B,CAAC;AAE9C,cAAc,0BAA0B,CAAC;AAEzC,cAAc,mBAAmB,CAAC;AAElC,cAAc,sBAAsB,CAAC"}
@@ -1,3 +1,8 @@
1
- export * from "./internal/message-resolver";
2
- export * from "./persistence/types";
3
- export * from "./money/index";
1
+ export * from "./internal/message-resolver.js";
2
+ export * from "./persistence/types.js";
3
+ export * from "./money/index.js";
4
+ export { MoneyPrimitive } from "./money/money-primitive.js";
5
+ export * from "./exchange-rate/strategies.js";
6
+ export * from "./design-tokens/props.js";
7
+ export * from "./layout/types.js";
8
+ export * from "./shortcuts/types.js";
@@ -4,7 +4,7 @@
4
4
  * Enables dynamic message function calls for config selectors.
5
5
  * Creates a resolver that dynamically looks up and calls message functions.
6
6
  */
7
- type MessageBundle = Record<string, (...args: any[]) => string>;
7
+ type MessageBundle = Record<string, (...args: unknown[]) => string>;
8
8
  interface MessageResolverConfig<T> {
9
9
  /**
10
10
  * Function to extract the message key from an option
@@ -1 +1 @@
1
- {"version":3,"file":"message-resolver.d.ts","sourceRoot":"","sources":["../../../src/sdk/core/src/internal/message-resolver.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC,CAAC;AAEhE,UAAU,qBAAqB,CAAC,CAAC;IAC/B;;;OAGG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,CAAC;IAEpC;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;CAC1C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC,IAExB,QAAQ,CAAC,KAAG,MAAM,CAmB3B;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAExE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,CAAC,EAAE,EACZ,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAC/B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxB"}
1
+ {"version":3,"file":"message-resolver.d.ts","sourceRoot":"","sources":["../../../src/sdk/core/src/internal/message-resolver.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,CAAC,CAAC;AAEpE,UAAU,qBAAqB,CAAC,CAAC;IAC/B;;;OAGG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,CAAC;IAEpC;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;CAC1C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC,IAExB,QAAQ,CAAC,KAAG,MAAM,CAmB3B;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAExE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,CAAC,EAAE,EACZ,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAC/B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxB"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Describes a single zone within a workspace layout.
3
+ * Zones are rendered in array order by the LayoutEngine in sdk/ui.
4
+ */
5
+ export interface LayoutZone {
6
+ /** Unique identifier for this zone (e.g., "navigation", "content", "detail"). */
7
+ id: string;
8
+ /**
9
+ * Component reference to render in this zone.
10
+ * Typed as `unknown` at the core level — the UI layer resolves this
11
+ * to a concrete Svelte component reference.
12
+ */
13
+ component?: unknown;
14
+ /**
15
+ * Store binding key. When set, the LayoutEngine will pass the corresponding
16
+ * store from the registry as a prop to the component.
17
+ */
18
+ storeKey?: string;
19
+ /**
20
+ * CSS width value for this zone (e.g., "280px", "1fr", "auto").
21
+ * @default "auto"
22
+ */
23
+ width?: string;
24
+ /**
25
+ * Whether the zone can be collapsed by the user.
26
+ * @default false
27
+ */
28
+ collapsible?: boolean;
29
+ /**
30
+ * Store boolean path that controls whether this zone is visible.
31
+ * When set, the zone is only rendered when the referenced boolean is `true`.
32
+ * @example "layout.showNavigation"
33
+ */
34
+ conditional?: string;
35
+ /**
36
+ * Minimum width before the zone collapses automatically.
37
+ * Only relevant when `collapsible` is `true`.
38
+ */
39
+ minWidth?: string;
40
+ /**
41
+ * Position of the zone relative to the content area.
42
+ * @default "start"
43
+ */
44
+ position?: "start" | "end";
45
+ }
46
+ /**
47
+ * Complete layout configuration — an ordered array of zones.
48
+ * The LayoutEngine renders zones in array order (left-to-right by default).
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * const dashboardLayout: LayoutConfig = [
53
+ * { id: "navigation", width: "280px", collapsible: true },
54
+ * { id: "content", width: "1fr" },
55
+ * { id: "detail", width: "320px", collapsible: true, conditional: "layout.showDetail" },
56
+ * ];
57
+ * ```
58
+ */
59
+ export type LayoutConfig = LayoutZone[];
60
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/sdk/core/src/layout/types.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IAEX;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;CAC5B;AAID;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ // sdk/core/src/layout/types.ts
2
+ // Framework-agnostic layout configuration types.
3
+ // No Svelte dependency — `component` is typed as `unknown` (resolved by sdk/ui).
4
+ export {};
@@ -1,2 +1,2 @@
1
- export { addMoney, createMoney, CURRENCY_MAP, type Dinero, type DineroCurrency, formatAmount, formatMoney, type ISO4217Code, multiplyMoney, registerCurrency, safeAmount, subtractMoney, toMinorUnit, } from "./money";
1
+ export { addMoney, convertAmount, convertMoney, createMoney, CURRENCY_MAP, type Dinero, type DineroCurrency, type DineroSnapshot, formatAmount, formatMoney, fromMoneySnapshot, type ISO4217Code, multiplyMoney, type RateMap, registerCurrency, safeAmount, type ScaledRate, scaledRate, subtractMoney, toAdyenMoney, toMinorUnit, toMoneySnapshot, toPaypalMoney, toSquareMoney, toStripeMoney, } from "./money.ts";
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sdk/core/src/money/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,YAAY,EACZ,WAAW,EACX,KAAK,WAAW,EAChB,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,WAAW,GACZ,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sdk/core/src/money/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,KAAK,WAAW,EAChB,aAAa,EACb,KAAK,OAAO,EACZ,gBAAgB,EAChB,UAAU,EACV,KAAK,UAAU,EACf,UAAU,EACV,aAAa,EACb,YAAY,EACZ,WAAW,EACX,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC"}
@@ -1,2 +1,2 @@
1
1
  // sdk/core/src/money/index.ts
2
- export { addMoney, createMoney, CURRENCY_MAP, formatAmount, formatMoney, multiplyMoney, registerCurrency, safeAmount, subtractMoney, toMinorUnit, } from "./money";
2
+ export { addMoney, convertAmount, convertMoney, createMoney, CURRENCY_MAP, formatAmount, formatMoney, fromMoneySnapshot, multiplyMoney, registerCurrency, safeAmount, scaledRate, subtractMoney, toAdyenMoney, toMinorUnit, toMoneySnapshot, toPaypalMoney, toSquareMoney, toStripeMoney, } from "./money.js";
@@ -0,0 +1,101 @@
1
+ import { type ISO4217Code } from "./money.ts";
2
+ /**
3
+ * Serializable representation of a MoneyPrimitive.
4
+ * Used for persistence drivers and JSON round-trips.
5
+ */
6
+ export interface MoneyJSON {
7
+ amount: number;
8
+ currencyCode: string;
9
+ scale: number;
10
+ }
11
+ /**
12
+ * Immutable Value Object that encapsulates a monetary amount, its currency,
13
+ * and the scale (number of decimal places).
14
+ *
15
+ * Amounts are always stored in minor units (e.g., cents for USD, centavos for MXN).
16
+ * The scale is derived from the currency's exponent in CURRENCY_MAP.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * const price = MoneyPrimitive.fromMajor(12.99, "USD");
21
+ * price.minor; // 1299
22
+ * price.major; // 12.99
23
+ * price.format("en-US"); // "$12.99"
24
+ *
25
+ * const json = price.toJSON();
26
+ * const restored = MoneyPrimitive.fromJSON(json);
27
+ * ```
28
+ */
29
+ export declare class MoneyPrimitive {
30
+ /** Raw amount in minor units (e.g., cents). */
31
+ readonly amount: number;
32
+ /** ISO 4217 currency code. */
33
+ readonly currencyCode: string;
34
+ /** Number of decimal places for this currency (e.g., 2 for USD, 0 for JPY). */
35
+ readonly scale: number;
36
+ private constructor();
37
+ /**
38
+ * Create a MoneyPrimitive from a minor-unit integer amount.
39
+ * @param amount - Amount in minor units (e.g., 1299 for $12.99)
40
+ * @param currencyCode - ISO 4217 currency code
41
+ */
42
+ static fromMinor(amount: number, currencyCode: ISO4217Code | string): MoneyPrimitive;
43
+ /**
44
+ * Create a MoneyPrimitive from a major-unit float amount.
45
+ * @param amount - Amount in major units (e.g., 12.99 for $12.99)
46
+ * @param currencyCode - ISO 4217 currency code
47
+ */
48
+ static fromMajor(amount: number, currencyCode: ISO4217Code | string): MoneyPrimitive;
49
+ /**
50
+ * Restore a MoneyPrimitive from its JSON representation.
51
+ */
52
+ static fromJSON(json: MoneyJSON): MoneyPrimitive;
53
+ /** Amount in minor units (alias for `amount`). */
54
+ get minor(): number;
55
+ /** Amount in major units (e.g., 12.99 for 1299 cents). */
56
+ get major(): number;
57
+ /**
58
+ * Format this monetary value as a locale-aware currency string.
59
+ * @param locale - BCP 47 locale string (default: "en-US")
60
+ */
61
+ format(locale?: string): string;
62
+ /**
63
+ * Add another MoneyPrimitive (must be same currency).
64
+ * Returns a new MoneyPrimitive.
65
+ */
66
+ add(other: MoneyPrimitive): MoneyPrimitive;
67
+ /**
68
+ * Subtract another MoneyPrimitive (must be same currency).
69
+ * Returns a new MoneyPrimitive.
70
+ */
71
+ subtract(other: MoneyPrimitive): MoneyPrimitive;
72
+ /**
73
+ * Multiply by a scalar factor. Returns a new MoneyPrimitive.
74
+ */
75
+ multiply(factor: number): MoneyPrimitive;
76
+ /**
77
+ * Value equality — two MoneyPrimitives are equal if they have the same
78
+ * amount, currency code, and scale.
79
+ */
80
+ equals(other: MoneyPrimitive): boolean;
81
+ /**
82
+ * Returns true if this amount is zero.
83
+ */
84
+ isZero(): boolean;
85
+ /**
86
+ * Returns true if this amount is negative.
87
+ */
88
+ isNegative(): boolean;
89
+ /**
90
+ * Serialize to a plain JSON-compatible object.
91
+ */
92
+ toJSON(): MoneyJSON;
93
+ toString(): string;
94
+ private assertSameCurrency;
95
+ /**
96
+ * Resolves the scale (exponent) for a currency code from CURRENCY_MAP.
97
+ * Throws if the currency is not registered.
98
+ */
99
+ private static resolveScale;
100
+ }
101
+ //# sourceMappingURL=money-primitive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"money-primitive.d.ts","sourceRoot":"","sources":["../../../src/sdk/core/src/money/money-primitive.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,cAAc;IACzB,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,8BAA8B;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,OAAO;IAQP;;;;OAIG;IACH,MAAM,CAAC,SAAS,CACd,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,WAAW,GAAG,MAAM,GACjC,cAAc;IAKjB;;;;OAIG;IACH,MAAM,CAAC,SAAS,CACd,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,WAAW,GAAG,MAAM,GACjC,cAAc;IAMjB;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,cAAc;IAMhD,kDAAkD;IAClD,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,0DAA0D;IAC1D,IAAI,KAAK,IAAI,MAAM,CAGlB;IAID;;;OAGG;IACH,MAAM,CAAC,MAAM,GAAE,MAAgB,GAAG,MAAM;IAWxC;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,cAAc,GAAG,cAAc;IAS1C;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,cAAc;IAS/C;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc;IAUxC;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO;IAQtC;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;OAEG;IACH,UAAU,IAAI,OAAO;IAMrB;;OAEG;IACH,MAAM,IAAI,SAAS;IAQnB,QAAQ,IAAI,MAAM;IAMlB,OAAO,CAAC,kBAAkB;IAQ1B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;CAS5B"}
@@ -0,0 +1,161 @@
1
+ // sdk/core/src/money/money-primitive.ts
2
+ // Immutable Value Object for monetary amounts.
3
+ // Zero Svelte dependencies — pure TypeScript class.
4
+ import { CURRENCY_MAP } from "./money.js";
5
+ /**
6
+ * Immutable Value Object that encapsulates a monetary amount, its currency,
7
+ * and the scale (number of decimal places).
8
+ *
9
+ * Amounts are always stored in minor units (e.g., cents for USD, centavos for MXN).
10
+ * The scale is derived from the currency's exponent in CURRENCY_MAP.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const price = MoneyPrimitive.fromMajor(12.99, "USD");
15
+ * price.minor; // 1299
16
+ * price.major; // 12.99
17
+ * price.format("en-US"); // "$12.99"
18
+ *
19
+ * const json = price.toJSON();
20
+ * const restored = MoneyPrimitive.fromJSON(json);
21
+ * ```
22
+ */
23
+ export class MoneyPrimitive {
24
+ /** Raw amount in minor units (e.g., cents). */
25
+ amount;
26
+ /** ISO 4217 currency code. */
27
+ currencyCode;
28
+ /** Number of decimal places for this currency (e.g., 2 for USD, 0 for JPY). */
29
+ scale;
30
+ constructor(amount, currencyCode, scale) {
31
+ this.amount = Math.round(amount);
32
+ this.currencyCode = currencyCode;
33
+ this.scale = scale;
34
+ }
35
+ // ── Factories ────────────────────────────────────────────────────────────
36
+ /**
37
+ * Create a MoneyPrimitive from a minor-unit integer amount.
38
+ * @param amount - Amount in minor units (e.g., 1299 for $12.99)
39
+ * @param currencyCode - ISO 4217 currency code
40
+ */
41
+ static fromMinor(amount, currencyCode) {
42
+ const scale = MoneyPrimitive.resolveScale(currencyCode);
43
+ return new MoneyPrimitive(amount, currencyCode, scale);
44
+ }
45
+ /**
46
+ * Create a MoneyPrimitive from a major-unit float amount.
47
+ * @param amount - Amount in major units (e.g., 12.99 for $12.99)
48
+ * @param currencyCode - ISO 4217 currency code
49
+ */
50
+ static fromMajor(amount, currencyCode) {
51
+ const scale = MoneyPrimitive.resolveScale(currencyCode);
52
+ const factor = Math.pow(10, scale);
53
+ return new MoneyPrimitive(Math.round(amount * factor), currencyCode, scale);
54
+ }
55
+ /**
56
+ * Restore a MoneyPrimitive from its JSON representation.
57
+ */
58
+ static fromJSON(json) {
59
+ return new MoneyPrimitive(json.amount, json.currencyCode, json.scale);
60
+ }
61
+ // ── Computed Getters ─────────────────────────────────────────────────────
62
+ /** Amount in minor units (alias for `amount`). */
63
+ get minor() {
64
+ return this.amount;
65
+ }
66
+ /** Amount in major units (e.g., 12.99 for 1299 cents). */
67
+ get major() {
68
+ if (this.scale === 0)
69
+ return this.amount;
70
+ return this.amount / Math.pow(10, this.scale);
71
+ }
72
+ // ── Formatting ───────────────────────────────────────────────────────────
73
+ /**
74
+ * Format this monetary value as a locale-aware currency string.
75
+ * @param locale - BCP 47 locale string (default: "en-US")
76
+ */
77
+ format(locale = "en-US") {
78
+ return new Intl.NumberFormat(locale, {
79
+ style: "currency",
80
+ currency: this.currencyCode,
81
+ minimumFractionDigits: this.scale,
82
+ maximumFractionDigits: this.scale,
83
+ }).format(this.major);
84
+ }
85
+ // ── Arithmetic (returns new instances — immutability) ────────────────────
86
+ /**
87
+ * Add another MoneyPrimitive (must be same currency).
88
+ * Returns a new MoneyPrimitive.
89
+ */
90
+ add(other) {
91
+ this.assertSameCurrency(other);
92
+ return new MoneyPrimitive(this.amount + other.amount, this.currencyCode, this.scale);
93
+ }
94
+ /**
95
+ * Subtract another MoneyPrimitive (must be same currency).
96
+ * Returns a new MoneyPrimitive.
97
+ */
98
+ subtract(other) {
99
+ this.assertSameCurrency(other);
100
+ return new MoneyPrimitive(this.amount - other.amount, this.currencyCode, this.scale);
101
+ }
102
+ /**
103
+ * Multiply by a scalar factor. Returns a new MoneyPrimitive.
104
+ */
105
+ multiply(factor) {
106
+ return new MoneyPrimitive(Math.round(this.amount * factor), this.currencyCode, this.scale);
107
+ }
108
+ // ── Comparison ───────────────────────────────────────────────────────────
109
+ /**
110
+ * Value equality — two MoneyPrimitives are equal if they have the same
111
+ * amount, currency code, and scale.
112
+ */
113
+ equals(other) {
114
+ return (this.amount === other.amount &&
115
+ this.currencyCode === other.currencyCode &&
116
+ this.scale === other.scale);
117
+ }
118
+ /**
119
+ * Returns true if this amount is zero.
120
+ */
121
+ isZero() {
122
+ return this.amount === 0;
123
+ }
124
+ /**
125
+ * Returns true if this amount is negative.
126
+ */
127
+ isNegative() {
128
+ return this.amount < 0;
129
+ }
130
+ // ── Serialization ────────────────────────────────────────────────────────
131
+ /**
132
+ * Serialize to a plain JSON-compatible object.
133
+ */
134
+ toJSON() {
135
+ return {
136
+ amount: this.amount,
137
+ currencyCode: this.currencyCode,
138
+ scale: this.scale,
139
+ };
140
+ }
141
+ toString() {
142
+ return `MoneyPrimitive(${this.amount} ${this.currencyCode} scale=${this.scale})`;
143
+ }
144
+ // ── Private Helpers ──────────────────────────────────────────────────────
145
+ assertSameCurrency(other) {
146
+ if (this.currencyCode !== other.currencyCode) {
147
+ throw new Error(`Currency mismatch: cannot operate on ${this.currencyCode} and ${other.currencyCode}`);
148
+ }
149
+ }
150
+ /**
151
+ * Resolves the scale (exponent) for a currency code from CURRENCY_MAP.
152
+ * Throws if the currency is not registered.
153
+ */
154
+ static resolveScale(currencyCode) {
155
+ const currency = CURRENCY_MAP[currencyCode];
156
+ if (!currency) {
157
+ throw new Error(`Unknown currency code: ${currencyCode}. Register it first via registerCurrency().`);
158
+ }
159
+ return currency.exponent;
160
+ }
161
+ }