@penner/smart-primitive 0.0.1 → 0.1.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 (81) hide show
  1. package/README.md +215 -180
  2. package/dist/SmartPrimitive.d.ts +87 -37
  3. package/dist/SmartPrimitive.d.ts.map +1 -1
  4. package/dist/SmartPrimitive.test-d.d.ts.map +1 -0
  5. package/dist/SmartPrimitiveConfig.test-d.d.ts +2 -0
  6. package/dist/SmartPrimitiveConfig.test-d.d.ts.map +1 -0
  7. package/dist/convert.cjs.js +2 -0
  8. package/dist/convert.cjs.js.map +1 -0
  9. package/dist/convert.d.ts +136 -0
  10. package/dist/convert.d.ts.map +1 -0
  11. package/dist/convert.es.js +51 -0
  12. package/dist/convert.es.js.map +1 -0
  13. package/dist/convert.test-d.d.ts +2 -0
  14. package/dist/convert.test-d.d.ts.map +1 -0
  15. package/dist/index.cjs.js +1 -1
  16. package/dist/index.cjs.js.map +1 -1
  17. package/dist/index.d.ts +7 -2
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.es.js +65 -2
  20. package/dist/index.es.js.map +1 -1
  21. package/dist/strings/css.d.ts +143 -0
  22. package/dist/strings/css.d.ts.map +1 -0
  23. package/dist/strings/data.d.ts +140 -0
  24. package/dist/strings/data.d.ts.map +1 -0
  25. package/dist/strings/index.cjs.js +2 -0
  26. package/dist/strings/index.cjs.js.map +1 -0
  27. package/dist/strings/index.d.ts +14 -0
  28. package/dist/strings/index.d.ts.map +1 -0
  29. package/dist/strings/index.es.js +2 -0
  30. package/dist/strings/index.es.js.map +1 -0
  31. package/dist/strings/web.d.ts +55 -0
  32. package/dist/strings/web.d.ts.map +1 -0
  33. package/dist/trait-utils.d.ts +107 -0
  34. package/dist/trait-utils.d.ts.map +1 -0
  35. package/dist/traits.d.ts +14 -0
  36. package/dist/traits.d.ts.map +1 -0
  37. package/dist/traits.examples.d.ts +7 -0
  38. package/dist/traits.examples.d.ts.map +1 -0
  39. package/dist/traits.test-d.d.ts +5 -0
  40. package/dist/traits.test-d.d.ts.map +1 -0
  41. package/dist/units/angle.d.ts +43 -0
  42. package/dist/units/angle.d.ts.map +1 -0
  43. package/dist/units/angle.test-d.d.ts +2 -0
  44. package/dist/units/angle.test-d.d.ts.map +1 -0
  45. package/dist/units/color.d.ts +35 -0
  46. package/dist/units/color.d.ts.map +1 -0
  47. package/dist/units/color.test-d.d.ts +2 -0
  48. package/dist/units/color.test-d.d.ts.map +1 -0
  49. package/dist/units/index.cjs.js +2 -0
  50. package/dist/units/index.cjs.js.map +1 -0
  51. package/dist/units/index.d.ts +19 -0
  52. package/dist/units/index.d.ts.map +1 -0
  53. package/dist/units/index.es.js +86 -0
  54. package/dist/units/index.es.js.map +1 -0
  55. package/dist/units/integer.d.ts +12 -0
  56. package/dist/units/integer.d.ts.map +1 -0
  57. package/dist/units/integer.test-d.d.ts +2 -0
  58. package/dist/units/integer.test-d.d.ts.map +1 -0
  59. package/dist/units/length.d.ts +101 -0
  60. package/dist/units/length.d.ts.map +1 -0
  61. package/dist/units/length.test-d.d.ts +2 -0
  62. package/dist/units/length.test-d.d.ts.map +1 -0
  63. package/dist/units/normalized.d.ts +111 -0
  64. package/dist/units/normalized.d.ts.map +1 -0
  65. package/dist/units/normalized.test-d.d.ts +2 -0
  66. package/dist/units/normalized.test-d.d.ts.map +1 -0
  67. package/dist/units/temperature.d.ts +16 -0
  68. package/dist/units/temperature.d.ts.map +1 -0
  69. package/dist/units/temperature.test-d.d.ts +2 -0
  70. package/dist/units/temperature.test-d.d.ts.map +1 -0
  71. package/dist/units/time.d.ts +38 -0
  72. package/dist/units/time.d.ts.map +1 -0
  73. package/dist/units/time.test-d.d.ts +2 -0
  74. package/dist/units/time.test-d.d.ts.map +1 -0
  75. package/dist/units/velocity.d.ts +78 -0
  76. package/dist/units/velocity.d.ts.map +1 -0
  77. package/dist/units/velocity.test-d.d.ts +2 -0
  78. package/dist/units/velocity.test-d.d.ts.map +1 -0
  79. package/package.json +39 -21
  80. package/dist/__tests__/SmartPrimitive.test-d.d.ts.map +0 -1
  81. /package/dist/{__tests__/SmartPrimitive.test-d.d.ts → SmartPrimitive.test-d.d.ts} +0 -0
@@ -1,7 +1,8 @@
1
1
  /**
2
- * 🔧 FEATURE FLAG: Toggle smart primitive type checking
3
- * When false (default): SmartPrimitive types provide type safety
4
- * When true: All SmartNumber, SmartString, etc. become plain primitives
2
+ * 🔧 CONFIGURATION: Toggle smart primitive type checking
3
+ *
4
+ * When `usePlainPrimitives` is false (default): SmartPrimitive types provide type safety
5
+ * When `usePlainPrimitives` is true: All SmartNumber, SmartString, etc. become plain primitives
5
6
  *
6
7
  * Use cases:
7
8
  * - Performance testing (eliminate type overhead)
@@ -9,26 +10,39 @@
9
10
  * - Gradual migration to/from smart primitives
10
11
  * - Bundle size optimization
11
12
  *
12
- * How to use:
13
- * 1. Change `false` to `true` below
14
- * 2. Your entire codebase now treats Pixels, URLs, etc. as plain primitives
15
- * 3. Cross-brand assignments that were errors become allowed
16
- * 4. All type extraction utilities become no-ops
17
- * 5. Change back to `false` to re-enable smart primitive type safety
13
+ * How to configure (module augmentation):
14
+ * ```ts
15
+ * // In a .d.ts file in your project (e.g., smart-primitive.d.ts):
16
+ * declare module '@penner/smart-primitive' {
17
+ * interface SmartPrimitiveConfig {
18
+ * usePlainPrimitives: true;
19
+ * }
20
+ * }
21
+ * ```
22
+ *
23
+ * This uses TypeScript's declaration merging so consumers can override the
24
+ * default without modifying the library source.
18
25
  */
19
- export declare const USE_PLAIN_PRIMITIVES: false;
20
- export type USE_PLAIN_PRIMITIVES_TYPE = typeof USE_PLAIN_PRIMITIVES;
21
26
  /**
22
- * Clean type extraction using the brand pattern
23
- * Respects the USE_PLAIN_PRIMITIVES flag.
27
+ * Configuration interface for SmartPrimitive behavior.
28
+ * Empty by default — consumers augment this to add properties.
29
+ *
30
+ * To disable branded types, augment with `usePlainPrimitives: true`.
31
+ * The interface is intentionally empty so that declaration merging
32
+ * can add the property (TypeScript doesn't allow changing a property's type).
24
33
  */
25
- type BaseOf<T> = USE_PLAIN_PRIMITIVES_TYPE extends true ? T : T extends number & {
26
- readonly __brand?: unknown;
27
- } ? number : T extends string & {
28
- readonly __brand?: unknown;
29
- } ? string : T extends boolean & {
30
- readonly __brand?: unknown;
31
- } ? boolean : T;
34
+ export interface SmartPrimitiveConfig {
35
+ }
36
+ /**
37
+ * Resolves to `true` when SmartPrimitiveConfig has been augmented with
38
+ * `usePlainPrimitives: true`, otherwise defaults to `false`.
39
+ */
40
+ export type UsePlainPrimitives = SmartPrimitiveConfig extends {
41
+ usePlainPrimitives: infer V;
42
+ } ? V : false;
43
+ interface Brand<BrandName extends string> {
44
+ readonly _brand?: BrandName;
45
+ }
32
46
  /**
33
47
  * Generic smart primitive type that provides **opt-in type safety** while staying flexible.
34
48
  *
@@ -36,7 +50,7 @@ type BaseOf<T> = USE_PLAIN_PRIMITIVES_TYPE extends true ? T : T extends number &
36
50
  * - ✅ **Accepts plain values**: You can use regular numbers, strings, etc. directly
37
51
  * - ✅ **Prevents cross-domain mixing**: TypeScript stops you from using pixels where milliseconds are expected
38
52
  * - ✅ **Zero runtime cost**: No performance impact - it's just TypeScript magic
39
- * - ✅ **Easy to disable**: Toggle `USE_PLAIN_PRIMITIVES` to turn off all smart typing
53
+ * - ✅ **Easy to disable**: Augment `SmartPrimitiveConfig` to turn off all smart typing
40
54
  *
41
55
  * **Example:**
42
56
  * ```ts
@@ -51,9 +65,7 @@ type BaseOf<T> = USE_PLAIN_PRIMITIVES_TYPE extends true ? T : T extends number &
51
65
  * This prevents bugs like accidentally using milliseconds where pixels are expected,
52
66
  * while keeping your code simple and readable.
53
67
  */
54
- export type SmartPrimitive<Base extends string | number | boolean | bigint | symbol, BrandName extends string> = USE_PLAIN_PRIMITIVES_TYPE extends true ? Base : Base & {
55
- readonly __brand?: BrandName;
56
- };
68
+ export type SmartPrimitive<Base extends string | number | boolean | bigint | symbol, BrandName extends string> = UsePlainPrimitives extends true ? Base : Base & Brand<BrandName>;
57
69
  /**
58
70
  * A smart number type for domain-specific numeric values like pixels, milliseconds, etc.
59
71
  *
@@ -67,7 +79,7 @@ export type SmartPrimitive<Base extends string | number | boolean | bigint | sym
67
79
  * - ✅ Catches domain mix-ups: `let width: Pixels = duration` → TypeScript error
68
80
  * - ✅ Zero runtime cost: Just TypeScript checking, no JavaScript overhead
69
81
  *
70
- * Built on `SmartPrimitive` - respects the USE_PLAIN_PRIMITIVES flag for easy toggling.
82
+ * Built on `SmartPrimitive` - respects `SmartPrimitiveConfig` for easy toggling.
71
83
  *
72
84
  * **Example:**
73
85
  * ```ts
@@ -79,16 +91,16 @@ export type SmartPrimitive<Base extends string | number | boolean | bigint | sym
79
91
  * let badAssign: Pixels = delay; // ❌ type error - caught the mistake!
80
92
  * ```
81
93
  *
82
- * When USE_PLAIN_PRIMITIVES = false (default):
94
+ * When `usePlainPrimitives` is false (default):
83
95
  * - Full smart number system with type safety between different units
84
96
  * - Plain numbers accepted seamlessly
85
97
  * - Clean tooltip display
86
98
  *
87
- * When USE_PLAIN_PRIMITIVES = true:
99
+ * When `usePlainPrimitives` is true:
88
100
  * - All smart number types collapse to plain `number`
89
101
  * - Zero runtime overhead, maximum performance
90
102
  *
91
- * Usage remains the same regardless of flag state:
103
+ * Usage remains the same regardless of config:
92
104
  * ```ts
93
105
  * let distance: Pixels = 300; // ✅ always works
94
106
  * let branded: Pixels = 300 as Pixels; // ✅ always works
@@ -125,20 +137,58 @@ export type SmartString<BrandName extends string> = SmartPrimitive<string, Brand
125
137
  * ```
126
138
  */
127
139
  export type SmartBoolean<BrandName extends string> = SmartPrimitive<boolean, BrandName>;
140
+ /**
141
+ * A smart bigint type that accepts plain `bigint` values but maintains
142
+ * a distinct branded identity.
143
+ *
144
+ * Useful for domain-specific big integers such as IDs or counters where
145
+ * accidental mixing with other numeric types should be prevented.
146
+ *
147
+ * Usage:
148
+ * ```ts
149
+ * type EntityId = SmartBigInt<'EntityId'>;
150
+ * type UserId = SmartBigInt<'UserId'>;
151
+ * let id: EntityId = 123n; // ✅ works
152
+ * let user: UserId = 456n; // ✅ works
153
+ * let badAssign: EntityId = user; // ❌ type error
154
+ * ```
155
+ */
156
+ export type SmartBigInt<BrandName extends string> = SmartPrimitive<bigint, BrandName>;
157
+ /**
158
+ * A smart symbol type that accepts plain `symbol` values but maintains
159
+ * a distinct branded identity.
160
+ *
161
+ * Useful for domain-specific symbol tokens (e.g. event types, internal
162
+ * keys) where mixing distinct tokens should be prevented by the type system.
163
+ *
164
+ * Usage:
165
+ * ```ts
166
+ * type EventType = SmartSymbol<'EventType'>;
167
+ * type Token = SmartSymbol<'Token'>;
168
+ * let e: EventType = Symbol('click'); // ✅ works
169
+ * let t: Token = Symbol('auth'); // ✅ works
170
+ * let badAssign: EventType = t; // ❌ type error
171
+ * ```
172
+ */
173
+ export type SmartSymbol<BrandName extends string> = SmartPrimitive<symbol, BrandName>;
128
174
  /**
129
175
  * Simplified Unbrand using the generic brand pattern.
130
- * Also respects the USE_PLAIN_PRIMITIVES flag.
176
+ * Also respects the `SmartPrimitiveConfig` toggle.
131
177
  *
132
- * When USE_PLAIN_PRIMITIVES = true: This becomes a no-op (types pass through unchanged)
133
- * When USE_PLAIN_PRIMITIVES = false: Full unbranding to base types
178
+ * When `usePlainPrimitives` is true: This becomes a no-op (types pass through unchanged)
179
+ * When `usePlainPrimitives` is false (default): Full unbranding to base types
134
180
  */
135
- export type Unbrand<T> = USE_PLAIN_PRIMITIVES_TYPE extends true ? T : T extends number & {
136
- readonly __brand?: unknown;
181
+ export type Unbrand<T> = UsePlainPrimitives extends true ? T : T extends number & {
182
+ readonly _brand?: unknown;
137
183
  } ? number : T extends string & {
138
- readonly __brand?: unknown;
184
+ readonly _brand?: unknown;
139
185
  } ? string : T extends boolean & {
140
- readonly __brand?: unknown;
141
- } ? boolean : T extends Record<string, unknown> ? {
186
+ readonly _brand?: unknown;
187
+ } ? boolean : T extends bigint & {
188
+ readonly _brand?: unknown;
189
+ } ? bigint : T extends symbol & {
190
+ readonly _brand?: unknown;
191
+ } ? symbol : T extends Record<string, unknown> ? {
142
192
  [K in keyof T]: Unbrand<T[K]>;
143
193
  } : T;
144
194
  /**
@@ -149,5 +199,5 @@ export type Unbrand<T> = USE_PLAIN_PRIMITIVES_TYPE extends true ? T : T extends
149
199
  export type UnbrandFn<F, UnbrandReturn extends boolean = false> = F extends (...args: infer A) => infer R ? A extends readonly unknown[] ? (...args: {
150
200
  [K in keyof A]: Unbrand<A[K]>;
151
201
  }) => UnbrandReturn extends true ? Unbrand<R> : R : never : never;
152
- export type { BaseOf };
202
+ export {};
153
203
  //# sourceMappingURL=SmartPrimitive.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SmartPrimitive.d.ts","sourceRoot":"","sources":["../src/SmartPrimitive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,eAAO,MAAM,oBAAoB,EAAG,KAAc,CAAC;AACnD,MAAM,MAAM,yBAAyB,GAAG,OAAO,oBAAoB,CAAC;AAEpE;;;GAGG;AACH,KAAK,MAAM,CAAC,CAAC,IAAI,yBAAyB,SAAS,IAAI,GACnD,CAAC,GACD,CAAC,SAAS,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/C,MAAM,GACN,CAAC,SAAS,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/C,MAAM,GACN,CAAC,SAAS,OAAO,GAAG;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAChD,OAAO,GACP,CAAC,CAAC;AAEZ;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,cAAc,CACxB,IAAI,SAAS,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,EACxD,SAAS,SAAS,MAAM,IACtB,yBAAyB,SAAS,IAAI,GACtC,IAAI,GACJ,IAAI,GAAG;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,MAAM,WAAW,CAAC,SAAS,SAAS,MAAM,IAAI,cAAc,CAChE,MAAM,EACN,SAAS,CACV,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,WAAW,CAAC,SAAS,SAAS,MAAM,IAAI,cAAc,CAChE,MAAM,EACN,SAAS,CACV,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,YAAY,CAAC,SAAS,SAAS,MAAM,IAAI,cAAc,CACjE,OAAO,EACP,SAAS,CACV,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,yBAAyB,SAAS,IAAI,GAC3D,CAAC,GAGD,CAAC,SAAS,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/C,MAAM,GACN,CAAC,SAAS,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/C,MAAM,GACN,CAAC,SAAS,OAAO,GAAG;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAChD,OAAO,GAEP,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAEjC,CAAC,CAAC;AAEd;;;;GAIG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,aAAa,SAAS,OAAO,GAAG,KAAK,IAAI,CAAC,SAAS,CAC1E,GAAG,IAAI,EAAE,MAAM,CAAC,KACb,MAAM,CAAC,GACR,CAAC,SAAS,SAAS,OAAO,EAAE,GAC1B,CACE,GAAG,IAAI,EAAE;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,KACvC,aAAa,SAAS,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAChD,KAAK,GACP,KAAK,CAAC;AAGV,YAAY,EAAE,MAAM,EAAE,CAAC"}
1
+ {"version":3,"file":"SmartPrimitive.d.ts","sourceRoot":"","sources":["../src/SmartPrimitive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;;GAOG;AAEH,MAAM,WAAW,oBAAoB;CAAG;AAExC;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,oBAAoB,SAAS;IAC5D,kBAAkB,EAAE,MAAM,CAAC,CAAC;CAC7B,GACG,CAAC,GACD,KAAK,CAAC;AAGV,UAAU,KAAK,CAAC,SAAS,SAAS,MAAM;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,cAAc,CACxB,IAAI,SAAS,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,EACxD,SAAS,SAAS,MAAM,IACtB,kBAAkB,SAAS,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,MAAM,WAAW,CAAC,SAAS,SAAS,MAAM,IAAI,cAAc,CAChE,MAAM,EACN,SAAS,CACV,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,WAAW,CAAC,SAAS,SAAS,MAAM,IAAI,cAAc,CAChE,MAAM,EACN,SAAS,CACV,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,YAAY,CAAC,SAAS,SAAS,MAAM,IAAI,cAAc,CACjE,OAAO,EACP,SAAS,CACV,CAAC;AACF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,WAAW,CAAC,SAAS,SAAS,MAAM,IAAI,cAAc,CAChE,MAAM,EACN,SAAS,CACV,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,WAAW,CAAC,SAAS,SAAS,MAAM,IAAI,cAAc,CAChE,MAAM,EACN,SAAS,CACV,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,kBAAkB,SAAS,IAAI,GACpD,CAAC,GAGD,CAAC,SAAS,MAAM,GAAG;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9C,MAAM,GACN,CAAC,SAAS,MAAM,GAAG;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9C,MAAM,GACN,CAAC,SAAS,OAAO,GAAG;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/C,OAAO,GACP,CAAC,SAAS,MAAM,GAAG;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9C,MAAM,GACN,CAAC,SAAS,MAAM,GAAG;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9C,MAAM,GAEN,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAEjC,CAAC,CAAC;AAElB;;;;GAIG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,aAAa,SAAS,OAAO,GAAG,KAAK,IAAI,CAAC,SAAS,CAC1E,GAAG,IAAI,EAAE,MAAM,CAAC,KACb,MAAM,CAAC,GACR,CAAC,SAAS,SAAS,OAAO,EAAE,GAC1B,CACE,GAAG,IAAI,EAAE;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,KACvC,aAAa,SAAS,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAChD,KAAK,GACP,KAAK,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SmartPrimitive.test-d.d.ts","sourceRoot":"","sources":["../src/SmartPrimitive.test-d.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=SmartPrimitiveConfig.test-d.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SmartPrimitiveConfig.test-d.d.ts","sourceRoot":"","sources":["../src/SmartPrimitiveConfig.test-d.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function n(e){return(r=>e(r))}function i(e,r){return{to:n(e),from:n(r)}}function c(e){return i(r=>r*e,r=>r/e)}function s(e){return(r=>(e&&e(r),r))}function u(e,r){return(t=>r(e(t)))}function v(){return(e=>e)}class a{constructor(){this.converters=new Map}register(r,t){return this.converters.set(r,t),this}convert(r,t){const o=this.converters.get(t);if(!o)throw new Error(`No converter registered for target: ${t}`);return o(r)}has(r){return this.converters.has(r)}}exports.ConverterRegistry=a;exports.chain=u;exports.createBiConverter=i;exports.createConverter=n;exports.createLinearConverter=c;exports.createStringConverter=s;exports.identity=v;
2
+ //# sourceMappingURL=convert.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert.cjs.js","sources":["../src/convert.ts"],"sourcesContent":["/**\n * 🔄 Conversion Utilities for Smart Primitives\n *\n * Type-safe conversion functions between branded types with a clean factory pattern.\n * Supports both one-way and bidirectional conversions.\n */\n\nimport type { SmartNumber, SmartString } from './SmartPrimitive';\n\n/* ═══════════════════════════════════════════════════════════════\n CORE CONVERSION TYPES\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * A type-safe conversion function from one branded type to another.\n *\n * @example\n * ```ts\n * const degreesToRadians: Converter<Degrees, Radians> = (deg) => (deg * Math.PI / 180) as Radians;\n * ```\n */\nexport type Converter<From, To> = (value: From) => To;\n\n/**\n * A bidirectional converter with forward and reverse operations.\n *\n * @example\n * ```ts\n * const degreesRadians: BiConverter<Degrees, Radians> = {\n * to: (deg) => (deg * Math.PI / 180) as Radians,\n * from: (rad) => (rad * 180 / Math.PI) as Degrees,\n * };\n * ```\n */\nexport interface BiConverter<A, B> {\n /** Convert from A to B */\n to: Converter<A, B>;\n /** Convert from B to A */\n from: Converter<B, A>;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n CONVERSION FACTORY\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * Create a type-safe converter between two branded number types.\n *\n * @param transform - The mathematical transformation function\n * @returns A typed converter function\n *\n * @example\n * ```ts\n * type Celsius = SmartNumber<'Celsius'>;\n * type Fahrenheit = SmartNumber<'Fahrenheit'>;\n *\n * const celsiusToFahrenheit = createConverter<Celsius, Fahrenheit>(c => c * 9/5 + 32);\n * const temp: Fahrenheit = celsiusToFahrenheit(100 as Celsius); // 212\n * ```\n */\nexport function createConverter<\n From extends SmartNumber<string>,\n To extends SmartNumber<string>,\n>(transform: (value: number) => number): Converter<From, To> {\n return ((value: From) => transform(value) as To) as Converter<From, To>;\n}\n\n/**\n * Create a bidirectional converter between two branded number types.\n *\n * @param toTransform - Transform from A to B\n * @param fromTransform - Transform from B to A\n * @returns A BiConverter with both directions\n *\n * @example\n * ```ts\n * const celsiusFahrenheit = createBiConverter<Celsius, Fahrenheit>(\n * c => c * 9/5 + 32,\n * f => (f - 32) * 5/9\n * );\n *\n * celsiusFahrenheit.to(0 as Celsius); // 32 as Fahrenheit\n * celsiusFahrenheit.from(32 as Fahrenheit); // 0 as Celsius\n * ```\n */\nexport function createBiConverter<\n A extends SmartNumber<string>,\n B extends SmartNumber<string>,\n>(\n toTransform: (value: number) => number,\n fromTransform: (value: number) => number,\n): BiConverter<A, B> {\n return {\n to: createConverter<A, B>(toTransform),\n from: createConverter<B, A>(fromTransform),\n };\n}\n\n/**\n * Create a linear converter (multiply by factor).\n * Useful for unit conversions with simple ratios.\n *\n * @param factor - The multiplication factor (A * factor = B)\n * @returns A BiConverter using the linear relationship\n *\n * @example\n * ```ts\n * // 1 meter = 100 centimeters\n * const metersCentimeters = createLinearConverter<Meters, Centimeters>(100);\n *\n * metersCentimeters.to(2 as Meters); // 200 as Centimeters\n * metersCentimeters.from(50 as Centimeters); // 0.5 as Meters\n * ```\n */\nexport function createLinearConverter<\n A extends SmartNumber<string>,\n B extends SmartNumber<string>,\n>(factor: number): BiConverter<A, B> {\n return createBiConverter<A, B>(\n a => a * factor,\n b => b / factor,\n );\n}\n\n/**\n * Create a converter for string types with validation.\n *\n * @param validate - Optional validation function (throws on invalid input)\n * @returns A converter that casts strings to the target type\n *\n * @example\n * ```ts\n * type URL = SmartString<'URL'>;\n *\n * const toURL = createStringConverter<string, URL>((s) => {\n * if (!s.startsWith('http')) throw new Error('Invalid URL');\n * });\n *\n * const url: URL = toURL('https://example.com'); // ✅\n * const bad: URL = toURL('not-a-url'); // ❌ throws\n * ```\n */\nexport function createStringConverter<\n From extends string,\n To extends SmartString<string>,\n>(validate?: (value: From) => void): Converter<From, To> {\n return ((value: From) => {\n if (validate) validate(value);\n return value as unknown as To;\n }) as Converter<From, To>;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n CHAINING & COMPOSITION\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * Chain two converters together: A → B → C\n *\n * @example\n * ```ts\n * const turnsToRadians = chain(turnsToDegrees, degreesToRadians);\n * ```\n */\nexport function chain<A, B, C>(\n first: Converter<A, B>,\n second: Converter<B, C>,\n): Converter<A, C> {\n return ((value: A) => second(first(value))) as Converter<A, C>;\n}\n\n/**\n * Create an identity converter (no-op, for type coercion).\n *\n * @example\n * ```ts\n * const pixelsIdentity = identity<Pixels>();\n * ```\n */\nexport function identity<T>(): Converter<T, T> {\n return ((value: T) => value) as Converter<T, T>;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n CONVERSION REGISTRY (Optional Pattern)\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * A registry of converters for runtime lookup.\n * Useful when converter selection depends on runtime values.\n *\n * @example\n * ```ts\n * const angleConverters = new ConverterRegistry<Degrees>();\n * angleConverters.register('radians', degreesToRadians);\n * angleConverters.register('turns', degreesToTurns);\n *\n * const converted = angleConverters.convert(90 as Degrees, 'radians');\n * ```\n */\nexport class ConverterRegistry<From> {\n private converters = new Map<string, Converter<From, unknown>>();\n\n register<To>(name: string, converter: Converter<From, To>): this {\n this.converters.set(name, converter as Converter<From, unknown>);\n return this;\n }\n\n convert<To>(value: From, targetName: string): To {\n const converter = this.converters.get(targetName);\n if (!converter) {\n throw new Error(`No converter registered for target: ${targetName}`);\n }\n return converter(value) as To;\n }\n\n has(targetName: string): boolean {\n return this.converters.has(targetName);\n }\n}\n"],"names":["createConverter","transform","value","createBiConverter","toTransform","fromTransform","createLinearConverter","factor","a","b","createStringConverter","validate","chain","first","second","identity","ConverterRegistry","name","converter","targetName"],"mappings":"gFA4DO,SAASA,EAGdC,EAA2D,CAC3D,OAASC,GAAgBD,EAAUC,CAAK,EAC1C,CAoBO,SAASC,EAIdC,EACAC,EACmB,CACnB,MAAO,CACL,GAAIL,EAAsBI,CAAW,EACrC,KAAMJ,EAAsBK,CAAa,CAAA,CAE7C,CAkBO,SAASC,EAGdC,EAAmC,CACnC,OAAOJ,KACAK,EAAID,KACJE,EAAIF,CAAA,CAEb,CAoBO,SAASG,EAGdC,EAAuD,CACvD,OAAST,IACHS,KAAmBT,CAAK,EACrBA,GAEX,CAcO,SAASU,EACdC,EACAC,EACiB,CACjB,OAASZ,GAAaY,EAAOD,EAAMX,CAAK,CAAC,EAC3C,CAUO,SAASa,GAA+B,CAC7C,OAASb,GAAaA,EACxB,CAmBO,MAAMc,CAAwB,CAA9B,aAAA,CACL,KAAQ,eAAiB,GAAsC,CAE/D,SAAaC,EAAcC,EAAsC,CAC/D,YAAK,WAAW,IAAID,EAAMC,CAAqC,EACxD,IACT,CAEA,QAAYhB,EAAaiB,EAAwB,CAC/C,MAAMD,EAAY,KAAK,WAAW,IAAIC,CAAU,EAChD,GAAI,CAACD,EACH,MAAM,IAAI,MAAM,uCAAuCC,CAAU,EAAE,EAErE,OAAOD,EAAUhB,CAAK,CACxB,CAEA,IAAIiB,EAA6B,CAC/B,OAAO,KAAK,WAAW,IAAIA,CAAU,CACvC,CACF"}
@@ -0,0 +1,136 @@
1
+ import { SmartNumber, SmartString } from './SmartPrimitive';
2
+ /**
3
+ * A type-safe conversion function from one branded type to another.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * const degreesToRadians: Converter<Degrees, Radians> = (deg) => (deg * Math.PI / 180) as Radians;
8
+ * ```
9
+ */
10
+ export type Converter<From, To> = (value: From) => To;
11
+ /**
12
+ * A bidirectional converter with forward and reverse operations.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const degreesRadians: BiConverter<Degrees, Radians> = {
17
+ * to: (deg) => (deg * Math.PI / 180) as Radians,
18
+ * from: (rad) => (rad * 180 / Math.PI) as Degrees,
19
+ * };
20
+ * ```
21
+ */
22
+ export interface BiConverter<A, B> {
23
+ /** Convert from A to B */
24
+ to: Converter<A, B>;
25
+ /** Convert from B to A */
26
+ from: Converter<B, A>;
27
+ }
28
+ /**
29
+ * Create a type-safe converter between two branded number types.
30
+ *
31
+ * @param transform - The mathematical transformation function
32
+ * @returns A typed converter function
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * type Celsius = SmartNumber<'Celsius'>;
37
+ * type Fahrenheit = SmartNumber<'Fahrenheit'>;
38
+ *
39
+ * const celsiusToFahrenheit = createConverter<Celsius, Fahrenheit>(c => c * 9/5 + 32);
40
+ * const temp: Fahrenheit = celsiusToFahrenheit(100 as Celsius); // 212
41
+ * ```
42
+ */
43
+ export declare function createConverter<From extends SmartNumber<string>, To extends SmartNumber<string>>(transform: (value: number) => number): Converter<From, To>;
44
+ /**
45
+ * Create a bidirectional converter between two branded number types.
46
+ *
47
+ * @param toTransform - Transform from A to B
48
+ * @param fromTransform - Transform from B to A
49
+ * @returns A BiConverter with both directions
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * const celsiusFahrenheit = createBiConverter<Celsius, Fahrenheit>(
54
+ * c => c * 9/5 + 32,
55
+ * f => (f - 32) * 5/9
56
+ * );
57
+ *
58
+ * celsiusFahrenheit.to(0 as Celsius); // 32 as Fahrenheit
59
+ * celsiusFahrenheit.from(32 as Fahrenheit); // 0 as Celsius
60
+ * ```
61
+ */
62
+ export declare function createBiConverter<A extends SmartNumber<string>, B extends SmartNumber<string>>(toTransform: (value: number) => number, fromTransform: (value: number) => number): BiConverter<A, B>;
63
+ /**
64
+ * Create a linear converter (multiply by factor).
65
+ * Useful for unit conversions with simple ratios.
66
+ *
67
+ * @param factor - The multiplication factor (A * factor = B)
68
+ * @returns A BiConverter using the linear relationship
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * // 1 meter = 100 centimeters
73
+ * const metersCentimeters = createLinearConverter<Meters, Centimeters>(100);
74
+ *
75
+ * metersCentimeters.to(2 as Meters); // 200 as Centimeters
76
+ * metersCentimeters.from(50 as Centimeters); // 0.5 as Meters
77
+ * ```
78
+ */
79
+ export declare function createLinearConverter<A extends SmartNumber<string>, B extends SmartNumber<string>>(factor: number): BiConverter<A, B>;
80
+ /**
81
+ * Create a converter for string types with validation.
82
+ *
83
+ * @param validate - Optional validation function (throws on invalid input)
84
+ * @returns A converter that casts strings to the target type
85
+ *
86
+ * @example
87
+ * ```ts
88
+ * type URL = SmartString<'URL'>;
89
+ *
90
+ * const toURL = createStringConverter<string, URL>((s) => {
91
+ * if (!s.startsWith('http')) throw new Error('Invalid URL');
92
+ * });
93
+ *
94
+ * const url: URL = toURL('https://example.com'); // ✅
95
+ * const bad: URL = toURL('not-a-url'); // ❌ throws
96
+ * ```
97
+ */
98
+ export declare function createStringConverter<From extends string, To extends SmartString<string>>(validate?: (value: From) => void): Converter<From, To>;
99
+ /**
100
+ * Chain two converters together: A → B → C
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * const turnsToRadians = chain(turnsToDegrees, degreesToRadians);
105
+ * ```
106
+ */
107
+ export declare function chain<A, B, C>(first: Converter<A, B>, second: Converter<B, C>): Converter<A, C>;
108
+ /**
109
+ * Create an identity converter (no-op, for type coercion).
110
+ *
111
+ * @example
112
+ * ```ts
113
+ * const pixelsIdentity = identity<Pixels>();
114
+ * ```
115
+ */
116
+ export declare function identity<T>(): Converter<T, T>;
117
+ /**
118
+ * A registry of converters for runtime lookup.
119
+ * Useful when converter selection depends on runtime values.
120
+ *
121
+ * @example
122
+ * ```ts
123
+ * const angleConverters = new ConverterRegistry<Degrees>();
124
+ * angleConverters.register('radians', degreesToRadians);
125
+ * angleConverters.register('turns', degreesToTurns);
126
+ *
127
+ * const converted = angleConverters.convert(90 as Degrees, 'radians');
128
+ * ```
129
+ */
130
+ export declare class ConverterRegistry<From> {
131
+ private converters;
132
+ register<To>(name: string, converter: Converter<From, To>): this;
133
+ convert<To>(value: From, targetName: string): To;
134
+ has(targetName: string): boolean;
135
+ }
136
+ //# sourceMappingURL=convert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAMjE;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,KAAK,EAAE,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,EAAE,CAAC;IAC/B,0BAA0B;IAC1B,EAAE,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpB,0BAA0B;IAC1B,IAAI,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CACvB;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,IAAI,SAAS,WAAW,CAAC,MAAM,CAAC,EAChC,EAAE,SAAS,WAAW,CAAC,MAAM,CAAC,EAC9B,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAE3D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,SAAS,WAAW,CAAC,MAAM,CAAC,EAC7B,CAAC,SAAS,WAAW,CAAC,MAAM,CAAC,EAE7B,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EACtC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GACvC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAKnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CACnC,CAAC,SAAS,WAAW,CAAC,MAAM,CAAC,EAC7B,CAAC,SAAS,WAAW,CAAC,MAAM,CAAC,EAC7B,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAKnC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,SAAS,MAAM,EACnB,EAAE,SAAS,WAAW,CAAC,MAAM,CAAC,EAC9B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAKvD;AAMD;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC3B,KAAK,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EACtB,MAAM,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GACtB,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAEjB;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAE7C;AAMD;;;;;;;;;;;;GAYG;AACH,qBAAa,iBAAiB,CAAC,IAAI;IACjC,OAAO,CAAC,UAAU,CAA+C;IAEjE,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI;IAKhE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,EAAE;IAQhD,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;CAGjC"}
@@ -0,0 +1,51 @@
1
+ function o(e) {
2
+ return ((r) => e(r));
3
+ }
4
+ function c(e, r) {
5
+ return {
6
+ to: o(e),
7
+ from: o(r)
8
+ };
9
+ }
10
+ function i(e) {
11
+ return c(
12
+ (r) => r * e,
13
+ (r) => r / e
14
+ );
15
+ }
16
+ function s(e) {
17
+ return ((r) => (e && e(r), r));
18
+ }
19
+ function u(e, r) {
20
+ return ((t) => r(e(t)));
21
+ }
22
+ function v() {
23
+ return ((e) => e);
24
+ }
25
+ class f {
26
+ constructor() {
27
+ this.converters = /* @__PURE__ */ new Map();
28
+ }
29
+ register(r, t) {
30
+ return this.converters.set(r, t), this;
31
+ }
32
+ convert(r, t) {
33
+ const n = this.converters.get(t);
34
+ if (!n)
35
+ throw new Error(`No converter registered for target: ${t}`);
36
+ return n(r);
37
+ }
38
+ has(r) {
39
+ return this.converters.has(r);
40
+ }
41
+ }
42
+ export {
43
+ f as ConverterRegistry,
44
+ u as chain,
45
+ c as createBiConverter,
46
+ o as createConverter,
47
+ i as createLinearConverter,
48
+ s as createStringConverter,
49
+ v as identity
50
+ };
51
+ //# sourceMappingURL=convert.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert.es.js","sources":["../src/convert.ts"],"sourcesContent":["/**\n * 🔄 Conversion Utilities for Smart Primitives\n *\n * Type-safe conversion functions between branded types with a clean factory pattern.\n * Supports both one-way and bidirectional conversions.\n */\n\nimport type { SmartNumber, SmartString } from './SmartPrimitive';\n\n/* ═══════════════════════════════════════════════════════════════\n CORE CONVERSION TYPES\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * A type-safe conversion function from one branded type to another.\n *\n * @example\n * ```ts\n * const degreesToRadians: Converter<Degrees, Radians> = (deg) => (deg * Math.PI / 180) as Radians;\n * ```\n */\nexport type Converter<From, To> = (value: From) => To;\n\n/**\n * A bidirectional converter with forward and reverse operations.\n *\n * @example\n * ```ts\n * const degreesRadians: BiConverter<Degrees, Radians> = {\n * to: (deg) => (deg * Math.PI / 180) as Radians,\n * from: (rad) => (rad * 180 / Math.PI) as Degrees,\n * };\n * ```\n */\nexport interface BiConverter<A, B> {\n /** Convert from A to B */\n to: Converter<A, B>;\n /** Convert from B to A */\n from: Converter<B, A>;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n CONVERSION FACTORY\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * Create a type-safe converter between two branded number types.\n *\n * @param transform - The mathematical transformation function\n * @returns A typed converter function\n *\n * @example\n * ```ts\n * type Celsius = SmartNumber<'Celsius'>;\n * type Fahrenheit = SmartNumber<'Fahrenheit'>;\n *\n * const celsiusToFahrenheit = createConverter<Celsius, Fahrenheit>(c => c * 9/5 + 32);\n * const temp: Fahrenheit = celsiusToFahrenheit(100 as Celsius); // 212\n * ```\n */\nexport function createConverter<\n From extends SmartNumber<string>,\n To extends SmartNumber<string>,\n>(transform: (value: number) => number): Converter<From, To> {\n return ((value: From) => transform(value) as To) as Converter<From, To>;\n}\n\n/**\n * Create a bidirectional converter between two branded number types.\n *\n * @param toTransform - Transform from A to B\n * @param fromTransform - Transform from B to A\n * @returns A BiConverter with both directions\n *\n * @example\n * ```ts\n * const celsiusFahrenheit = createBiConverter<Celsius, Fahrenheit>(\n * c => c * 9/5 + 32,\n * f => (f - 32) * 5/9\n * );\n *\n * celsiusFahrenheit.to(0 as Celsius); // 32 as Fahrenheit\n * celsiusFahrenheit.from(32 as Fahrenheit); // 0 as Celsius\n * ```\n */\nexport function createBiConverter<\n A extends SmartNumber<string>,\n B extends SmartNumber<string>,\n>(\n toTransform: (value: number) => number,\n fromTransform: (value: number) => number,\n): BiConverter<A, B> {\n return {\n to: createConverter<A, B>(toTransform),\n from: createConverter<B, A>(fromTransform),\n };\n}\n\n/**\n * Create a linear converter (multiply by factor).\n * Useful for unit conversions with simple ratios.\n *\n * @param factor - The multiplication factor (A * factor = B)\n * @returns A BiConverter using the linear relationship\n *\n * @example\n * ```ts\n * // 1 meter = 100 centimeters\n * const metersCentimeters = createLinearConverter<Meters, Centimeters>(100);\n *\n * metersCentimeters.to(2 as Meters); // 200 as Centimeters\n * metersCentimeters.from(50 as Centimeters); // 0.5 as Meters\n * ```\n */\nexport function createLinearConverter<\n A extends SmartNumber<string>,\n B extends SmartNumber<string>,\n>(factor: number): BiConverter<A, B> {\n return createBiConverter<A, B>(\n a => a * factor,\n b => b / factor,\n );\n}\n\n/**\n * Create a converter for string types with validation.\n *\n * @param validate - Optional validation function (throws on invalid input)\n * @returns A converter that casts strings to the target type\n *\n * @example\n * ```ts\n * type URL = SmartString<'URL'>;\n *\n * const toURL = createStringConverter<string, URL>((s) => {\n * if (!s.startsWith('http')) throw new Error('Invalid URL');\n * });\n *\n * const url: URL = toURL('https://example.com'); // ✅\n * const bad: URL = toURL('not-a-url'); // ❌ throws\n * ```\n */\nexport function createStringConverter<\n From extends string,\n To extends SmartString<string>,\n>(validate?: (value: From) => void): Converter<From, To> {\n return ((value: From) => {\n if (validate) validate(value);\n return value as unknown as To;\n }) as Converter<From, To>;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n CHAINING & COMPOSITION\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * Chain two converters together: A → B → C\n *\n * @example\n * ```ts\n * const turnsToRadians = chain(turnsToDegrees, degreesToRadians);\n * ```\n */\nexport function chain<A, B, C>(\n first: Converter<A, B>,\n second: Converter<B, C>,\n): Converter<A, C> {\n return ((value: A) => second(first(value))) as Converter<A, C>;\n}\n\n/**\n * Create an identity converter (no-op, for type coercion).\n *\n * @example\n * ```ts\n * const pixelsIdentity = identity<Pixels>();\n * ```\n */\nexport function identity<T>(): Converter<T, T> {\n return ((value: T) => value) as Converter<T, T>;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n CONVERSION REGISTRY (Optional Pattern)\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * A registry of converters for runtime lookup.\n * Useful when converter selection depends on runtime values.\n *\n * @example\n * ```ts\n * const angleConverters = new ConverterRegistry<Degrees>();\n * angleConverters.register('radians', degreesToRadians);\n * angleConverters.register('turns', degreesToTurns);\n *\n * const converted = angleConverters.convert(90 as Degrees, 'radians');\n * ```\n */\nexport class ConverterRegistry<From> {\n private converters = new Map<string, Converter<From, unknown>>();\n\n register<To>(name: string, converter: Converter<From, To>): this {\n this.converters.set(name, converter as Converter<From, unknown>);\n return this;\n }\n\n convert<To>(value: From, targetName: string): To {\n const converter = this.converters.get(targetName);\n if (!converter) {\n throw new Error(`No converter registered for target: ${targetName}`);\n }\n return converter(value) as To;\n }\n\n has(targetName: string): boolean {\n return this.converters.has(targetName);\n }\n}\n"],"names":["createConverter","transform","value","createBiConverter","toTransform","fromTransform","createLinearConverter","factor","a","b","createStringConverter","validate","chain","first","second","identity","ConverterRegistry","name","converter","targetName"],"mappings":"AA4DO,SAASA,EAGdC,GAA2D;AAC3D,UAAQ,CAACC,MAAgBD,EAAUC,CAAK;AAC1C;AAoBO,SAASC,EAIdC,GACAC,GACmB;AACnB,SAAO;AAAA,IACL,IAAIL,EAAsBI,CAAW;AAAA,IACrC,MAAMJ,EAAsBK,CAAa;AAAA,EAAA;AAE7C;AAkBO,SAASC,EAGdC,GAAmC;AACnC,SAAOJ;AAAA,IACL,OAAKK,IAAID;AAAA,IACT,OAAKE,IAAIF;AAAA,EAAA;AAEb;AAoBO,SAASG,EAGdC,GAAuD;AACvD,UAAQ,CAACT,OACHS,OAAmBT,CAAK,GACrBA;AAEX;AAcO,SAASU,EACdC,GACAC,GACiB;AACjB,UAAQ,CAACZ,MAAaY,EAAOD,EAAMX,CAAK,CAAC;AAC3C;AAUO,SAASa,IAA+B;AAC7C,UAAQ,CAACb,MAAaA;AACxB;AAmBO,MAAMc,EAAwB;AAAA,EAA9B,cAAA;AACL,SAAQ,iCAAiB,IAAA;AAAA,EAAsC;AAAA,EAE/D,SAAaC,GAAcC,GAAsC;AAC/D,gBAAK,WAAW,IAAID,GAAMC,CAAqC,GACxD;AAAA,EACT;AAAA,EAEA,QAAYhB,GAAaiB,GAAwB;AAC/C,UAAMD,IAAY,KAAK,WAAW,IAAIC,CAAU;AAChD,QAAI,CAACD;AACH,YAAM,IAAI,MAAM,uCAAuCC,CAAU,EAAE;AAErE,WAAOD,EAAUhB,CAAK;AAAA,EACxB;AAAA,EAEA,IAAIiB,GAA6B;AAC/B,WAAO,KAAK,WAAW,IAAIA,CAAU;AAAA,EACvC;AACF;"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=convert.test-d.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert.test-d.d.ts","sourceRoot":"","sources":["../src/convert.test-d.ts"],"names":[],"mappings":""}
package/dist/index.cjs.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=!1;exports.USE_PLAIN_PRIMITIVES=e;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./convert.cjs.js"),e=require("./units/index.cjs.js");function t(i,o,r){return Math.min(Math.max(i,o),r)}function l(i,o,r){const n=r-o;return((i-o)%n+n)%n+o}exports.ConverterRegistry=s.ConverterRegistry;exports.chain=s.chain;exports.createBiConverter=s.createBiConverter;exports.createConverter=s.createConverter;exports.createLinearConverter=s.createLinearConverter;exports.createStringConverter=s.createStringConverter;exports.identity=s.identity;exports.applyVelocity=e.applyVelocity;exports.celsiusToFahrenheit=e.celsiusToFahrenheit;exports.centimetersToInches=e.centimetersToInches;exports.centimetersToMeters=e.centimetersToMeters;exports.centimetersToMillimeters=e.centimetersToMillimeters;exports.clampAlpha=e.clampAlpha;exports.clampNormalized=e.clampNormalized;exports.clampPercentage=e.clampPercentage;exports.clampSignedNormalized=e.clampSignedNormalized;exports.degreesToRadians=e.degreesToRadians;exports.degreesToTurns=e.degreesToTurns;exports.emsToPixels=e.emsToPixels;exports.fahrenheitToCelsius=e.fahrenheitToCelsius;exports.hoursToMinutes=e.hoursToMinutes;exports.inchesToCentimeters=e.inchesToCentimeters;exports.inchesToPixels=e.inchesToPixels;exports.inchesToPoints=e.inchesToPoints;exports.metersToCentimeters=e.metersToCentimeters;exports.millimetersToCentimeters=e.millimetersToCentimeters;exports.millisecondsToSeconds=e.millisecondsToSeconds;exports.minutesToHours=e.minutesToHours;exports.minutesToSeconds=e.minutesToSeconds;exports.normalizeDegrees=e.normalizeDegrees;exports.normalizeRadians=e.normalizeRadians;exports.normalizeTurns=e.normalizeTurns;exports.normalizedProgressToPercent=e.normalizedProgressToPercent;exports.normalizedToPercentage=e.normalizedToPercentage;exports.percentToNormalizedProgress=e.percentToNormalizedProgress;exports.percentageToNormalized=e.percentageToNormalized;exports.pixelsToEms=e.pixelsToEms;exports.pixelsToInches=e.pixelsToInches;exports.pixelsToRems=e.pixelsToRems;exports.pixelsToVh=e.pixelsToVh;exports.pixelsToVw=e.pixelsToVw;exports.pointsToInches=e.pointsToInches;exports.radiansToDegrees=e.radiansToDegrees;exports.radiansToTurns=e.radiansToTurns;exports.remsToPixels=e.remsToPixels;exports.secondsToMilliseconds=e.secondsToMilliseconds;exports.secondsToMinutes=e.secondsToMinutes;exports.turnsToDegrees=e.turnsToDegrees;exports.turnsToRadians=e.turnsToRadians;exports.velocityFromValues=e.velocityFromValues;exports.velocityMillisecondsToSeconds=e.velocityMillisecondsToSeconds;exports.velocitySecondsToMilliseconds=e.velocitySecondsToMilliseconds;exports.vhToPixels=e.vhToPixels;exports.vwToPixels=e.vwToPixels;exports.clamp=t;exports.wrap=l;
2
2
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/SmartPrimitive.ts"],"sourcesContent":["/**\n * 🔧 FEATURE FLAG: Toggle smart primitive type checking\n * When false (default): SmartPrimitive types provide type safety\n * When true: All SmartNumber, SmartString, etc. become plain primitives\n *\n * Use cases:\n * - Performance testing (eliminate type overhead)\n * - Debugging type issues\n * - Gradual migration to/from smart primitives\n * - Bundle size optimization\n *\n * How to use:\n * 1. Change `false` to `true` below\n * 2. Your entire codebase now treats Pixels, URLs, etc. as plain primitives\n * 3. Cross-brand assignments that were errors become allowed\n * 4. All type extraction utilities become no-ops\n * 5. Change back to `false` to re-enable smart primitive type safety\n */\n\n// 🔧 FEATURE FLAG: Both runtime constant AND compile-time type\nexport const USE_PLAIN_PRIMITIVES = false as const; // 👈 Change to `true` for plain primitives, `false` for branded types\nexport type USE_PLAIN_PRIMITIVES_TYPE = typeof USE_PLAIN_PRIMITIVES;\n\n/**\n * Clean type extraction using the brand pattern\n * Respects the USE_PLAIN_PRIMITIVES flag.\n */\ntype BaseOf<T> = USE_PLAIN_PRIMITIVES_TYPE extends true\n ? T // 🚫 Smart types disabled: type is already the base\n : T extends number & { readonly __brand?: unknown }\n ? number\n : T extends string & { readonly __brand?: unknown }\n ? string\n : T extends boolean & { readonly __brand?: unknown }\n ? boolean\n : T; // 🎯 Extract base type or return as-is\n\n/**\n * Generic smart primitive type that provides **opt-in type safety** while staying flexible.\n *\n * **How it works:**\n * - **Accepts plain values**: You can use regular numbers, strings, etc. directly\n * - **Prevents cross-domain mixing**: TypeScript stops you from using pixels where milliseconds are expected\n * - **Zero runtime cost**: No performance impact - it's just TypeScript magic\n * - **Easy to disable**: Toggle `USE_PLAIN_PRIMITIVES` to turn off all smart typing\n *\n * **Example:**\n * ```ts\n * type Pixels = SmartPrimitive<number, 'Pixels'>;\n * type Milliseconds = SmartPrimitive<number, 'Milliseconds'>;\n *\n * let width: Pixels = 300; // Plain number works\n * let delay: Milliseconds = 500; // ✅ Plain number works\n * let oops: Pixels = delay; // ❌ TypeScript error - caught the mistake!\n * ```\n *\n * This prevents bugs like accidentally using milliseconds where pixels are expected,\n * while keeping your code simple and readable.\n */\nexport type SmartPrimitive<\n Base extends string | number | boolean | bigint | symbol,\n BrandName extends string,\n> = USE_PLAIN_PRIMITIVES_TYPE extends true\n ? Base\n : Base & { readonly __brand?: BrandName };\n\n/**\n * A smart number type for domain-specific numeric values like pixels, milliseconds, etc.\n *\n * **Why use this?** Prevents common bugs like mixing up different kinds of numbers:\n * - Using milliseconds where pixels are expected\n * - Passing a width value to a duration parameter\n * - Confusing degrees with radians\n *\n * **How it works:**\n * - Works with plain numbers: `let width: Pixels = 300`\n * - Catches domain mix-ups: `let width: Pixels = duration` → TypeScript error\n * - Zero runtime cost: Just TypeScript checking, no JavaScript overhead\n *\n * Built on `SmartPrimitive` - respects the USE_PLAIN_PRIMITIVES flag for easy toggling.\n *\n * **Example:**\n * ```ts\n * type Pixels = SmartNumber<'Pixels'>;\n * type Milliseconds = SmartNumber<'Milliseconds'>;\n *\n * let width: Pixels = 300; // works\n * let delay: Milliseconds = 500; // ✅ works\n * let badAssign: Pixels = delay; // type error - caught the mistake!\n * ```\n *\n * When USE_PLAIN_PRIMITIVES = false (default):\n * - Full smart number system with type safety between different units\n * - Plain numbers accepted seamlessly\n * - Clean tooltip display\n *\n * When USE_PLAIN_PRIMITIVES = true:\n * - All smart number types collapse to plain `number`\n * - Zero runtime overhead, maximum performance\n *\n * Usage remains the same regardless of flag state:\n * ```ts\n * let distance: Pixels = 300; // always works\n * let branded: Pixels = 300 as Pixels; // ✅ always works\n * ```\n */\nexport type SmartNumber<BrandName extends string> = SmartPrimitive<\n number,\n BrandName\n>;\n\n/**\n * A smart string type that accepts plain strings but maintains type identity.\n * Perfect for things like URLs, CSS selectors, or other domain-specific strings.\n *\n * Usage:\n * ```ts\n * type URL = SmartString<'URL'>;\n * type CSSSelector = SmartString<'CSSSelector'>;\n *\n * let url: URL = \"https://example.com\"; // ✅ works\n * let selector: CSSSelector = \".my-class\"; // ✅ works\n * let badAssign: URL = selector; // type error\n * ```\n */\nexport type SmartString<BrandName extends string> = SmartPrimitive<\n string,\n BrandName\n>;\n\n/**\n * A smart boolean type that accepts plain booleans but maintains type identity.\n * Useful for domain-specific flags or state indicators.\n *\n * Usage:\n * ```ts\n * type IsVisible = SmartBoolean<'IsVisible'>;\n * type IsEnabled = SmartBoolean<'IsEnabled'>;\n *\n * let visible: IsVisible = true; // works\n * let enabled: IsEnabled = false; // ✅ works\n * let badAssign: IsVisible = enabled; // type error\n * ```\n */\nexport type SmartBoolean<BrandName extends string> = SmartPrimitive<\n boolean,\n BrandName\n>;\n\n/**\n * Simplified Unbrand using the generic brand pattern.\n * Also respects the USE_PLAIN_PRIMITIVES flag.\n *\n * When USE_PLAIN_PRIMITIVES = true: This becomes a no-op (types pass through unchanged)\n * When USE_PLAIN_PRIMITIVES = false: Full unbranding to base types\n */\nexport type Unbrand<T> = USE_PLAIN_PRIMITIVES_TYPE extends true\n ? T // 🚫 Smart types disabled: types pass through unchanged\n : // 🎯 Smart types enabled: extract base types and recurse\n // 1️⃣ If T has a brand, extract the base type (could be number, string, etc.)\n T extends number & { readonly __brand?: unknown }\n ? number\n : T extends string & { readonly __brand?: unknown }\n ? string\n : T extends boolean & { readonly __brand?: unknown }\n ? boolean\n : // 2️⃣ If T is an object (e.g. your params bag), recurse each field\n T extends Record<string, unknown>\n ? { [K in keyof T]: Unbrand<T[K]> }\n : // 3️⃣ Everything else stays the same\n T;\n\n/**\n * Given any function type F, produce a new function type whose\n * arguments have been passed through Unbrand<…>, and whose return\n * type you can also choose to unbrand (or leave alone).\n */\nexport type UnbrandFn<F, UnbrandReturn extends boolean = false> = F extends (\n ...args: infer A\n) => infer R\n ? A extends readonly unknown[]\n ? (\n ...args: { [K in keyof A]: Unbrand<A[K]> }\n ) => UnbrandReturn extends true ? Unbrand<R> : R\n : never\n : never;\n\n// Export the BaseOf utility for advanced users\nexport type { BaseOf };\n"],"names":["USE_PLAIN_PRIMITIVES"],"mappings":"gFAoBO,MAAMA,EAAuB"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/trait-utils.ts"],"sourcesContent":["/**\n * 🏷️ Trait System Utilities\n *\n * Core trait interfaces and wrapper types for the orthogonal trait system.\n * These are used across all unit type definitions to provide composable,\n * flag-aware type annotations.\n */\n\nimport type { UsePlainPrimitives } from './SmartPrimitive';\n\n/* ═══════════════════════════════════════════════════════════════\n CORE TRAIT INTERFACES (Internal)\n ═══════════════════════════════════════════════════════════════ */\n\ninterface Unit<U extends string> {\n readonly _unit?: U;\n}\n\ninterface Range<Min extends number, Max extends number> {\n readonly _range?: { readonly min: Min; readonly max: Max };\n}\n\ninterface Clamped {\n readonly _clamped?: true;\n}\n\ninterface Periodic {\n readonly _periodic?: true;\n}\n\ninterface Kind<K extends string> {\n readonly _kind?: K;\n}\n\ninterface Integer {\n readonly _integer?: true;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n EXPORTED TRAIT WRAPPERS (Flag-Aware)\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * Marks a number with measurement units.\n */\nexport type WithUnit<U extends string> = number &\n (UsePlainPrimitives extends true ? {} : Unit<U>);\n\n/**\n * Marks a number as having a reference range [Min, Max].\n */\nexport type WithRange<Min extends number, Max extends number> = number &\n (UsePlainPrimitives extends true ? {} : Range<Min, Max>);\n\n/**\n * Marks a number as being clamped (constrained) to its range.\n */\nexport type WithClamped = number &\n (UsePlainPrimitives extends true ? {} : Clamped);\n\n/**\n * Marks a number as periodic (wrapping around at boundaries).\n */\nexport type WithPeriodic = number &\n (UsePlainPrimitives extends true ? {} : Periodic);\n\n/**\n * Groups related unit types under a common archetype/kind.\n */\nexport type WithKind<K extends string> = number &\n (UsePlainPrimitives extends true ? {} : Kind<K>);\n\n/**\n * Marks a number as an integer (whole number).\n */\nexport type WithInteger = number &\n (UsePlainPrimitives extends true ? {} : Integer);\n\n/* ═══════════════════════════════════════════════════════════════\n TYPE EXTRACTION UTILITIES\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * Extract units from a type.\n * @returns The unit string, or never if type has no Units trait.\n */\nexport type UnitOf<T> = T extends Unit<infer U> ? U : never;\n\n/**\n * Extract range from a type as a tuple [Min, Max].\n * @returns [Min, Max] tuple, or never if type has no Range trait.\n */\nexport type RangeOf<T> =\n T extends Range<infer Min, infer Max> ? readonly [Min, Max] : never;\n\n/**\n * Extract min value from range trait.\n * @returns Min value, or never if type has no Range trait.\n */\nexport type MinOf<T> = T extends Range<infer Min, infer _Max> ? Min : never;\n\n/**\n * Extract max value from range trait.\n * @returns Max value, or never if type has no Range trait.\n */\nexport type MaxOf<T> = T extends Range<infer _Min, infer Max> ? Max : never;\n\n/**\n * Check if a type has the Clamped trait.\n * @returns true if clamped, false if not.\n */\nexport type IsClamped<T> = T extends Clamped ? true : false;\n\n/**\n * Check if a type has the Periodic trait.\n * @returns true if periodic, false if not.\n */\nexport type IsPeriodic<T> = T extends Periodic ? true : false;\n\n/**\n * Extract kind/archetype from a type.\n * @returns The kind string, or never if type has no Kind trait.\n */\nexport type KindOf<T> = T extends Kind<infer K> ? K : never;\n\n/* ═══════════════════════════════════════════════════════════════\n TRAIT MODIFICATION UTILITIES\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * Remove the Clamped trait from a type (return to unclamped).\n */\nexport type WithoutClamped<T> = T extends Clamped ? Omit<T, '_clamped'> : T;\n\n/**\n * Remove the Periodic trait from a type.\n */\nexport type WithoutPeriodic<T> = T extends Periodic ? Omit<T, '_periodic'> : T;\n\n/**\n * Change the units of a type (unit conversion).\n */\nexport type ChangeUnits<T, U extends string> = Omit<T, '_unit'> & WithUnit<U>;\n\n/**\n * Change the range of a type.\n */\nexport type ChangeRange<T, Min extends number, Max extends number> = Omit<\n T,\n '_range'\n> &\n WithRange<Min, Max>;\n\n/* ═══════════════════════════════════════════════════════════════\n RUNTIME UTILITIES\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * Clamp a value to specified bounds, preserve orthogonal traits, and mark as clamped.\n */\nexport function clamp<T extends number, Min extends number, Max extends number>(\n value: T,\n min: Min,\n max: Max,\n): WithRange<Min, Max> & WithClamped {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Wrap a value to specified bounds, preserve orthogonal traits, and mark as periodic.\n */\nexport function wrap<T, Min extends number, Max extends number>(\n value: T,\n min: Min,\n max: Max,\n): Omit<T, '_range' | '_periodic'> & WithRange<Min, Max> & WithPeriodic {\n const range = max - min;\n const normalized = ((((value as any) - min) % range) + range) % range;\n return (normalized + min) as any;\n}\n"],"names":["clamp","value","min","max","wrap","range"],"mappings":"sJAgKO,SAASA,EACdC,EACAC,EACAC,EACmC,CACnC,OAAO,KAAK,IAAI,KAAK,IAAIF,EAAOC,CAAG,EAAGC,CAAG,CAC3C,CAKO,SAASC,EACdH,EACAC,EACAC,EACsE,CACtE,MAAME,EAAQF,EAAMD,EAEpB,QADuBD,EAAgBC,GAAOG,EAASA,GAASA,EAC3CH,CACvB"}
package/dist/index.d.ts CHANGED
@@ -17,6 +17,11 @@
17
17
  * let oops: Pixels = delay; // ❌ type error - caught!
18
18
  * ```
19
19
  */
20
- export type { SmartPrimitive, SmartNumber, SmartString, SmartBoolean, Unbrand, UnbrandFn, USE_PLAIN_PRIMITIVES_TYPE, BaseOf, } from './SmartPrimitive';
21
- export { USE_PLAIN_PRIMITIVES } from './SmartPrimitive';
20
+ export type { SmartPrimitive, SmartPrimitiveConfig, SmartNumber, SmartString, SmartBoolean, SmartBigInt, SmartSymbol, Unbrand, UnbrandFn, UsePlainPrimitives, } from './SmartPrimitive';
21
+ export type { Converter, BiConverter } from './convert';
22
+ export { createConverter, createBiConverter, createLinearConverter, createStringConverter, chain, identity, ConverterRegistry, } from './convert';
23
+ export * from './units';
24
+ export type { WithUnit, WithRange, WithClamped, WithPeriodic, WithKind, WithInteger, UnitOf, RangeOf, MinOf, MaxOf, IsClamped, IsPeriodic, KindOf, WithoutClamped, WithoutPeriodic, ChangeUnits, ChangeRange, } from './trait-utils';
25
+ export { clamp, wrap } from './trait-utils';
26
+ export type { CSSEasing } from './strings/css';
22
27
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,YAAY,EACV,cAAc,EACd,WAAW,EACX,WAAW,EACX,YAAY,EACZ,OAAO,EACP,SAAS,EACT,yBAAyB,EACzB,MAAM,GACP,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,WAAW,EACX,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,EACX,OAAO,EACP,SAAS,EACT,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,EACL,QAAQ,EACR,iBAAiB,GAClB,MAAM,WAAW,CAAC;AAInB,cAAc,SAAS,CAAC;AAGxB,YAAY,EACV,QAAQ,EACR,SAAS,EACT,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,MAAM,EACN,OAAO,EACP,KAAK,EACL,KAAK,EACL,SAAS,EACT,UAAU,EACV,MAAM,EACN,cAAc,EACd,eAAe,EACf,WAAW,EACX,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAG5C,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC"}