@ogxjs/core 0.1.2 → 0.2.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/cache/hash.d.ts +66 -0
  2. package/dist/cache/hash.d.ts.map +1 -0
  3. package/dist/cache/hash.js +161 -0
  4. package/dist/cache/index.d.ts +10 -0
  5. package/dist/cache/index.d.ts.map +1 -0
  6. package/dist/cache/index.js +12 -0
  7. package/dist/cache/lru.d.ts +122 -0
  8. package/dist/cache/lru.d.ts.map +1 -0
  9. package/dist/cache/lru.js +269 -0
  10. package/dist/cache/snapshot.d.ts +116 -0
  11. package/dist/cache/snapshot.d.ts.map +1 -0
  12. package/dist/cache/snapshot.js +204 -0
  13. package/dist/cache.d.ts +2 -2
  14. package/dist/cache.js +2 -2
  15. package/dist/css.d.ts +19 -6
  16. package/dist/css.d.ts.map +1 -1
  17. package/dist/index.d.ts +17 -3
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +40 -9
  20. package/dist/ogx.js +2 -2
  21. package/dist/perf/index.d.ts +8 -0
  22. package/dist/perf/index.d.ts.map +1 -0
  23. package/dist/perf/index.js +7 -0
  24. package/dist/perf/timing.d.ts +160 -0
  25. package/dist/perf/timing.d.ts.map +1 -0
  26. package/dist/perf/timing.js +305 -0
  27. package/dist/presets/blog.js +1 -1
  28. package/dist/presets/docs.d.ts +2 -0
  29. package/dist/presets/docs.d.ts.map +1 -1
  30. package/dist/presets/docs.js +26 -23
  31. package/dist/presets/minimal.d.ts +2 -0
  32. package/dist/presets/minimal.d.ts.map +1 -1
  33. package/dist/presets/minimal.js +8 -16
  34. package/dist/presets/social.d.ts +2 -0
  35. package/dist/presets/social.d.ts.map +1 -1
  36. package/dist/presets/social.js +28 -18
  37. package/dist/render-png.d.ts.map +1 -1
  38. package/dist/render-png.js +9 -1
  39. package/dist/render-svg.d.ts.map +1 -1
  40. package/dist/render-svg.js +11 -1
  41. package/dist/tailwind/class-cache.d.ts +141 -0
  42. package/dist/tailwind/class-cache.d.ts.map +1 -0
  43. package/dist/tailwind/class-cache.js +212 -0
  44. package/dist/tailwind/index.d.ts +14 -1
  45. package/dist/tailwind/index.d.ts.map +1 -1
  46. package/dist/tailwind/index.js +15 -1
  47. package/dist/tailwind/lookup-tables.d.ts +30 -0
  48. package/dist/tailwind/lookup-tables.d.ts.map +1 -0
  49. package/dist/tailwind/lookup-tables.js +427 -0
  50. package/dist/tailwind/parser-v2.d.ts +54 -0
  51. package/dist/tailwind/parser-v2.d.ts.map +1 -0
  52. package/dist/tailwind/parser-v2.js +250 -0
  53. package/dist/tailwind/parser.d.ts +1 -0
  54. package/dist/tailwind/parser.d.ts.map +1 -1
  55. package/dist/tailwind/parser.js +1 -0
  56. package/dist/tailwind/prefix-handlers.d.ts +68 -0
  57. package/dist/tailwind/prefix-handlers.d.ts.map +1 -0
  58. package/dist/tailwind/prefix-handlers.js +931 -0
  59. package/package.json +17 -2
@@ -1,11 +1,12 @@
1
- import { absolute, h1, img, row, span, stack } from "../builder";
1
+ import { h1, img, row, span, stack } from "../builder";
2
2
  /**
3
3
  * Social preset - card-style for social media
4
4
  */
5
5
  export const socialPreset = (props) => {
6
- const { title, handle, avatar, brand, logo, gradient = "to-br", fromColor = "oklch(65% 0.25 260)", // Vibrant Indigo-ish
6
+ const { title, handle, avatar, brand, logo, colorScheme = "dark", gradient = "to-br", fromColor = "oklch(65% 0.25 260)", // Vibrant Indigo-ish
7
7
  toColor = "oklch(60% 0.3 300)", // Vibrant Purple-ish
8
8
  slots = {}, } = props;
9
+ const isDark = colorScheme === "dark";
9
10
  const gradientStyle = `linear-gradient(${gradient === "to-r"
10
11
  ? "90deg"
11
12
  : gradient === "to-br"
@@ -14,53 +15,62 @@ export const socialPreset = (props) => {
14
15
  ? "180deg"
15
16
  : "225deg"}, ${fromColor}, ${toColor})`;
16
17
  return stack(["w-full", "h-full", "p-20", "relative", "overflow-hidden"], [
17
- // Background Gradient
18
- absolute("", null, { style: { backgroundImage: gradientStyle } }),
19
- // Subtle Background Texture (Grain/Noise-like mesh)
20
- absolute(["inset-0 opacity-20", "bg-grid-white/5-32"]),
21
- absolute(["bg-grain/15"]), // Quality Boost: Dithering
22
- // Content Layout
18
+ // Content Layout (background applied on container to avoid extra layers)
23
19
  stack("flex-1 justify-between relative", [
24
20
  // Header
25
21
  slots.header ??
26
22
  row("items-center justify-between", [
27
23
  row("items-center gap-4", [
28
- logo ? img(logo, "w-12 h-12 rounded-xl bg-zinc-950") : null,
24
+ logo
25
+ ? img(logo, [
26
+ "w-12 h-12 rounded-xl shadow-lg",
27
+ isDark ? "bg-zinc-950" : "bg-white border border-zinc-200",
28
+ ])
29
+ : null,
29
30
  brand
30
- ? span(["text-2xl font-black text-white tracking-tighter"], brand.toUpperCase())
31
+ ? span([
32
+ "text-2xl font-black tracking-tighter",
33
+ isDark ? "text-white" : "text-zinc-950",
34
+ ], brand.toUpperCase())
31
35
  : null,
32
36
  ]),
33
37
  // Subtle platform indicator
34
- span(["text-white/30 text-xs font-bold tracking-widest"], "SOCIAL CARD"),
38
+ span([
39
+ isDark ? "text-white/30" : "text-black/30",
40
+ "text-xs font-bold tracking-widest",
41
+ ], "SOCIAL CARD"),
35
42
  ]),
36
43
  // Main content
37
44
  stack("gap-6 overflow-hidden", [
38
45
  h1([
39
46
  "text-7xl",
40
47
  "font-black",
41
- "text-white",
48
+ isDark ? "text-white" : "text-zinc-950",
42
49
  "leading-[1.05]",
43
- "tracking-tight", // Quality Boost
50
+ "tracking-tight",
44
51
  ], title),
45
52
  ]),
46
53
  // Footer with user info (Clean Glass Badge)
47
54
  slots.footer ??
48
55
  (handle || avatar
49
56
  ? row([
50
- "items-center gap-4 p-3 pr-6 rounded-full self-start shadow-premium",
51
- "bg-black/10 border border-white/10 backdrop-blur-md",
57
+ "items-center gap-4 p-3 pr-6 rounded-full self-start shadow-lg",
58
+ isDark
59
+ ? "bg-black/20 border border-white/20"
60
+ : "bg-white/40 border border-black/10",
52
61
  ], [
53
62
  avatar
54
63
  ? img(avatar, "w-10 h-10 rounded-full border border-white/20 shadow-sm")
55
64
  : null,
56
65
  handle
57
66
  ? span([
58
- "text-xl font-bold text-white/90 tracking-tight",
59
- "w-fit truncate shrink-0",
67
+ "text-xl font-bold tracking-tight",
68
+ isDark ? "text-white/90" : "text-zinc-900/90",
69
+ "truncate",
60
70
  ], handle)
61
71
  : null,
62
72
  ])
63
73
  : null),
64
74
  ]),
65
- ]);
75
+ ], { style: { backgroundImage: gradientStyle } });
66
76
  };
@@ -1 +1 @@
1
- {"version":3,"file":"render-png.d.ts","sourceRoot":"","sources":["../src/render-png.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEzD;;;GAGG;AACH,wBAAsB,MAAM,CAC3B,OAAO,EAAE,UAAU,EACnB,OAAO,GAAE,aAAkB,GACzB,OAAO,CAAC,UAAU,CAAC,CAiBrB"}
1
+ {"version":3,"file":"render-png.d.ts","sourceRoot":"","sources":["../src/render-png.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEzD;;;GAGG;AACH,wBAAsB,MAAM,CAC3B,OAAO,EAAE,UAAU,EACnB,OAAO,GAAE,aAAkB,GACzB,OAAO,CAAC,UAAU,CAAC,CA8BrB"}
@@ -4,7 +4,10 @@ import { renderToSVG } from "./render-svg";
4
4
  * Node.js only: uses @resvg/resvg-js for SVG → PNG conversion
5
5
  */
6
6
  export async function render(element, options = {}) {
7
+ const profile = process.env.OGX_PROFILE === "1";
8
+ const tStart = profile ? performance.now() : 0;
7
9
  const svg = await renderToSVG(element, options);
10
+ const tAfterSvg = profile ? performance.now() : 0;
8
11
  const width = options.width ?? 1200;
9
12
  const resvgPkg = "@resvg/resvg-js";
10
13
  const { Resvg } = await import(resvgPkg);
@@ -15,5 +18,10 @@ export async function render(element, options = {}) {
15
18
  },
16
19
  });
17
20
  const pngData = resvg.render();
18
- return pngData.asPng();
21
+ const result = pngData.asPng();
22
+ if (profile) {
23
+ const tEnd = performance.now();
24
+ console.log(`[OGX PROFILE] render png: svg=${(tAfterSvg - tStart).toFixed(2)}ms resvg=${(tEnd - tAfterSvg).toFixed(2)}ms total=${(tEnd - tStart).toFixed(2)}ms`);
25
+ }
26
+ return result;
19
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"render-svg.d.ts","sourceRoot":"","sources":["../src/render-svg.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEX,UAAU,EACV,aAAa,EAEb,MAAM,SAAS,CAAC;AAKjB;;;GAGG;AACH,wBAAsB,WAAW,CAChC,OAAO,EAAE,UAAU,EACnB,OAAO,GAAE,aAAkB,GACzB,OAAO,CAAC,MAAM,CAAC,CA2CjB"}
1
+ {"version":3,"file":"render-svg.d.ts","sourceRoot":"","sources":["../src/render-svg.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEX,UAAU,EACV,aAAa,EAEb,MAAM,SAAS,CAAC;AAKjB;;;GAGG;AACH,wBAAsB,WAAW,CAChC,OAAO,EAAE,UAAU,EACnB,OAAO,GAAE,aAAkB,GACzB,OAAO,CAAC,MAAM,CAAC,CAyDjB"}
@@ -9,6 +9,8 @@ const DEFAULT_HEIGHT = 630;
9
9
  * Browser-safe: uses only Satori (no Node.js dependencies)
10
10
  */
11
11
  export async function renderToSVG(element, options = {}) {
12
+ const profile = process.env.OGX_PROFILE === "1";
13
+ const tStart = profile ? performance.now() : 0;
12
14
  const platformDims = options.platform
13
15
  ? getPlatformDimensions(options.platform)
14
16
  : null;
@@ -35,13 +37,21 @@ export async function renderToSVG(element, options = {}) {
35
37
  theme: options.theme,
36
38
  colorScheme: options.colorScheme,
37
39
  };
40
+ const tTransformStart = profile ? performance.now() : 0;
38
41
  const transformedElement = transformElement(element, debug, fullOptions);
39
- return await satori(transformedElement, {
42
+ const tTransformEnd = profile ? performance.now() : 0;
43
+ const svg = await satori(transformedElement, {
40
44
  width,
41
45
  height,
42
46
  fonts: resolvedFonts.map(fontToSatoriFont),
43
47
  debug,
44
48
  });
49
+ if (profile) {
50
+ const tEnd = performance.now();
51
+ // Log coarse-grained timings for debugging hot paths
52
+ console.log(`[OGX PROFILE] renderToSVG transform=${(tTransformEnd - tTransformStart).toFixed(2)}ms satori=${(tEnd - tTransformEnd).toFixed(2)}ms total=${(tEnd - tStart).toFixed(2)}ms`);
53
+ }
54
+ return svg;
45
55
  }
46
56
  /**
47
57
  * Transform OGX element tree to Satori-compatible format
@@ -0,0 +1,141 @@
1
+ /**
2
+ * @ogxjs/core - Tailwind Class Cache
3
+ * Per-class caching for maximum performance
4
+ *
5
+ * @description
6
+ * Caches individual parsed classes instead of full class strings.
7
+ * This allows reuse across different elements with overlapping classes.
8
+ *
9
+ * @example
10
+ * Element A: "flex bg-blue-500 p-4"
11
+ * Element B: "flex bg-red-500 p-4"
12
+ * → "flex" and "p-4" are parsed once, reused for both
13
+ *
14
+ * @performance
15
+ * - Eliminates redundant parsing for common classes
16
+ * - Reduces memory by sharing parsed results
17
+ * - O(1) lookup per class
18
+ *
19
+ * @version 0.2.0 "Turbo"
20
+ */
21
+ import type { CSSProperties } from "../css";
22
+ /**
23
+ * Cache for individual parsed Tailwind classes
24
+ * Key: class name (e.g., "bg-blue-500")
25
+ * Value: parsed CSS properties
26
+ *
27
+ * @performance v0.2.0 Turbo optimizations:
28
+ * - Direct reference return (no spread copy) - trust consumers
29
+ * - No Object.freeze - avoid expensive operation
30
+ * - Lazy eviction check
31
+ */
32
+ declare class TailwindClassCache {
33
+ private cache;
34
+ private hits;
35
+ private misses;
36
+ /**
37
+ * Get cached CSS properties for a class
38
+ * @returns Cached properties or undefined if not cached
39
+ *
40
+ * @performance Returns direct reference - DO NOT MUTATE
41
+ */
42
+ get(cls: string): CSSProperties | undefined;
43
+ /**
44
+ * Cache CSS properties for a class
45
+ * @param cls - Tailwind class name
46
+ * @param props - Parsed CSS properties (will be stored directly)
47
+ */
48
+ set(cls: string, props: CSSProperties): void;
49
+ /**
50
+ * Check if a class has cached properties
51
+ */
52
+ has(cls: string): boolean;
53
+ /**
54
+ * Clear the entire cache
55
+ */
56
+ clear(): void;
57
+ /**
58
+ * Get cache statistics
59
+ */
60
+ getStats(): CacheStats;
61
+ /**
62
+ * Check if a class should not be cached
63
+ */
64
+ private isUncacheable;
65
+ /**
66
+ * Evict oldest entries (FIFO strategy)
67
+ * Removes 10% of cache to avoid frequent evictions
68
+ */
69
+ private evictOldest;
70
+ }
71
+ /**
72
+ * Cache for full class strings (entire tw prop)
73
+ * Useful when the same exact class string is used multiple times
74
+ *
75
+ * Key: "flex bg-blue-500 p-4"
76
+ * Value: merged CSS properties
77
+ *
78
+ * @performance v0.2.0 Turbo optimizations:
79
+ * - Direct reference return (no spread copy)
80
+ * - No Object.freeze
81
+ * - Efficient LRU-like eviction
82
+ */
83
+ declare class TailwindStringCache {
84
+ private cache;
85
+ private maxSize;
86
+ /**
87
+ * Get cached properties for a full class string
88
+ * @performance Returns direct reference - DO NOT MUTATE
89
+ */
90
+ get(key: string): CSSProperties | undefined;
91
+ /**
92
+ * Cache properties for a full class string
93
+ */
94
+ set(key: string, props: CSSProperties): void;
95
+ /**
96
+ * Check if a string has cached properties
97
+ */
98
+ has(key: string): boolean;
99
+ /**
100
+ * Clear the cache
101
+ */
102
+ clear(): void;
103
+ /**
104
+ * Get cache size
105
+ */
106
+ get size(): number;
107
+ }
108
+ export interface CacheStats {
109
+ /** Current number of cached classes */
110
+ size: number;
111
+ /** Maximum cache size */
112
+ maxSize: number;
113
+ /** Number of cache hits */
114
+ hits: number;
115
+ /** Number of cache misses */
116
+ misses: number;
117
+ /** Hit rate (0-1) */
118
+ hitRate: number;
119
+ }
120
+ /**
121
+ * Singleton instance for class-level caching
122
+ */
123
+ export declare const classCache: TailwindClassCache;
124
+ /**
125
+ * Singleton instance for full string caching
126
+ */
127
+ export declare const stringCache: TailwindStringCache;
128
+ /**
129
+ * Clear all Tailwind caches
130
+ * Useful for testing or when theme changes
131
+ */
132
+ export declare function clearAllCaches(): void;
133
+ /**
134
+ * Get combined cache statistics
135
+ */
136
+ export declare function getCacheStats(): {
137
+ classCache: CacheStats;
138
+ stringCacheSize: number;
139
+ };
140
+ export {};
141
+ //# sourceMappingURL=class-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"class-cache.d.ts","sourceRoot":"","sources":["../../src/tailwind/class-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAmB5C;;;;;;;;;GASG;AACH,cAAM,kBAAkB;IACvB,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;IAEnB;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAU3C;;;;OAIG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI;IAa5C;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,QAAQ,IAAI,UAAU;IAWtB;;OAEG;IACH,OAAO,CAAC,aAAa;IAIrB;;;OAGG;IACH,OAAO,CAAC,WAAW;CAUnB;AAID;;;;;;;;;;;GAWG;AACH,cAAM,mBAAmB;IACxB,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,OAAO,CAAQ;IAEvB;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI3C;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI;IAe5C;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACD;AAID,MAAM,WAAW,UAAU;IAC1B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;CAChB;AAID;;GAEG;AACH,eAAO,MAAM,UAAU,oBAA2B,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,WAAW,qBAA4B,CAAC;AAErD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAGrC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI;IAChC,UAAU,EAAE,UAAU,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACxB,CAKA"}
@@ -0,0 +1,212 @@
1
+ /**
2
+ * @ogxjs/core - Tailwind Class Cache
3
+ * Per-class caching for maximum performance
4
+ *
5
+ * @description
6
+ * Caches individual parsed classes instead of full class strings.
7
+ * This allows reuse across different elements with overlapping classes.
8
+ *
9
+ * @example
10
+ * Element A: "flex bg-blue-500 p-4"
11
+ * Element B: "flex bg-red-500 p-4"
12
+ * → "flex" and "p-4" are parsed once, reused for both
13
+ *
14
+ * @performance
15
+ * - Eliminates redundant parsing for common classes
16
+ * - Reduces memory by sharing parsed results
17
+ * - O(1) lookup per class
18
+ *
19
+ * @version 0.2.0 "Turbo"
20
+ */
21
+ // CONFIGURATION
22
+ /**
23
+ * Maximum cache size to prevent memory leaks
24
+ * ~5000 classes × ~200 bytes avg = ~1MB max
25
+ */
26
+ const MAX_CACHE_SIZE = 5000;
27
+ /**
28
+ * Classes to never cache (dynamic/theme-dependent)
29
+ */
30
+ const UNCACHEABLE_PATTERNS = [
31
+ /^dark:/, // Dark mode variants (theme-dependent)
32
+ ];
33
+ // CLASS CACHE
34
+ /**
35
+ * Cache for individual parsed Tailwind classes
36
+ * Key: class name (e.g., "bg-blue-500")
37
+ * Value: parsed CSS properties
38
+ *
39
+ * @performance v0.2.0 Turbo optimizations:
40
+ * - Direct reference return (no spread copy) - trust consumers
41
+ * - No Object.freeze - avoid expensive operation
42
+ * - Lazy eviction check
43
+ */
44
+ class TailwindClassCache {
45
+ cache = new Map();
46
+ hits = 0;
47
+ misses = 0;
48
+ /**
49
+ * Get cached CSS properties for a class
50
+ * @returns Cached properties or undefined if not cached
51
+ *
52
+ * @performance Returns direct reference - DO NOT MUTATE
53
+ */
54
+ get(cls) {
55
+ const cached = this.cache.get(cls);
56
+ if (cached !== undefined) {
57
+ this.hits++;
58
+ return cached; // Direct reference - no copy overhead
59
+ }
60
+ this.misses++;
61
+ return undefined;
62
+ }
63
+ /**
64
+ * Cache CSS properties for a class
65
+ * @param cls - Tailwind class name
66
+ * @param props - Parsed CSS properties (will be stored directly)
67
+ */
68
+ set(cls, props) {
69
+ // Don't cache theme-dependent classes
70
+ if (this.isUncacheable(cls))
71
+ return;
72
+ // Evict oldest entries if cache is full (lazy check)
73
+ if (this.cache.size >= MAX_CACHE_SIZE) {
74
+ this.evictOldest();
75
+ }
76
+ // Store directly - no copy, no freeze
77
+ this.cache.set(cls, props);
78
+ }
79
+ /**
80
+ * Check if a class has cached properties
81
+ */
82
+ has(cls) {
83
+ return this.cache.has(cls);
84
+ }
85
+ /**
86
+ * Clear the entire cache
87
+ */
88
+ clear() {
89
+ this.cache.clear();
90
+ this.hits = 0;
91
+ this.misses = 0;
92
+ }
93
+ /**
94
+ * Get cache statistics
95
+ */
96
+ getStats() {
97
+ const total = this.hits + this.misses;
98
+ return {
99
+ size: this.cache.size,
100
+ maxSize: MAX_CACHE_SIZE,
101
+ hits: this.hits,
102
+ misses: this.misses,
103
+ hitRate: total > 0 ? this.hits / total : 0,
104
+ };
105
+ }
106
+ /**
107
+ * Check if a class should not be cached
108
+ */
109
+ isUncacheable(cls) {
110
+ return UNCACHEABLE_PATTERNS.some((pattern) => pattern.test(cls));
111
+ }
112
+ /**
113
+ * Evict oldest entries (FIFO strategy)
114
+ * Removes 10% of cache to avoid frequent evictions
115
+ */
116
+ evictOldest() {
117
+ const toRemove = Math.ceil(MAX_CACHE_SIZE * 0.1);
118
+ const iterator = this.cache.keys();
119
+ for (let i = 0; i < toRemove; i++) {
120
+ const { value, done } = iterator.next();
121
+ if (done)
122
+ break;
123
+ this.cache.delete(value);
124
+ }
125
+ }
126
+ }
127
+ // FULL STRING CACHE
128
+ /**
129
+ * Cache for full class strings (entire tw prop)
130
+ * Useful when the same exact class string is used multiple times
131
+ *
132
+ * Key: "flex bg-blue-500 p-4"
133
+ * Value: merged CSS properties
134
+ *
135
+ * @performance v0.2.0 Turbo optimizations:
136
+ * - Direct reference return (no spread copy)
137
+ * - No Object.freeze
138
+ * - Efficient LRU-like eviction
139
+ */
140
+ class TailwindStringCache {
141
+ cache = new Map();
142
+ maxSize = 1000;
143
+ /**
144
+ * Get cached properties for a full class string
145
+ * @performance Returns direct reference - DO NOT MUTATE
146
+ */
147
+ get(key) {
148
+ return this.cache.get(key);
149
+ }
150
+ /**
151
+ * Cache properties for a full class string
152
+ */
153
+ set(key, props) {
154
+ if (this.cache.size >= this.maxSize) {
155
+ // Simple eviction: delete oldest entries (first 20%)
156
+ const toRemove = Math.ceil(this.maxSize * 0.2);
157
+ const iterator = this.cache.keys();
158
+ for (let i = 0; i < toRemove; i++) {
159
+ const { value, done } = iterator.next();
160
+ if (done)
161
+ break;
162
+ this.cache.delete(value);
163
+ }
164
+ }
165
+ // Store directly - no copy, no freeze
166
+ this.cache.set(key, props);
167
+ }
168
+ /**
169
+ * Check if a string has cached properties
170
+ */
171
+ has(key) {
172
+ return this.cache.has(key);
173
+ }
174
+ /**
175
+ * Clear the cache
176
+ */
177
+ clear() {
178
+ this.cache.clear();
179
+ }
180
+ /**
181
+ * Get cache size
182
+ */
183
+ get size() {
184
+ return this.cache.size;
185
+ }
186
+ }
187
+ // EXPORTS
188
+ /**
189
+ * Singleton instance for class-level caching
190
+ */
191
+ export const classCache = new TailwindClassCache();
192
+ /**
193
+ * Singleton instance for full string caching
194
+ */
195
+ export const stringCache = new TailwindStringCache();
196
+ /**
197
+ * Clear all Tailwind caches
198
+ * Useful for testing or when theme changes
199
+ */
200
+ export function clearAllCaches() {
201
+ classCache.clear();
202
+ stringCache.clear();
203
+ }
204
+ /**
205
+ * Get combined cache statistics
206
+ */
207
+ export function getCacheStats() {
208
+ return {
209
+ classCache: classCache.getStats(),
210
+ stringCacheSize: stringCache.size,
211
+ };
212
+ }
@@ -1,2 +1,15 @@
1
- export { borderRadius, colors, fontSize, fontWeight, opacity, parseTailwind, spacing, } from "./parser";
1
+ /**
2
+ * @ogxjs/core - Tailwind Module
3
+ * High-performance Tailwind CSS parser
4
+ *
5
+ * @version 0.2.0 "Turbo"
6
+ */
7
+ export type { CacheStats } from "./class-cache";
8
+ export { classCache, stringCache } from "./class-cache";
9
+ export { colors } from "./colors";
10
+ export { getStaticClass, isStaticClass, STATIC_CLASSES } from "./lookup-tables";
11
+ export { clearAllCaches, getCacheStats, parseTailwind, parseTailwindBatch, } from "./parser-v2";
12
+ export type { GradientState, ParseContext } from "./prefix-handlers";
13
+ export { ORDERED_PREFIXES, PREFIX_HANDLERS, parseSpacingValue, resolveColorValue, } from "./prefix-handlers";
14
+ export { borderRadius, fontSize, fontWeight, opacity, spacing } from "./scales";
2
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tailwind/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,EACZ,MAAM,EACN,QAAQ,EACR,UAAU,EACV,OAAO,EACP,aAAa,EACb,OAAO,GACP,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tailwind/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEhF,OAAO,EACN,cAAc,EACd,aAAa,EACb,aAAa,EACb,kBAAkB,GAClB,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EACN,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC"}
@@ -1 +1,15 @@
1
- export { borderRadius, colors, fontSize, fontWeight, opacity, parseTailwind, spacing, } from "./parser";
1
+ /**
2
+ * @ogxjs/core - Tailwind Module
3
+ * High-performance Tailwind CSS parser
4
+ *
5
+ * @version 0.2.0 "Turbo"
6
+ */
7
+ export { classCache, stringCache } from "./class-cache";
8
+ export { colors } from "./colors";
9
+ // Advanced exports for customization
10
+ export { getStaticClass, isStaticClass, STATIC_CLASSES } from "./lookup-tables";
11
+ // Main parser (v2 with O(1) lookups)
12
+ export { clearAllCaches, getCacheStats, parseTailwind, parseTailwindBatch, } from "./parser-v2";
13
+ export { ORDERED_PREFIXES, PREFIX_HANDLERS, parseSpacingValue, resolveColorValue, } from "./prefix-handlers";
14
+ // Scales and values
15
+ export { borderRadius, fontSize, fontWeight, opacity, spacing } from "./scales";
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @ogxjs/core - Tailwind Lookup Tables
3
+ * O(1) lookup for static classes (no dynamic values)
4
+ *
5
+ * @description
6
+ * This module provides instant lookup for ~200+ static Tailwind classes.
7
+ * Instead of iterating through if/else chains, we use Map for O(1) access.
8
+ *
9
+ * @performance
10
+ * - Before: O(n) where n = number of if/else conditions (~100)
11
+ * - After: O(1) constant time lookup
12
+ *
13
+ * @version 0.2.0 "Turbo"
14
+ */
15
+ import type { CSSProperties } from "../css";
16
+ /**
17
+ * Static classes that map directly to CSS properties
18
+ * No parsing needed - just lookup and return
19
+ */
20
+ export declare const STATIC_CLASSES: Map<string, CSSProperties>;
21
+ /**
22
+ * Check if a class is static (can be looked up directly)
23
+ */
24
+ export declare function isStaticClass(cls: string): boolean;
25
+ /**
26
+ * Get CSS properties for a static class
27
+ * Returns undefined if not a static class
28
+ */
29
+ export declare function getStaticClass(cls: string): CSSProperties | undefined;
30
+ //# sourceMappingURL=lookup-tables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lookup-tables.d.ts","sourceRoot":"","sources":["../../src/tailwind/lookup-tables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C;;;GAGG;AACH,eAAO,MAAM,cAAc,4BAsdzB,CAAC;AAEH;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAErE"}