bytecodealliance / jco

JavaScript toolchain for working with WebAssembly Components
https://bytecodealliance.github.io/jco/
Apache License 2.0
642 stars 63 forks source link

Support generating different case enum strings from wit enums #509

Open e-moran opened 1 month ago

e-moran commented 1 month ago

At Arcjet, we use jco to transpile our Wasm components. However, when transpiling enums, jco consistently outputs kebab-cased strings, while our configuration requires SCREAMING_SNAKE_CASE. As a result, we need to convert these enum strings before invoking Wasm using the generated bindings.

After discussing this with @blaine-arcjet, we believe the ideal solution would be to add configurable case options to jco, allowing users to specify the desired case for generated enums. We are happy to work on this feature ourselves and open a pull request, but we wanted to check in with you first to confirm that this is something you'd like to see in jco.

guybedford commented 1 month ago

Just to understand the usage you're referring to, to clarify, where currently we output:

export type SomeEnum = 'value-a' | 'value-b' | 'value-c';

you're wanting a configuration option to alter this to:

export type SomeEnum = 'VALUE_A' | 'VALUE_B' | 'VALUE_C';

Ideally in future, JS would have first-class enums and we could use:

export enum SomeEnum {
  valueA,
  valueB,
  valueC
}

in which case we'd likely have an option to use this feature while it's being developed, including whether or not it should define the values as symbols or kebab strings, but overall we do take a position that customization of these kinds of features isn't something Jco aims to offer as a first-class construct.

Please do let me know if I'm missing anything though.

blaine-arcjet commented 1 month ago

Yep! That's exactly what we're trying to achieve. Using strings in the format of "VALUE_A" helps with interop between Protobuf and other wire protocols with a codegen/compilation step.

Ideally in future, JS would have first-class enums

I thought this was off the table or is it still being discussed for JS? Even most things in TypeScript are moving towards string unions instead of their enum construct.

we do take a position that customization of these kinds of features isn't something Jco aims to offer as a first-class construct.

🤔 If that's the case, why chose "value-a" as your representation, given so many other systems represent enums as "VALUE_A"? Would it be better to change the representation wholesale?

guybedford commented 1 month ago

I was under the impressio that the convention for shout case in JS was usually restricted to top-level constants such as:

const MY_CONST = 'val';

where you might have a const representing an enum value but then you'd pass it by reference like foo(MY_CONST) even though the underlying string value would be foo('wal').

That said the TypeScript docs do have one example of uppercase strings used for enum values. Wondering if you know of any other references here?

In short, the Jco position is to try to go to with the combination of what is expected in the JS ecosystem with where the JS ecosystem is headed.

blaine-arcjet commented 1 month ago

That said the TypeScript docs do have one example of uppercase strings used for enum values. Wondering if you know of any other references here?

It seems that the TypeScript Enum handbook chapter typically uses all caps when the string value will be used. For example, Enums at Compile Time uses all caps for log levels since key strings are being used for access.

I don't think the JavaScript community really has common patterns for enums that aren't just re-implementations of what TypeScript has done for years.