Skip to content

Commit

Permalink
Memoize hash function (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
zoontek authored Jan 13, 2025
1 parent 7edfaab commit 12b2863
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 22 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@swan-io/css",
"version": "0.1.1",
"version": "0.1.2",
"license": "MIT",
"description": "A lightweight and performant atomic CSS-in-JS library",
"author": "Mathieu Acthernoene <[email protected]>",
Expand Down
4 changes: 4 additions & 0 deletions src/hash.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import rawHash from "@emotion/hash";
import { memoize } from "./utils";

export const hash = memoize(rawHash);
13 changes: 5 additions & 8 deletions src/hyphenateName.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
// https://github.com/facebook/react/blob/v19.0.0/packages/react-dom-bindings/src/shared/hyphenateStyleName.js

const uppercasePattern = /([A-Z])/g;
const hyphenateNameCache: Record<string, string> = {};
import { memoize } from "./utils";

export const hyphenateName = (name: string): string => {
hyphenateNameCache[name] ??= name
.replace(uppercasePattern, "-$1")
.toLowerCase();
const uppercasePattern = /([A-Z])/g;

return hyphenateNameCache[name];
};
export const hyphenateName = memoize((name: string): string =>
name.replace(uppercasePattern, "-$1").toLowerCase(),
);
13 changes: 5 additions & 8 deletions src/normalizeValue.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import normalizeColor from "@react-native/normalize-colors";
import { Property } from "./types";

const normalizeValueCache: Record<string, string> = {};
const normalizeValueCache: Record<string, string> = Object.create(null);

/**
* CSS properties which accept numbers but are not in units of "px"
Expand Down Expand Up @@ -64,16 +64,13 @@ const isWebColor = (color: string): boolean =>
color === "inherit" ||
color.indexOf("var(") === 0;

export const normalizeValue = (
value: string | number | undefined,
property: string,
): string | undefined => {
export const normalizeValue = (key: string, value: string | number): string => {
if (typeof value === "number") {
return unitlessProperties.has(property) ? String(value) : `${value}px`;
return unitlessProperties.has(key) ? String(value) : `${value}px`;
}

if (colorProperties.has(property)) {
if (value == null || isWebColor(value)) {
if (colorProperties.has(key)) {
if (isWebColor(value)) {
return value;
}

Expand Down
10 changes: 5 additions & 5 deletions src/sheet.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import hash from "@emotion/hash";
import { hash } from "./hash";
import { hyphenateName } from "./hyphenateName";
import { normalizeValue } from "./normalizeValue";
import { ClassNames, Keyframes, Nestable, Style } from "./types";
Expand Down Expand Up @@ -53,15 +53,15 @@ const insertRule = (sheet: CSSMediaRule, rule: string): void => {
}
};

const stringifyRule = (name: string, value: string | number): string => {
if (name === "appearance") {
const stringifyRule = (key: string, value: string | number): string => {
if (key === "appearance") {
return `-webkit-appearance: ${value}; appearance: ${value};`;
}
if (name === "lineClamp") {
if (key === "lineClamp") {
return `-webkit-line-clamp: ${value}; line-clamp: ${value};`;
}

return `${hyphenateName(name)}: ${normalizeValue(value, name)};`;
return `${hyphenateName(key)}: ${normalizeValue(key, value)};`;
};

const extractClassNames = (items: ClassNames, acc: string[]): string[] => {
Expand Down
12 changes: 12 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,15 @@ export const forEach = <T extends Record<PropertyKey, unknown>>(
}
}
};

export const memoize = <T>(fn: (arg: string) => T) => {
const cache: Record<string, T> = Object.create(null);

return (arg: string): T => {
if (cache[arg] == null) {
cache[arg] = fn(arg);
}

return cache[arg];
};
};

0 comments on commit 12b2863

Please sign in to comment.