Skip to content

Commit

Permalink
fix: prettier in scripts and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bbohlender committed Mar 6, 2024
1 parent 1b76104 commit 495d419
Show file tree
Hide file tree
Showing 4 changed files with 324 additions and 352 deletions.
4 changes: 2 additions & 2 deletions packages/uikit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
"inline-wasm": "wasmwrap --include-decode false --input node_modules/yoga-wasm-web/dist/yoga.wasm --output src/flex/wasm.ts",
"fix:inline-wasm": "replace-in-files --string 'const base64 =' --replacement 'const base64: string =' src/flex/wasm.ts",
"generate": "node --loader ts-node/esm scripts/flex-generate-setter.ts",
"check:prettier": "prettier --check src",
"check:prettier": "prettier --check src scripts tests",
"check:eslint": "eslint 'src/**/*.{tsx,ts}'",
"fix:prettier": "prettier --write src",
"fix:prettier": "prettier --write src scripts tests",
"fix:eslint": "eslint 'src/**/*.{tsx,ts}' --fix"
},
"peerDependencies": {
Expand Down
207 changes: 94 additions & 113 deletions packages/uikit/scripts/flex-generate-setter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { writeFileSync } from "fs";
import { writeFileSync } from 'fs'
import {
EDGE_BOTTOM,
EDGE_LEFT,
Expand All @@ -9,191 +9,172 @@ import {
UNIT_PERCENT,
UNIT_POINT,
UNIT_UNDEFINED,
} from "yoga-wasm-web";
import { GUTTER_ROW, GUTTER_COLUMN } from "yoga-wasm-web";
import { loadYogaBase64 } from "../src/flex/load-base64.js";
} from 'yoga-wasm-web'
import { GUTTER_ROW, GUTTER_COLUMN } from 'yoga-wasm-web'
import { loadYogaBase64 } from '../src/flex/load-base64.js'

async function main() {
const yoga = await loadYogaBase64();
const node = yoga.Node.create();
const yoga = await loadYogaBase64()
const node = yoga.Node.create()

const propertiesWithEdge = new Set(["border", "padding", "margin", "position"]);
const propertiesWithGutter = new Set(["gap"]);
const propertiesWithoutPointUnit = new Set(["aspectRatio", "flexGrow", "flexShrink"]);
const propertiesWithEdge = new Set(['border', 'padding', 'margin', 'position'])
const propertiesWithGutter = new Set(['gap'])
const propertiesWithoutPointUnit = new Set(['aspectRatio', 'flexGrow', 'flexShrink'])

const enumsToPrefix: { [key in string]: string } = {
alignContent: "ALIGN_",
alignItems: "ALIGN_",
alignSelf: "ALIGN_",
display: "DISPLAY_",
flexDirection: "FLEX_DIRECTION_",
flexWrap: "WRAP_",
justifyContent: "JUSTIFY_",
overflow: "OVERFLOW_",
positionType: "POSITION_TYPE_",
};
alignContent: 'ALIGN_',
alignItems: 'ALIGN_',
alignSelf: 'ALIGN_',
display: 'DISPLAY_',
flexDirection: 'FLEX_DIRECTION_',
flexWrap: 'WRAP_',
justifyContent: 'JUSTIFY_',
overflow: 'OVERFLOW_',
positionType: 'POSITION_TYPE_',
}

const edgeMap = {
Top: EDGE_TOP,
Left: EDGE_LEFT,
Right: EDGE_RIGHT,
Bottom: EDGE_BOTTOM,
};
}
const gutterMap = {
Row: GUTTER_ROW,
Column: GUTTER_COLUMN,
};
const yogaKeys = Object.entries(yoga);
}
const yogaKeys = Object.entries(yoga)

const kebabCaseFromSnakeCase = (str: string) =>
str.toLowerCase().replace(/_[a-z]/g, (letter) => `-${letter.slice(1)}`);
str.toLowerCase().replace(/_[a-z]/g, (letter) => `-${letter.slice(1)}`)

const nodeKeys = Object.keys(Object.getPrototypeOf(node));
const nodeKeys = Object.keys(Object.getPrototypeOf(node))

const properties = nodeKeys
.filter(
(keyName) =>
keyName.startsWith("get") &&
!keyName.includes("Child") &&
!keyName.includes("Parent") &&
!keyName.startsWith("getComputed"),
keyName.startsWith('get') &&
!keyName.includes('Child') &&
!keyName.includes('Parent') &&
!keyName.startsWith('getComputed'),
)
.map<[string, string]>((fnName) => {
const baseFnName = fnName.slice("get".length);
const propertyName = `${baseFnName.charAt(0).toLowerCase()}${baseFnName.slice(1)}`;
return [propertyName, baseFnName];
});
const lookupTables = new Map<string, string>();
const importedTypesFromYoga = new Set<string>();
const setterFunctions: Array<[string, string]> = [];
const baseFnName = fnName.slice('get'.length)
const propertyName = `${baseFnName.charAt(0).toLowerCase()}${baseFnName.slice(1)}`
return [propertyName, baseFnName]
})
const lookupTables = new Map<string, string>()
const importedTypesFromYoga = new Set<string>()
const setterFunctions: Array<[string, string]> = []
for (const [propertyName, functionName] of properties) {
const enumPrefix = enumsToPrefix[propertyName];
let convertFunction: (
defaultValue: string | number | null,
setter: (value?: string) => string,
) => string;
let types: Array<string>;
const enumPrefix = enumsToPrefix[propertyName]
let convertFunction: (defaultValue: string | number | null, setter: (value?: string) => string) => string
let types: Array<string>
if (enumPrefix != null) {
const enums = yogaKeys.filter(([key]) => key.startsWith(enumPrefix));
const lutName = `${enumPrefix}LUT`;
const enums = yogaKeys.filter(([key]) => key.startsWith(enumPrefix))
const lutName = `${enumPrefix}LUT`
if (!lookupTables.has(lutName)) {
lookupTables.set(
lutName,
createLookupTable(
lutName,
enums.map(([name, value]) => [
kebabCaseFromSnakeCase(name.slice(enumPrefix.length)),
value as any,
name,
]),
enums.map(([name, value]) => [kebabCaseFromSnakeCase(name.slice(enumPrefix.length)), value as any, name]),
importedTypesFromYoga,
),
);
)
}
convertFunction = (defaultValue, setter) => {
const enumType = enumPrefix
.slice(0, -1)
.split("_")
.split('_')
.map((split) => split[0] + split.slice(1).toLowerCase())
.join("");
importedTypesFromYoga.add(enumType);
.join('')
importedTypesFromYoga.add(enumType)
return setter(
`convertEnum(${lutName}, input, ${
defaultValue === null || isNaN(defaultValue as any)
? "NaN"
: JSON.stringify(defaultValue)
defaultValue === null || isNaN(defaultValue as any) ? 'NaN' : JSON.stringify(defaultValue)
} as ${enumType})`,
);
};
types = [
...enums.map(([name]) => `"${kebabCaseFromSnakeCase(name.slice(enumPrefix.length))}"`),
"undefined",
];
)
}
types = [...enums.map(([name]) => `"${kebabCaseFromSnakeCase(name.slice(enumPrefix.length))}"`), 'undefined']
} else {
const percentUnit = node[`set${functionName}Percent` as keyof Node] != null;
const autoUnit = node[`set${functionName}Auto` as keyof Node] != null;
const pointUnit = !propertiesWithoutPointUnit.has(propertyName);
types = ["undefined", "number"];
const percentUnit = node[`set${functionName}Percent` as keyof Node] != null
const autoUnit = node[`set${functionName}Auto` as keyof Node] != null
const pointUnit = !propertiesWithoutPointUnit.has(propertyName)
types = ['undefined', 'number']
if (percentUnit) {
types.push("`${number}%`");
types.push('`${number}%`')
}
if (autoUnit) {
types.push(`"auto"`);
types.push(`"auto"`)
}
convertFunction = (defaultValue, setter) => {
const defaultValueString =
defaultValue === null || isNaN(defaultValue as any)
? "NaN"
: JSON.stringify(defaultValue);
defaultValue === null || isNaN(defaultValue as any) ? 'NaN' : JSON.stringify(defaultValue)
return setter(
pointUnit
? `convertPoint(input, precision, ${defaultValueString})${
propertyName === "margin" ? " as number" : ""
}`
? `convertPoint(input, precision, ${defaultValueString})${propertyName === 'margin' ? ' as number' : ''}`
: `input ?? ${defaultValueString}`,
);
};
)
}
}
if (propertiesWithEdge.has(propertyName)) {
for (const [edgeKey, edge] of Object.entries(edgeMap)) {
const defaultValue = fromYoga(
propertyName,
node[`get${functionName}` as "getBorder"](edge),
);
const edgePropertyName = `${propertyName}${edgeKey}`;
const edgeType = `EDGE_${edgeKey.toUpperCase()}`;
importedTypesFromYoga.add(edgeType);
const defaultValue = fromYoga(propertyName, node[`get${functionName}` as 'getBorder'](edge))
const edgePropertyName = `${propertyName}${edgeKey}`
const edgeType = `EDGE_${edgeKey.toUpperCase()}`
importedTypesFromYoga.add(edgeType)
setterFunctions.push([
edgePropertyName,
`(node: Node, precision: number, input: ${types.join(" | ")}) =>
`(node: Node, precision: number, input: ${types.join(' | ')}) =>
${convertFunction(
defaultValue,
(value) => `
node.set${functionName}(${edge} as ${edgeType}, ${value})`,
)}`,
]);
])
}
} else if (propertiesWithGutter.has(propertyName)) {
for (const [gutterKey, gutter] of Object.entries(gutterMap)) {
const defaultValue = fromYoga(propertyName, node[`get${functionName}` as "getGap"](gutter));
const gutterPropertyName = `${propertyName}${gutterKey}`;
const gutterType = `GUTTER_${gutterKey.toUpperCase()}`;
importedTypesFromYoga.add(gutterType);
const defaultValue = fromYoga(propertyName, node[`get${functionName}` as 'getGap'](gutter))
const gutterPropertyName = `${propertyName}${gutterKey}`
const gutterType = `GUTTER_${gutterKey.toUpperCase()}`
importedTypesFromYoga.add(gutterType)
setterFunctions.push([
gutterPropertyName,
`(node: Node, precision: number, input: ${types.join(" | ")}) =>
`(node: Node, precision: number, input: ${types.join(' | ')}) =>
${convertFunction(
defaultValue,
(value) => `
node.set${functionName}(${gutter} as ${gutterType}, ${value})`,
)}`,
]);
])
}
} else {
const defaultValue = fromYoga(propertyName, node[`get${functionName}` as "getWidth"]());
const defaultValue = fromYoga(propertyName, node[`get${functionName}` as 'getWidth']())
setterFunctions.push([
propertyName,
`(node: Node, precision: number, input: ${types.join(" | ")}) =>
`(node: Node, precision: number, input: ${types.join(' | ')}) =>
${convertFunction(
defaultValue,
(value) => `
node.set${functionName}(${value})`,
)}`,
]);
])
}
}

writeFileSync(
"src/flex/setter.ts",
'src/flex/setter.ts',
`import { Node } from "yoga-wasm-web"
import type { ${Array.from(importedTypesFromYoga).join(", ")} } from "yoga-wasm-web"
import type { ${Array.from(importedTypesFromYoga).join(', ')} } from "yoga-wasm-web"
function convertEnum<T extends { [Key in string]: number }>(lut: T, input: keyof T | undefined, defaultValue: T[keyof T]): T[keyof T] {
if(input == null) {
return defaultValue
}
const resolvedValue = lut[input]
if(resolvedValue == null) {
throw new Error(\`unexpected value ${"${input as string}"}, expected ${'${Object.keys(lut).join(", ")}'}\`)
throw new Error(\`unexpected value ${'${input as string}'}, expected ${'${Object.keys(lut).join(", ")}'}\`)
}
return resolvedValue
}
Expand All @@ -203,11 +184,11 @@ async function main() {
}
return input ?? defaultValue
}
${Array.from(lookupTables.values()).join("\n")}
${Array.from(lookupTables.values()).join('\n')}
export const setter = { ${setterFunctions
.map(([propertyName, functionCode]) => `${propertyName}: ${functionCode}`)
.join(",\n")} }`,
);
.join(',\n')} }`,
)
}

function createLookupTable(
Expand All @@ -218,30 +199,30 @@ function createLookupTable(
return `const ${name} = {
${values
.map(([key, value, type]) => {
importedTypesFromYoga.add(type);
return `"${key}": ${value} as ${type}`;
importedTypesFromYoga.add(type)
return `"${key}": ${value} as ${type}`
})
.join(",\n")}
} as const`;
.join(',\n')}
} as const`
}

function fromYoga(name: string, value: any): "auto" | `${number}%` | number | null {
if (typeof value === "object") {
function fromYoga(name: string, value: any): 'auto' | `${number}%` | number | null {
if (typeof value === 'object') {
switch (value.unit) {
case UNIT_AUTO:
return "auto";
return 'auto'
case UNIT_PERCENT:
return `${value.value}%`;
return `${value.value}%`
case UNIT_POINT:
return value.value ?? null;
return value.value ?? null
case UNIT_UNDEFINED:
return null;
return null
}
}
if (typeof value === "number") {
return value;
if (typeof value === 'number') {
return value
}
throw `can't convert value "${JSON.stringify(value)}" for property "${name}" from yoga`;
throw `can't convert value "${JSON.stringify(value)}" for property "${name}" from yoga`
}

main().catch(console.error);
main().catch(console.error)
Loading

0 comments on commit 495d419

Please sign in to comment.