getTypeData = (type, attributes, otherStructLayouts) => {
	type = type.replaceAll(/\s/g, "");
	if (simpleTypes[type] != null) {
		let [align, size, baseType, defaultValue] = simpleTypes[type];
		if (attributes.align != null) {
			align = parseInt(attributes.align);
		}
		if (attributes.size != null) {
			size = parseInt(attributes.size);
		}
		return {
			baseType,
			align,
			size,
			defaultValue,
		};
	} else if (type in otherStructLayouts) {
		const innerLayout = otherStructLayouts[type];
		let { align, size } = innerLayout;
		if (attributes.align != null) {
			align = parseInt(attributes.align);
		}
		if (attributes.size != null) {
			size = parseInt(attributes.size);
		}
		return {
			isStruct: true,
			innerLayout,
			size,
			align,
			defaultValue: () => makeDataForLayout(otherStructLayouts, innerLayout),
		};
	} else if (type.startsWith("array<")) {
		const arrayMatch = type.match(/array<(.*?),?(\d+)?>$/);
		const [_, innerType, fixedSize] = arrayMatch;
		if (innerType == null) {
			return null;
		}
		const elementTypeData = getTypeData(innerType, [], otherStructLayouts);

		const mult = parseInt(fixedSize ?? "0");
		const align = elementTypeData.align;
		let stride = elementTypeData.size;
		if (attributes.stride != null) {
			stride = parseInt(attributes.stride);
		}
		const size = stride * mult;

		return {
			isArray: true,
			isFixedSize: mult > 0,
			elementTypeData,
			mult,
			size,
			align,
			stride,
			defaultValue: () =>
				Array(mult)
					.fill()
					.map((_) => elementTypeData.defaultValue()),
		};
	} else {
		console.warn(`Unrecognized type ${type}.`);
		return null;
	}
}
Meant to conform to the WGSL spec:

https://gpuweb.github.io/gpuweb/wgsl/#alignment-and-size
https://gpuweb.github.io/gpuweb/wgsl/#structure-layout-rules

TODO:
- Put in own repo
- create mocha tests
- Document. Provide examples of the simple constructor and from WGSL