Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements/stylecaching #371

Merged
merged 2 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bambooapp/bamboo-molecules",
"version": "0.3.74",
"version": "0.3.75",
"repository": {
"type": "git",
"url": "git+https://github.com/webbeetechnologies/bamboo-molecules.git"
Expand Down Expand Up @@ -73,6 +73,7 @@
"lodash.noop": "^3.0.1",
"lodash.omit": "^4.5.0",
"lodash.omitby": "^4.6.0",
"lru-cache": "^11.0.2",
"react-native-actions-sheet": "^0.8.10",
"react-native-mask-input": "^1.2.2",
"react-native-super-grid": "^5.0.0",
Expand Down
95 changes: 49 additions & 46 deletions src/utils/normalizeStyles.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,73 @@
import type { StyleProp } from 'react-native';
import type { MD3Theme, MD3Typescale } from '../core/theme/types';
import { allArgumentResolver, createMemoizedFunction, get } from './lodash';
import { get, allArgumentResolver } from './lodash'; // Assuming you have a `get` utility function

export const maybeIsToken = (value: any) => typeof value === 'string' && value.includes('.');
import { LRUCache } from 'lru-cache';

const normalizeStylesMemo = createMemoizedFunction({
/**
*
* @param styles the style object to normalize
* @param currentTheme for switching between themes
* @param cacheKey to resolve unique values for different components
*/
resolver: (
styles: StyleProp<any> | StyleProp<any>[],
{ themeName }: MD3Theme,
cacheKey: string,
) => `${cacheKey}_${themeName}_${allArgumentResolver(styles)}`,
const cache = new LRUCache({
max: 1000,
});

export const maybeIsToken = (value: any) => typeof value === 'string' && value.includes('.');

const flattenTypescale = (style: Partial<Record<string, any> & { typescale: MD3Typescale }>) => {
if ('typescale' in style) {
const { typescale = {}, ...rest } = style;
style = { ...rest, ...typescale };
}

return style;
};

// normalize tokens inside the styles object and the subsequent objects inside it
const normalizeStyles = normalizeStylesMemo(
/**
*
* @param styles the style object to normalize
* @param currentTheme for switching between themes
* @param cacheKey to resolve unique values for different components
*/
(styles: StyleProp<any> | StyleProp<any>[], currentTheme: MD3Theme, cacheKey: string) => {
// if the styles is an array, we want to normalize each entry
if (Array.isArray(styles)) {
return styles.map(styleObj => normalizeStyles(styleObj, currentTheme, cacheKey));
}
/**
*
* @param styles the style object to normalize
* @param currentTheme for switching between themes
* @param cacheKey to resolve unique values for different components
*/
function normalizeStyles(
styles: StyleProp<any> | StyleProp<any>[],
currentTheme: MD3Theme,
_cacheKey: string,
): any {
// Generate a unique cache key
const cacheKey = `${_cacheKey}_${currentTheme.themeName}_${allArgumentResolver(styles)}`;

if (!styles) {
return undefined;
}
// Check if the result is cached
if (cache.has(cacheKey)) {
return cache.get(cacheKey);
}

const newStyles = Object.assign({}, styles);
// Proceed to normalize styles
let normalizedStyles;
if (Array.isArray(styles)) {
// if the styles is an array, we want to normalize each entry
normalizedStyles = styles.map(styleObj =>
normalizeStyles(styleObj, currentTheme, cacheKey),
);
} else if (!styles) {
normalizedStyles = undefined;
} else {
const newStyles = { ...styles };

const normalizableProperties = [];
for (const key in styles) {
if (maybeIsToken(styles[key]) || typeof styles[key] === 'object') {
normalizableProperties.push(key);
for (const [key, value] of Object.entries(newStyles)) {
if (maybeIsToken(value)) {
// Replace token with actual value from theme
newStyles[key] = get(currentTheme, value as string, '');
} else if (typeof value === 'object' && value !== null) {
// it's an object // we want to normalize everything inside it as well
newStyles[key] = normalizeStyles(value, currentTheme, cacheKey);
}
// Primitive values (numbers, booleans, etc.) are left as is
}

normalizableProperties.forEach(key => {
if (typeof newStyles[key] === 'string') {
newStyles[key] = get(currentTheme, newStyles[key], '');
} else {
// it's an object // we want to normalize everything inside it as well
newStyles[key] = normalizeStyles(newStyles[key], currentTheme, cacheKey);
}
});
normalizedStyles = flattenTypescale(newStyles);
}

// Cache the result
cache.set(cacheKey, normalizedStyles);

return flattenTypescale(newStyles);
},
);
return normalizedStyles;
}

export default normalizeStyles;
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3475,6 +3475,7 @@ __metadata:
lodash.noop: ^3.0.1
lodash.omit: ^4.5.0
lodash.omitby: ^4.6.0
lru-cache: ^11.0.2
prettier: ^2.7.1
react: ^18.2.0
react-dom: ^18.2.0
Expand Down Expand Up @@ -20856,6 +20857,13 @@ __metadata:
languageName: node
linkType: hard

"lru-cache@npm:^11.0.2":
version: 11.0.2
resolution: "lru-cache@npm:11.0.2"
checksum: f9c27c58919a30f42834de9444de9f75bcbbb802c459239f96dd449ad880d8f9a42f51556d13659864dc94ab2dbded9c4a4f42a3e25a45b6da01bb86111224df
languageName: node
linkType: hard

"lru-cache@npm:^5.1.1":
version: 5.1.1
resolution: "lru-cache@npm:5.1.1"
Expand Down
Loading