@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
package/dist/index.es.js CHANGED
@@ -1,5 +1,68 @@
1
- const I = !1;
1
+ import { ConverterRegistry as c, chain as T, createBiConverter as m, createConverter as d, createLinearConverter as p, createStringConverter as u, identity as h } from "./convert.es.js";
2
+ import { applyVelocity as x, celsiusToFahrenheit as z, centimetersToInches as P, centimetersToMeters as v, centimetersToMillimeters as C, clampAlpha as M, clampNormalized as y, clampPercentage as S, clampSignedNormalized as f, degreesToRadians as R, degreesToTurns as N, emsToPixels as V, fahrenheitToCelsius as w, hoursToMinutes as D, inchesToCentimeters as I, inchesToPixels as F, inchesToPoints as A, metersToCentimeters as B, millimetersToCentimeters as E, millisecondsToSeconds as H, minutesToHours as L, minutesToSeconds as b, normalizeDegrees as j, normalizeRadians as k, normalizeTurns as q, normalizedProgressToPercent as G, normalizedToPercentage as J, percentToNormalizedProgress as K, percentageToNormalized as O, pixelsToEms as Q, pixelsToInches as U, pixelsToRems as W, pixelsToVh as X, pixelsToVw as Y, pointsToInches as Z, radiansToDegrees as _, radiansToTurns as $, remsToPixels as ee, secondsToMilliseconds as oe, secondsToMinutes as se, turnsToDegrees as re, turnsToRadians as ie, velocityFromValues as ne, velocityMillisecondsToSeconds as te, velocitySecondsToMilliseconds as le, vhToPixels as ae, vwToPixels as ce } from "./units/index.es.js";
3
+ function n(o, e, s) {
4
+ return Math.min(Math.max(o, e), s);
5
+ }
6
+ function t(o, e, s) {
7
+ const r = s - e;
8
+ return ((o - e) % r + r) % r + e;
9
+ }
2
10
  export {
3
- I as USE_PLAIN_PRIMITIVES
11
+ c as ConverterRegistry,
12
+ x as applyVelocity,
13
+ z as celsiusToFahrenheit,
14
+ P as centimetersToInches,
15
+ v as centimetersToMeters,
16
+ C as centimetersToMillimeters,
17
+ T as chain,
18
+ n as clamp,
19
+ M as clampAlpha,
20
+ y as clampNormalized,
21
+ S as clampPercentage,
22
+ f as clampSignedNormalized,
23
+ m as createBiConverter,
24
+ d as createConverter,
25
+ p as createLinearConverter,
26
+ u as createStringConverter,
27
+ R as degreesToRadians,
28
+ N as degreesToTurns,
29
+ V as emsToPixels,
30
+ w as fahrenheitToCelsius,
31
+ D as hoursToMinutes,
32
+ h as identity,
33
+ I as inchesToCentimeters,
34
+ F as inchesToPixels,
35
+ A as inchesToPoints,
36
+ B as metersToCentimeters,
37
+ E as millimetersToCentimeters,
38
+ H as millisecondsToSeconds,
39
+ L as minutesToHours,
40
+ b as minutesToSeconds,
41
+ j as normalizeDegrees,
42
+ k as normalizeRadians,
43
+ q as normalizeTurns,
44
+ G as normalizedProgressToPercent,
45
+ J as normalizedToPercentage,
46
+ K as percentToNormalizedProgress,
47
+ O as percentageToNormalized,
48
+ Q as pixelsToEms,
49
+ U as pixelsToInches,
50
+ W as pixelsToRems,
51
+ X as pixelsToVh,
52
+ Y as pixelsToVw,
53
+ Z as pointsToInches,
54
+ _ as radiansToDegrees,
55
+ $ as radiansToTurns,
56
+ ee as remsToPixels,
57
+ oe as secondsToMilliseconds,
58
+ se as secondsToMinutes,
59
+ re as turnsToDegrees,
60
+ ie as turnsToRadians,
61
+ ne as velocityFromValues,
62
+ te as velocityMillisecondsToSeconds,
63
+ le as velocitySecondsToMilliseconds,
64
+ ae as vhToPixels,
65
+ ce as vwToPixels,
66
+ t as wrap
4
67
  };
5
68
  //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.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":"AAoBO,MAAMA,IAAuB;"}
1
+ {"version":3,"file":"index.es.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":";;AAgKO,SAASA,EACdC,GACAC,GACAC,GACmC;AACnC,SAAO,KAAK,IAAI,KAAK,IAAIF,GAAOC,CAAG,GAAGC,CAAG;AAC3C;AAKO,SAASC,EACdH,GACAC,GACAC,GACsE;AACtE,QAAME,IAAQF,IAAMD;AAEpB,WADuBD,IAAgBC,KAAOG,IAASA,KAASA,IAC3CH;AACvB;"}
@@ -0,0 +1,143 @@
1
+ import { SmartString } from '../SmartPrimitive';
2
+ /**
3
+ * A CSS selector string
4
+ *
5
+ * @example
6
+ * const btnSelector: CSSSelector = ".nav .button.primary";
7
+ */
8
+ export type CSSSelector = SmartString<'CSSSelector'>;
9
+ /**
10
+ * An XPath expression
11
+ *
12
+ * @example
13
+ * const firstLink: XPath = "//div[@id='main']//a[1]";
14
+ */
15
+ export type XPath = SmartString<'XPath'>;
16
+ /**
17
+ * An HTML element ID
18
+ *
19
+ * @example
20
+ * const mainId: HTMLElementID = "main-content";
21
+ */
22
+ export type HTMLElementID = SmartString<'HTMLElementID'>;
23
+ /**
24
+ * A CSS class name
25
+ *
26
+ * @example
27
+ * const primaryClass: CSSClassName = "button-primary";
28
+ */
29
+ export type CSSClassName = SmartString<'CSSClassName'>;
30
+ /**
31
+ * An HTML attribute name
32
+ *
33
+ * @example
34
+ * const trackingAttr: HTMLAttribute = "data-tracking-id";
35
+ */
36
+ export type HTMLAttribute = SmartString<'HTMLAttribute'>;
37
+ /**
38
+ * A CSS color value (hex, rgb, hsl, etc.)
39
+ *
40
+ * @example
41
+ * const accent: CSSColor = "#ffcc00";
42
+ * const overlay: CSSColor = "rgba(0, 0, 0, 0.5)";
43
+ */
44
+ export type CSSColor = SmartString<'CSSColor'>;
45
+ /**
46
+ * CSS length units
47
+ *
48
+ * Absolute: px, cm, mm, in, pt, pc
49
+ * Relative: em, rem, ex, ch, %
50
+ * Viewport: vw, vh, vmin, vmax
51
+ */
52
+ export type CSSLengthUnit = 'px' | 'em' | 'rem' | '%' | 'vw' | 'vh' | 'vmin' | 'vmax' | 'ch' | 'ex' | 'cm' | 'mm' | 'in' | 'pt' | 'pc';
53
+ /**
54
+ * CSS angle units
55
+ */
56
+ export type CSSAngleUnit = 'deg' | 'rad' | 'grad' | 'turn';
57
+ /**
58
+ * CSS time units
59
+ */
60
+ export type CSSTimeUnit = 'ms' | 's';
61
+ /**
62
+ * All CSS unit types
63
+ */
64
+ export type CSSUnit = CSSLengthUnit | CSSAngleUnit | CSSTimeUnit;
65
+ /**
66
+ * A CSS value with a number and unit (e.g., "16px", "1.5em")
67
+ *
68
+ * @example
69
+ * const width: CSSValue<'px'> = "16px";
70
+ * const fontSize: CSSValue<'em'> = "1.5em";
71
+ * const duration: CSSValue<'ms'> = "300ms";
72
+ */
73
+ export type CSSUnitValue<U extends CSSUnit = CSSUnit> = `${number}${U}`;
74
+ /**
75
+ * A CSS length value with unit
76
+ *
77
+ * @example
78
+ * const width: CSSLength = "16px";
79
+ * const padding: CSSLength = "2rem";
80
+ */
81
+ export type CSSLength = CSSUnitValue<CSSLengthUnit>;
82
+ /**
83
+ * A CSS angle value with unit
84
+ *
85
+ * @example
86
+ * const rotation: CSSAngle = "45deg";
87
+ * const hueRotation: CSSAngle = "0.5turn";
88
+ */
89
+ export type CSSAngle = CSSUnitValue<CSSAngleUnit>;
90
+ /**
91
+ * A CSS time value with unit
92
+ *
93
+ * @example
94
+ * const duration: CSSTime = "300ms";
95
+ * const delay: CSSTime = "0.5s";
96
+ */
97
+ export type CSSTime = CSSUnitValue<CSSTimeUnit>;
98
+ /**
99
+ * A percentage string with `%` suffix (e.g., "30%", "100%")
100
+ *
101
+ * Used for CSS percentage values and formatted display strings.
102
+ *
103
+ * @example
104
+ * const opacity: PercentageString = "50%";
105
+ * const progress: PercentageString = "100%";
106
+ */
107
+ export type PercentageString = `${number}%`;
108
+ /**
109
+ * A CSS easing function string
110
+ *
111
+ * @example
112
+ * const easeInOut: CSSEasing = "ease-in-out";
113
+ * const easeInOutBezier: CSSEasing = "cubic-bezier(0.42, 0, 0.58, 1)";
114
+ * const easeBounce: CSSEasing = "linear(0 0%, 0.01 1.25%, 0.04 5%, ...)";
115
+ */
116
+ export type CSSEasing = SmartString<'CSSEasing'>;
117
+ /**
118
+ * A CSS custom property name
119
+ *
120
+ * Should start with two hyphens (--)
121
+ *
122
+ * @example
123
+ * const themeProp: CSSCustomProperty = "--theme-color";
124
+ * const spacing: CSSCustomProperty = "--spacing-lg";
125
+ */
126
+ export type CSSCustomProperty = SmartString<'CSSCustomProperty'>;
127
+ /**
128
+ * CSS cursor property values
129
+ *
130
+ * Standard cursor types for interactive elements. Provides autocomplete and
131
+ * type safety for cursor assignments. Includes a fallback for custom cursor
132
+ * URLs like `url("cursor.png"), auto`.
133
+ *
134
+ * @example
135
+ * const dragCursor: CSSCursor = "move";
136
+ * const resizeCursor: CSSCursor = "ns-resize";
137
+ * element.style.cursor = dragCursor;
138
+ *
139
+ * // Custom cursor with fallback
140
+ * const customCursor: CSSCursor = 'url("cursor.png"), pointer';
141
+ */
142
+ export type CSSCursor = 'default' | 'pointer' | 'wait' | 'text' | 'help' | 'move' | 'grab' | 'grabbing' | 'copy' | 'alias' | 'n-resize' | 's-resize' | 'e-resize' | 'w-resize' | 'ne-resize' | 'nw-resize' | 'se-resize' | 'sw-resize' | 'ns-resize' | 'ew-resize' | 'nwse-resize' | 'nesw-resize' | 'col-resize' | 'row-resize' | 'crosshair' | 'cell' | 'zoom-in' | 'zoom-out' | 'not-allowed' | 'no-drop' | 'progress' | 'context-menu' | 'vertical-text' | 'all-scroll' | 'none' | 'auto' | 'inherit' | 'initial' | 'unset' | (string & {});
143
+ //# sourceMappingURL=css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../../src/strings/css.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMhD;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;AAMzC;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,eAAe,CAAC,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,eAAe,CAAC,CAAC;AAMzD;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;AAE/C;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GACrB,IAAI,GACJ,IAAI,GACJ,KAAK,GACL,GAAG,GACH,IAAI,GACJ,IAAI,GACJ,MAAM,GACN,MAAM,GACN,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,CAAC;AAET;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,GAAG,CAAC;AAErC;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,aAAa,GAAG,YAAY,GAAG,WAAW,CAAC;AAEjE;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,IAAI,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC;AAExE;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;AAElD;;;;;;GAMG;AACH,MAAM,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;AAEhD;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG,GAAG,MAAM,GAAG,CAAC;AAE5C;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;AAEjD;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,mBAAmB,CAAC,CAAC;AAEjE;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,SAAS,GAEjB,SAAS,GACT,SAAS,GACT,MAAM,GACN,MAAM,GACN,MAAM,GAEN,MAAM,GACN,MAAM,GACN,UAAU,GACV,MAAM,GACN,OAAO,GAEP,UAAU,GACV,UAAU,GACV,UAAU,GACV,UAAU,GAEV,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GAEX,WAAW,GACX,WAAW,GACX,aAAa,GACb,aAAa,GAEb,YAAY,GACZ,YAAY,GAEZ,WAAW,GACX,MAAM,GACN,SAAS,GACT,UAAU,GACV,aAAa,GACb,SAAS,GACT,UAAU,GACV,cAAc,GACd,eAAe,GACf,YAAY,GAEZ,MAAM,GACN,MAAM,GACN,SAAS,GACT,SAAS,GACT,OAAO,GAEP,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC"}
@@ -0,0 +1,140 @@
1
+ import { SmartString } from '../SmartPrimitive';
2
+ /**
3
+ * A JSON-formatted string
4
+ *
5
+ * @example
6
+ * const config: JSONString = '{"name":"app","version":"1.0"}';
7
+ */
8
+ export type JSONString = SmartString<'JSONString'>;
9
+ /**
10
+ * An XML-formatted string
11
+ *
12
+ * @example
13
+ * const doc: XMLString = '<?xml version="1.0"?><root><item>data</item></root>';
14
+ */
15
+ export type XMLString = SmartString<'XMLString'>;
16
+ /**
17
+ * A YAML-formatted string
18
+ *
19
+ * @example
20
+ * const config: YAMLString = 'name: app\nversion: 1.0\nitems:\n - one\n - two';
21
+ */
22
+ export type YAMLString = SmartString<'YAMLString'>;
23
+ /**
24
+ * A CSV-formatted string
25
+ *
26
+ * @example
27
+ * const data: CSVString = 'name,age,city\nAlice,30,NYC\nBob,25,LA';
28
+ */
29
+ export type CSVString = SmartString<'CSVString'>;
30
+ /**
31
+ * A Base64-encoded string
32
+ *
33
+ * @example
34
+ * const encoded: Base64String = 'SGVsbG8gV29ybGQ=';
35
+ */
36
+ export type Base64String = SmartString<'Base64String'>;
37
+ /**
38
+ * A UUID string
39
+ *
40
+ * @example
41
+ * const id: UUID = '550e8400-e29b-41d4-a716-446655440000';
42
+ */
43
+ export type UUID = SmartString<'UUID'>;
44
+ /**
45
+ * A ULID string
46
+ *
47
+ * @example
48
+ * const id: ULID = '01ARZ3NDEKTSV4RRFFQ69G5FAV';
49
+ */
50
+ export type ULID = SmartString<'ULID'>;
51
+ /**
52
+ * A nanoid string
53
+ *
54
+ * @example
55
+ * const id: NanoID = 'V1StGXR_Z5j3eK6b';
56
+ */
57
+ export type NanoID = SmartString<'NanoID'>;
58
+ /**
59
+ * A slug string (URL-safe identifier)
60
+ *
61
+ * @example
62
+ * const urlPath: Slug = 'my-awesome-article';
63
+ */
64
+ export type Slug = SmartString<'Slug'>;
65
+ /**
66
+ * An email address
67
+ *
68
+ * @example
69
+ * const contact: EmailAddress = 'user@example.com';
70
+ */
71
+ export type EmailAddress = SmartString<'EmailAddress'>;
72
+ /**
73
+ * A phone number
74
+ *
75
+ * @example
76
+ * const phone: PhoneNumber = '+1-555-123-4567';
77
+ */
78
+ export type PhoneNumber = SmartString<'PhoneNumber'>;
79
+ /**
80
+ * An IP address (v4 or v6)
81
+ *
82
+ * @example
83
+ * const ipv4: IPAddress = '192.168.1.1';
84
+ * const ipv6: IPAddress = '2001:0db8:85a3::8a2e:0370:7334';
85
+ */
86
+ export type IPAddress = SmartString<'IPAddress'>;
87
+ /**
88
+ * A hostname
89
+ *
90
+ * @example
91
+ * const host: Hostname = 'example.com';
92
+ * const subdomain: Hostname = 'api.example.com';
93
+ */
94
+ export type Hostname = SmartString<'Hostname'>;
95
+ /**
96
+ * An ISO 8601 date string
97
+ *
98
+ * @example
99
+ * const date: ISODateString = '2024-12-21';
100
+ */
101
+ export type ISODateString = SmartString<'ISODateString'>;
102
+ /**
103
+ * An ISO 8601 datetime string
104
+ *
105
+ * @example
106
+ * const datetime: ISODateTimeString = '2024-12-21T15:30:45Z';
107
+ */
108
+ export type ISODateTimeString = SmartString<'ISODateTimeString'>;
109
+ /**
110
+ * A time string (HH:MM:SS)
111
+ *
112
+ * @example
113
+ * const time: TimeString = '15:30:45';
114
+ */
115
+ export type TimeString = SmartString<'TimeString'>;
116
+ /**
117
+ * A file path
118
+ *
119
+ * @example
120
+ * const path: FilePath = '/home/user/documents/file.txt';
121
+ * const winPath: FilePath = 'C:\\Users\\user\\Documents\\file.txt';
122
+ */
123
+ export type FilePath = SmartString<'FilePath'>;
124
+ /**
125
+ * A directory path
126
+ *
127
+ * @example
128
+ * const dir: DirectoryPath = '/home/user/documents';
129
+ * const winDir: DirectoryPath = 'C:\\Users\\user\\Documents';
130
+ */
131
+ export type DirectoryPath = SmartString<'DirectoryPath'>;
132
+ /**
133
+ * A file extension (including dot)
134
+ *
135
+ * @example
136
+ * const txtExt: FileExtension = '.txt';
137
+ * const jsExt: FileExtension = '.js';
138
+ */
139
+ export type FileExtension = SmartString<'FileExtension'>;
140
+ //# sourceMappingURL=data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../src/strings/data.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMhD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;AAMvD;;;;;GAKG;AACH,MAAM,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAEvC;;;;;GAKG;AACH,MAAM,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAEvC;;;;;GAKG;AACH,MAAM,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;AAE3C;;;;;GAKG;AACH,MAAM,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAMvC;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;AAM/C;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,eAAe,CAAC,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,mBAAmB,CAAC,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;AAMnD;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;AAE/C;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,eAAe,CAAC,CAAC;AAEzD;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,eAAe,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 📝 Strings Index
3
+ *
4
+ * Re-exports all SmartString types and constructors from category modules.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { URL, CSSSelector, UUID, EmailAddress } from '@penner/smart-primitive/strings';
9
+ * ```
10
+ */
11
+ export * from './web';
12
+ export * from './css';
13
+ export * from './data';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/strings/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC"}
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=index.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.es.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ import { SmartString } from '../SmartPrimitive';
2
+ /**
3
+ * An absolute URL with protocol (subtype of URL)
4
+ *
5
+ * Must include a protocol (http://, https://, etc.)
6
+ *
7
+ * @example
8
+ * const apiEndpoint: AbsoluteURL = "https://api.example.com/v1/users";
9
+ * const fileLink: AbsoluteURL = "file:///path/to/file.html";
10
+ */
11
+ export type AbsoluteURL = SmartString<'AbsoluteURL'>;
12
+ /**
13
+ * A relative URL path (subtype of URL)
14
+ *
15
+ * Path-only URL without protocol. Can start with / (root-relative) or not (relative).
16
+ *
17
+ * @example
18
+ * const aboutPath: RelativeURL = "/about/team"; // root-relative
19
+ * const nested: RelativeURL = "./components/button"; // relative
20
+ * const parent: RelativeURL = "../assets/image.png"; // parent-relative
21
+ */
22
+ export type RelativeURL = SmartString<'RelativeURL'>;
23
+ /**
24
+ * A URL string
25
+ *
26
+ * @example
27
+ * const homepage: URL = "https://example.com";
28
+ */
29
+ export type URL = AbsoluteURL | RelativeURL;
30
+ /**
31
+ * A data URL (base64 encoded)
32
+ *
33
+ * @example
34
+ * const imageData: DataURL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...";
35
+ */
36
+ export type DataURL = SmartString<'DataURL'>;
37
+ /**
38
+ * An HTTP method (GET, POST, PUT, DELETE, PATCH, etc.)
39
+ *
40
+ * @example
41
+ * const getMethod: HTTPMethod = "GET";
42
+ * const postMethod: HTTPMethod = "POST";
43
+ * const deleteMethod: HTTPMethod = "DELETE";
44
+ */
45
+ export type HTTPMethod = SmartString<'HTTPMethod'>;
46
+ /**
47
+ * A MIME type (media type)
48
+ *
49
+ * @example
50
+ * const jsonType: MIMEType = "application/json";
51
+ * const htmlType: MIMEType = "text/html";
52
+ * const imageType: MIMEType = "image/png";
53
+ */
54
+ export type MIMEType = SmartString<'MIMEType'>;
55
+ //# sourceMappingURL=web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/strings/web.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMhD;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC;AAErD;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,GAAG,GAAG,WAAW,GAAG,WAAW,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;AAM7C;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC"}
@@ -0,0 +1,107 @@
1
+ import { UsePlainPrimitives } from './SmartPrimitive';
2
+ interface Unit<U extends string> {
3
+ readonly _unit?: U;
4
+ }
5
+ interface Range<Min extends number, Max extends number> {
6
+ readonly _range?: {
7
+ readonly min: Min;
8
+ readonly max: Max;
9
+ };
10
+ }
11
+ interface Clamped {
12
+ readonly _clamped?: true;
13
+ }
14
+ interface Periodic {
15
+ readonly _periodic?: true;
16
+ }
17
+ interface Kind<K extends string> {
18
+ readonly _kind?: K;
19
+ }
20
+ interface Integer {
21
+ readonly _integer?: true;
22
+ }
23
+ /**
24
+ * Marks a number with measurement units.
25
+ */
26
+ export type WithUnit<U extends string> = number & (UsePlainPrimitives extends true ? {} : Unit<U>);
27
+ /**
28
+ * Marks a number as having a reference range [Min, Max].
29
+ */
30
+ export type WithRange<Min extends number, Max extends number> = number & (UsePlainPrimitives extends true ? {} : Range<Min, Max>);
31
+ /**
32
+ * Marks a number as being clamped (constrained) to its range.
33
+ */
34
+ export type WithClamped = number & (UsePlainPrimitives extends true ? {} : Clamped);
35
+ /**
36
+ * Marks a number as periodic (wrapping around at boundaries).
37
+ */
38
+ export type WithPeriodic = number & (UsePlainPrimitives extends true ? {} : Periodic);
39
+ /**
40
+ * Groups related unit types under a common archetype/kind.
41
+ */
42
+ export type WithKind<K extends string> = number & (UsePlainPrimitives extends true ? {} : Kind<K>);
43
+ /**
44
+ * Marks a number as an integer (whole number).
45
+ */
46
+ export type WithInteger = number & (UsePlainPrimitives extends true ? {} : Integer);
47
+ /**
48
+ * Extract units from a type.
49
+ * @returns The unit string, or never if type has no Units trait.
50
+ */
51
+ export type UnitOf<T> = T extends Unit<infer U> ? U : never;
52
+ /**
53
+ * Extract range from a type as a tuple [Min, Max].
54
+ * @returns [Min, Max] tuple, or never if type has no Range trait.
55
+ */
56
+ export type RangeOf<T> = T extends Range<infer Min, infer Max> ? readonly [Min, Max] : never;
57
+ /**
58
+ * Extract min value from range trait.
59
+ * @returns Min value, or never if type has no Range trait.
60
+ */
61
+ export type MinOf<T> = T extends Range<infer Min, infer _Max> ? Min : never;
62
+ /**
63
+ * Extract max value from range trait.
64
+ * @returns Max value, or never if type has no Range trait.
65
+ */
66
+ export type MaxOf<T> = T extends Range<infer _Min, infer Max> ? Max : never;
67
+ /**
68
+ * Check if a type has the Clamped trait.
69
+ * @returns true if clamped, false if not.
70
+ */
71
+ export type IsClamped<T> = T extends Clamped ? true : false;
72
+ /**
73
+ * Check if a type has the Periodic trait.
74
+ * @returns true if periodic, false if not.
75
+ */
76
+ export type IsPeriodic<T> = T extends Periodic ? true : false;
77
+ /**
78
+ * Extract kind/archetype from a type.
79
+ * @returns The kind string, or never if type has no Kind trait.
80
+ */
81
+ export type KindOf<T> = T extends Kind<infer K> ? K : never;
82
+ /**
83
+ * Remove the Clamped trait from a type (return to unclamped).
84
+ */
85
+ export type WithoutClamped<T> = T extends Clamped ? Omit<T, '_clamped'> : T;
86
+ /**
87
+ * Remove the Periodic trait from a type.
88
+ */
89
+ export type WithoutPeriodic<T> = T extends Periodic ? Omit<T, '_periodic'> : T;
90
+ /**
91
+ * Change the units of a type (unit conversion).
92
+ */
93
+ export type ChangeUnits<T, U extends string> = Omit<T, '_unit'> & WithUnit<U>;
94
+ /**
95
+ * Change the range of a type.
96
+ */
97
+ export type ChangeRange<T, Min extends number, Max extends number> = Omit<T, '_range'> & WithRange<Min, Max>;
98
+ /**
99
+ * Clamp a value to specified bounds, preserve orthogonal traits, and mark as clamped.
100
+ */
101
+ export declare function clamp<T extends number, Min extends number, Max extends number>(value: T, min: Min, max: Max): WithRange<Min, Max> & WithClamped;
102
+ /**
103
+ * Wrap a value to specified bounds, preserve orthogonal traits, and mark as periodic.
104
+ */
105
+ export declare function wrap<T, Min extends number, Max extends number>(value: T, min: Min, max: Max): Omit<T, '_range' | '_periodic'> & WithRange<Min, Max> & WithPeriodic;
106
+ export {};
107
+ //# sourceMappingURL=trait-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trait-utils.d.ts","sourceRoot":"","sources":["../src/trait-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * ���️ Legacy Traits Module
3
+ *
4
+ * This file provides backward compatibility for imports from './traits'.
5
+ * Most functionality has been migrated to:
6
+ * - trait-utils.ts: Core trait infrastructure
7
+ * - units/*.ts: Individual unit type definitions
8
+ */
9
+ export type { WithUnit, WithRange, WithClamped, WithPeriodic, WithKind, UnitOf, RangeOf, MinOf, MaxOf, IsClamped, IsPeriodic, KindOf, WithoutClamped, WithoutPeriodic, ChangeUnits, ChangeRange, } from './trait-utils';
10
+ export { clamp, wrap } from './trait-utils';
11
+ export type { Normalized, SignedNormalized, Percentage, ClampedNormalized, Alpha, Ratio, Factor, NormalizedTime, NormalizedProgress, PercentProgress, } from './units/normalized';
12
+ export type { Degrees, Radians, Turns } from './units/angle';
13
+ export type { Pixels } from './units/length';
14
+ //# sourceMappingURL=traits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traits.d.ts","sourceRoot":"","sources":["../src/traits.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,YAAY,EACV,QAAQ,EACR,SAAS,EACT,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,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,EACV,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,KAAK,EACL,KAAK,EACL,MAAM,EACN,cAAc,EACd,kBAAkB,EAClB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC7D,YAAY,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC"}